窗口和消息
Windows程序所作的一切,都是响应发送给窗口消息处理程序的消息。
别呼叫我,我会呼叫您
窗口消息处理程序和窗口类别相关,窗口类别是程序呼叫RegisterClass注册的。依据该类别建立的窗口使用这个窗口消息处理程序来处理窗口的所有消息 。Windows通过呼叫窗口消息处理程序对窗口发送消息。
在第一次建立窗口时,Windows呼叫WndProc。在窗口关闭时,Windows也呼叫WndProc。 窗口改变大小、移动或者变成图示时,从菜单中选择某一项目、挪动滚动条、按下鼠标按钮或者从键盘输入字符时,以及窗口显示区域必须被及时更新时,Windows都要呼叫WndProc。
所有这些WndProc呼叫都以消息的形式进行。在大多数的Windows程序中,程序的主要部分用来处理消息。Windows可以发送给窗口消息处理程序 的消息通常都以WM开头的名字标识,并且都在WINUSER.H表头中定义。
在windows中,窗口中发送的一切都以消息的形式传给窗口处理程序。然后,窗口消息处理程序以某种方式响应这个消息,或者将消息传给DefWindowProc,进行内定处理。
wParam和lParam中包含了消息的详细信息。 例如WM_SIZE消息的参数wParam的值是SIZE_RESTORED、SIZE_MINIMIZED、SIZE_MAXIMIZED、SIZE_MAXSHOW或者SIZE_MAXHIDE,参数wParam表明窗口是非最小化还是非最大化,是最小化、最大化,还是隐藏。 lParam参数包含了新窗口的大小,新宽度和新高度均为16位的值,合在一起成为32位的lParam。 WINDEF.H中提供了帮助程序写作者从lParam中取出这两个值的宏。
DefWindowProc处理完消息后会产生其他的消息。 假设用户单击了Close按钮,或者假设用建盘或者鼠标从系统菜单中选择了Close,DefWindowProc处理这一键盘或者鼠标输入,在检测到使用者选择了Close选项之后,它给窗口消息处理程序发送一条WM_SYSCOMMAND消息。WndProc建这个消息传给DefWindowProc。 DefWindowProc给窗口消息处理程序发送一条WM_CLOSE消息来响应之。WndProc再次将它传给DefWindowProc。 DestroyWindow呼叫来响应这条WM_CLOSE消息。DestroyWindow导致Windows给消息处理程序发送一条WM_DESTORY消息。WndProc再呼叫PostQuitMessage,将一条WM_QUIT消息放入消息队列中,以此来响应此消息。
队列化消息与非队列化消息
Windows程序有一个消息循环,它呼叫GetMessage从消息队列中取出消息,并且呼叫DispatchMessage将消息发送给窗口消息处理程序。
消息能够被分为 队列化的消息 和 非队列化的消息。 队列化的消息是由Windows放入程序消息队列中的。在程序的消息循环中,中心传回并分配给窗口消息处理程序。非队列化的消息在Windows呼叫窗口时直接送给窗口消息处理程序。也就是说队列化的消息被 发送给 消息队列, 而非队列化的消息则 发送给 窗口消息处理程序。在任何情况下,窗口消息处理程序都将获得窗口所有的消息——包括队列化的和非队列化的消息。 窗口消息处理程序是窗口的消息中心。
队列化的消息基本上是使用者输入的结果,以击键(WM_KEYDOWN和WM_KEYUP消息)、击键产生的字符( WM_CHAR) 、鼠标移动(WM_MOUSEMOVE) 和鼠标按钮( WM_LBUTTONDOWN) 的形式给出。 队列化的消息还有 时钟消息(WM_TIMER)、更新消息( WM_PAINT ) 、退出消息 ( WM_QUIT )。
非队列化消息则是其它消息。在许多情况下,非队列化消息来自呼叫特定的Windows函数。例如,当WinMain呼叫CreateWindow时,Windows将建立窗口并在处理中给窗口消息处理程序发送一个WM_CREATE消息。当WinMain呼叫ShowWindow时,Windows将给窗口消息处理程序发送WM_SIZE和WM_SHOWWINDOW消息。当WinMain呼叫UpdateWindow时,Windows将给窗口消息处理程序发送WM_PAINT消息。键盘或鼠标输入时发出的队列化消息信号,也能在非队列化消息中出现。例如,用键盘或鼠标选择了一个菜单项时,键盘或鼠标消息就是队列化的,而说明菜单项已选中的WM_COMMAND消息则可能就是非队列化的。
从窗口消息处理程序的角度来看,这些消息是以一种有序的、同步的方式进出的。窗口消息处理程序可以处理它们,也可以不处理。消息与硬件的中断不同。在一个窗口消息处理程序中处理消息时,程序不会被其它消息突然中断。
参考《windows程序设计》