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