• <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>

            luqingfei@C++

            為中華之崛起而崛起!
            兼聽則明,偏聽則暗。

            Win32匯編--窗口程序實驗--行為與消息之間的關系

             

            窗口程序實驗--行為與消息之間的關系

            在這一節中,將通過不同的實驗,進一步介紹窗口的運行。首先構造一個程序,在程序中將收到的消息查表翻譯成文本以WM_XXX格式顯示出來,并且將調用各個API函數的過程也顯示出來,這樣可以分析窗口的各種行為和消息之間的關系。

             

            一、MsgWindow程序

            為了把需要的內容顯示出來,可以選擇在客戶區顯示文本,但這樣會引入新的消息,干擾實驗,所以,這里選擇了另一方法,就是先打開Windows附件中自帶的Notepad記事本程序,然后在程序中將要顯示的內容通過SendMessage發送到記事本中,可以通過查看記事本中的內容來了解MsgWindows的運行情況。

             

            同樣,先拷貝一份FirstWindow程序進行修改,共增加3個部分。第一部分是將消息查表轉換為字符串,首先在.const段中增加兩個表:16進制的消息編號列表dwMsgTable和字符串列表szStringTable,兩表中的項目一一對應,代碼如下:

                                        .const

                   dwMsgTable                 dd           WM_NULL

                                                      dd           WM_CREATE

                                                      dd           WM_DESTROY

                                                      dd           WM_MOVE

             

                                                      dd           WM_EXITSIZEMOVE

                   MSG_TABLE_LEN       equ         ($ - dwMsgTable) / sizeof dword

                   ;注釋:equ偽指令,是宏匯編特有的,是一種宏定義,而非高級語言中常量的概念。

                   ;不會為符號分配空間。

                   ;在匯編器編譯的時候,直接將標識符MSG_TABLE_LEN替換為后面的值。

             

                   MSG_STRING_LEN     equ         sizeof szStringTable

                   szStringTable                db           ‘WM_NULL                        ’,0

                                                      db           ‘WM_CREATE                    ’,0

                                                      db           ‘WM_DESTROY                 ’,0

                                                      db           ‘WM_MOVE                       ’,0

             

                                                      db           ‘WM_EXITSIZEMOVE        ’,0

                   szFormat                      db           ‘WndProc: [%04x] %s %08x %08x’,0dh,0

             

            MSG_TABLE_LEN定義了表的項數,MSG_STRING_LEN定義了字符串表中每一項的長度。sizeof操作符取的是szStringTable這一行中的數據長度,而非包括下面全部的字符串行。為了簡化處理,全部字符串的長度保持相等。由于篇幅所限,這里沒有列出全部的消息列表。程序在窗口過程的入口處調用_ShowMessage子程序來翻譯消息并傳給記事本。

                   _ProcWinMain       proc        uses ebx edi esi, hWnd, uMsg, wParam, lParam

             

                                               invoke     _ShowMessage, uMsg, wParam, lParam

                                               mov        eax, uMsg

                                               .if           eax == WM_XXX

            _ShowMessage子程序用來將消息查表翻譯成字符串,源程序如下

                   _ShowMessage      proc        _uMsg, _wParam, -lParam

                                               local        @suBuffer[128]:byte

             

                                               pushad

                   ;*************************************************

                   ; 查找消息的說明字符串

                   ; *************************************************

                                               mov        eax, _uMsg

                                               mov        edi, offset dwMsgTable

                                               mov        ecx, MSG_TABLE_LEN

                                               cld

                                               repnz      scads

                                               .if           ZERO?

                                                             sub         edi, offset dwMsgTable + sizeof dword

                                                             shr          edi, 2

                                                             mov        eax, edi

                                                             ;eax寄存器中存放的是當前消息的索引號

                                                             mov        ecx, MSG_STRING_LEN

                                                             mul         ecx

                                                             add         eax, offset szStringTable

                                                             ; 索引號乘以項長度再加上消息字符串基址,就得到

                                                             ;當前消息字符串的地址

                   ;*************************************************

                   ; 翻譯格式并發送到Notepad窗口

                   ; *************************************************

                                                             invoke     wsprintf, addr @szBuffer, addr szFormat, \

                                                                           _uMsg, eax, _wParam, _lParam

                                                             invoke     _SendNotepad, addr @szBuffer

                                               .endif

                                               popad

                                               ret

                   _ShowMessage      endp

            在這里要用到repnz scasd指令,scasd指令是把eax中的值從[edi]開始的內存中按雙字比較,同時將edi4,如果相等,則ZR標志置位,否則為NZrepnz表示如果標志為NZ,則以ecx為重復次重復搜索,直到相等或ecx為零為止。

             

            ecx賦值為消息表的項數MSG_TABLE_LEN,將edi賦值為消息表的開始地址offset dwMsgTable,然后開始查找,停止后可以查看標志Zero位,如果是非ZERO,表示查完全部都沒有找到,如果是ZERO,則表示找到表項。

             

            當標志為ZERO時,edi指向找到項目的后一項,將edi減去一項的長度(sizeof dword)以及表的基址,再除以表項的長度(sizeof dword等于4,除以4等于右移兩位,所以程序中用shr edi,2),就是消息在表中的索引了,接下來算出消息字符串的位置,位置等于:索引字符串長+字符串基址,代碼如下:

                   mov        ecx, MSG_STRING_LEN

                   mul         ecx

                   add         eax, offset szStringTable

            這樣,eax中就是字符串的地址了。最后將消息編號、名稱和參數用wsprintf函數格式化成可以發送的字符串存放到@szBuffer中,并用_SendtoNotepad子程序將@szBuffer中的內容發送到記事本去。

             

            程序增加的第二部分就是下面這個_SendtoNotepad子程序:

                   szDestClass           db           ‘Notepad’,0

                   _SendtoNotepad     proc        _lpsz

                                               local        @hWinNotepad

             

                                               pushed

                                               invoke     FindWindow, addr szDestClass, NULL

                                               .if           eax

                                                             mov        ecx,eax

                                                             invoke     ChildWindowFromPoint, ecx, 20, 20

                                               .endif

                                               .if           eax

                                                             mov        @hWinNotepad, eax

                                                             mov        esi,_lpsz

                                                             @@:

                                                             lodsb

                                                             or           al,al

                                                             jz            @F

                                                             movzx     eax,al

                                                             invoke     PostMessage,@hWinNotepad,WM_CHAR,eax,1

                                                             jmp         @B

                                                             @@:

                                               .endif

                                               popad

                                               ret

                   _SendtoNotepad     endp

            該子程序中首先用FindWindow函數來查找記事本程序是否已經運行,記事本程序的窗口類名稱為“Notepad”,FindWindow可以用窗口類當做第一個參數來查找,如果找到,返回的是記事本的主窗口句柄,否則返回0

             

            要發送的是模擬按鍵的消息WM_CHAR,這樣就好像在記事本中人工鍵入字符,但直接向記事本主窗口發送WM_CHAR消息是不行的,要向記事本窗口客戶區中的編輯子窗口發送消息才行,所以程序中又用從位置獲取子窗口句柄的函數ChildWindowFromPoint來獲得編輯子窗口的句柄。

             

            鎖定了最后的目標即記事本中的編輯子窗口后,程序用PostMessage向它發送消息,根據字符串的長度,用一個循環每次發送一個WM_CHAR消息,WM_CHAR消息的wParamlParam的含義是:

                   wParam = chCharCode                //wParam的鍵值

                   lParam = lKeyData                       //lParam是鍵數據(重復次數)

             

            程序中用movzx eax, al將鍵值擴展到參數所需的32位,當做wParam參數發送,lParam1,表示鍵的值重復次數為1次,這樣一來,記事本中就源源不斷地顯示出MsgWindow程序的運行軌跡了。

             

            MsgWindow程序增加的第三部分是在每個函數的前后增加了顯示狀態的語句,它們只是簡單地把一個字符串發送到記事本中去:

                   ;定義一些字符串

                   szCreateWindow1          db           ‘Creating Window…’,0dh,0

                   szCreateWindow2          db           ‘CreateWindow end’,0dh,0

                   szShowWindow1          db           ‘Showing Window…’,0dh,0

                   szShowWindow2          db           ‘ShowWindown end’,0dh,0

                   szUpdateWindow1         db           ‘Updating Window…’,0dh,0

                   szUpdateWindow2         db           ‘UpdateWindow end’,0dh,0

                   szGetMsg1                   db           ‘Getting Message…’,0dh,0

                   szGetMsg2                   db           ‘[%04x]Message gotten’,odh,0

                   szDispatchMsg1            db           ‘Dispatching Message…’,0dh,0

                   szDispatchMsg2            db           ‘DispatchMessge end’,0dh,0

             

                   invoke     _SendtoNotepad, addr szCreateWindow1

                   invoke     CreateWindowEx,

                   invoke     _SendtoNotepad, addr szCreateWindow2

                   invoke     _SendtoNotepad, addr szShowWindow1

                   invoke     ShowWindow, hWinMain, sw_SHOWNORMAL

                   invoke     _SendtoNotepad, addr szShowWindow2

                   invoke     _SendtoNotepad, addr szUpdateWindow1

                   invoke    UpdateWindow, hWinMain

                   invoke    _SendtoNotepad, addr szUpdateWindow2

             

            實驗一:驗證收到消息的順序

            打開記事本,然后運行MsgWindow程序,記事本上出現的內容為:

            Creating Window...

            WndProc: [0024] WM_GETMINMAXINFO          00000000 0012f900

            WndProc: [0081] WM_NCCREATE               00000000 0012f8e8

            WndProc: [0083] WM_NCCALCSIZE             00000000 0012f920

            WndProc: [0001] WM_CREATE                 00000000 0012f8c4

            CreateWindow end

            Showing Window...

            WndProc: [0018] WM_SHOWWINDOW             00000001 00000000

            WndProc: [0046] WM_WINDOWPOSCHANGING      00000000 0012febc

            WndProc: [0046] WM_WINDOWPOSCHANGING      00000000 0012febc

            WndProc: [001c] WM_ACTIVATEAPP            00000001 000006d4

            WndProc: [0086] WM_NCACTIVATE             00000001 00000000

            WndProc: [000d] WM_GETTEXT                000001fe 0012f484

            WndProc: [0006] WM_ACTIVATE               00000001 00000000

            WndProc: [0007] WM_SETFOCUS               00000000 00000000

            WndProc: [0085] WM_NCPAINT                00000001 00000000

            WndProc: [000d] WM_GETTEXT                000001fe 0012f484

            WndProc: [0014] WM_ERASEBKGND             01010058 00000000

            WndProc: [0047] WM_WINDOWPOSCHANGED       00000000 0012febc

            WndProc: [0005] WM_SIZE                   00000000 0171024c

            WndProc: [0003] WM_MOVE                   00000000 007d006a

            ShowWindow end

            Updating Window...

            WndProc: [000f] WM_PAINT                  00000000 00000000

            UpdateWindow end

            Getting Message...

             

            WndProc開頭的是在窗口過程中收到的消息,在調用CreateWindowEx的時候,窗口過程就開始接收消息,里面有重要的WM_CREATE,然后在ShowWindow的時候,Window向窗口過程發送了很多的消息,而UpdateWindow只給窗口過程發送了一條WM_PAINT消息,接下來就進入了循環。

             

            可以看到,GetMessage函數是程序主動上交空閑時間的辦法之一,因為顯示Getting Message以后,程序就等著那里了,這表示程序的空閑時間并不浪費在消息循環中,而是在GetMessage函數的內部由Windows自動分配了。

             

            接下來把鼠標移過MsgWindow窗口,在記事本上看到了什么?用戶一個小小的動作就夠窗口過程忙的了。我們看到了多次重復的下列內容:

            WndProc: [0084] WM_NCHITTEST              00000000 0125024a

            WndProc: [0020] WM_SETCURSOR              001305e2 02000001

            [0200]Message gotten

            Dispatching Message...

            WndProc: [0200] WM_MOUSEMOVE              00000000 00a801e0

            DispatchMessage end

            Getting Message...

             

            首先,WindowsGetMessage沒有返回的時候調用了兩次窗口過程,分別是處理WM_NCHITTESTWM_SETCURSOR,它們并不經過消息循環;然后,GetMessage取到[0200]消息并返回,0200WM_MOUSEMOVE消息的編號;接下來,DispatchMessage函數開始工作,在這個函數的內部,消息被Windows發送給窗口過程處理,最后DispatchMessage返回,然后開始新的GetMessage

             

            最后在MsgWindow上單擊“關閉”按鈕,看發生了什么:

            [00a1]Message gotten

            Dispatching Message...

            WndProc: [00a1] WM_NCLBUTTONDOWN          00000014 007302b5

            WndProc: [0215] WM_CAPTURECHANGED         00000000 00000000

            WndProc: [0112] WM_SYSCOMMAND             0000f060 007302b5

            WndProc: [0010] WM_CLOSE                  00000000 00000000

            WndProc: [0046] WM_WINDOWPOSCHANGING      00000000 0012f984

            WndProc: [0047] WM_WINDOWPOSCHANGED       00000000 0012f984

            WndProc: [0086] WM_NCACTIVATE             00000000 00000000

            WndProc: [0006] WM_ACTIVATE               00000000 00000000

            WndProc: [001c] WM_ACTIVATEAPP            00000000 000006d4

            WndProc: [0008] WM_KILLFOCUS              00000000 00000000

            WndProc: [0002] WM_DESTROY                00000000 00000000

            WndProc: [0082] WM_NCDESTROY              00000000 00000000

            DispatchMessage end

            Getting Message...

            [0012]Message gotten

             

            GetMessage收到的是按下鼠標的WM_NCLBUTTONDOWN消息,由DispatchMessage轉給窗口過程處理后,窗口過程將它轉手給了DefWindowProcDefWindowProc根據鼠標的位置得出結論:用戶按的是“關閉”按鈕,放到鼠標后,它就給窗口過程發送WM_CLOSE消息,當窗口過程調用DestroyWindow后,窗口被摧毀,窗口過程最后收到的是WM_DESTROY消息和WM_NCDESTROY消息,而消息循球中GetMessage最后收到的是0012WM_QUIT消息,消息循環結束。

             

             

            實驗二:全部消息都經過消息循環嗎?

            上一實驗中可以看到GetMessage返回的次數明顯地比調用窗口過程的次數次,這意味著窗口過程有很多次是由Windows直接調用的。

             

            這次,我們用極端的方式來驗證,先把消息循環中的DispatchMessage去掉,這樣,GetMessage得到的消息將不會再被送到窗口過程了,窗口過程收到的就是由Windows直接調用的了。

            WndProc: [0084] WM_NCHITTEST              00000000 00c20076

            WndProc: [0020] WM_SETCURSOR              000c03e6 02000001

             

            由于沒有了DispatchMessage,大部分消息被忽略了,窗口就停在了屏幕上,不能進行移動、縮放或關閉等操作,但還是有一部分消息直接由Windows發送給窗口過程,它們是鼠標位置測試的WM_NCHITTEST消息的要求設置光標的WM_SETCURSOR消息,所以在鼠標移動邊框的時候,鼠標光標還是會變成雙箭頭的樣子。

             

            另外,嘗試著單擊別的窗口來切換焦點,然后再單擊標題欄來重新激活窗口,可以發現WM_MOUSEACTIVATEWM_ACTIVATEWM_KILLFOCUS等消息也是不經過消息循環的。接下來,把一個窗口移動到MsgWindow窗口覆蓋它的位置,再移開,可以發現WM_SYNCPAINTWM_ERASEBKGND等消息也是由Windows直接發給窗口過程的。

             

            最后,關閉窗口,當然這個窗口只能在任務管理器中以結束進程的方法關閉了!

             

             

            實驗三:TranslateMessage有什么用

            在窗口上敲幾個鍵,每次敲一個鍵,得到的消息是:WM_KEYDOWN,WM_CHARWM_KEYUP。如果按下鍵盤不放,則首先得到一個WM_KEYDOWN,接下來就是重復的WM_CHARWM_KEYUP消息,直到放開鍵盤為止,最后才會看到一個WM_KEYUP。顯示如下:

            WndProc: [0100] WM_KEYDOWN               00000041 001e0001

            WndProc: [0102] WM_CHAR                  00000061 001e0001

            WndProc: [0101] WM_KEYUP                  00000041 c01e0001

             

            WM_KEYDOWNWM_KEYUP消息中,wParam中是按鍵的掃描碼,上面的數據是按下了鍵“A”得到的,00000041h是“A”的掃描碼,到了WM_CHAR消息中,wParam中就是已經轉換過的ASCII61了,代表輸入的是小寫的字母“a”。

             

            好!現在從程序中去掉“TranslateMessage”語句,然后看這個程序的運行結果,同樣,按幾次鍵以及按下鍵盤不放,我們發現:這中間的區別就是少了WM_CHAR,所以只有在處理鍵盤輸入要用到轉換后的ASCII碼的時候,TranslareMessage函數才是有用的,在別的時候完全可以省略這個語句。這個函數的功能就是看到WM_KEYDOWN的時候把消息檢查一下,然后根據鍵值將一條新的WM_CHARWM_SYSCHAR的消息放入消息循環中。

             

             

            實驗四:DefWindowProc做了什么工作

            現在把DefWindowProc語句去掉,然后再以同樣的方法運行,窗口根本就沒有出現!看記事本中出現了什么:

            Creating Window...

            WndProc: [0024] WM_GETMINMAXINFO          00000000 0012f900

            WndProc: [0081] WM_NCCREATE               00000000 0012f8e8

            WndProc: [0083] WM_NCCALCSIZE             00000000 0012f920

            WndProc: [0001] WM_CREATE                 00000000 0012f8e8

            CreateWindow end

            Showing Window...

            WndProc: [0018] WM_SHOWWINDOW             00000001 00000000

            WndProc: [0046] WM_WINDOWPOSCHANGING      00000000 0012febc

            WndProc: [0046] WM_WINDOWPOSCHANGING      00000000 0012febc

            WndProc: [001c] WM_ACTIVATEAPP            00000001 000006d4

            WndProc: [0086] WM_NCACTIVATE             00000001 00000000

            WndProc: [0006] WM_ACTIVATE               00000001 00000000

            WndProc: [0007] WM_SETFOCUS               00000000 00000000

            WndProc: [0085] WM_NCPAINT                00000001 00000000

            WndProc: [0014] WM_ERASEBKGND             01010055 00000000

            WndProc: [0047] WM_WINDOWPOSCHANGED       00000000 0012febc

            WndProc: [0005] WM_SIZE                   00000000 01900258

            WndProc: [0003] WM_MOVE                   00000000 00640064

            ShowWindow end

            Updating Window...

            WndProc: [000f] WM_PAINT                  00000000 00000000

            UpdateWindow end

            Getting Message...

            [c0aa]Message gotten

            Dispatching Message...

            DispatchMessage end

            Getting Message...

            [000f]Message gotten

            Dispatching Message...

            WndProc: [000f] WM_PAINT                  00000000 00000000

            DispatchMessage end

            Getting Message...

            [000f]Message gotten

            Dispatching Message...

            WndProc: [000f] WM_PAINT                  00000000 00000000

            DispatchMessage end

            Getting Message...

            [000f]Message gotten

            Dispatching Message...

            WndProc: [000f] WM_PAINT                  00000000 00000000

            DispatchMessage end

            Getting Message...

            [000f]Message gotten

            Dispatching Message...

            WndProc: [000f] WM_PAINT                  00000000 00000000

             

            似乎陷入了死循環,因為記事本上不停地有消息冒出來,而且只是冒出WM_PAINT消息來,為什么呢?原來WM_PAINT消息是不能不處理的,也不能丟棄,只要Windows認為窗口的客戶區需要繪畫(或者說是無效的),它就會不停地向窗口發送WM_PAINT消息,一般WM_PAINT消息的處理中用BeginPaintEndPaint會隱含地讓客戶區有效,如果不用BeginPaint/EndPaint,程序必須顯式地把客戶區設置為有效,Windows才不會再發送WM_PAINT消息。這個函數是ValidateRect,現在在分支中再加上處理WM_PAINT的代碼:

            .elseif eax == WM_PAINT

                 invoke ValidateRect, hWnd, NULL

            再編譯執行,現在記事本出現的信息顯示程序停留在了GetMessage處,一切正常。但是,窗口在哪里呢,屏幕上什么都沒有,隱身了?把鼠標移動窗口原來應該出現的地方,記事本中熟悉的WM_NCHITTESTWM_SETCURSOR消息出現了,原來窗口還在那里,只不過沒有了DefWindowProc的處理,窗口的繪畫等所有工作都沒有做,窗口的邊框與與客戶區等所有的東西連畫都沒有畫上去,所以窗口是存在的,但我們看不到它!

            是不是再加上WM_NCPAINT消息自己畫邊框呢,這就不是這個實驗的內容了,我們已經知道,DefWindowProc做的工作太多了,缺了它我們要補上的代碼可不是一兩個分支的問題,而是上百個分支了!

             

            實驗的程序的完整代碼如下:

                            .386

                            .model flat,stdcall

                            option casemap:none

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

            ; Include 文件定義

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

            include         windows.inc

            include         gdi32.inc

            includelib      gdi32.lib

            include         user32.inc

            includelib      user32.lib

            include         kernel32.inc

            includelib      kernel32.lib

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

            ; 數據段

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                            .data?

            hInstance       dd      ?

            hWinMain        dd      ?

             

                            .const

            szClassName     db      'MyClass',0

            szCaptionMain   db      'Message Tester',0

             

            ;******************************************************************

            ; 消息ID列表

            ;******************************************************************

            dwMsgTable      dd WM_NULL

                            dd    WM_CREATE

                            dd    WM_DESTROY

                            dd    WM_MOVE

                            dd    WM_SIZE

                            dd    WM_ACTIVATE

                            dd    WM_SETFOCUS

                            dd    WM_KILLFOCUS

                            dd    WM_ENABLE

                            dd    WM_SETREDRAW

                            dd    WM_SETTEXT

                            dd    WM_GETTEXT

                            dd    WM_GETTEXTLENGTH

                            dd    WM_PAINT

                            dd    WM_CLOSE

                            dd    WM_QUERYENDSESSION

                            dd    WM_QUIT

                            dd    WM_QUERYOPEN

                            dd    WM_ERASEBKGND

                            dd    WM_SYSCOLORCHANGE

                            dd    WM_ENDSESSION

                            dd    WM_SHOWWINDOW

                            dd    WM_WININICHANGE

                            dd    WM_DEVMODECHANGE

                            dd    WM_ACTIVATEAPP

                            dd    WM_FONTCHANGE

                            dd    WM_TIMECHANGE

                            dd    WM_CANCELMODE

                            dd    WM_SETCURSOR

                            dd    WM_MOUSEACTIVATE

                            dd    WM_CHILDACTIVATE

                            dd    WM_QUEUESYNC

                            dd    WM_GETMINMAXINFO

                            dd    WM_PAINTICON

                            dd    WM_ICONERASEBKGND

                            dd    WM_NEXTDLGCTL

                            dd    WM_SPOOLERSTATUS

                            dd    WM_DRAWITEM

                            dd    WM_MEASUREITEM

                            dd    WM_DELETEITEM

                            dd    WM_VKEYTOITEM

                            dd    WM_CHARTOITEM

                            dd    WM_SETFONT

                            dd    WM_GETFONT

                            dd    WM_SETHOTKEY

                            dd    WM_GETHOTKEY

                            dd    WM_QUERYDRAGICON

                            dd    WM_COMPAREITEM

                            dd    WM_GETOBJECT

                            dd    WM_COMPACTING

                            dd    WM_OTHERWINDOWCREATED

                            dd    WM_OTHERWINDOWDESTROYED

                            dd    WM_COMMNOTIFY

                            dd    WM_WINDOWPOSCHANGING

                            dd    WM_WINDOWPOSCHANGED

                            dd    WM_POWER

                            dd    WM_COPYDATA

                            dd    WM_CANCELJOURNAL

                            dd    WM_NOTIFY

                            dd    WM_INPUTLANGCHANGEREQUEST

                            dd    WM_INPUTLANGCHANGE

                            dd    WM_TCARD

                            dd    WM_HELP

                            dd    WM_USERCHANGED

                            dd    WM_NOTIFYFORMAT

                            dd    WM_CONTEXTMENU

                            dd    WM_STYLECHANGING

                            dd    WM_STYLECHANGED

                            dd    WM_DISPLAYCHANGE

                            dd    WM_GETICON

                            dd    WM_SETICON

                            dd    WM_NCCREATE

                            dd    WM_NCDESTROY

                            dd    WM_NCCALCSIZE

                            dd    WM_NCHITTEST

                            dd    WM_NCPAINT

                            dd    WM_NCACTIVATE

                            dd    WM_GETDLGCODE

                            dd    WM_SYNCPAINT

                            dd    WM_NCMOUSEMOVE

                            dd    WM_NCLBUTTONDOWN

                            dd    WM_NCLBUTTONUP

                            dd    WM_NCLBUTTONDBLCLK

                            dd    WM_NCRBUTTONDOWN

                            dd    WM_NCRBUTTONUP

                            dd    WM_NCRBUTTONDBLCLK

                            dd    WM_NCMBUTTONDOWN

                            dd    WM_NCMBUTTONUP

                            dd    WM_NCMBUTTONDBLCLK

                            dd    WM_KEYDOWN

                            dd    WM_KEYUP

                            dd    WM_CHAR

                            dd    WM_DEADCHAR

                            dd    WM_SYSKEYDOWN

                            dd    WM_SYSKEYUP

                            dd    WM_SYSCHAR

                            dd    WM_SYSDEADCHAR

                            dd    WM_KEYLAST

                            dd    WM_INITDIALOG

                            dd    WM_COMMAND

                            dd    WM_SYSCOMMAND

                            dd    WM_TIMER

                            dd    WM_HSCROLL

                            dd    WM_VSCROLL

                            dd    WM_INITMENU

                            dd    WM_INITMENUPOPUP

                            dd    WM_MENUSELECT

                            dd    WM_MENUCHAR

                            dd    WM_ENTERIDLE

                            dd    WM_CTLCOLORMSGBOX

                            dd    WM_CTLCOLOREDIT

                            dd    WM_CTLCOLORLISTBOX

                            dd    WM_CTLCOLORBTN

                            dd    WM_CTLCOLORDLG

                            dd    WM_CTLCOLORSCROLLBAR

                            dd    WM_CTLCOLORSTATIC

                            dd    WM_MOUSEMOVE

                            dd    WM_LBUTTONDOWN

                            dd    WM_LBUTTONUP

                            dd    WM_LBUTTONDBLCLK

                            dd    WM_RBUTTONDOWN

                            dd    WM_RBUTTONUP

                            dd    WM_RBUTTONDBLCLK

                            dd    WM_MBUTTONDOWN

                            dd    WM_MBUTTONUP

                            dd    WM_MBUTTONDBLCLK

                            dd    WM_MOUSELAST

                            dd    WM_PARENTNOTIFY

                            dd    WM_ENTERMENULOOP

                            dd    WM_EXITMENULOOP

                            dd    WM_MDICREATE

                            dd    WM_MDIDESTROY

                            dd    WM_MDIACTIVATE

                            dd    WM_MDIRESTORE

                            dd    WM_MDINEXT

                            dd    WM_MDIMAXIMIZE

                            dd    WM_MDITILE

                            dd    WM_MDICASCADE

                            dd    WM_MDIICONARRANGE

                            dd    WM_MDIGETACTIVE

                            dd    WM_MDISETMENU

                            dd    WM_DROPFILES

                            dd    WM_MDIREFRESHMENU

                            dd    WM_CUT

                            dd    WM_COPY

                            dd    WM_PASTE

                            dd    WM_CLEAR

                            dd    WM_UNDO

                            dd    WM_RENDERFORMAT

                            dd    WM_RENDERALLFORMATS

                            dd    WM_DESTROYCLIPBOARD

                            dd    WM_DRAWCLIPBOARD

                            dd    WM_PAINTCLIPBOARD

                            dd    WM_VSCROLLCLIPBOARD

                            dd    WM_SIZECLIPBOARD

                            dd    WM_ASKCBFORMATNAME

                            dd    WM_CHANGECBCHAIN

                            dd    WM_HSCROLLCLIPBOARD

                            dd    WM_QUERYNEWPALETTE

                            dd    WM_PALETTEISCHANGING

                            dd    WM_PALETTECHANGED

                            dd    WM_HOTKEY

                            dd    WM_PRINT

                            dd    WM_PRINTCLIENT

                            dd    WM_PENWINFIRST

                            dd    WM_PENWINLAST

                            dd    WM_MENURBUTTONUP

                            dd    WM_MENUDRAG

                            dd    WM_MENUGETOBJECT

                            dd    WM_UNINITMENUPOPUP

                            dd    WM_MENUCOMMAND

                            dd    WM_NEXTMENU

                            dd    WM_SIZING

                            dd    WM_CAPTURECHANGED

                            dd    WM_MOVING

                            dd    WM_POWERBROADCAST

                            dd    WM_DEVICECHANGE

                            dd    WM_ENTERSIZEMOVE

                            dd    WM_EXITSIZEMOVE

            MSG_TABLE_LEN   equ     ($ - dwMsgTable)/sizeof dword

            ;******************************************************************

            ; 消息名稱字符串列表

            ;******************************************************************

            MSG_STRING_LEN equ     sizeof szStringTable

            szStringTable   db 'WM_NULL                  ',0

                            db    'WM_CREATE                ',0

                            db    'WM_DESTROY               ',0

                            db    'WM_MOVE                  ',0

                            db    'WM_SIZE                  ',0

                            db    'WM_ACTIVATE              ',0

                            db    'WM_SETFOCUS              ',0

                            db    'WM_KILLFOCUS             ',0

                            db    'WM_ENABLE                ',0

                            db    'WM_SETREDRAW             ',0

                            db    'WM_SETTEXT               ',0

                            db    'WM_GETTEXT               ',0

                            db    'WM_GETTEXTLENGTH         ',0

                            db    'WM_PAINT                 ',0

                            db    'WM_CLOSE                 ',0

                            db    'WM_QUERYENDSESSION       ',0

                            db    'WM_QUIT                  ',0

                            db    'WM_QUERYOPEN             ',0

                            db    'WM_ERASEBKGND            ',0

                            db    'WM_SYSCOLORCHANGE        ',0

                            db    'WM_ENDSESSION            ',0

                            db    'WM_SHOWWINDOW            ',0

                            db    'WM_WININICHANGE          ',0

                            db    'WM_DEVMODECHANGE         ',0

                            db    'WM_ACTIVATEAPP           ',0

                            db    'WM_FONTCHANGE            ',0

                            db    'WM_TIMECHANGE            ',0

                            db    'WM_CANCELMODE            ',0

                            db    'WM_SETCURSOR             ',0

                            db    'WM_MOUSEACTIVATE         ',0

                            db    'WM_CHILDACTIVATE         ',0

                            db    'WM_QUEUESYNC             ',0

                            db    'WM_GETMINMAXINFO         ',0

                            db    'WM_PAINTICON             ',0

                           db    'WM_ICONERASEBKGND        ',0

                            db    'WM_NEXTDLGCTL            ',0

                            db    'WM_SPOOLERSTATUS         ',0

                            db    'WM_DRAWITEM              ',0

                            db    'WM_MEASUREITEM           ',0

                            db    'WM_DELETEITEM            ',0

                            db    'WM_VKEYTOITEM            ',0

                            db    'WM_CHARTOITEM            ',0

                            db    'WM_SETFONT               ',0

                            db    'WM_GETFONT               ',0

                            db    'WM_SETHOTKEY             ',0

                            db    'WM_GETHOTKEY             ',0

                            db    'WM_QUERYDRAGICON         ',0

                            db    'WM_COMPAREITEM           ',0

                            db    'WM_GETOBJECT             ',0

                            db    'WM_COMPACTING           ',0

                            db    'WM_OTHERWINDOWCREATED    ',0

                            db    'WM_OTHERWINDOWDESTROYED ',0

                            db    'WM_COMMNOTIFY            ',0

                            db    'WM_WINDOWPOSCHANGING     ',0

                            db    'WM_WINDOWPOSCHANGED      ',0

                            db    'WM_POWER                 ',0

                            db    'WM_COPYDATA              ',0

                            db    'WM_CANCELJOURNAL         ',0

                            db    'WM_NOTIFY                ',0

                            db    'WM_INPUTLANGCHANGEREQUEST',0

                            db    'WM_INPUTLANGCHANGE       ',0

                            db    'WM_TCARD                 ',0

                            db    'WM_HELP                  ',0

                            db    'WM_USERCHANGED           ',0

                            db    'WM_NOTIFYFORMAT          ',0

                            db    'WM_CONTEXTMENU           ',0

                            db    'WM_STYLECHANGING         ',0

                            db    'WM_STYLECHANGED          ',0

                            db    'WM_DISPLAYCHANGE         ',0

                            db    'WM_GETICON               ',0

                            db    'WM_SETICON               ',0

                            db    'WM_NCCREATE              ',0

                            db    'WM_NCDESTROY             ',0

                            db    'WM_NCCALCSIZE            ',0

                            db    'WM_NCHITTEST             ',0

                            db    'WM_NCPAINT               ',0

                            db    'WM_NCACTIVATE            ',0

                            db    'WM_GETDLGCODE            ',0

                            db    'WM_SYNCPAINT             ',0

                            db    'WM_NCMOUSEMOVE           ',0

                            db    'WM_NCLBUTTONDOWN         ',0

                            db    'WM_NCLBUTTONUP           ',0

                            db    'WM_NCLBUTTONDBLCLK       ',0

                            db    'WM_NCRBUTTONDOWN         ',0

                            db    'WM_NCRBUTTONUP           ',0

                            db    'WM_NCRBUTTONDBLCLK       ',0

                            db    'WM_NCMBUTTONDOWN         ',0

                            db    'WM_NCMBUTTONUP           ',0

                            db    'WM_NCMBUTTONDBLCLK       ',0

                            db    'WM_KEYDOWN               ',0

                            db    'WM_KEYUP                 ',0

                            db    'WM_CHAR                  ',0

                            db    'WM_DEADCHAR              ',0

                            db    'WM_SYSKEYDOWN            ',0

                            db    'WM_SYSKEYUP              ',0

                            db    'WM_SYSCHAR               ',0

                            db    'WM_SYSDEADCHAR          ',0

                            db    'WM_KEYLAST               ',0

                            db    'WM_INITDIALOG            ',0

                            db    'WM_COMMAND               ',0

                            db    'WM_SYSCOMMAND            ',0

                            db    'WM_TIMER                 ',0

                            db    'WM_HSCROLL               ',0

                            db    'WM_VSCROLL               ',0

                            db    'WM_INITMENU              ',0

                            db    'WM_INITMENUPOPUP         ',0

                            db    'WM_MENUSELECT            ',0

                            db    'WM_MENUCHAR              ',0

                            db    'WM_ENTERIDLE             ',0

                            db    'WM_CTLCOLORMSGBOX        ',0

                            db    'WM_CTLCOLOREDIT          ',0

                            db    'WM_CTLCOLORLISTBOX       ',0

                            db    'WM_CTLCOLORBTN           ',0

                            db    'WM_CTLCOLORDLG           ',0

                            db    'WM_CTLCOLORSCROLLBAR     ',0

                            db    'WM_CTLCOLORSTATIC        ',0

                            db    'WM_MOUSEMOVE             ',0

                            db    'WM_LBUTTONDOWN           ',0

                            db    'WM_LBUTTONUP             ',0

                            db    'WM_LBUTTONDBLCLK         ',0

                            db    'WM_RBUTTONDOWN           ',0

                            db    'WM_RBUTTONUP             ',0

                            db    'WM_RBUTTONDBLCLK         ',0

                            db    'WM_MBUTTONDOWN           ',0

                            db    'WM_MBUTTONUP             ',0

                            db    'WM_MBUTTONDBLCLK         ',0

                            db    'WM_MOUSELAST             ',0

                            db    'WM_PARENTNOTIFY          ',0

                            db    'WM_ENTERMENULOOP         ',0

                            db    'WM_EXITMENULOOP          ',0

                            db    'WM_MDICREATE             ',0

                            db    'WM_MDIDESTROY            ',0

                            db    'WM_MDIACTIVATE           ',0

                            db    'WM_MDIRESTORE            ',0

                            db    'WM_MDINEXT               ',0

                            db    'WM_MDIMAXIMIZE           ',0

                            db    'WM_MDITILE               ',0

                            db    'WM_MDICASCADE            ',0

                            db    'WM_MDIICONARRANGE        ',0

                            db    'WM_MDIGETACTIVE          ',0

                            db    'WM_MDISETMENU            ',0

                            db    'WM_DROPFILES             ',0

                            db    'WM_MDIREFRESHMENU        ',0

                            db    'WM_CUT                   ',0

                            db    'WM_COPY                  ',0

                            db    'WM_PASTE                 ',0

                            db    'WM_CLEAR                 ',0

                            db    'WM_UNDO                  ',0

                            db    'WM_RENDERFORMAT          ',0

                            db    'WM_RENDERALLFORMATS      ',0

                            db    'WM_DESTROYCLIPBOARD      ',0

                            db    'WM_DRAWCLIPBOARD         ',0

                            db    'WM_PAINTCLIPBOARD        ',0

                            db    'WM_VSCROLLCLIPBOARD      ',0

                            db    'WM_SIZECLIPBOARD         ',0

                            db    'WM_ASKCBFORMATNAME       ',0

                            db    'WM_CHANGECBCHAIN         ',0

                            db    'WM_HSCROLLCLIPBOARD      ',0

                            db    'WM_QUERYNEWPALETTE       ',0

                            db    'WM_PALETTEISCHANGING     ',0

                            db    'WM_PALETTECHANGED        ',0

                            db    'WM_HOTKEY                ',0

                            db    'WM_PRINT                 ',0

                            db    'WM_PRINTCLIENT           ',0

                            db    'WM_PENWINFIRST           ',0

                            db    'WM_PENWINLAST            ',0

                            db    'WM_MENURBUTTONUP         ',0

                            db    'WM_MENUDRAG              ',0

                            db    'WM_MENUGETOBJECT         ',0

                            db    'WM_UNINITMENUPOPUP       ',0

                            db    'WM_MENUCOMMAND           ',0

                            db    'WM_NEXTMENU              ',0

                            db    'WM_SIZING                ',0

                            db    'WM_CAPTURECHANGED        ',0

                            db    'WM_MOVING                ',0

                            db    'WM_POWERBROADCAST        ',0

                            db    'WM_DEVICECHANGE          ',0

                            db    'WM_ENTERSIZEMOVE         ',0

                            db    'WM_EXITSIZEMOVE          ',0

            ;*************************************************************************

            szDestClass     db      'Notepad',0

            szFormat        db      'WndProc: [%04x] %s %08x %08x',0dh,0

            szCreateWindow1 db      'Creating Window...',0dh,0

            szCreateWindow2 db      'CreateWindow end',0dh,0

            szShowWindow1   db      'Showing Window...',0dh,0

            szShowWindow2   db      'ShowWindow end',0dh,0

            szUpdateWindow1 db      'Updating Window...',0dh,0

            szUpdateWindow2 db      'UpdateWindow end',0dh,0

            szGetMsg1       db      'Getting Message...',0dh,0

            szGetMsg2       db      '[%04x]Message gotten',0dh,0

            szDispatchMsg1 db      'Dispatching Message...',0dh,0

            szDispatchMsg2 db      'DispatchMessage end',0dh,0

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

            ; 代碼段

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                            .code

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

            _SendtoNotepad proc    _lpsz

                            local   @hWinNotepad

                           

                            pushad

                            invoke FindWindow, addr szDestClass, NULL

                            .if eax

                                mov ecx, eax

                                invoke ChildWindowFromPoint,ecx,20,20

                            .endif

                            .if eax

                                mov @hWinNotepad, eax

                                mov esi, _lpsz

                                @@:

                                lodsb

                                or al, al

                                jz @F

                                movzx eax,al

                                invoke PostMessage, @hWinNotepad, WM_CHAR, eax, 1

                                jmp @B

                                @@:

                            .endif

                            popad

                            ret

            _SendtoNotepad endp

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

            _ShowMessage    proc _uMsg, _wParam, _lParam

                            local @szBuffer[128]:byte

                           

                            pushad

            ;*****************************************************************

            ; 查找消息的說明字符串

            ;*****************************************************************

                            mov eax, _uMsg

                            mov edi, offset dwMsgTable

                            mov ecx, MSG_TABLE_LEN

                            cld

                            repnz scasd

                            .if ZERO?

                                sub edi, offset dwMsgTable + sizeof dword

                                shr edi, 2

                                mov eax, edi

                                mov ecx, MSG_STRING_LEN

                                mul ecx

                                add eax, offset szStringTable

            ;*****************************************************************

            ; 翻譯格式并發送到Notepad窗口

            ;*****************************************************************

                                invoke wsprintf, addr @szBuffer, addr szFormat, _uMsg, eax, _wParam, _lParam

                                invoke _SendtoNotepad, addr @szBuffer

                            .endif

                            popad

                            ret               

            _ShowMessage endp

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

            ; 窗口過程

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

            _ProcWinMain    proc uses ebx edi esi, hWnd, uMsg, wParam, lParam

                           

                            invoke _ShowMessage, uMsg, wParam, lParam

             

                            mov eax,uMsg

            ;*************************************************************************

                            .if     eax == WM_CLOSE

                                   invoke     DestroyWindow,hWinMain

                                    invoke     PostQuitMessage,NULL

                            .elseif eax == WM_NCCREATE

                                    mov eax,1

                                    ret

                            .elseif eax == WM_PAINT

                                    invoke ValidateRect, hWnd, NULL

            ;***************************************************************************

                            .else

                                    ;invoke    DefWindowProc,hWnd,uMsg,wParam,lParam

                                    ret

                            .endif

            ;***************************************************************************

                            xor     eax,eax

                            ret

            _ProcWinMain    endp

             

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

            _WinMain        proc

                            local   @szBuffer[128]:byte

                            local   @stWndClass:WNDCLASSEX

                            local   @stMsg:MSG

             

                            invoke     GetModuleHandle,NULL

                            mov     hInstance,eax

                            invoke     RtlZeroMemory,addr @stWndClass,sizeof @stWndClass

            ;**************************************************************************

            ; 注冊窗口類

            ;**************************************************************************

                            invoke     LoadCursor,0,IDC_ARROW

                            mov     @stWndClass.hCursor,eax

                            push    hInstance

                            pop     @stWndClass.hInstance

                            mov     @stWndClass.cbSize, sizeof WNDCLASSEX

                            mov     @stWndClass.style, CS_HREDRAW or CS_VREDRAW

                            mov     @stWndClass.lpfnWndProc, offset _ProcWinMain

                            mov     @stWndClass.hbrBackground,COLOR_WINDOW + 1

                            mov     @stWndClass.lpszClassName, offset szClassName

                            invoke     RegisterClassEx, addr @stWndClass

            ;***************************************************************************

            ; 建立并顯示窗口

            ;***************************************************************************

                            invoke _SendtoNotepad, addr szCreateWindow1

                            invoke     CreateWindowEx, WS_EX_CLIENTEDGE, \

                                    offset szClassName, offset szCaptionMain, \

                                    WS_OVERLAPPEDWINDOW, \

                                    100, 100, 600, 400, \

                                    NULL, NULL, hInstance, NULL

                            mov     hWinMain,eax

                            invoke _SendtoNotepad, addr szCreateWindow2

                           

                            invoke _SendtoNotepad, addr szShowWindow1

                            invoke     ShowWindow,hWinMain,SW_SHOWNORMAL

                            invoke _SendtoNotepad, addr szShowWindow2

                           

                            invoke _SendtoNotepad, addr szUpdateWindow1

                            invoke     UpdateWindow,hWinMain

                            invoke _SendtoNotepad, addr szUpdateWindow2

            ;**************************************************************************

            ; 消息循環

            ;**************************************************************************

                            .while TRUE

                                    invoke _SendtoNotepad, addr szGetMsg1

                                    invoke     GetMessage, addr @stMsg, NULL, 0, 0

                                   

                                   push eax

                                    invoke wsprintf, addr @szBuffer, addr szGetMsg2, @stMsg.message

                                    invoke _SendtoNotepad, addr @szBuffer

                                    pop eax

                                   

                                    .break     .if eax == 0

                                   

                                    invoke     TranslateMessage, addr @stMsg

                                   

                                    invoke _SendtoNotepad, addr szDispatchMsg1

                                    invoke     DispatchMessage, addr @stMsg

                                    invoke _SendtoNotepad, addr szDispatchMsg2

                            .endw

                            ret

            _WinMain        endp

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

            start:

                            call    _WinMain

                            invoke ExitProcess, NULL

            ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                            end start

            posted on 2010-08-23 13:11 luqingfei 閱讀(1208) 評論(0)  編輯 收藏 引用 所屬分類: Win32匯編程語言序設計

            導航

            <2009年2月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            1234567

            統計

            留言簿(6)

            隨筆分類(109)

            隨筆檔案(105)

            Blogers

            Game

            Life

            NodeJs

            Python

            Useful Webs

            大牛

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            久久亚洲AV永久无码精品| 三级片免费观看久久| 亚洲午夜久久久精品影院| 久久久WWW成人免费毛片| 久久婷婷国产综合精品 | 久久亚洲2019中文字幕| 香蕉久久久久久狠狠色| 国产精品九九九久久九九| 欧美亚洲国产精品久久| 四虎影视久久久免费观看| 久久婷婷五月综合97色一本一本| AA级片免费看视频久久| 99久久国产综合精品五月天喷水 | 性欧美大战久久久久久久久 | 97热久久免费频精品99| 亚洲欧洲精品成人久久曰影片| 久久一区二区三区免费| 91精品国产乱码久久久久久 | 亚洲国产精品无码久久SM| 丰满少妇人妻久久久久久4| 一本色道久久88精品综合| 97久久国产综合精品女不卡| 国产亚洲精久久久久久无码AV| 久久精品国产精品亚洲人人| 久久精品国产亚洲av麻豆色欲 | 老男人久久青草av高清| 久久精品国产亚洲5555| 久久国产一区二区| 久久精品无码免费不卡| 久久最新精品国产| 无码任你躁久久久久久老妇| 香蕉久久一区二区不卡无毒影院 | 88久久精品无码一区二区毛片| 97精品依人久久久大香线蕉97 | 久久综合给久久狠狠97色| 97久久国产综合精品女不卡| 无码任你躁久久久久久老妇App| 亚洲精品无码久久久久AV麻豆| 久久久精品波多野结衣| 久久99精品久久久久久野外| 国内精品久久久久久久久|