(1)没有按下菜单时,WndProc()执行,而AboutDlgProc()和EllipPushWndProc()不执行。(2)按下菜单时,WndProc()中执行:DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ;创建模式对话框About,其AboutDlgProc()执行, 此时*.rc里的 CONTROL "OK",IDMM,"EllipPush",WS_GROUP | WS_TABSTOP,73,79,32,14表明对话框About中有一个子窗口作为一个窗口有消息处理函数EllipPushWndProc,然后
EllipPushWndProc()执行,其中的WM_PAINT会画一个椭圆。当按下这个窗口时时,响应case WM_LBUTTONUP :SendMessage (GetParent (hwnd), WM_COMMAND,
GetWindowLong (hwnd, GWL_ID), (LPARAM) hwnd) ;发送IDMM这个命令给其父窗口(对话框About),在对话框About的事件处理函数AboutDlgProc()中处理IDMM:case IDMM : EndDialog (hDlg, 0) ;其中关闭了对话框.
注意:WndProc:RegisterClass()了,CreateWindow()了。EllipPushWndProc: 只RegisterClass(),但
没有CreateWindow(),但为什么最后能正常运行呢?是因为*.rc里的 CONTROL "OK",IDMM,"EllipPush",WS_GROUP | WS_TABSTOP,73,79,32,14会被转换成一个CreateWindow()函数.当编译资源描述档时,这条叙述在.RES和.EXE文件中的编码是相同的:即CONTROL这行就相当于
CreateWindow(),而且CONTROL后面的相关参数与CreateWindow()的参数一样,这也说明了这一点.
=========================================================源代码如下(由windows程序设计第11章的about3程序修改而来):
#include <windows.h>#include "resource.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;LRESULT CALLBACK EllipPushWndProc (HWND, UINT, WPARAM, LPARAM) ;
static WNDCLASS wndclass ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("About3") ; MSG msg ; HWND hwnd ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (hInstance, szAppName) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = EllipPushWndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = NULL ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = TEXT ("EllipPush") ;
RegisterClass (&wndclass) ; hwnd = CreateWindow (szAppName, TEXT ("About Box Demo Program"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ;}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static HINSTANCE hInstance ; switch (message) { case WM_CREATE : hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; return 0 ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDM_APP_ABOUT ://打开模式对话框ABOUT DialogBox (hInstance, MAKEINTRESOURCE(ABOUTBOX), hwnd, AboutDlgProc) ; return 0 ; } break ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_INITDIALOG : return TRUE ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDMM ://子窗口的ID号 EndDialog (hDlg, 0) ; return TRUE ; } break ; } return FALSE ;}
LRESULT CALLBACK EllipPushWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ TCHAR szText[40] ; HBRUSH hBrush ; HDC hdc ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_PAINT ://画一个椭圆 GetClientRect (hwnd, &rect) ; GetWindowText (hwnd, szText, sizeof (szText)) ; hdc = BeginPaint (hwnd, &ps) ; hBrush = CreateSolidBrush (GetSysColor (COLOR_WINDOW)) ; hBrush = (HBRUSH) SelectObject (hdc, hBrush) ; SetBkColor (hdc, GetSysColor (COLOR_WINDOW)) ; SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)) ; Ellipse (hdc, rect.left, rect.top, rect.right, rect.bottom) ; DrawText (hdc, szText, -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; DeleteObject (SelectObject (hdc, hBrush)) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_KEYUP : if (wParam != VK_SPACE) break ; case WM_LBUTTONUP ://向其父窗口(对话框About)发信息,包含了ID号IDMM,然后About会响应case
//WM_COMMAND : ... case IDMM :... SendMessage (GetParent (hwnd), WM_COMMAND, GetWindowLong (hwnd, GWL_ID), (LPARAM) hwnd) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}