一.废话少说,直接上图
0x0 当
用户
运行一个应用程序
,通过对鼠标的点击或键盘按键
,产生一些特定事件
;
0x1 由于Windows一直监控
着I/O设备
,该事件首先会被翻译成消息
,由系统捕获
,存放于系统消息队列
;
0x2 经分析,Windows知道该消息
应由哪个应用程序
处理,则拷贝
到相应的应用程序消息队列
;
0x3 由于消息循环不断检索自身的消息队列
,当发现应用程序消息队列里有消息
,就用GetMessage()
取出消息,封装成Msg()结构
。如果该消息是由键盘按键产生的,用TranslateMessage()
翻译为WM_CHAR消息,否则,用DisPatchMessage()
将取出的消息分发到相应的应用程序窗口
,交由窗口处理程序处理;
0x4 Windows为每个窗体预留了过程窗口函数
,该函数是一个回调函数,由系统调用
,应用程序不能调用
;但是我们可以通过重载该函数
处理我们”感兴趣”的消息。对于不感兴趣
的消息,则由系统默认的窗口过程处理程序做出处理。
二.基本骨架
while (GetMessageW(&msg, NULL, 0, 0) != 0) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
if (msg.message == WM_KEYDOWN) {
if (msg.wParam == VK_ESCAPE/*虚拟键*/) {
break;
}
}
};
二.Window窗口特性
所有的
Window窗口
都是从一个线程里面
去派生
出来的,当需要使用到这个界面上的控件数据
的时候,必须确保是在本线程去获取和读写
。否则会导致程序奔溃
(做了一层校验),这是设计者
为了否则出现以下情况:
本线程
在读写界面控件变量,另一个线程
也在读写界面控件变量!
如果
遇到
了上面的情况,我们应该怎么去解决呢?
答:自定义消息,然后把获取界面控件变量
的代码放到本线程去执行
-
步骤一:定义
消息号
#define WM_SEND_PACKET (WM_USER+1)
-
步骤二:定义
消息映射函数
afx_msg LRESULT OnSendPacket(WPARAM wParam, LPARAM lParam);
-
步骤三:添加到
消息映射表
ON_MESSAGE(WM_SEND_PACKET, &CRemoteClientDlg::OnSendPacket)
-
步骤四:替换
导致奔溃
的代码int ret = SendMessage(WM_SEND_PACKET, 4 << 1 | 0, (LPARAM)(LPCSTR)strFile);
总结:
消息机制
是Window最大的特点之一,所以我们在Window下编程最好使用
它这个特点来设计和编程;切记不要在Window下使用Linux特有的机制,在Linux使用