1 /*---------------------------------------------
2 CHECKER4.C -- Mouse Hit-Test Demo Program No.4
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 int idFocus = 0;
14 TCHAR szChildClass[] = TEXT("Checker4_Child");
15
16 int WINAPI WinMain( __in HINSTANCE hInstance
17 , __in_opt HINSTANCE hPrevInstance
18 , __in LPSTR lpCmdLine
19 , __in int nShowCmd )
20 {
21 static TCHAR szAppName[] = TEXT("Checker4");
22 HWND hwnd;
23 MSG msg;
24 WNDCLASS wndclass;
25
26 wndclass.style = CS_HREDRAW | CS_VREDRAW;
27 wndclass.lpfnWndProc = WndProc;
28 wndclass.cbClsExtra = 0;
29 wndclass.cbWndExtra = 0;
30 wndclass.hInstance = hInstance;
31 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
32 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
33 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
34 wndclass.lpszMenuName = NULL;
35 wndclass.lpszClassName = szAppName;
36
37 if (!RegisterClass(&wndclass))
38 {
39 MessageBox(NULL, TEXT("Program requires Windows NT!")
40 , szAppName, MB_ICONERROR);
41 return 0;
42 }
43
44 wndclass.lpfnWndProc = ChildWndProc;
45 wndclass.cbWndExtra = sizeof(long);
46 wndclass.hIcon = NULL;
47 wndclass.lpszClassName = szChildClass;
48
49 RegisterClass(&wndclass);
50
51 hwnd = CreateWindow(szAppName, TEXT("Checker4 Mouse Hit-Test Demo")
52 , WS_OVERLAPPEDWINDOW
53 , CW_USEDEFAULT, CW_USEDEFAULT
54 , CW_USEDEFAULT, CW_USEDEFAULT
55 , NULL, NULL, hInstance, NULL);
56
57 ShowWindow(hwnd, nShowCmd);
58 UpdateWindow(hwnd);
59
60 while (GetMessage(&msg, NULL, 0, 0))
61 {
62 TranslateMessage(&msg);
63 DispatchMessage(&msg);
64 }
65
66 return msg.wParam;
67 }
68
69 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
70 {
71 static HWND hwndChild[DIVISIONS][DIVISIONS];
72 int cxBlock, cyBlock, x, y;
73
74 switch (message)
75 {
76 case WM_CREATE:
77 for (x = 0; x != DIVISIONS; ++x)
78 for (y = 0; y != DIVISIONS; ++y)
79 {
80 hwndChild[x][y] = CreateWindow(szChildClass, NULL
81 , WS_CHILDWINDOW | WS_VISIBLE
82 , 0, 0, 0, 0
83 , hwnd, (HMENU)(y << 8 | x)
84 , (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 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 //on set-focus message, set focus to child window
106 case WM_SETFOCUS:
107 SetFocus(GetDlgItem(hwnd, idFocus));
108 return 0;
109
110 //on key-down message, possibly change the focus window
111 case WM_KEYDOWN:
112 x = idFocus & 0xff;
113 y = idFocus >> 8;
114
115 switch (wParam)
116 {
117 case VK_UP:
118 --y;
119 break;
120
121 case VK_DOWN:
122 ++y;
123 break;
124
125 case VK_LEFT:
126 --x;
127 break;
128
129 case VK_RIGHT:
130 ++x;
131 break;
132
133 case VK_HOME:
134 x = y = 0;
135 break;
136
137 case VK_END:
138 x = y = DIVISIONS - 1;
139 break;
140
141 default:
142 return 0;
143 }
144
145 x = (x + DIVISIONS) % DIVISIONS;
146 y = (y + DIVISIONS) % DIVISIONS;
147
148 idFocus = y << 8 | x;
149 SetFocus(GetDlgItem(hwnd, idFocus));
150 return 0;
151
152 case WM_DESTROY:
153 PostQuitMessage(0);
154 return 0;
155 }
156
157 return DefWindowProc(hwnd, message, wParam, lParam);
158 }
159
160 LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
161 {
162 HDC hdc;
163 PAINTSTRUCT ps;
164 RECT rect;
165
166 switch (message)
167 {
168 case WM_CREATE:
169 SetWindowLong(hwnd, DWL_MSGRESULT, 0); // on/off flag
170 return 0;
171
172 case WM_KEYDOWN:
173 //send most key press to the parent window
174 if (wParam != VK_RETURN && wParam != VK_SPACE)
175 {
176 SendMessage(GetParent(hwnd), message, wParam, lParam);
177 return 0;
178 }
179
180 //for Return and Space, fall through to toggle the square
181 case WM_LBUTTONDOWN:
182 SetWindowLong(hwnd, DWL_MSGRESULT, 1 ^ GetWindowLong(hwnd, DWL_MSGRESULT));
183 SetFocus(hwnd);
184 InvalidateRect(hwnd, &rect, FALSE);
185 return 0;
186
187 //for focus message, invalidate the window for repaint
188 case WM_SETFOCUS:
189 idFocus = GetWindowLong(hwnd, GWL_ID);
190
191 //fall through
192 case WM_KILLFOCUS:
193 InvalidateRect(hwnd, NULL, TRUE);
194 return 0;
195
196 case WM_PAINT:
197 hdc = BeginPaint(hwnd, &ps);
198
199 GetClientRect(hwnd, &rect);
200 Rectangle(hdc, 0, 0, rect.right, rect.bottom);
201
202 //draw the "x" mark
203 if (GetWindowLong(hwnd, DWL_MSGRESULT))
204 {
205 MoveToEx(hdc, 0, 0, NULL);
206 LineTo(hdc, rect.right, rect.bottom);
207 MoveToEx(hdc, 0, rect.bottom, NULL);
208 LineTo(hdc, rect.right, 0);
209 }
210
211 //draw the "focus" rectangle
212 if (hwnd == GetFocus())
213 {
214 rect.left += rect.right / 10;
215 rect.right -= rect.left;
216 rect.top += rect.bottom / 10;
217 rect.bottom -= rect.top;
218
219 SelectObject(hdc, GetStockObject(NULL_BRUSH));
220 SelectObject(hdc, CreatePen(PS_DASH, 0, 0));
221 Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
222 DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
223 }
224
225 EndPaint(hwnd, &ps);
226 return 0;
227 }
228
229 return DefWindowProc(hwnd, message, wParam, lParam);
230 }
澳门金沙国际,第七章 鼠标(CHECKER4)。CHECKER4.C