如何用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,然後用前面的那些方法試試。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章