改章节是一篇关于窗口函数的帖子
窗口消息
#define WM_LBUTTONDOWN 0x0201
有一些消息具有与它们相关的数据,比如 WM_LBUTTONDOWWN 消息包含了鼠标以后位置的X坐标与Y坐标。
消息循环
MSG msg; GetMessage(&msg, NULL, 0, 0);
这个函数从队列头部删除第一条消息,如果队列是空的,直到另外一个功能块的消息停止排队。事实上,GetMessage阻塞并不会使你的程序没有反应。如果没有消息,程序不做任何事情。如果你须要执行后台处理,你可以创建额外的线程继续运行,而GetMessage函数等待另外一条消息。(查看写窗口进程)
TranslateMessage(&msg); DispatchMessage(&msg);
TranslateMessage函数与键盘输入关联,它把键盘的键击(键按下,按键摊开)转换成字符,你不须要真正的晓得这个函数是如何工作的,只须要晓得在调用DispatchMessage函数之前调用它。如果你须要更深入的懂得,MSDN文档的链接会给你更多的信息。
- 操作系统在消息队列放置一个WM_LBUTTONDOWN消息。
- 你的程序调用GetMessage函数。
- GetMessage中队列中提取WM_LBUTTONDOWN并填充MSG结构。
- 你的程序调用TranslateMessage和DispatchMessage函数。
- 在DispatchMessage,操作系统调用你的窗口进程。
- 你的窗口函数可以响应消息或忽略它。
当窗口函数返回,它将返回到DispatchMessage,下一条消息再回到消息循环。只要你的程序在运行,消息将继续达到队列。因此,你须要一个循环,不断的从队列中提取消息并调度它们。你可能想到的循环执行以下操作:
//警告:实际上不要这样写循环 while (1) { GetMessage(&msg, NULL, 0, 0); TranslateMessage(&msg); DispatchMessage(&msg); }
正如以上所写,这个循环永远不会结束。这是GetMessage函数放在循环内的返回值。正常情况下,GetMessage函数返回一个非零值。当你想要退出程序和中断消息循环,简单的调用PostQuitMessage函数。
PostQuitMessage(0);
PostQuitMessage函数将一个WM_QUIT消息放入队列,WM_QUIT是一条特别的消息,它引发GetMessage函数返回零值,消息循环结束的信号。这是修改后的消息循环:
// 正确的消息循环 MSG msg = { }; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
只要GetMessage函数返回非零值,在while循环中表达式的值就是真值,在调用PostQuitMessage函数后,表达式值为假值程序跳出循环。(这类行为有一个有趣的结果,你的窗口进程从未收到WM_QUIT消息,所以并不须要在窗口进程中为这个消息应用case语句。)
下一个显著的问题是:你应该在什么时候调用PostQuitMessage函数?我们回到本主题中的窗口关闭的问题。但我们首先要写我们的窗口进程。
宣布消息和发送消息
上一节谈到进入队列的消息,在某些情况下,操作系统将绕过消息队列,直接调用窗口进程。
停止这类辨别的术语有可能造成混杂:
宣布(Post)一条消息意味着消息在消息队列中,并通过消息循环调度(GetMessage和DispatchMessage)。
发送(Send)一条消息意味着跳过消息队列,操作系统直接调用窗口进程。
现在,区别不是很主要。窗口进程处理所有消息,但某些消息绕过消息队列,直接进入你的窗口进程。然而,如果你的应用程序窗口之间停止通信它可以有所作为。你可以在关于消息和消息队列(About Messages and Message Queues)的主题中找到更深入的探讨。
下一节:誊写窗口进程
文章结束给大家分享下程序员的一些笑话语录:
警告
有一个小伙子在一个办公大楼的门口抽着烟,一个妇女路过他身边,并对他 说, “你知道不知道这个东西会危害你的健康?我是说, 你有没有注意到香烟 盒上的那个警告(Warning)?”
小伙子说,“没事儿,我是一个程序员”。
那妇女说,“这又怎样?”
程序员说,“我们从来不关心 Warning,只关心 Error”
---------------------------------
原创文章 By
窗口和函数
---------------------------------