[MAGNIFY]
[reactos.git] / reactos / base / applications / magnify / magnifier.c
1 /*
2 * PROJECT: ReactOS Magnify
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/magnify/magnifier.c
5 * PURPOSE: Magnification of parts of the screen.
6 * AUTHORS:
7 * Marc Piulachs <marc.piulachs@codexchange.net>
8 * David Quintana <gigaherz@gmail.com>
9 */
10
11 /* TODO: AppBar */
12 #include "magnifier.h"
13
14 #include <winbase.h>
15 #include <winuser.h>
16 #include <wingdi.h>
17 #include <winnls.h>
18 #include <shellapi.h>
19 #include <windowsx.h>
20
21 #include "resource.h"
22
23 const TCHAR szWindowClass[] = TEXT("MAGNIFIER");
24
25 #define MAX_LOADSTRING 100
26
27 /* Global Variables */
28 HINSTANCE hInst;
29 HWND hMainWnd;
30
31 TCHAR szTitle[MAX_LOADSTRING];
32
33 #define TIMER_SPEED 1
34 #define REPAINT_SPEED 100
35
36 DWORD lastTicks = 0;
37
38 HWND hDesktopWindow = NULL;
39
40 #define APPMSG_NOTIFYICON (WM_APP+1)
41 HICON notifyIcon;
42 NOTIFYICONDATA nid;
43 HMENU notifyMenu;
44 HWND hOptionsDialog;
45 BOOL bOptionsDialog = FALSE;
46
47 BOOL bRecreateOffscreenDC = TRUE;
48 LONG sourceWidth = 0;
49 LONG sourceHeight = 0;
50 HDC hdcOffscreen = NULL;
51 HANDLE hbmpOld;
52 HBITMAP hbmpOffscreen = NULL;
53
54 /* Current magnified area */
55 POINT cp;
56
57 /* Last positions */
58 POINT pMouse;
59 POINT pCaret;
60 POINT pFocus;
61 HWND pCaretWnd;
62 HWND pFocusWnd;
63
64 ATOM MyRegisterClass(HINSTANCE hInstance);
65 BOOL InitInstance(HINSTANCE, int);
66 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
67 INT_PTR CALLBACK AboutProc(HWND, UINT, WPARAM, LPARAM);
68 INT_PTR CALLBACK OptionsProc(HWND, UINT, WPARAM, LPARAM);
69 INT_PTR CALLBACK WarningProc(HWND, UINT, WPARAM, LPARAM);
70
71 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
72 {
73 MSG msg;
74 HACCEL hAccelTable;
75
76 UNREFERENCED_PARAMETER(hPrevInstance);
77 UNREFERENCED_PARAMETER(lpCmdLine);
78
79 switch (GetUserDefaultUILanguage())
80 {
81 case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT):
82 SetProcessDefaultLayout(LAYOUT_RTL);
83 break;
84
85 default:
86 break;
87 }
88
89 /* Initialize global strings */
90 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
91 MyRegisterClass(hInstance);
92
93 /* Perform application initialization */
94 if (!InitInstance(hInstance, nCmdShow))
95 return FALSE;
96
97 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MAGNIFIER));
98
99 /* Main message loop */
100 while (GetMessage(&msg, NULL, 0, 0))
101 {
102 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
103 {
104 TranslateMessage(&msg);
105 DispatchMessage(&msg);
106 }
107 }
108
109
110 SelectObject(hdcOffscreen, hbmpOld);
111 DeleteObject (hbmpOffscreen);
112 DeleteDC(hdcOffscreen);
113
114 return (int) msg.wParam;
115 }
116
117 ATOM MyRegisterClass(HINSTANCE hInstance)
118 {
119 WNDCLASS wc;
120
121 wc.style = CS_HREDRAW | CS_VREDRAW;
122 wc.lpfnWndProc = WndProc;
123 wc.cbClsExtra = 0;
124 wc.cbWndExtra = 0;
125 wc.hInstance = hInstance;
126 wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON));
127 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
128 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
129 wc.lpszMenuName = NULL; //MAKEINTRESOURCE(IDC_MAGNIFIER);
130 wc.lpszClassName = szWindowClass;
131
132 return RegisterClass(&wc);
133 }
134
135 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
136 {
137 RECT rcWorkArea;
138 hInst = hInstance; // Store instance handle in our global variable
139
140 SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0);
141
142 /* Create the Window */
143 hMainWnd = CreateWindowEx(
144 WS_EX_TOPMOST | WS_EX_PALETTEWINDOW,
145 szWindowClass,
146 szTitle,
147 WS_OVERLAPPEDWINDOW,
148 CW_USEDEFAULT,
149 CW_USEDEFAULT,
150 (rcWorkArea.right - rcWorkArea.left) * 2 / 3,
151 200,
152 NULL,
153 NULL,
154 hInstance,
155 NULL);
156
157 if (!hMainWnd)
158 return FALSE;
159
160 ShowWindow(hMainWnd, bStartMinimized ? SW_MINIMIZE : nCmdShow);
161 UpdateWindow(hMainWnd);
162
163 // Windows 2003's Magnifier always shows this dialog, and exits when the dialog isclosed.
164 // Should we add a custom means to prevent opening it?
165 hOptionsDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOGOPTIONS), hMainWnd, OptionsProc);
166
167 if (bShowWarning)
168 DialogBox(hInstance, MAKEINTRESOURCE(IDD_WARNINGDIALOG), hMainWnd, WarningProc);
169
170 return TRUE;
171 }
172
173 void Refresh()
174 {
175 if (!IsIconic(hMainWnd))
176 {
177 /* Invalidate the client area forcing a WM_PAINT message */
178 InvalidateRgn(hMainWnd, NULL, TRUE);
179 }
180 }
181
182 void GetBestOverlapWithMonitors(LPRECT rect)
183 {
184 int rcLeft, rcTop;
185 int rcWidth, rcHeight;
186 RECT rcMon;
187 HMONITOR hMon = MonitorFromRect(rect, MONITOR_DEFAULTTONEAREST);
188 MONITORINFO info;
189 info.cbSize = sizeof(info);
190
191 GetMonitorInfo(hMon, &info);
192
193 rcMon = info.rcMonitor;
194
195 rcLeft = rect->left;
196 rcTop = rect->top;
197 rcWidth = (rect->right - rect->left);
198 rcHeight = (rect->bottom - rect->top);
199
200 if (rcLeft < rcMon.left)
201 rcLeft = rcMon.left;
202
203 if (rcTop < rcMon.top)
204 rcTop = rcMon.top;
205
206 if (rcLeft > (rcMon.right - rcWidth))
207 rcLeft = (rcMon.right - rcWidth);
208
209 if (rcTop > (rcMon.bottom - rcHeight))
210 rcTop = (rcMon.bottom - rcHeight);
211
212 OffsetRect(rect, (rcLeft-rect->left), (rcTop-rect->top));
213 }
214
215 void Draw(HDC aDc)
216 {
217 HDC desktopHdc = NULL;
218
219 RECT sourceRect, intersectedRect;
220 RECT targetRect, appRect;
221 DWORD rop = SRCCOPY;
222 CURSORINFO cinfo;
223 ICONINFO iinfo;
224
225 int AppWidth, AppHeight;
226
227 if (bInvertColors)
228 rop = NOTSRCCOPY;
229
230 desktopHdc = GetDC(0);
231
232 GetClientRect(hMainWnd, &appRect);
233 AppWidth = (appRect.right - appRect.left);
234 AppHeight = (appRect.bottom - appRect.top);
235
236 ZeroMemory(&cinfo, sizeof(cinfo));
237 ZeroMemory(&iinfo, sizeof(iinfo));
238 cinfo.cbSize = sizeof(cinfo);
239 GetCursorInfo(&cinfo);
240 GetIconInfo(cinfo.hCursor, &iinfo);
241
242 targetRect = appRect;
243 ClientToScreen(hMainWnd, (POINT*)&targetRect.left);
244 ClientToScreen(hMainWnd, (POINT*)&targetRect.right);
245
246 if (bRecreateOffscreenDC || !hdcOffscreen)
247 {
248 bRecreateOffscreenDC = FALSE;
249
250 if(hdcOffscreen)
251 {
252 SelectObject(hdcOffscreen, hbmpOld);
253 DeleteObject (hbmpOffscreen);
254 DeleteDC(hdcOffscreen);
255 }
256
257 sourceWidth = AppWidth / iZoom;
258 sourceHeight = AppHeight / iZoom;
259
260 /* Create a memory DC compatible with client area DC */
261 hdcOffscreen = CreateCompatibleDC(desktopHdc);
262
263 /* Create a bitmap compatible with the client area DC */
264 hbmpOffscreen = CreateCompatibleBitmap(
265 desktopHdc,
266 sourceWidth,
267 sourceHeight);
268
269 /* Select our bitmap in memory DC and save the old one */
270 hbmpOld = SelectObject(hdcOffscreen , hbmpOffscreen);
271 }
272
273 GetWindowRect(hDesktopWindow, &sourceRect);
274 sourceRect.left = (cp.x) - (sourceWidth /2);
275 sourceRect.top = (cp.y) - (sourceHeight /2);
276 sourceRect.right = sourceRect.left + sourceWidth;
277 sourceRect.bottom = sourceRect.top + sourceHeight;
278
279 GetBestOverlapWithMonitors(&sourceRect);
280
281 /* Paint the screen bitmap to our in memory DC */
282 BitBlt(
283 hdcOffscreen,
284 0,
285 0,
286 sourceWidth,
287 sourceHeight,
288 desktopHdc,
289 sourceRect.left,
290 sourceRect.top,
291 rop);
292
293 if (IntersectRect(&intersectedRect, &sourceRect, &targetRect))
294 {
295 OffsetRect(&intersectedRect, -sourceRect.left, -sourceRect.top);
296 FillRect(hdcOffscreen, &intersectedRect, GetStockObject(DC_BRUSH));
297 }
298
299 /* Draw the mouse pointer in the right position */
300 DrawIcon(
301 hdcOffscreen ,
302 pMouse.x - iinfo.xHotspot - sourceRect.left, // - 10,
303 pMouse.y - iinfo.yHotspot - sourceRect.top, // - 10,
304 cinfo.hCursor);
305
306 /* Blast the stretched image from memory DC to window DC */
307 StretchBlt(
308 aDc,
309 0,
310 0,
311 AppWidth,
312 AppHeight,
313 hdcOffscreen,
314 0,
315 0,
316 sourceWidth,
317 sourceHeight,
318 SRCCOPY | NOMIRRORBITMAP);
319
320 /* Cleanup */
321 if (iinfo.hbmMask)
322 DeleteObject(iinfo.hbmMask);
323 if (iinfo.hbmColor)
324 DeleteObject(iinfo.hbmColor);
325 ReleaseDC(hDesktopWindow, desktopHdc);
326 }
327
328 void HandleNotifyIconMessage(HWND hWnd, WPARAM wParam, LPARAM lParam)
329 {
330 POINT pt;
331
332 switch(lParam)
333 {
334 case WM_LBUTTONUP:
335 PostMessage(hMainWnd, WM_COMMAND, IDM_OPTIONS, 0);
336 break;
337 case WM_RBUTTONUP:
338 GetCursorPos (&pt);
339 TrackPopupMenu(notifyMenu, 0, pt.x, pt.y, 0, hWnd, NULL);
340 break;
341 }
342 }
343
344 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
345 {
346 int wmId;
347
348 switch (message)
349 {
350 case WM_TIMER:
351 {
352 BOOL hasMoved = FALSE;
353 HWND hwndForeground = GetForegroundWindow ();
354 DWORD threadId = GetWindowThreadProcessId(hwndForeground, NULL);
355 GUITHREADINFO guiInfo;
356 guiInfo.cbSize = sizeof(guiInfo);
357
358 GetGUIThreadInfo(threadId, &guiInfo);
359
360 if (bFollowMouse)
361 {
362 POINT pNewMouse;
363
364 //Get current mouse position
365 GetCursorPos (&pNewMouse);
366
367 //If mouse has moved ...
368 if (((pMouse.x != pNewMouse.x) || (pMouse.y != pNewMouse.y)))
369 {
370 //Update to new position
371 pMouse = pNewMouse;
372 cp = pNewMouse;
373 hasMoved = TRUE;
374 }
375 }
376
377 if (bFollowCaret && hwndForeground && guiInfo.hwndCaret)
378 {
379 POINT ptCaret;
380 ptCaret.x = (guiInfo.rcCaret.left + guiInfo.rcCaret.right) / 2;
381 ptCaret.y = (guiInfo.rcCaret.top + guiInfo.rcCaret.bottom) / 2;
382
383 if (guiInfo.hwndCaret && ((pCaretWnd != guiInfo.hwndCaret) || (pCaret.x != ptCaret.x) || (pCaret.y != ptCaret.y)))
384 {
385 //Update to new position
386 pCaret = ptCaret;
387 pCaretWnd = guiInfo.hwndCaret;
388 if(!hasMoved)
389 {
390 ClientToScreen (guiInfo.hwndCaret, (LPPOINT) &ptCaret);
391 cp = ptCaret;
392 }
393 hasMoved = TRUE;
394 }
395 }
396
397 if (bFollowFocus && hwndForeground && guiInfo.hwndFocus)
398 {
399 POINT ptFocus;
400 RECT activeRect;
401
402 //Get current control focus
403 GetWindowRect (guiInfo.hwndFocus, &activeRect);
404 ptFocus.x = (activeRect.left + activeRect.right) / 2;
405 ptFocus.y = (activeRect.top + activeRect.bottom) / 2;
406
407 if(guiInfo.hwndFocus && ((guiInfo.hwndFocus != pFocusWnd) || (pFocus.x != ptFocus.x) || (pFocus.y != ptFocus.y)))
408 {
409 //Update to new position
410 pFocus = ptFocus;
411 pFocusWnd = guiInfo.hwndFocus;
412 if(!hasMoved)
413 cp = ptFocus;
414 hasMoved = TRUE;
415 }
416 }
417
418 if(!hasMoved)
419 {
420 DWORD newTicks = GetTickCount();
421 DWORD elapsed = (newTicks - lastTicks);
422 if(elapsed > REPAINT_SPEED)
423 {
424 hasMoved = TRUE;
425 }
426 }
427
428 if(hasMoved)
429 {
430 lastTicks = GetTickCount();
431 Refresh();
432 }
433 }
434 break;
435
436 case WM_COMMAND:
437 {
438 wmId = LOWORD(wParam);
439 /* Parse the menu selections */
440 switch (wmId)
441 {
442 case IDM_OPTIONS:
443 if(bOptionsDialog)
444 {
445 ShowWindow(hOptionsDialog, SW_HIDE);
446 }
447 else
448 {
449 ShowWindow(hOptionsDialog, SW_SHOW);
450 }
451 break;
452 case IDM_ABOUT:
453 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutProc);
454 break;
455 case IDM_EXIT:
456 DestroyWindow(hWnd);
457 break;
458 default:
459 return DefWindowProc(hWnd, message, wParam, lParam);
460 }
461 break;
462 }
463
464 case WM_PAINT:
465 {
466 PAINTSTRUCT PaintStruct;
467 HDC dc;
468 dc = BeginPaint(hWnd, &PaintStruct);
469 Draw(dc);
470 EndPaint(hWnd, &PaintStruct);
471 break;
472 }
473
474 case WM_CONTEXTMENU:
475 TrackPopupMenu(notifyMenu, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, hWnd, NULL);
476 break;
477
478 case WM_SIZE:
479 case WM_DISPLAYCHANGE:
480 bRecreateOffscreenDC = TRUE;
481 Refresh();
482 return DefWindowProc(hWnd, message, wParam, lParam);
483
484 case WM_ERASEBKGND:
485 // handle WM_ERASEBKGND by simply returning non-zero because we did all the drawing in WM_PAINT.
486 break;
487
488 case WM_DESTROY:
489 /* Save settings to registry */
490 SaveSettings();
491 KillTimer(hWnd , 1);
492 PostQuitMessage(0);
493
494 /* Cleanup notification icon */
495 ZeroMemory(&nid, sizeof(nid));
496 nid.cbSize = sizeof(nid);
497 nid.uFlags = NIF_MESSAGE;
498 nid.hWnd = hWnd;
499 nid.uCallbackMessage = APPMSG_NOTIFYICON;
500 Shell_NotifyIcon(NIM_DELETE, &nid);
501
502 DestroyIcon(notifyIcon);
503
504 DestroyWindow(hOptionsDialog);
505 break;
506
507 case WM_CREATE:
508 {
509 HMENU tempMenu;
510
511 /* Load settings from registry */
512 LoadSettings();
513
514 /* Get the desktop window */
515 hDesktopWindow = GetDesktopWindow();
516
517 /* Set the timer */
518 SetTimer (hWnd , 1, TIMER_SPEED , NULL);
519
520 /* Notification icon */
521 notifyIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0);
522
523 ZeroMemory(&nid, sizeof(nid));
524 nid.cbSize = sizeof(nid);
525 nid.uFlags = NIF_ICON | NIF_MESSAGE;
526 nid.hWnd = hWnd;
527 nid.uCallbackMessage = APPMSG_NOTIFYICON;
528 nid.hIcon = notifyIcon;
529 Shell_NotifyIcon(NIM_ADD, &nid);
530
531 tempMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDC_MAGNIFIER));
532 notifyMenu = GetSubMenu(tempMenu, 0);
533 RemoveMenu(tempMenu, 0, MF_BYPOSITION);
534 DestroyMenu(tempMenu);
535
536 break;
537 }
538
539 case APPMSG_NOTIFYICON:
540 HandleNotifyIconMessage(hWnd, wParam, lParam);
541
542 break;
543
544 default:
545 return DefWindowProc(hWnd, message, wParam, lParam);
546 }
547
548 return 0;
549 }
550
551 INT_PTR CALLBACK AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
552 {
553 UNREFERENCED_PARAMETER(lParam);
554 switch (message)
555 {
556 case WM_INITDIALOG:
557 return (INT_PTR)TRUE;
558
559 case WM_COMMAND:
560 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
561 {
562 EndDialog(hDlg, LOWORD(wParam));
563 return (INT_PTR)TRUE;
564 }
565 break;
566 }
567
568 return (INT_PTR)FALSE;
569 }
570
571 INT_PTR CALLBACK OptionsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
572 {
573 UNREFERENCED_PARAMETER(lParam);
574 switch (message)
575 {
576 case WM_SHOWWINDOW:
577 bOptionsDialog = wParam;
578 break;
579 case WM_INITDIALOG:
580 {
581 // Add the zoom items...
582 SendDlgItemMessage(hDlg, IDC_ZOOM, CB_ADDSTRING, 0, (LPARAM)("1"));
583 SendDlgItemMessage(hDlg, IDC_ZOOM, CB_ADDSTRING, 0, (LPARAM)("2"));
584 SendDlgItemMessage(hDlg, IDC_ZOOM, CB_ADDSTRING, 0, (LPARAM)("3"));
585 SendDlgItemMessage(hDlg, IDC_ZOOM, CB_ADDSTRING, 0, (LPARAM)("4"));
586 SendDlgItemMessage(hDlg, IDC_ZOOM, CB_ADDSTRING, 0, (LPARAM)("5"));
587 SendDlgItemMessage(hDlg, IDC_ZOOM, CB_ADDSTRING, 0, (LPARAM)("6"));
588 SendDlgItemMessage(hDlg, IDC_ZOOM, CB_ADDSTRING, 0, (LPARAM)("7"));
589 SendDlgItemMessage(hDlg, IDC_ZOOM, CB_ADDSTRING, 0, (LPARAM)("8"));
590
591 SendDlgItemMessage(hDlg, IDC_ZOOM, CB_SETCURSEL, iZoom - 1, 0);
592
593 if (bFollowMouse)
594 SendDlgItemMessage(hDlg,IDC_FOLLOWMOUSECHECK,BM_SETCHECK , wParam ,0);
595
596 if (bFollowFocus)
597 SendDlgItemMessage(hDlg,IDC_FOLLOWKEYBOARDCHECK,BM_SETCHECK , wParam ,0);
598
599 if (bFollowCaret)
600 SendDlgItemMessage(hDlg,IDC_FOLLOWTEXTEDITINGCHECK,BM_SETCHECK , wParam ,0);
601
602 if (bInvertColors)
603 SendDlgItemMessage(hDlg,IDC_INVERTCOLORSCHECK,BM_SETCHECK , wParam ,0);
604
605 if (bStartMinimized)
606 SendDlgItemMessage(hDlg,IDC_STARTMINIMIZEDCHECK,BM_SETCHECK , wParam ,0);
607
608 if (bShowMagnifier)
609 SendDlgItemMessage(hDlg,IDC_SHOWMAGNIFIERCHECK,BM_SETCHECK , wParam ,0);
610
611 return (INT_PTR)TRUE;
612 }
613
614 case WM_COMMAND:
615 switch (LOWORD(wParam))
616 {
617 case IDOK:
618 case IDCANCEL:
619 ShowWindow(hDlg, SW_HIDE);
620 return (INT_PTR)TRUE;
621
622 case IDC_BUTTON_HELP:
623 /* Unimplemented */
624 MessageBox(hDlg , TEXT("Magnifier help not available yet!") , TEXT("Help") , MB_OK);
625 break;
626 case IDC_ZOOM:
627 if (HIWORD(wParam) == CBN_SELCHANGE)
628 {
629 HWND hCombo = GetDlgItem(hDlg,IDC_ZOOM);
630
631 /* Get index of current selection and the text of that selection */
632 iZoom = SendMessage( hCombo, CB_GETCURSEL, (WPARAM) wParam, (LPARAM) lParam ) + 1;
633
634 /* Update the magnifier UI */
635 Refresh();
636 }
637 break;
638 case IDC_INVERTCOLORSCHECK:
639 bInvertColors = IsDlgButtonChecked(hDlg, IDC_INVERTCOLORSCHECK);
640 Refresh();
641 break;
642 case IDC_FOLLOWMOUSECHECK:
643 bFollowMouse = IsDlgButtonChecked(hDlg, IDC_FOLLOWMOUSECHECK);
644 break;
645 case IDC_FOLLOWKEYBOARDCHECK:
646 bFollowFocus = IsDlgButtonChecked(hDlg, IDC_FOLLOWKEYBOARDCHECK);
647 break;
648 case IDC_FOLLOWTEXTEDITINGCHECK:
649 bFollowCaret = IsDlgButtonChecked(hDlg, IDC_FOLLOWTEXTEDITINGCHECK);
650 break;
651 case IDC_STARTMINIMIZEDCHECK:
652 bStartMinimized = IsDlgButtonChecked(hDlg, IDC_STARTMINIMIZEDCHECK);
653 break;
654 case IDC_SHOWMAGNIFIER:
655 bShowMagnifier = IsDlgButtonChecked(hDlg, IDC_SHOWMAGNIFIERCHECK);
656 if (bShowMagnifier)
657 ShowWindow (hMainWnd , SW_SHOW);
658 else
659 ShowWindow (hMainWnd , SW_HIDE);
660 break;
661 }
662 }
663
664 return (INT_PTR)FALSE;
665 }
666
667 INT_PTR CALLBACK WarningProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
668 {
669 UNREFERENCED_PARAMETER(lParam);
670
671 switch (message)
672 {
673 case WM_INITDIALOG:
674 return (INT_PTR)TRUE;
675
676 case WM_COMMAND:
677 switch (LOWORD(wParam))
678 {
679 case IDC_SHOWWARNINGCHECK:
680 bShowWarning = !IsDlgButtonChecked(hDlg, IDC_SHOWWARNINGCHECK);
681 break;
682 }
683 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
684 {
685 EndDialog(hDlg, LOWORD(wParam));
686 return (INT_PTR)TRUE;
687 }
688 break;
689 }
690
691 return (INT_PTR)FALSE;
692 }