2010.11.18 关于向窗口发送消息
请区别PostMessage和SendMessage,与::PostMessage、::SendMessage的区别
1、在VC中“::”是C++里的,是“域操作符”。比如声明了一个类A,类A里声明了一个成员函数void f(),但没有在类的声明里给出f的定义,那么在类外定义f时,就要写成void A::f(),表示这个f()函数是类A的成员函数。
::一般还有一种用法,就是直接用在全局函数前,表示是全局函数。比如在VC里,你可以在调用API函数里,在API函数名前加::
全局调用,调用windows api的SendMessage,而不是成员函数CWnd::SendMessage
2、WM_COMMAND消息的,响应的wParam和IParam变量的含义如下:
LOWORD(wParam) 子窗口ID
HIWORD(wParam) 消息通知码
IParam 子窗口句柄
3、我们调用MFC控件的方法,其实也是给控件发消息。每个控件都是一个子窗口,既然是子窗口,就有窗口过程。通过给子控件的窗口过程发消息,从而得到或改变子窗口(也是子控件的状态)。当然,也可以自己给子控件(子窗口)定义窗口过程。
LRESULT SendMessage(
HWND hWnd, // handle to destination window目的窗口句柄
UINT Msg, // message消息,如:WM_MYMESSAGE
WPARAM wParam, // first message parameter//消息参数
LPARAM lParam // second message parameter//消息参数
);
例如,向主窗口发送消息WM_MYMESSAGE,参数一为字符串,二为整数:
CString str = "mytest ";
int nTest = 10;
WPARAM wParam = (WPARAM)&str;
LPARAM lParam = (LPARAM)nTest;
SendMessage(AfxGetMainWnd()-> m_hWnd,MY_MYMESSAGE,wParam,lParam);
主程序定义消息处理函数:
afx_msg void OnMyTest(WPARAM wParam,LPARAM lParam)
影射此处理函数:
ON_MESSAGE(MY_MYMESSAGE,OnMyTest)
函数定义:
void CMytest::OnMyTest(WPARAM wParam,LPARAM lParam)
{
CStrng *pStr = (CString *)wParam;
int n = (int)lParam;
}
以上有错,错误是OnMyTest缺少返回值,LRESULT
另外,注意,wParam、lParam传得都是指针,不要传局部变量的地址。
MSDN:
This function sends the specified message to a window or windows. SendMessage calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread's message queue and returns immediately.
does not return until the window procedure has processed the message.如果sendMessage没有处理该怎么办???
利用SendMessage函数还可以实现一些有趣的效果,例如在按钮的Click事件中加入如下语句:
::SendMessage(Button.Handle,BM_SETSTYLE,BS_RADIOBUTTON,1);运行后点击按钮,就可以把按钮变成一个收音机按钮。 (注意SendMessage与::SendMessage区别)
用SendMessage发送的消息在处理上存在着一定困难。因为该消息不经过消息队列,所以无法用OnMessage方式来指定对消息的响应,甚至用HookMainWindow也不行,因为消息直接发送到控件,绕过了主窗体。要对这种类型的消息作出响应,需要重载控件的WndProc方法。