第七章 鼠标(CHECKER3)
1 /*--------------------------------------------- 2 CHECKER3.C -- Mouse Hit-Test Demo Program No.3 3 (c) Charles Petzold, 1998 4 ---------------------------------------------*/ 5 6 #include <Windows.h> 7 8 #define DIVISIONS 5 9 10 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 11 LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM); 12 13 TCHAR szChildClass[] = TEXT("Checker3_Child"); 14 15 int WINAPI WinMain( __in HINSTANCE hInstance 16 , __in_opt HINSTANCE hPrevInstance 17 , __in LPSTR lpCmdLine 18 , __in int nShowCmd ) 19 { 20 static TCHAR szAppName[] = TEXT("Checker3"); 21 HWND hwnd; 22 MSG msg; 23 WNDCLASS wndclass; 24 25 wndclass.style = CS_HREDRAW | CS_VREDRAW; 26 wndclass.lpfnWndProc = WndProc; 27 wndclass.cbClsExtra = 0; 28 wndclass.cbWndExtra = 0; 29 wndclass.hInstance = hInstance; 30 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 31 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 32 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 33 wndclass.lpszMenuName = NULL; 34 wndclass.lpszClassName = szAppName; 35 36 if (!RegisterClass(&wndclass)) 37 { 38 MessageBox(NULL, TEXT("Program requires Windows NT!") 39 , szAppName, MB_ICONERROR); 40 return 0; 41 } 42 43 wndclass.lpfnWndProc = ChildWndProc; 44 wndclass.cbWndExtra = sizeof(long); 45 wndclass.hIcon = NULL; 46 wndclass.lpszClassName = szChildClass; 47 48 RegisterClass(&wndclass); 49 50 hwnd = CreateWindow(szAppName, TEXT("Checker3 Mouse Hit-Test Demo") 51 , WS_OVERLAPPEDWINDOW 52 , CW_USEDEFAULT, CW_USEDEFAULT 53 , CW_USEDEFAULT, CW_USEDEFAULT 54 , NULL, NULL, hInstance, NULL); 55 56 ShowWindow(hwnd, nShowCmd); 57 UpdateWindow(hwnd); 58 59 while (GetMessage(&msg, NULL, 0, 0)) 60 { 61 TranslateMessage(&msg); 62 DispatchMessage(&msg); 63 } 64 65 return msg.wParam; 66 } 67 68 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 69 { 70 static HWND hwndChild[DIVISIONS][DIVISIONS]; 71 int cxBlock, cyBlock, x, y; 72 73 switch (message) 74 { 75 case WM_CREATE: 76 for (x = 0; x != DIVISIONS; ++x) 77 for (y = 0; y != DIVISIONS; ++y) 78 { 79 hwndChild[x][y] = CreateWindow(szChildClass, NULL 80 , WS_CHILDWINDOW | WS_VISIBLE 81 , 0, 0, 0, 0 82 , hwnd, (HMENU)(y << 8 | x) 83 , (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE) 84 , NULL); 85 } 86 return 0; 87 88 case WM_SIZE: 89 cxBlock = LOWORD(lParam) / DIVISIONS; 90 cyBlock = HIWORD(lParam) / DIVISIONS; 91 92 for (x = 0; x != DIVISIONS; ++x) 93 for(y = 0; y != DIVISIONS; ++y) 94 { 95 MoveWindow(hwndChild[x][y] 96 , x * cxBlock, y * cyBlock 97 , cxBlock, cyBlock, TRUE); 98 } 99 return 0; 100 101 case WM_LBUTTONDOWN: 102 MessageBeep(0); 103 return 0; 104 105 case WM_DESTROY: 106 PostQuitMessage(0); 107 return 0; 108 } 109 110 return DefWindowProc(hwnd, message, wParam, lParam); 111 } 112 113 LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 114 { 115 HDC hdc; 116 PAINTSTRUCT ps; 117 RECT rect; 118 119 switch (message) 120 { 121 case WM_CREATE: 122 SetWindowLong(hwnd, 0, 0); // on/off flag 123 return 0; 124 125 case WM_LBUTTONDOWN: 126 SetWindowLong(hwnd, 0, 1 ^ GetWindowLong(hwnd, 0)); 127 InvalidateRect(hwnd, NULL, FALSE); 128 return 0; 129 130 case WM_PAINT: 131 hdc = BeginPaint(hwnd, &ps); 132 133 GetClientRect(hwnd, &rect); 134 Rectangle(hdc, 0, 0, rect.right, rect.bottom); 135 136 if (GetWindowLong(hwnd, 0)) 137 { 138 MoveToEx(hdc, 0, 0, NULL); 139 LineTo(hdc, rect.right, rect.bottom); 140 MoveToEx(hdc, 0, rect.bottom, NULL); 141 LineTo(hdc, rect.right, 0); 142 } 143 144 EndPaint(hwnd, &ps); 145 return 0; 146 } 147 148 return DefWindowProc(hwnd, message, wParam, lParam); 149 }