• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            小山日志
            讀書(shū),學(xué)習(xí)與思考.
            posts - 9,comments - 14,trackbacks - 0
            本文譯自codeproject.com,原文鏈接與工具及其源代碼下載點(diǎn)擊這里
            -----------------------------------
            ?導(dǎo)引:WINDOWSX.H頭文件簡(jiǎn)化Win32 SDK編程

            許多的新手或者調(diào)試程序員在編寫(xiě)C/C++的Windows API程序時(shí)都要面對(duì)像意大利面一樣的switch...case代碼塊。當(dāng)你需要加入一個(gè)消息處理到你的窗口處理過(guò)程中時(shí),在些代碼塊中查找例如:WM_COMMANDWM_CHAR,是相當(dāng)讓人恐懼的事情。

            早在Windows 3.1時(shí)代的Windows軟件開(kāi)發(fā)工具包和C/C++7.0編譯器就附帶一個(gè)包含一千多行Windows處理代碼的頭文件。這個(gè)頭文件是<windowsX.h>,它包含
            了許多有用的宏。微軟的對(duì)這個(gè)頭文件的介紹如下:

            • 對(duì)C程序做更嚴(yán)格的類型檢查的STRICT宏。
            • 一些簡(jiǎn)化Windows編程的通用操作的宏。
            • 一些簡(jiǎn)化與Windows控件交流的控件宏。
            • 消息分流器(一種方便,輕便并且類型安全的處理消息的方法)以及它們?cè)赪indows環(huán)境下的參數(shù)和返回值。

            在Message Cracker Wizard被設(shè)計(jì)出現(xiàn)之前,我就從使用這些的宏中獲得了效率。如果你對(duì)Windows.h的簡(jiǎn)單描述感興趣,你可以參見(jiàn)MS知識(shí)庫(kù)的文章#8356

            好了,讓我們來(lái)介紹消息分流器的便利,以及,為什么這里發(fā)布的工具可以你編寫(xiě)代碼的效率。

            當(dāng)你在編寫(xiě)Win32 SDK程序時(shí),你處理窗口消息通過(guò)一個(gè)窗口函數(shù),通常命名為WndProc。在Windows C 程序中常見(jiàn)的是窗口函數(shù)通過(guò)關(guān)鍵字switch和分支標(biāo)簽case處理所有你需要處理的消息。

            可以料想的是我們通常需要在主窗口中處理WM_COMMANDWM_KEYUPWM_CLOSEWM_DESTROY消息。理論上我們會(huì)把窗口函數(shù)寫(xiě)成這樣:
            LRESULT?CALLBACK?MainWndProc?(HWND?hwnd,?UINT?msg,???WPARAM?wParam,?LPARAM?lParam)
            {
            ??
            switch
            (msg)
            ??{
            ????
            case
            ?WM_COMMAND:
            ????
            //?

            ????break;????
            ?????
            ????
            case
            ?WM_KEYUP:
            ????
            //?

            ????break;

            ????
            case
            ?WM_CLOSE:
            ????
            //?

            ????break;???????
            ?????
            ????
            case
            ?WM_DESTROY:
            ????
            //

            ????break;??????
            ????????
            ????
            default
            :???
            ???????
            return
            ?DefWindowProc(hwnd,?msg,?wParam,?lParam);
            ??}
            }
            這是自Windows 1.0時(shí)代以來(lái)處理Windows消息使用最多的,確實(shí)地,它工作。但是問(wèn)題是當(dāng)你開(kāi)始向你程序中加入更多復(fù)雜的特性,例如 MDI,OLE,通用控件,等等,你會(huì)獲得一個(gè)行數(shù)以千記的窗口函數(shù)。你開(kāi)始反復(fù)使用PageDn和PageUp鍵跳躍,來(lái)尋找你需要修改的消息。

            這是使用消息分流器的第一個(gè)好處:它們提供了處理函數(shù)來(lái)簡(jiǎn)化case標(biāo)簽意大利面,就像MFC做的那樣。

            第二個(gè)好處是正確的參數(shù)規(guī)范化了你的處理函數(shù)的使用。你可以簡(jiǎn)單地使用switch(id)來(lái)替代switch(LOWORD(wparam)),因?yàn)槟惆?span style="COLOR: rgb(204,0,0)">id作為一個(gè)“分流器”的參數(shù)傳遞給消息函數(shù)時(shí),等同于LOWORD(wparam)

            消息處理宏HANDLE_MSG定義在windows.h中,如下:

            #define?HANDLE_MSG(hwnd,?message,?fn)?\
            ????
            case?(message)?:?return?HANDLE_##message((hwnd),?(wParam),?(lParam),?(fn))?

            如你從上面宏定義中可以想到的是,將你的代碼轉(zhuǎn)換成“消息分流器”版本,你必須支持分流宏,HANDLE_MSG,并且使用函數(shù)來(lái)處理消息。現(xiàn)在將HANDLE_MSG宏加入到窗口函數(shù)中來(lái)。這個(gè)宏需要三個(gè)參數(shù):一個(gè)窗口句柄(hwnd),你要處理的消息(WM_xxxx),以及你用來(lái)處理此消息的函數(shù)。為了更好的說(shuō)明,我把之前的窗口函數(shù)替換成下面的消息分流版:
            LRESULT?CALLBACK?MainWndProc?(HWND?hwnd,?UINT?msg,?WPARAM?wParam,?LPARAM?lParam)
            {
            ??
            switch(msg)
            ??{
            ????HANDLE_MSG?(hwnd,?WM_COMMAND,?OnCommand);
            ????HANDLE_MSG?(hwnd,?WM_KEYUP,???OnKeyup);
            ????HANDLE_MSG?(hwnd,?WM_CLOSE,???OnClose);
            ????HANDLE_MSG?(hwnd,?WM_DESTROY,?OnDestroy);
            ????
            default:
            ????????
            return?DefWindowProc(hwnd,?msg,?wParam,?lParam);
            ??}
            }


            哇!這是更好的,簡(jiǎn)潔的并且容易控制的窗口函數(shù)。現(xiàn)在你需要定義的的消息處理函數(shù)(OnKeyUp, OnCloseOnDestroy)。更加便利的是你可以使用Visual Studio IDE跳到你消息處理函數(shù):


            問(wèn)題是每一次你增加一個(gè)消息處理你都必須搜尋WINDOWS.H里的定義,以匹配你的消息處理函數(shù)的參數(shù)類型,因?yàn)槟悴荒茈S意的使用參數(shù)類型:處理函數(shù)的格式是清楚定義的。在頭文件中反復(fù)的查找是單調(diào)乏味的任務(wù),且容易出錯(cuò)。消息分流器Wizard工具來(lái)搭救你了:它允許你粘貼任何你需要的消息處理的正確的參數(shù)。如果你剛剛開(kāi)始編寫(xiě)代碼,它還可以生成一個(gè)窗口模板或者對(duì)話框函數(shù)作為你處理窗口消息的開(kāi)始。

            Message forwarding宏:另一個(gè)WINDOWS.H特色

            頭文件windowsx.h的另一個(gè)特色大約是message forwarding。它用來(lái)“拆除”消息處理函數(shù)的參數(shù)為有效的WPARAMLPARAM的值,以調(diào)用諸如PostMessageSendMessageCallWindowProc等等,此類的函數(shù)。


            假設(shè)你你希望使用SendMessage函數(shù)來(lái)發(fā)送WM_COMMAND消息給父窗口,通過(guò)以一個(gè)通知碼BN_DBLCLK來(lái)“模擬”雙擊一個(gè)命名為IDC_USERCTL的控件。你通常會(huì)這樣寫(xiě):

            SendMessage (hwndParent, WM_COMMAND,
            ??? MAKEWPARAM(IDC_USERCTL, BN_DBLCLK),
            ???? (LPARAM)GetDlgItem(hwnd, ID_USERCTL));

            這是一個(gè)復(fù)雜的的語(yǔ)法:函數(shù)SendMessage期望WPARAM參數(shù)的底字節(jié)是控件的ID,高字節(jié)是通知碼;并且我們要通過(guò)API函數(shù)GetDlgItem獲得控件句柄,傳給LPARAM參數(shù)。

            上面的代碼可以用Windows.h的message forwarding宏替換,FORWARD_WM_XXXX。對(duì)于每一個(gè)消息,forwarding宏都使用和消息分流器生成的消息處理函數(shù)相同的“捆扎”參數(shù),增加你希望調(diào)用的函數(shù)并且傳給它“拆除”后的LPARAM/WPARAMs。例如,消息分流器Wizard為WM_COMMAND消息和窗口IDmyWnd生成如下的函數(shù)原型:
            void myWnd_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
            好了,這些分流器參數(shù)也同樣被用于forwarding宏--因此,如你所期望的,我們之前調(diào)用SendMessage函數(shù)時(shí)展現(xiàn)的混亂可以減少了:
            FORWARD_WM_COMMAND (hwndParent, IDC_USERCTL, 
            GetDlgItem(hwnd, ID_USERCTL), BN_DBLCLK, SendMessage);
            這種方式非常簡(jiǎn)便,并且可以為所有消息分流器Wizard支持的消息工作。


            使用消息分流Wizard工具

            當(dāng)你運(yùn)行消息分流器Wizard時(shí),你可以看到下面的窗口:



            Wizard在左上角的列表框里為你提供了WINDOWS.H里有的消息處理,你可以點(diǎn)擊一個(gè)或者多個(gè)消息。你可以在窗口ID編輯框里指定一個(gè)窗口標(biāo)識(shí),以指定你要發(fā)送消息的
            窗口。通用的ID有
            MainWnd ,About (關(guān)于對(duì)話框),等等。這個(gè)標(biāo)識(shí)會(huì)體現(xiàn)在消息處理函數(shù)中,和 HANDLE_MSG 宏中,如果你剛剛開(kāi)始編寫(xiě)代碼,它還可以體現(xiàn)在窗
            口/對(duì)話框處理函數(shù)中。“ Make Window Procedure”選定框的作用是:允許你通過(guò)選定的消息分流器的宏來(lái)生成一個(gè)窗口/對(duì)話框函數(shù)的框架。以這種方式來(lái)開(kāi)始一
            個(gè)Windows API項(xiàng)目,你可以清晰的編寫(xiě)和組織你的代碼,當(dāng)然還有,避免錯(cuò)誤。在窗口下面的兩個(gè)編輯框會(huì)包含分流器的宏和處理所選消息的函數(shù)(只是原型)生成的代
            碼。要注意的是,當(dāng)你選擇“Make Window Procedure”時(shí)窗口處理函數(shù)的模板代碼不出現(xiàn)在這里:它僅體現(xiàn)在你點(diǎn)擊了“Copy Macro”時(shí)復(fù)制到你的C++編輯器中
            的代碼里。

            讓我們通過(guò)例子來(lái)快速的瀏覽消息分流器Wizard工具的特性。記住你必須先通過(guò)#include <windowsx.h>將頭文件<windowsx.h>包含到你.C/.CPP文件中。

            快速瀏覽消息分流器Wizard特性

            讓我們開(kāi)始吧。假設(shè)你已經(jīng)編寫(xiě)了你的 WinMain 的基本代碼:已經(jīng)成功填充了 WNDCLASS 結(jié)構(gòu),注冊(cè)了窗口類,并且編寫(xiě)了消息循環(huán)。現(xiàn)在你需要一個(gè)為你主函數(shù)編寫(xiě)
            的消息處理函數(shù)。

            打開(kāi)消息分流器Wizard。我們需要為我們的窗口選擇消息,因?yàn)镸CW需要用它來(lái)生成我們的消息處理函數(shù)。如你所知,Windows程序非常常見(jiàn)的處理消息是
            WM_CLOSE
            WM_DESTROY WM_CREATE ,所以讓我們選擇消息分流器處理這些消息來(lái)創(chuàng)建窗口函數(shù)。然后,我們創(chuàng)建窗口函數(shù)的主體消息處理函數(shù)。

            在列表框中選擇
            WM_CLOSE , WM_DESTROY WM_CREATE 。因?yàn)榇舜翱谑俏覀兂绦虻闹鞔翱冢覀冞x用main做為窗口的ID。這個(gè)窗口ID表識(shí)了我們的窗口/對(duì)話框,并且
            使分流宏和出理函數(shù)作為后綴。當(dāng)然,你要使特定窗口的所有消息處理保持一致。觀察下面的編輯框。它們顯示 HANDLE_MSG 分流宏和關(guān)聯(lián)的消息處理函數(shù)的原型。



            但是,等一下......我們說(shuō)我們需要一個(gè)準(zhǔn)備好的窗口處理函數(shù)。所以單擊“Make Window Procedure”選定框,并且確認(rèn)Window 單選按鈕已經(jīng)被選擇了。現(xiàn)在
            我們準(zhǔn)備好了。要注意的是,對(duì)話框的工作也像這樣,但是要改變處理函數(shù)為對(duì)話框類型。

            首先,我們需要我們?cè)创a的窗口處理函數(shù)。點(diǎn)擊“Copy Macro”按鈕(或者使用Ctrl-M),最小化Wizard(或者把它放到一邊),回到你的IDE并且從剪貼板粘貼
            Ctrl-V)代碼到你的窗口函數(shù)的位置。
            Voilá(阿根廷拉丁語(yǔ),認(rèn)識(shí)的通知下)!你可以得到像下面的代碼:
            //
            //?main??Window?Procedure
            //
            LRESULT?CALLBACK?main_WndProc?(HWND?hwnd,?UINT?msg,?WPARAM?wParam,???LPARAM?lParam)
            {
            ??
            switch
            (msg)
            ??{
            ????HANDLE_MSG?(hwnd,?WM_CLOSE,?main_OnClose);
            ????HANDLE_MSG?(hwnd,?WM_CREATE,?main_OnCreate);
            ????HANDLE_MSG?(hwnd,?WM_DESTROY,?main_OnDestroy);
            ??????
            ////?TODO:?Add?window?message?crackers?here

            ??default:?return?DefWindowProc?(hwnd,?msg,?wParam,?lParam);
            ??}
            }


            這個(gè)窗口處理函數(shù)以三個(gè)消息分流宏展開(kāi)工作!并且,通過(guò)TODO注釋提示你記得必須在這里添加消息分流器宏。當(dāng)你只是要添加一個(gè) HANDLE_MSG 宏到窗口函數(shù)中時(shí),
            記得取消“Mke Window Procedure”選定框的選擇。


            但是這些代碼現(xiàn)在還什么都做不了,因?yàn)槲覀冞€需要添加三個(gè)我們需要的消息處理函數(shù)。回到消息分流器Wizard工具的界面,并且單擊“Copy Function”按鈕。切
            換到你的代碼,用鼠標(biāo)定位到你需要函數(shù)主體插入的位置,然后用Ctrl+V或者菜單Edit/Paste粘貼。Wizard自動(dòng)生成函數(shù),使用 main 標(biāo)識(shí)窗口ID,并修正參數(shù)類型
            使之符合 WINDOWSX.H 頭文件的宏:

            //
            //Process?WM_CLOSE?message?for?window/dialog:?main
            //
            void
            ?main_OnClose(HWND?hwnd)
            {
            ??
            //?TODO:?Add?your?message?processing?code?here

            }
            //

            //??Process?WM_CREATE?message?for?window/dialog:?main
            //
            BOOL?main_OnCreate(HWND?hwnd,?LPCREATESTRUCT?lpCreateStruct)
            {
            ??
            //?TODO:?Add?your?message?processing?code?here

            }
            //

            //??Process?WM_DESTROY?message?for?window/dialog:?main
            //
            void
            ?main_OnDestroy(HWND?hwnd)
            {
            ??
            //?TODO:?Add?your?message?processing?code?here

            }




            Wizard還可以自動(dòng)生成開(kāi)頭注釋,和TODO行以提醒你添加代碼。現(xiàn)在你可以添加消息處理了,可以是簡(jiǎn)單的處理處理邏輯,或者復(fù)雜窗口函數(shù)。你也可以通過(guò)選定框移除
            注釋。

            更多的消息分流器Wizard特性

            消息過(guò)濾

            你可以過(guò)濾你暫時(shí)不打算處理的消息。單擊“Filters..”按鈕(或者Ctrl+L),你會(huì)打開(kāi)下面對(duì)話框。列表的消息按類型分類(分類標(biāo)準(zhǔn)來(lái)自Microsoft Spy++的效果),
            你可以取消選定你不處理的消息。


            要注意的是在 v2.0 當(dāng)前的問(wèn)題是,當(dāng)你打開(kāi)消息過(guò)濾對(duì)話框時(shí)所有類型的消息都是選定的,當(dāng)你點(diǎn)擊OK,之前選定的消息會(huì)丟失(這并不意味著你粘貼到目標(biāo)代碼的
            內(nèi)容會(huì)消失)。



            簡(jiǎn)潔窗口模式

            你可能需要減小消息分流Wizard窗體的大小。這可以通過(guò)取消菜單 View 的 “Show Target Code”選項(xiàng)的選定(或者使用Ctrl+F11)。主窗口會(huì)取消目標(biāo)代碼區(qū)域:

            窗體透明,取消注釋和置頂

            (譯注:Sorry,暫不做翻譯了,你可以通過(guò)嘗試菜單 View 的其它幾個(gè)選項(xiàng)自己體會(huì)^_^)



            未來(lái)特性

            下面的特性會(huì)在下一次發(fā)布時(shí)實(shí)現(xiàn):
            • 幫助文件。
            • 所有消息分流的參數(shù)和消息的完整幫助。
            • 支持WTL!:)
            • 窗口ID和配置保存(這個(gè)會(huì)在下一個(gè)2.x版本實(shí)現(xiàn))。
            • 項(xiàng)目配置和“消息映射”(a la MFC)(譯注:好像是西班牙語(yǔ),不認(rèn)識(shí):P)(這個(gè)也會(huì)在之后的2.5版本實(shí)現(xiàn))。

            快樂(lè)的編程!

            我希望這個(gè)小工具可以讓每個(gè) Windows SDK 程序員感興趣,并且干凈的編寫(xiě) Win32 API 程序。我樂(lè)于接受改進(jìn)這個(gè)工具的主意。如果你發(fā)現(xiàn)這個(gè)程序很好用,請(qǐng)給我發(fā)郵件,因?yàn)槲曳浅8吲d聽(tīng)到任何好的意見(jiàn)。

            謝謝所有支持!!You know who you are!(譯注:不太明白這個(gè)要表達(dá)什么意思,“你知道你是誰(shuí)!”乎?)

            任何時(shí)候,打開(kāi)我的主頁(yè),你可以在那里找到這個(gè)程序的最新更新。

            歷史:
            ? 略...

            關(guān)于作者:
            Hernán Di Pietro

            業(yè)余程序員。

            開(kāi)始于1986年,在Commodore 64上編寫(xiě)B(tài)ASIC程序。
            在1990年第一臺(tái) 8086 PC 上開(kāi)始編寫(xiě) QB 4.x。
            1995-1996年轉(zhuǎn)移到Visual Basic。
            2002年,23歲時(shí)開(kāi)始編寫(xiě)C++程序,并對(duì) Windows API 上癮。

            主頁(yè): http://usuarios.lycos.es/hernando



            posted on 2006-11-02 00:00 小山日志 閱讀(1271) 評(píng)論(3)  編輯 收藏 引用 所屬分類: windows program

            FeedBack:
            # re: Message Crack Wizard for Win32 SDK Developer
            2006-11-02 19:15 | 刀劍如夢(mèng)
            嗯~~,不錯(cuò)不錯(cuò)。還有這么個(gè)好東西。  回復(fù)  更多評(píng)論
              
            # re: Message Crack Wizard for Win32 SDK Developer
            2007-02-05 20:34 | Lidi
            很好,謝謝  回復(fù)  更多評(píng)論
              
            # re: Message Crack Wizard for Win32 SDK Developer
            2007-12-06 20:39 | oldnwind
            Programming application for Microsoft Windows 的附錄中有詳細(xì)說(shuō)明。
            應(yīng)該是很方便的,關(guān)鍵是要有個(gè)熟悉過(guò)程。  回復(fù)  更多評(píng)論
              

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            亚洲国产一成人久久精品| 狠狠色婷婷久久一区二区三区| 国内精品久久久久久久影视麻豆| 久久精品一区二区影院 | 国产精品成人无码久久久久久| 国产激情久久久久影院| 久久精品国产免费观看三人同眠| 国产精品久久影院| 久久久久久久久久久精品尤物| 99精品久久精品一区二区| 亚洲国产天堂久久久久久| 狠狠88综合久久久久综合网| 日本精品久久久久影院日本| 99久久久精品免费观看国产| 性高湖久久久久久久久AAAAA| 欧美777精品久久久久网| 色欲久久久天天天综合网精品| 久久夜色精品国产| 欧美精品一区二区精品久久| 久久久久久亚洲精品成人| 亚洲午夜久久久| 无码任你躁久久久久久| 精品国产一区二区三区久久蜜臀| 麻豆一区二区99久久久久| 欧美激情精品久久久久久| 久久精品成人免费观看97| 精品国产91久久久久久久| 久久久久久久97| 人妻少妇久久中文字幕| 伊人久久综合成人网| 99精品国产99久久久久久97| 久久亚洲精品无码VA大香大香| 久久久久女教师免费一区| 一级做a爰片久久毛片人呢| 精品精品国产自在久久高清| 国产精品久久网| 7国产欧美日韩综合天堂中文久久久久| 99久久精品午夜一区二区| 久久亚洲国产精品一区二区| 91精品国产91久久久久久青草| 国产精品日韩深夜福利久久|