標(biāo)簽: mfc消息sendmessage對話框 | 分類: MFC學(xué)習(xí)筆記 |
1.
2.
3.
LRESULT 類名::AAA(WPARAM wparam,LPARAM lparam)
{
}
4.
HWNDhWnd = ::FindWindowEx( m_hWnd, NULL, NULL,WINDOW_TEXT ) ;
FromHandle(hWnd)->SendMessage(MESSAGE_ID,a,b);
其中,m_hWnd為接收消息的父窗口的句柄,WINDOW_TEXT為接收消息窗口的標(biāo)題,得到的hWnd為接收消息窗口的句柄。調(diào)用該窗口的SendMessage函數(shù),MESSAGE_ID為剛剛設(shè)定的消息ID,a和b是要傳遞的參數(shù)。
注:在這4個步驟中,前三個我在做的時候基本沒什么障礙。問題主要出現(xiàn)在第4步。開始找到網(wǎng)上的例子給的都是FindWindow函數(shù),怎么用都不好使。后來看到有人說FindWindow是找操作系統(tǒng)下打開的窗口的句柄,找窗口中子窗口要用FindWindowEx函數(shù)。我也嘗試過用對話框的ID找到相應(yīng)的句柄,像GetDlgItem(ID)函數(shù)一樣,未果。我使用的對話框都是沒有標(biāo)題欄的,所以也就沒有窗口的標(biāo)題,當(dāng)然這并不會影響我設(shè)置標(biāo)題。只要在生成該窗口的區(qū)域內(nèi)添加SetWindowText(“窗口標(biāo)題”)就可以了。也就是說窗口標(biāo)題可以設(shè)置,但是不會顯示。最后一點在SendMessage()函數(shù)中,MFC默認傳遞的參數(shù)是WPARAM和LPARAM型(一個是UINT型,一個LONG型),如果要傳遞浮點類型,或者其它不是整數(shù)的類型,就可以用指針的形式傳遞(如果發(fā)送方只是申請一個變量并以地址的形式傳遞,然后接收方以指針的形式接收,如果在執(zhí)行完SendMessage之后原函數(shù)體立即結(jié)束了,我不知道在接收函數(shù)體接收和使用該變量的之間的一瞬間,該內(nèi)存區(qū)域會不會被占用,我覺得還是有這種可能的。所以我覺得還是在原函數(shù)體先申請一塊內(nèi)存,然后在接收函數(shù)使用完之后再釋放該內(nèi)存比較合理吧)。
在以下這個例子中是一個MFC的對話框應(yīng)用程序,名字為MessageTest。它包括左邊的一個發(fā)送對話框,和右邊的兩個接收對話框,其中發(fā)送對話框和接收對話框1分別是主對話框的子對話框,在接受對話框中有一個Tab Control,在Tab Control中有個接受對話框2。這么做的目的主要是為了理解如何找句柄的,為此我把幾個對話框設(shè)置成深陷下去的便于觀察。
準備工作:
1.
2.
#defineRECEIVE1_TITLE "receive1 title"
#defineRECEIVE2_TITLE "receive2 title"
#defineGET_INT WM_USER+1000
#defineGET_DOUBLE WM_USER+1001
#defineGET_STRING WM_USER+1002
#defineGET_STRUCT WM_USER+1003
structSendStruct
{
};
RECEIVE1_TITLE和RECEIVE2_TITLE定義兩個接收對話框的標(biāo)題,后邊的4個GET_是4個消息ID,WM_USER是用戶自定義消息的起始ID。
3.
4.
例1:從發(fā)送對話框發(fā)送整數(shù)到接受對話框1中。
1.
afx_msg LRESULT GetInt(WPARAM wparam,LPARAMlparam);
2.
ON_MESSAGE(GET_INT,Receive1Dlg::GetInt)
3.
LRESULTReceive1Dlg::GetInt(WPARAM wparam,LPARAM lparam)
{
}
4.
inta=1;
intb=2;
HWNDhWnd = ::FindWindowEx(this->GetParent()->m_hWnd, NULL,NULL, RECEIVE1_TITLE);
FromHandle(hWnd)->SendMessage(GET_INT,a,b);
注:在這個部分中只是簡單地傳遞兩個整數(shù)。第3步是將得到的兩個整數(shù)顯示到編輯框中,wparam和lparam如果是整數(shù)可以直接使用。第4步中this->GetParent()->m_hWnd是找到了接收對話框1父窗口的句柄,將a和b的值發(fā)過去。
例2:從發(fā)送對話框發(fā)送小數(shù)到接受對話框1中。
1.
afx_msg LRESULT GetDouble(WPARAM wparam,LPARAMlparam);
2.
ON_MESSAGE(GET_DOUBLE,Receive1Dlg::GetDouble)
3.
LRESULT Receive1Dlg::GetDouble(WPARAM wparam, LPARAMlparam)
{
}
4.
double *a=new double;
*a=1.111;
HWND hWnd = ::FindWindowEx(this->GetParent()->m_hWnd, NULL,NULL, RECEIVE1_TITLE);
FromHandle(hWnd)->SendMessage(GET_DOUBLE,(WPARAM)(a),0);
注:在這個部分中是傳遞1個小數(shù)。第3步是將得到的小數(shù)顯示到編輯框中。第4步中先為double類型的變量申請一塊內(nèi)存并為其負值,然后以指針的形式發(fā)送消息過去。在第3步中首先獲得double型指針,最后將內(nèi)存釋放。
例3:從發(fā)送對話框發(fā)送字符串到接受對話框2中。
1.
afx_msg LRESULT GetString(WPARAM wparam,LPARAMlparam);
2.
ON_MESSAGE(GET_STRING,Receive2Dlg::GetString)
3.
LRESULTReceive2Dlg::GetString(WPARAM wparam,LPARAM lparam)
{
}
4.
CString *p_str=new CString("Hello");
HWND hWnd =::FindWindowEx(this->GetParent()->m_hWnd,NULL, NULL, RECEIVE1_TITLE);
hWnd=::FindWindowEx(FromHandle(hWnd)->GetDlgItem(IDC_TAB1)->m_hWnd,NULL, NULL, RECEIVE2_TITLE);
FromHandle(hWnd)->SendMessage(GET_STRING,(WPARAM)(p_str),0);
注:在這個部分中是傳遞1個字符串。第3步是將得到的字符串顯示到編輯框中。第4步中先為CString類型的變量申請一塊內(nèi)存并為其賦值,然后以指針的形式發(fā)送消息過去。這個我在獲得對話框句柄的時候遇到了一些問題,首先一定要弄清楚各個窗口之間的父子關(guān)系,并知道對話框和控件獲得句柄的方法是不同的。在這個例子中,接收對話框2的父窗口是那個Tab Control,Tab Control的父窗口是接收對話框1,接收對話框1和發(fā)送對話框擁有共同的父窗口。調(diào)理清晰了就好寫了。HWND hWnd =::FindWindowEx(this->GetParent()->m_hWnd,NULL, NULL, RECEIVE1_TITLE);前邊已經(jīng)說過了,是獲得了接收對話框1的句柄,下邊那條語句中的FromHandle(hWnd)->GetDlgItem(IDC_TAB1)->m_hWnd是獲得Tab Control的句柄,hWnd= ::FindWindowEx(FromHandle(hWnd)->GetDlgItem(IDC_TAB1)-> m_hWnd, NULL, NULL,RECEIVE2_TITLE);就是獲得接收對話框2的句柄了。
例4:從發(fā)送對話框發(fā)送結(jié)構(gòu)到接受對話框2中。
1.
afx_msgLRESULT GetStruct(WPARAM wparam,LPARAM lparam);
2.
ON_MESSAGE(GET_STRUCT,Receive2Dlg::GetStruct)
3.
LRESULTReceive2Dlg::GetStruct(WPARAM wparam,LPARAM lparam)
{
}
4.
SendStruct *ss = (SendStruct*)malloc(sizeof(SendStruct));
ss->a=1;
ss->b=2;
ss->c=3;
ss->d=4;
HWNDhWnd =::FindWindowEx(this->GetParent()->m_hWnd,NULL, NULL, RECEIVE1_TITLE);
hWnd =::FindWindowEx( FromHandle(hWnd)->GetDlgItem(IDC_TAB1)-> m_hWnd, NULL, NULL,RECEIVE2_TITLE);
FromHandle(hWnd)->SendMessage(GET_STRUCT,(WPARAM)(ss),0);
這個就不多做解釋了。
錯誤的情況:下面說一下我在開始使用消息時使用錯誤的情況(我認為這是錯的)。拿例2的第4步來說:
double a=1.1111;
HWND hWnd = ::FindWindowEx(this->GetParent()->m_hWnd, NULL,NULL, RECEIVE1_TITLE);
FromHandle(hWnd)->SendMessage(GET_DOUBLE,(WPARAM)(&a),0);
第3步中去掉delete a;
我認為這是錯的,為什么呢?很多時候在發(fā)送完成消息之后,函數(shù)體就結(jié)束了,a的內(nèi)存就會被收回了,而消息接收的函數(shù)可能在很久的時間內(nèi)都使用這個變量,說不定什么時候a的內(nèi)存就被重新占用了。如果a是一個很龐大的對象,這種現(xiàn)象可能會更明顯。