时间仓促,草草完成1234,没有完成5,因为设计方案不好。
1 /*---------------------------------------------
2 OWNDRAW.C -- Owner-Draw Button Demo Program
3 (c) Charles Petzold, 1998
4 ---------------------------------------------*/
5 /*
6 修改为:QuizZJ.cpp
7 修改者:赵杰
8 */
9
10 #include <windows.h>
11
12 #define ID_SMALLER 1
13 #define ID_LARGER 2
14
15 #define BTN_WIDTH (8 * cxChar)
16 #define BTN_HEIGHT (4 * cyChar)
17
18 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
19
20 HINSTANCE hInst ;
21
22 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
23 PSTR szCmdLine, int iCmdShow)
24 {
25 static TCHAR szAppName[] = TEXT ("QuizZJ") ;
26 MSG msg ;
27 HWND hwnd ;
28 WNDCLASS wndclass ;
29
30 hInst = hInstance ;
31
32 wndclass.style = CS_HREDRAW | CS_VREDRAW ;
33 wndclass.lpfnWndProc = WndProc ;
34 wndclass.cbClsExtra = 0 ;
35 wndclass.cbWndExtra = 0 ;
36 wndclass.hInstance = hInstance ;
37 wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
38 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
39 wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
40 wndclass.lpszMenuName = NULL ;
41 wndclass.lpszClassName = szAppName ;
42
43 if (!RegisterClass (&wndclass))
44 {
45 MessageBox (NULL, TEXT ("This program requires Windows NT!"),
46 szAppName, MB_ICONERROR) ;
47 return 0 ;
48 }
49
50 hwnd = CreateWindow (szAppName, TEXT ("Quiz 2"),
51 WS_OVERLAPPEDWINDOW,
52 CW_USEDEFAULT, CW_USEDEFAULT,
53 CW_USEDEFAULT, CW_USEDEFAULT,
54 NULL, NULL, hInstance, NULL) ;
55
56 ShowWindow (hwnd, iCmdShow) ;
57 UpdateWindow (hwnd) ;
58
59 while (GetMessage (&msg, NULL, 0, 0))
60 {
61 TranslateMessage (&msg) ;
62 DispatchMessage (&msg) ;
63 }
64 return msg.wParam ;
65 }
66
67 void Triangle (HDC hdc, POINT pt[])
68 {
69 SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
70 Polygon (hdc, pt, 3) ;
71 SelectObject (hdc, GetStockObject (WHITE_BRUSH)) ;
72 }
73
74 WNDPROC BtnWndProcPrev;
75
76 LRESULT CALLBACK BtnWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
77 switch ( uMsg ) {
78 case WM_KEYDOWN :
79 case WM_KEYUP :
80 case WM_CHAR :
81 switch ( wParam ) {
82 case VK_F1 :
83 case VK_TAB :
84 case TEXT('R') :
85 case TEXT('B') :
86 case TEXT('G') :
87 ::SendMessage( ::GetParent( hWnd ), uMsg, wParam, lParam );
88 return 0;
89 case TEXT('E') :
90 case VK_RETURN :
91 wParam = VK_SPACE;
92 }
93 break;
94 }
95 return ::CallWindowProc( BtnWndProcPrev, hWnd, uMsg, wParam, lParam );
96 }
97
98 LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
99 {
100 static HWND hwndSmaller, hwndLarger ;
101 static int cxClient, cyClient, cxChar, cyChar ;
102 static BOOL bFirstFocus = TRUE;
103 static HBRUSH hbrBack;
104 int cx, cy ;
105 LPDRAWITEMSTRUCT pdis ;
106 POINT pt[3] ;
107 RECT rc ;
108
109 switch (message)
110 {
111 case WM_CREATE :
112 hbrBack = ::CreateSolidBrush( RGB(255,255,255) );
113 ::SetClassLong( hwnd, GCL_HBRBACKGROUND, (LONG)hbrBack );
114
115 cxChar = LOWORD (GetDialogBaseUnits ()) ;
116 cyChar = HIWORD (GetDialogBaseUnits ()) ;
117
118 // Create the owner-draw pushbuttons
119
120 hwndSmaller = CreateWindow (TEXT ("button"), TEXT (""),
121 WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
122 0, 0, BTN_WIDTH, BTN_HEIGHT,
123 hwnd, (HMENU) ID_SMALLER, hInst, NULL) ;
124
125 hwndLarger = CreateWindow (TEXT ("button"), TEXT (""),
126 WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
127 0, 0, BTN_WIDTH, BTN_HEIGHT,
128 hwnd, (HMENU) ID_LARGER, hInst, NULL) ;
129 BtnWndProcPrev = (WNDPROC)::GetWindowLong( hwndSmaller, GWL_WNDPROC );
130 ::SetWindowLong( hwndSmaller, GWL_WNDPROC, (LONG)BtnWndProc );
131 ::SetWindowLong( hwndLarger, GWL_WNDPROC, (LONG)BtnWndProc );
132 return 0 ;
133
134 case WM_SIZE :
135 cxClient = LOWORD (lParam) ;
136 cyClient = HIWORD (lParam) ;
137
138 // Move the buttons to the new center
139
140 MoveWindow (hwndSmaller, cxClient / 2 - 3 * BTN_WIDTH / 2,
141 cyClient / 2 - BTN_HEIGHT / 2,
142 BTN_WIDTH, BTN_HEIGHT, TRUE) ;
143
144 MoveWindow (hwndLarger, cxClient / 2 + BTN_WIDTH / 2,
145 cyClient / 2 - BTN_HEIGHT / 2,
146 BTN_WIDTH, BTN_HEIGHT, TRUE) ;
147 return 0 ;
148
149 case WM_LBUTTONUP :
150 hbrBack = ::CreateSolidBrush( RGB(255,255,255) );
151 ::SetClassLong( hwnd, GCL_HBRBACKGROUND, (LONG)hbrBack );
152 ::InvalidateRect( hwnd, NULL, TRUE );
153 return 0;
154
155 case WM_SETFOCUS :
156 ::SetFocus( bFirstFocus ? hwndSmaller : hwndLarger );
157 return 0;
158
159 case WM_KEYDOWN :
160 // case WM_CHAR :
161 // case WM_KEYUP :
162 switch ( wParam ) {
163 case VK_TAB :
164 bFirstFocus = ! bFirstFocus;
165 ::SetFocus( bFirstFocus ? hwndSmaller : hwndLarger );
166 return 0;
167 case VK_F1 :
168 MessageBox( hwnd, TEXT("作者:赵杰\n学号:10092130243"), TEXT("作者信息"), MB_OK );
169 return 0;
170 case TEXT('R') :
171 if ( (::GetKeyState(VK_RCONTROL)<0)||(::GetKeyState(VK_LCONTROL)<0) ) {
172 hbrBack = ::CreateSolidBrush( RGB(255,0,0) );
173 ::SetClassLong( hwnd, GCL_HBRBACKGROUND, (LONG)hbrBack );
174 ::InvalidateRect( hwnd, NULL, TRUE );
175 }
176 return 0;
177 case TEXT('G') :
178 if ( (::GetKeyState(VK_RCONTROL)<0)||(::GetKeyState(VK_LCONTROL)<0) ) {
179 hbrBack = ::CreateSolidBrush( RGB(0,255,0) );
180 ::SetClassLong( hwnd, GCL_HBRBACKGROUND, (LONG)hbrBack );
181 ::InvalidateRect( hwnd, NULL, TRUE );
182 }
183 return 0;
184 case TEXT('B') :
185 if ( (::GetKeyState(VK_RCONTROL)<0)||(::GetKeyState(VK_LCONTROL)<0) ) {
186 hbrBack = ::CreateSolidBrush( RGB(0,0,255) );
187 ::SetClassLong( hwnd, GCL_HBRBACKGROUND, (LONG)hbrBack );
188 ::InvalidateRect( hwnd, NULL, TRUE );
189 }
190 return 0;
191 }
192 return 0;
193
194 case WM_COMMAND :
195 GetWindowRect (hwnd, &rc) ;
196
197 // Make the window 10% smaller or larger
198
199 switch (wParam)
200 {
201 case ID_SMALLER :
202 rc.left += cxClient / 20 ;
203 rc.right -= cxClient / 20 ;
204 rc.top += cyClient / 20 ;
205 rc.bottom -= cyClient / 20 ;
206 break ;
207
208 case ID_LARGER :
209 rc.left -= cxClient / 20 ;
210 rc.right += cxClient / 20 ;
211 rc.top -= cyClient / 20 ;
212 rc.bottom += cyClient / 20 ;
213 break ;
214 }
215
216 MoveWindow (hwnd, rc.left, rc.top, rc.right - rc.left,
217 rc.bottom - rc.top, TRUE) ;
218 return 0 ;
219
220 case WM_DRAWITEM :
221 pdis = (LPDRAWITEMSTRUCT) lParam ;
222
223 // Fill area with white and frame it black
224
225 FillRect (pdis->hDC, &pdis->rcItem,
226 (HBRUSH) GetStockObject (WHITE_BRUSH)) ;
227
228 FrameRect (pdis->hDC, &pdis->rcItem,
229 (HBRUSH) GetStockObject (BLACK_BRUSH)) ;
230
231 // Draw inward and outward black triangles
232
233 cx = pdis->rcItem.right - pdis->rcItem.left ;
234 cy = pdis->rcItem.bottom - pdis->rcItem.top ;
235
236 switch (pdis->CtlID)
237 {
238 case ID_SMALLER :
239 pt[0].x = 3 * cx / 8 ; pt[0].y = 1 * cy / 8 ;
240 pt[1].x = 5 * cx / 8 ; pt[1].y = 1 * cy / 8 ;
241 pt[2].x = 4 * cx / 8 ; pt[2].y = 3 * cy / 8 ;
242
243 Triangle (pdis->hDC, pt) ;
244
245 pt[0].x = 7 * cx / 8 ; pt[0].y = 3 * cy / 8 ;
246 pt[1].x = 7 * cx / 8 ; pt[1].y = 5 * cy / 8 ;
247 pt[2].x = 5 * cx / 8 ; pt[2].y = 4 * cy / 8 ;
248
249 Triangle (pdis->hDC, pt) ;
250
251 pt[0].x = 5 * cx / 8 ; pt[0].y = 7 * cy / 8 ;
252 pt[1].x = 3 * cx / 8 ; pt[1].y = 7 * cy / 8 ;
253 pt[2].x = 4 * cx / 8 ; pt[2].y = 5 * cy / 8 ;
254
255 Triangle (pdis->hDC, pt) ;
256
257 pt[0].x = 1 * cx / 8 ; pt[0].y = 5 * cy / 8 ;
258 pt[1].x = 1 * cx / 8 ; pt[1].y = 3 * cy / 8 ;
259 pt[2].x = 3 * cx / 8 ; pt[2].y = 4 * cy / 8 ;
260
261 Triangle (pdis->hDC, pt) ;
262 break ;
263
264 case ID_LARGER :
265 pt[0].x = 5 * cx / 8 ; pt[0].y = 3 * cy / 8 ;
266 pt[1].x = 3 * cx / 8 ; pt[1].y = 3 * cy / 8 ;
267 pt[2].x = 4 * cx / 8 ; pt[2].y = 1 * cy / 8 ;
268
269 Triangle (pdis->hDC, pt) ;
270
271 pt[0].x = 5 * cx / 8 ; pt[0].y = 5 * cy / 8 ;
272 pt[1].x = 5 * cx / 8 ; pt[1].y = 3 * cy / 8 ;
273 pt[2].x = 7 * cx / 8 ; pt[2].y = 4 * cy / 8 ;
274
275 Triangle (pdis->hDC, pt) ;
276
277 pt[0].x = 3 * cx / 8 ; pt[0].y = 5 * cy / 8 ;
278 pt[1].x = 5 * cx / 8 ; pt[1].y = 5 * cy / 8 ;
279 pt[2].x = 4 * cx / 8 ; pt[2].y = 7 * cy / 8 ;
280
281 Triangle (pdis->hDC, pt) ;
282
283 pt[0].x = 3 * cx / 8 ; pt[0].y = 3 * cy / 8 ;
284 pt[1].x = 3 * cx / 8 ; pt[1].y = 5 * cy / 8 ;
285 pt[2].x = 1 * cx / 8 ; pt[2].y = 4 * cy / 8 ;
286
287 Triangle (pdis->hDC, pt) ;
288 break ;
289 }
290
291 // Invert the rectangle if the button is selected
292
293 if (pdis->itemState & ODS_SELECTED)
294 InvertRect (pdis->hDC, &pdis->rcItem) ;
295
296 // Draw a focus rectangle if the button has the focus
297
298 if (pdis->itemState & ODS_FOCUS)
299 {
300 pdis->rcItem.left += cx / 16 ;
301 pdis->rcItem.top += cy / 16 ;
302 pdis->rcItem.right -= cx / 16 ;
303 pdis->rcItem.bottom -= cy / 16 ;
304
305 DrawFocusRect (pdis->hDC, &pdis->rcItem) ;
306 }
307 return 0 ;
308
309 case WM_DESTROY :
310 PostQuitMessage (0) ;
311 return 0 ;
312 }
313 return DefWindowProc (hwnd, message, wParam, lParam) ;
314 }
315