1. 程式人生 > >如何用SendMessage模擬某一按鈕的點選事件

如何用SendMessage模擬某一按鈕的點選事件

今天在寫程式的時候,用到了程序間的通訊,上網查了些相關的資料,一般都是通過訊息、共享記憶體、 socket,管道(Pipe),信箱(Mailslot),等等。因為我程序間通訊的時候資料量不太大,所以就先測試了一下訊息。

一 般情況下,用訊息來實現程序通訊相對比較簡單,自定義訊息、手動新增訊息對映、編寫響應函式,傳送端先FindWindow(),然後就向目標程序 SendMessage()。自定義訊息的測試沒有什麼問題,但在向目標程序傳送系統訊息時遇到了些問題,傳送WM_CLOSE訊息也可以,但是在我嘗試 傳送按鈕訊息時,遇到了些麻煩,在查資料,並多次測試後終於搞定,看到網上一些資料都沒有明確的答案,就把我的一些體會發在這裡,有朋友遇到這個問題時也 就少走點彎路。當然,我個人水平也很菜,高手就不要看了!

自定義訊息和訊息對映就不多說了,獲取視窗程序:
CWnd *pWnd=CWnd::FindWindow(NULL,str);

模擬其中視窗上的按鈕點選事件可以採用以下的方法:

1、pWnd->SendMessage(WM_COMMAND,IDC_BUTTON1,0);

2、pWnd->SendMessage(WM_COMMAND,((WPARAM)BN_CLICKED)<<8|(WPARAM)IDC_BUTTON1,0L);

3、pWnd->SendDlgItemMessage(IDC_BUTTON1,BM_CLICK,0,0);

4、::SendMessage(pWnd->GetSafeHwnd(),WM_COMMAND,IDC_BUTTON1,NULL);

5、::SendMessage(pWnd->GetDlgItem(IDC_BUTTON1)->GetSafeHwnd(),WM_LBUTTONDOWN,IDC_BUTTON1,0);
::SendMessage(pWnd->GetDlgItem(IDC_BUTTON1)->GetSafeHwnd(),WM_LBUTTONUP,IDC_BUTTON1,0);

6、pWnd->GetDlgItem(IDC_BUTTON1)->SendMessage(WM_LBUTTONDOWN);
pWnd->GetDlgItem(IDC_BUTTON1)->SendMessage(WM_LBUTTONUP);

注意:
1、如果模擬自己程序內的按鈕,前面的方法都可以使用,將其中pWnd替換為this或直接為空即可。

2、如果是向另外一個程序傳送訊息,並模擬另外程序中的按鈕的點選事件,那麼有一點要注意,就是其中的按鈕ID號,不能使用比如IDC_BUTTON1這樣的巨集,因為在本程式裡也有定義,並且這個值可能和你想要模擬的按鈕的ID在它所在的程序中的ID不同,它會被預設
替換為本程序內的值。
舉個例子,現在你編寫了兩個對話方塊程式A和B,在程式A中,定義了兩個按鈕,分別為IDC_BUTTON1和IDC_BUTTON2,開啟Resource.h檢視一下它們的ID值:
#define IDC_BUTTON1 1000
#define IDC_BUTTON2 1001
在程式B中,定義了一個按鈕,名字為IDC_BUTTON1,開啟Resource.h檢視一下該按鈕的ID值:
#define IDC_BUTTON1 1001
從兩個標頭檔案中可以看出,程式A中的IDC_BUTTON2和ID值和程式B中的IDC_BUTTON1的ID值相同,而兩個程式的IDC_BUTTON1的值並不相同。
注意,問題就出在這這兒。如果我們想模擬程式B中按鈕IDC_BUTTON1的點選事件,按照前面的方法是行不通的,不信可以試試。
但 如果我們在使用前面的那些方法時,改變一下傳遞的引數,將其中的IDC_BUTTON1改為IDC_BUTTON2,試一下,程序B中的按鈕成功的模擬出 來了,竟然達到了我們的目標。那麼奇怪,明明B程式中按鈕的ID是IDC_BUTTON1啊!現在改為IDC_BUTTON2反而成功了呢?為什麼會這樣 呢?
其實這主要是因為兩個程式的不同引起的,因為我們在A程式中呼叫前面的方法來模擬程式B的按鈕時,程式B中的IDC_BUTTON1按鈕的實 際的ID值是非曲直1001,而程式A中卻把IDC_BUTTON1的值設為了1000,所以無論你怎麼傳送訊息都沒用,程式B裡面1000的ID值並不 是IDC_BUTTON1對應的值,它實際的值應該是1001。不信的話,可以用1001代替IDC_BUTTON1,然後用前面的那些方法試試。