1. 发送一个消息:
发送一个消息,直接调用窗口的进程函数,直到函数执行完之后返回,发送一个消息时即
时的。
LRESULT ret = pWnd->SendMessage(UINT Msg,WPARAM wParam,LPARAM lParam);
LRESULT ret = ::SendMessage(HWND hWnd,UINT Msg,WPARAM wPara,LPARAM lParam);
2. 寄送一个消息:
寄送一个消息是把消息发送到那个拥有窗口的应用程序的消息队列里面,一有空闲应用程
序就收搜队列,删除消息,并发送到指定的窗口中,键盘和鼠标消息是寄送的,其他消息
是发送的,
BOOL ret = ::PostMessage(HWND hWnd,UINT Msg,WPARAM wPara,LPARAM lParam)
BOOL ret = pWnd-> PostMessage (UINT Msg,WPARAM wParam,LPARAM lParam);
MFC处理一个寄送和发送消息的唯一明显不同是寄送的消息要在应用程序的消息队列中花费
一些时间。在消息泵(message pump)弹出它之前,它要一直在队列中。
MFC 应用程序中的消息泵在CWi nA pp的成员函数Run( )中。应用程序开始运行时, Run(
)就被调用,Run( )把时间分割成两部分。一部分用来执行后台处理,如取消临时C W n
d对象;另一部分用来检查消息队列。当一个新的消息进来时,Run( )抽取它—即用GetMe
ssage( )从队列中取出该消息,运行两个消息翻译函数,然后用DispatchMessage( )函数
调用该消息预期的目标窗口进程
消息泵调用的两个翻译函数是Pre TranslateMessage( )和::TranslateMessage( )。目标
窗口的,MFC类可调用PreTranslateMessage在发送消息给它之前进行消息翻译,例如, C
FrameWnd用PreTranslateMessage( )将加速键(如,C t r l + S存储文件)转换为命令消息
。翻译前的消息通常被处理掉,而翻译后的消息(如果有的话)将被重新寄送到队列里。::
TranslateMessage是一个窗口函数,将原始键码转换为键字符。消息一旦被DispatchMess
age( )发送, M F C处理它就像处理SendMessage( )发送的消息一样。
3. 从消息队列中删除一个消息
BOOL ret = ::PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsFiterMin,UINT wRemoveMs
g);
变量hWnd指定要截获消息的窗口,如果该变量设为NULL,所有窗口消息将被截获。wMsg F
ilterMin和wMsgFilterMax变量与SendMessage( )中的变量Msg相对应,指定查看消息的范
围。如果用“ 0,0”,则所有的消息都将被截获。如果用WM _KEYFIRST,WM_KEYLAST或WM
_M OUSEFIRST, WM_MOUSELAST,则所有键盘或鼠标的消息将被截获。
WRemoveMsg的取值可以是:
PM_NOREMOVE,PeekMessage( )将把消息留在队列里,并返回它的一个拷贝。
PM_REMOVE,PeekMessage( )将删除消息
BOOL ret = ::GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsFiterMin,UIINT wMsgFilte
rMax);
GetMessage()总是删除消息。
4. 消息结构体:
typedef struct tagMSG {
HWND hwnd ;
UINT messaage ;
WPARAM wParam ;
LPARAM lParam ;
DWORD time ;
POINT pt ;
} MSG;
5. 消息类型:
窗口消息,命令消息,控件消息
6. 窗口消息:
窗口消息一般与窗口的内部运作有关,如创建窗口,绘制窗口,销毁窗口,可以用SengMe
ssage或PeekMessage发送消息,可以由系统象窗口发送,也可以由窗口向窗口发送。
Message wParam lParam
WM_****** 定义的命令 定义的命令
7. 命令消息
命令消息一般与处理用户请求相关,当用户单击一个菜单项或工具栏时,命令消息产生,
并被发送到能处理该请求的类对象
Message wParam lParam
W M _ COMMAND COMMANDID或0 0
Command ID要么是选中菜单项的I D,要么是被单击的工具栏按钮。注意Command ID不
能大于一个字长,如果使它大于一个字长,系统就只用0来填充高位字。
某些控件通知也用WM_COMMAND消息,区别两种消息的唯一方法是lParam是否为NULL。
8. 控件消息
控件消息可以是窗口消息的子集
Message wParam lParam
WM_****** 定义的命令 定义的命令
控件通知消息使用命令格式
Message wParam lParam
W M _ COMMAND 控件ID或XN_XXX 窗口句柄
控件通知消息
Message wParam lParam
W M _ NOTIFY 控件ID 指向N M H D R的指针
typedef struct tagNMHDR {
HWND hwndFrom; // Window handle of Control Window
// making the notification.
UINT idFrom; // Control ID of Control Window
// making the notification.
UINT code; // notification code ex: the user
// has clicked the Control Window
} NMHDR;
9. 自定义消息
Windows保留了0和WM_USER-1之间的整数范围,作为系统定义的窗口消息;还有一个从W M
_ USER一直到OX7fff的整数范围,留给自定义消息用。可以用一个简单的#define语句
定义消息:
#define WM_MYMESSAGE WM_USER + 1
然后增加消息映射:
ON_MESSAGE(WM_MYMESSAGE, Handler)
增加处理函数
LRESULT Handle(WPARAM ,LPARAM)
可以像其他消息一样发送:
SendMessage(WM_MYMESSAGE, wParam, lParam)
或者
PostMessage(WM_MYMESSAGE, wParam, lParam).
动态分配窗口消息:
为了在应用程序间发送消息,应该用下面的语句创建一个基于描述性字符串的新的窗口
消息。
UINT WM_MYMESSAGE=::RegisterWindowMessage(LPCSTR Identifier);
Identifier是描述性字符串。
WM_MYMESSAGE是在0xc000和0xffff之间的一个动态分配的窗口消息
在消息映射中加入:
ON_REGISTERED_MESSAGE (MYMESSAGE , Handler )
增加处理函数
LRESULT Handle(WPARAM ,LPARAM)
10. 添加命令范围消息处理函数:
在类中添加处理某个范围的命令消息或者修改命令接口的处理函数。
手工添加两个消息映像宏: ON_COMMAND_RANGE和ON_UPDATE_COMMAND_UI_RANG E到用户类
的消息映像中。
消息映射
ON_COMMAND_RANGE ( ID_TEST _WZD1 , ID_TEST _WZD4 , OnWzdCommandRange )
处理函数
afx_msg void OnWzdCommandRange(UINT nID);
void CWzdView::OnWzdCommandRange(UINT nID)
{
switch (nID)
{
case ID_TEST_WZD1:
break ;
case ID_TEST_WZD2:
break ;
case ID_TEST_WZD3:
break ;
case ID_TEST_WZD4:
break ;
}
}
ON _UPDATE _ COMMAND _ UI _ RANGE ( ID_ TEST_ WD1 , ID_ TEST_WZD4 ,
OnUpdateWzdCommandRange )
void CWzdView::OnUpdateWzdCommandRange(CCmdUI *pCmdUI)
{
switch (pCmdUI->m_nID)
{
case ID_TEST_WZD1:
break ;
case ID_TEST_WZD2:
break ;
case ID_TEST_WZD3:
break ;
case ID_TEST_WZD4:
break ;
}
}