Windows 消息機制API
xiaoxi guanli jizhi
Windows平臺上的應用程序是事件驅動的 ,它們不會顯式地調用底層函數以獲得用戶輸入或其它信息,而是等待系統將這些信息提供給它們。同類定義的窗口向系統聲明一個唯一的 窗口過程函數 (Window Procedures)。當有關某一窗口句柄的事件發生時(比如:鼠標單擊這個窗口,或鍵盤向這個窗口輸入一個字符),系統調用這個函數,把某個特定的消息作為參數。
要向特定的窗口過程發送消息,Windows提供了以下函數:
由于lpPrevWndFunc為同一類窗口共有,發送的消息在被某一窗口處理前事實上可能已被多個窗口接收。本文不會用到這一函數,關于此函數的完整定義請參閱:
這一函數在中定義,它向唯一的窗口句柄發送消息,并只在發送的消息被處理后返回。與之相似的是PostMessageW,它在發送消息后立即返回,即只將消息添加到目的窗口句柄的消息隊列里,并不等待其處理。
HWND hwnd:接收消息的窗口句柄
(特別地(HWND)0xffff為廣播)
UINT Msg:發送的消息類型
WPARAM wParam:發送的消息
LPARAM lParam:發送消息的附加參數
實現刷屏
mian dui dui xiang
獲得Windows提供的API函數后,下面用C++實現。
首先將刷屏過程封裝到一個類中
--------Bomb.h--------
構造類時向構造函數提供刷屏消息的重復次數和刷屏消息 (UTF-16格式)
ShowMessage()用于調試,把當前類保存的消息輸出到控制臺上
StartBombing(int)用于開始刷屏,參數定義開始刷屏前的延時。用戶可在這段延時內把鍵盤焦點設置到目標窗口上去,使目標窗口句柄或得消息后把消息內容加入到文本輸入框中去。此函數有一個無延遲參數的重載。
消息內容存儲在私有段中一個類型為WPARAM的數組中(該類型在上文中有介紹),附加消息是一個值為NULL的LPARAM類型——實現本例中的功能不需要向SendMessageW()提供附加消息。
--------Bomb.cpp--------
出于某些考量,我們在此不提供主要函數的定義。在StartBombing()中,程序按用戶設定的刷屏消息重復次數循環times次,并按消息長度循環MessageLength,每次將消息字符串中的第j個字符以WH_CHAR模式向所有窗口廣播。獲得鍵盤輸入焦點的窗口會將其加入到文本框中。
在發送完一條消息后,通過keybd_event函數模擬一次【回車鍵按下】事件,使目標窗口(比如:wechat)發送消息或換行。
--------Main.cpp--------
這是應用程序入口點。注意它設置了wcout/wcin的本地化,使其將儲存在WPARAM類型(其本質是unsigned int)中的UTF-16數據轉化為中文字符輸出/輸入。
可見,按以上代碼編譯的應用程序已經可以完成質問馬人王的任務。然而, 這速度也太慢了?? 這個速度比打字快不了多少,如果這樣的話就沒必要用刷屏軟件了。哪里出了問題呢?
問題在于,如本文開頭介紹:SendMessageW()強制在目標窗口過程將消息處理完畢后才返回,這使得整個過程變得相當緩慢。
解決方法是顯而易見的:用PostMessageW()取代原函數。但是這樣做會帶來新的問題:Post函數只是簡單地把消息加入到目標的消息隊列去,之后立即返回。而原程序在Post/Send函數返回后會調用keybd_event()模擬一個鍵盤事件。然而,窗口過程處理消息的速度現在看來并不盡如人意,這往往會導致大量字符消息堆積在消息隊列中,最終導致鍵盤事件和消息發送間不協調(比如:微信PC端輸入框中堆積了很多信息而不發送,因為回車鍵按下事件沒有按正常順序處理)
所以,要兼顧消息的穩定性和發送速度,就要把keybd_event替換成另一個PostMessageW(),使【回車鍵按下】這一事件也像其它字符事件那樣加入到消息隊列中去,這樣就能保證字符消息和回車間的先后順序不變。
-
存儲器
+關注
關注
38文章
7528瀏覽量
164344 -
WINDOWS
+關注
關注
4文章
3569瀏覽量
89303 -
C++語言
+關注
關注
0文章
147瀏覽量
7027
發布評論請先 登錄
相關推薦
評論