11.2.2 消息处理函数(3)
3. 结束程序
有人可能认为,关闭窗口就会关闭应用程序;但为了获得这样的特性,实际上必须添加一些代码。关闭窗口时应用程序不会自动关闭的原因在于可能需要做一些清理工作,应用程序也可能有多个窗口。当用户通过双击标题栏图标或单击关闭按钮关闭窗口时,系统将生成一条WM_DESTROY消息。因此,为了关闭应用程序,需要在WindowProc()函数中处理WM_DESTROY消息。可以使用下面这条语句生成一条WM_QUIT消息进行处理:
- PostQuitMessage(0);
这里的实参是一个退出代码。顾名思义,该Windows API函数在应用程序的消息队列中添加一条WM_QUIT消息。该消息导致WinMain()中的GetMessage()函数返回FALSE,并结束消息循环,从而终止程序。
4. 完整的WindowProc()函数
我们已经讨论了构成本示例中完整的WindowProc()函数所需的所有元素。该函数的代码如下所示:
- // Listing OFWIN_2
- LRESULT CALLBACK WindowProc(HWND hWnd, UINT message,
- WPARAM wParam, LPARAM lParam)
- {
- switch(message) // Process selected messages
- {
- case WM_PAINT: // Message is to redraw the window
- HDC hDC; // Display context handle
- PAINTSTRUCT PaintSt; // Structure defining area to be drawn
- RECT aRect; // A working rectangle
- hDC = BeginPaint(hWnd, &PaintSt); // Prepare to draw the window
- // Get upper left and lower right of client area
- GetClientRect(hWnd, &aRect);
- SetBkMode(hDC, TRANSPARENT); // Set text background mode
- // Now draw the text in the window client area
- DrawText(
- hDC, // Device context handle
- _T("But, soft! What light through yonder window breaks "),
- -1, // Indicate null terminated string
- &aRect, // Rectangle in which text is to be drawn
- DT_SINGLELINE| // Text format - single line
- DT_CENTER| // - centered in the line
- DT_VCENTER); // - line centered in aRect
- EndPaint(hWnd, &PaintSt); // Terminate window redraw operation
- return 0;
- case WM_DESTROY: // Window is being destroyed
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
示例说明
除了最后一条语句外,整个函数体只是一条switch语句而已。特定的case是基于message参数传递给该函数的消息ID而选择的。由于本示例相当简单,只需要处理两种不同的消息:WM_PAINT和WM_DESTROY。在switch语句的后面,通过调用DefWindowProc()函数,将所有其他消息回传给Windows。DefWindowProc()函数的实参就是传递给本函数的实参,因此只需要按照原样将它们传回去即可。注意每种消息类型处理代码最后的return语句。就处理的这两种消息而言,返回值是0。