• <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匯編--窗口間的消息互發(fā)

             

            窗口間的消息互發(fā)

             

            在不同應用程序之間的窗口中可以互發(fā)消息,方法是通過SendMessage或者PostMessage函數,它們的用法如下:

                   invoke PostMessage, hWnd, Msg, wParam, lParam

                   invoke SendMessage, hWnd, Msg, wParam, lParam

             

            對于不同的MsgwParamlParam的含義是不同的,如對于WM_SETTEXT是:

                   wParam = 0;                                             //未定義,必須為0

                   lParam = (LPARAM)(LPCTSTR)lpsz;         //要設置的字符串地址

             

             

            想一想就會發(fā)現一個問題:Windows中不同應用程序的地址空間是隔離的,全市程序1要用SendMessage調用程序2所屬窗口的窗口過程,但程序2窗口過程的代碼并不在程序1的地址空間中,那么SendMessage如何調用它呢?其實很簡單,當程序1調用SendMessage函數的時候,Windows會先保存wParamlParam參數并等待,等輪到程序2的時間片的時候再去調用它的窗口過程,并把保存的wParamlParam參數發(fā)給它,等窗口過程返回的時候,Windows記下返回值并等待程序1,這樣程序1看上去就像自己直接在調用程序2的窗口過程一樣。

             

            但又一個問題出現了:Windows在做“牽線紅娘”的時候傳遞了wParamlParam以及返回值,如果參數指向一個字符串呢,比如說上面的WM_SETTEXT消息中的lParam指向一個字符串,假設程序1lParam指向字符串的地址為xxxxxxxx,把這個地址傳給程序2的時候,程序2不可能訪問到程序1的地址空間,在程序2xxxxxxxx指向的可能是其他內容,也可能是不可訪問的,這又該如何處理呢?

             

            寫一個源程序實驗一下,用一個程序向另一個程序的窗口發(fā)送WM_SETTEXT消息,然后在另一個程序中將接收到的WM_SETTEXT消息的參數顯示出來。先來打造接收程序,首先拷貝一份FirstWindows的代碼,然后在窗口過程的分支中加上以下代碼:

                   .elseif      eax == WM_SETTEXT

                                 invoke     wsprintf, addr szBuffer, addr szReceive, lParam, lParam

                                 invoke     MessageBox, hWnd, offset szBuffer, addr szCaptionMain, MB_ok

             

            同時在數據段中加上下列定義:

                   szCaptionMain       db    ‘Receive Messag’,0

                   szReceive              db    ‘Receive WM_SETTEXT message’,0dh,0ah

                                               db    ‘param: %08x’, 0dh, 0ah

                                               db    ‘text: “%s”, 0dh, 0ah, 0

             

            在這里,要提及Win32 API中一個很常用的函數wsprintf,這是一個字符串格式化函數,可以將數值按指定格式翻譯成字符串,類似于C語言中的printf函數,它的原型是這樣的:

                   int    wsprintf (

                                 LPTSTR        lpOut,            //輸出緩沖地址

                                 LPCTSTR      lpFmt             //格式化串地址

                                                                        //變量列表

                   );

            變量列表的數目由格式化字符串規(guī)定,wsprintf處理格式化字符串,遇到普通的字符則直接拷貝到輸出,遇到%字符則代表有一個變量,%后面不同的字母表示不同的輸出格式,如%d表示輸出為整數,%x表示輸出為16進制,%s表示輸出字符串等。

             

            %符號和表示格式的dxs等字母間可以用數字來指定輸出時占用的位長,這時輸出的位長不夠時函數會用空格填齊。另外,表示位長的數字前可以加0來表示填齊時用“0而非空格,如%08x表示輸出為8位前面用0填齊的16進制數。

             

            wsprintfWin32 API中唯一一個參數數量不定的函數,使用wsprintf函數的時候,參數的數量取決于格式化字符串中用%號指定的數量,變量列表的數目和格式化串中的%格式一定要一一對應。這里szReceive中有兩個%號定義,那么后面就要額外跟兩個參數:

                   invoke     wsprintf, addr szBuffer, addr szReceive, lParam, lParam

             

            這條語句將lParam的數值以及lParam的字符串按照szReceive格式化串定義的格式轉換,并將結果存放到szBuffer中,然后程序將szBuffer中的內容在一個消息框中顯示出來:

                   invoke     MessageBox, hWnd, offset szBuffer, addr szCaptionMain, MB_OK

            執(zhí)行程序寫好了,現在寫一個發(fā)送程序,如下所示:

                            .386

                            .model flat, stdcall

                            option casemap:none

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

            include         windows.inc

            include         user32.inc

            includelib      user32.lib

            include         kernel32.inc

            includelib      kernel32.lib

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

                            .data

            hWnd            dd          ?

            szBuffer        db          256 dup (?)

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

                            .const

            szCaption       db          'SendMessage',0

            szStart         db          'Press OK to start SendMessage, param:%08x!',0

            szReturn        db          'SendMessage returned!',0

            szDestClass     db          'MyClass',0

            szText          db          'Text send to other windows',0

            szNotFound      db          'Receive Message Window no found!',0

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

                            .code

            start:

                            invoke FindWindow,addr szDestClass, NULL

                            .if     eax

                                    mov hWnd,eax

                                    invoke wsprintf, addr szBuffer, addr szStart, addr szText

                                    invoke MessageBox, NULL, offset szBuffer, offset szCaption, MB_OK

                                    invoke SendMessage, hWnd, WM_SETTEXT, 0, addr szText

                                    invoke MessageBox, NULL, offset szReturn, offset szCaption, MB_OK

                            .else

                                    invoke MessageBox, NULL, offset szNotFound, offset szCaption, MB_OK

                            .endif

                            invoke ExitProcess, NULL

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

            end start

             

            在這個程序中首先用FindWindow函數找到接收窗口的窗口句柄,FindWindow函數的使用方法是:

                   invoke     FindWindow, lpClassName, lpWindowName

                   .if           eax

                                 mov hWin, eax

                   .endif

             

            兩個參數都指向字符串lpClassName指向需要尋找的窗口的窗口類,lpWindowName指向需要尋找窗口的窗口標題,如果目標窗口存在的話,函數的返回值是找到的窗口句柄,否則函數返回0

             

            用接收窗口的窗口類當做參數尋找窗口,如果沒有找到則顯示“Receive Message Window not found”,找到的話則把“Text send to other windows”字符串的地址當做WM_SETTEXT消息的參數用SendMessage發(fā)送給接收窗口。

             

            好!,現在發(fā)送開始,首先執(zhí)行Receive.exe,窗口出來了,然后執(zhí)行Send.exe,屏幕上出現一個對話框:Press OK to start SendMessage, param:00402072,表示在Send程序中字符串的地址是00402072h,現在單擊“確定”按鈕執(zhí)行SendMessage函數,單擊后對話框消失,但接收程序顯示出了一個對話框,內容為:

                   Receive WM_SETTEXT message

                   param: 0012fflc

                   text: “Text send to other windows”

             

            可見字符串是正確地傳了過來,但地址卻不是發(fā)送程序的00402072h,這是為何?

            答案是Window做“紅娘”做到底,它拷貝了WM_SETTEXT消息的lParam參數指向的字符串,并在接收程序的地址空間中開了一塊內存放上這個字符串,然后把新的地址值當做lParam傳給接收程序,畢竟在WM_SETTEXT消息中,lParam的數值是多少并不重要,重要的是它指向的字符串是否正確。

             

            最后,單擊接收程序中的“確定”按鈕,發(fā)送程序馬上彈出一個消息框并顯示:SendMessage returned,這是SendMessage函數告訴我們:我回來了!

             

            其實Windows在處理SendMessagePostMessage的時候要檢查消息的類型,并對不同的消息做不同的處理,當消息的參數是一個指針的時候,Windows要把指針指向的內容復制到緩沖區(qū),以便在兩個程序的地址空間中傳遞。

             

            注意:在用戶自定義的消息中(WM_USER等)不要在消息參數中傳遞指針,這只會引發(fā)非法訪問內存,因為Windows不知道用戶的意圖,它只會把lParamwParam當兩個普通的數值傳遞,而不會幫用戶把指針指向的內容復制到一個緩沖區(qū)中。

             

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

            導航

            <2010年8月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            統(tǒng)計

            留言簿(6)

            隨筆分類(109)

            隨筆檔案(105)

            Blogers

            Game

            Life

            NodeJs

            Python

            Useful Webs

            大牛

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            亚洲国产精品无码久久一线| 99久久免费国产精品特黄| 国产精品久久久久影院色| 久久久久国产精品| 亚洲欧美日韩久久精品| 久久ww精品w免费人成| 久久精品国产黑森林| 欧洲成人午夜精品无码区久久| 国产激情久久久久影院小草 | 国产免费久久久久久无码| 狠狠色丁香婷婷久久综合五月| 久久久久久夜精品精品免费啦| 久久久久99精品成人片牛牛影视| 亚洲精品高清国产一线久久| 国产成人无码精品久久久久免费| 97精品依人久久久大香线蕉97| 欧美一区二区三区久久综合| 99国内精品久久久久久久| 中文字幕久久精品无码| 久久AAAA片一区二区| 久久国产乱子伦精品免费强 | 国产成人久久精品一区二区三区| 久久强奷乱码老熟女网站| 国产精品美女久久久| 浪潮AV色综合久久天堂| 漂亮人妻被中出中文字幕久久| 久久高清一级毛片| 精品久久人人做人人爽综合| 久久综合久久久| 久久精品国产精品青草app| 国产Av激情久久无码天堂| 精品久久8x国产免费观看| 中文精品久久久久人妻不卡| 久久人人爽人人爽人人片av麻烦| 久久久久这里只有精品| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 精品久久久久成人码免费动漫| 日韩一区二区三区视频久久| 三级片免费观看久久| 久久频这里精品99香蕉久| 亚洲va中文字幕无码久久|