2 * PROJECT: ReactOS Magnify
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/magnify/magnifier.c
6 * COPYRIGHT: Copyright 2007 Marc Piulachs <marc.piulachs@codexchange.net>
12 #include "magnifier.h"
15 const TCHAR szWindowClass
[] = TEXT("MAGNIFIER");
17 #define MAX_LOADSTRING 100
20 HINSTANCE hInst
; // current instance
23 TCHAR szTitle
[MAX_LOADSTRING
]; // The title bar text
25 #define REPAINT_SPEED 100
27 HWND hDesktopWindow
= NULL
;
29 //Current magnified area
37 // Forward declarations of functions included in this code module:
38 ATOM
MyRegisterClass(HINSTANCE hInstance
);
39 BOOL
InitInstance(HINSTANCE
, int);
40 LRESULT CALLBACK
WndProc(HWND
, UINT
, WPARAM
, LPARAM
);
41 INT_PTR CALLBACK
AboutProc(HWND
, UINT
, WPARAM
, LPARAM
);
42 INT_PTR CALLBACK
OptionsProc(HWND
, UINT
, WPARAM
, LPARAM
);
43 INT_PTR CALLBACK
WarningProc(HWND
, UINT
, WPARAM
, LPARAM
);
45 int WINAPI
WinMain( HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR lpCmdLine
, int nCmdShow
)
47 UNREFERENCED_PARAMETER(hPrevInstance
);
48 UNREFERENCED_PARAMETER(lpCmdLine
);
50 // TODO: Place code here.
54 // Initialize global strings
55 LoadString(hInstance
, IDS_APP_TITLE
, szTitle
, MAX_LOADSTRING
);
56 MyRegisterClass(hInstance
);
58 // Perform application initialization:
59 if (!InitInstance (hInstance
, nCmdShow
))
64 hAccelTable
= LoadAccelerators(hInstance
, MAKEINTRESOURCE(IDC_MAGNIFIER
));
67 while (GetMessage(&msg
, NULL
, 0, 0))
69 if (!TranslateAccelerator(msg
.hwnd
, hAccelTable
, &msg
))
71 TranslateMessage(&msg
);
72 DispatchMessage(&msg
);
76 return (int) msg
.wParam
;
82 // FUNCTION: MyRegisterClass()
84 // PURPOSE: Registers the window class.
88 // This function and its usage are only necessary if you want this code
89 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
90 // function that was added to Windows 95. It is important to call this function
91 // so that the application will get 'well formed' small icons associated
94 ATOM
MyRegisterClass(HINSTANCE hInstance
)
98 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
99 wc
.lpfnWndProc
= WndProc
;
102 wc
.hInstance
= hInstance
;
103 wc
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_ICON
));
104 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
105 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+1);
106 wc
.lpszMenuName
= MAKEINTRESOURCE(IDC_MAGNIFIER
);
107 wc
.lpszClassName
= szWindowClass
;
109 return RegisterClass(&wc
);
113 // FUNCTION: InitInstance(HINSTANCE, int)
115 // PURPOSE: Saves instance handle and creates main window
119 // In this function, we save the instance handle in a global variable and
120 // create and display the main program window.
122 BOOL
InitInstance(HINSTANCE hInstance
, int nCmdShow
)
124 hInst
= hInstance
; // Store instance handle in our global variable
127 hMainWnd
= CreateWindowEx(
146 ShowWindow(hMainWnd
, nCmdShow
);
147 UpdateWindow(hMainWnd
);
154 if (!IsIconic(hMainWnd
))
156 // Invalidate the client area forcing a WM_PAINT message
157 InvalidateRgn(hMainWnd
, NULL
, TRUE
);
163 HDC desktopHdc
= NULL
;
174 desktopHdc
= GetWindowDC (hDesktopWindow
);
176 GetClientRect(hMainWnd
, &appRect
);
177 GetWindowRect(hDesktopWindow
, &R
);
179 memset(&info
, 0, sizeof(info
));
180 info
.cbSize
= sizeof(info
);
181 GetCursorInfo(&info
);
182 hCursor
= info
.hCursor
;
184 /* Create a memory DC compatible with client area DC.*/
185 HdcStrech
= CreateCompatibleDC(desktopHdc
);
187 /* Create a bitmap compatible with the client area DC.*/
188 HbmpStrech
= CreateCompatibleBitmap(
193 /* Select our bitmap in memory DC and save the old one.*/
194 hOld
= SelectObject (HdcStrech
, HbmpStrech
);
196 /* Paint the screen bitmap to our in memory DC */
208 /* Draw the mouse pointer in the right position */
215 int Width
= (R
.right
- R
.left
);
216 int Height
= (R
.bottom
- R
.top
);
218 int AppWidth
= (appRect
.right
- appRect
.left
);
219 int AppHeight
= (appRect
.bottom
- appRect
.top
);
221 LONG blitAreaWidth
= AppWidth
/ iZoom
;
222 LONG blitAreaHeight
= AppHeight
/ iZoom
;
224 LONG blitAreaX
= (cp
.x
) - (blitAreaWidth
/2);
225 LONG blitAreaY
= (cp
.y
) - (blitAreaHeight
/2);
237 if (blitAreaX
> (Width
- blitAreaWidth
))
239 blitAreaX
= (Width
- blitAreaWidth
);
242 if (blitAreaY
> (Height
- blitAreaHeight
))
244 blitAreaY
= (Height
- blitAreaHeight
);
265 /* Blast the image from memory DC to client DC.*/
278 SelectObject (HdcStrech
, hOld
);
279 DeleteObject (HbmpStrech
);
280 DeleteDC (HdcStrech
);
281 ReleaseDC(hDesktopWindow
, desktopHdc
);
285 // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
287 // PURPOSE: Processes messages for the main window.
289 // WM_COMMAND - process the application menu
290 // WM_PAINT - Paint the main window
291 // WM_DESTROY - post a quit message and return
294 LRESULT CALLBACK
WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
306 //Get current mouse position
307 GetCursorPos (&pNewMouse
);
310 HWND hwnd1
= GetForegroundWindow ();
311 DWORD a
= GetWindowThreadProcessId(hwnd1
, NULL
);
312 DWORD b
= GetCurrentThreadId();
313 AttachThreadInput (a
, b
, TRUE
);
314 HWND hwnd2
= GetFocus();
316 GetCaretPos( &pNewCaret
);
317 ClientToScreen (hwnd2
, (LPPOINT
) &pNewCaret
);
318 AttachThreadInput (a
, b
, FALSE
);
320 //Get current control focus
321 HWND hwnd3
= GetFocus ();
323 GetWindowRect (hwnd3
, &controlRect
);
324 pNewFocus
.x
= controlRect
.left
;
325 pNewFocus
.y
= controlRect
.top
;
327 //If mouse has moved ....
328 if (((pMouse
.x
!= pNewMouse
.x
) || (pMouse
.y
!= pNewMouse
.y
)) && bFollowMouse
)
330 //Update to new position
335 else if (((pCaret
.x
!= pNewCaret
.x
) || (pCaret
.y
!= pNewCaret
.y
)) && bFollowCaret
)
337 //Update to new position
342 else if (((pFocus
.x
!= pNewFocus
.x
) || (pFocus
.y
!= pNewFocus
.y
)) && bFollowFocus
)
344 //Update to new position
352 wmId
= LOWORD(wParam
);
353 wmEvent
= HIWORD(wParam
);
354 // Parse the menu selections:
358 DialogBox(hInst
, MAKEINTRESOURCE(IDD_DIALOGOPTIONS
), hWnd
, (DLGPROC
)OptionsProc
);
361 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, (DLGPROC
)AboutProc
);
367 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
372 PAINTSTRUCT PaintStruct
;
374 dc
= BeginPaint(hWnd
, &PaintStruct
);
376 EndPaint(hWnd
, &PaintStruct
);
380 //handle WM_ERASEBKGND by simply returning non-zero because we did all the drawing in WM_PAINT.
383 //Save settings to registry
385 KillTimer (hWnd
, 1);
389 //Load settings from registry
392 //Get the desktop window
393 hDesktopWindow
= GetDesktopWindow();
397 DialogBox (hInst
, MAKEINTRESOURCE(IDD_WARNINGDIALOG
), hWnd
, (DLGPROC
)WarningProc
);
402 ShowWindow (hMainWnd
, SW_MINIMIZE
);
406 SetTimer (hWnd
, 1, REPAINT_SPEED
, NULL
);
409 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
414 // Message handler for about box.
415 INT_PTR CALLBACK
AboutProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
417 UNREFERENCED_PARAMETER(lParam
);
421 return (INT_PTR
)TRUE
;
424 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
426 EndDialog(hDlg
, LOWORD(wParam
));
427 return (INT_PTR
)TRUE
;
431 return (INT_PTR
)FALSE
;
434 // Message handler for options box.
435 INT_PTR CALLBACK
OptionsProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
437 UNREFERENCED_PARAMETER(lParam
);
442 //Add the zoom items....
443 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("1"));
444 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("2"));
445 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("3"));
446 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("4"));
447 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("5"));
448 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("6"));
449 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("7"));
450 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("8"));
453 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_SETCURSEL
, iZoom
- 1, 0);
456 SendDlgItemMessage(hDlg
,IDC_FOLLOWMOUSECHECK
,BM_SETCHECK
, wParam
,0);
459 SendDlgItemMessage(hDlg
,IDC_FOLLOWKEYBOARDCHECK
,BM_SETCHECK
, wParam
,0);
462 SendDlgItemMessage(hDlg
,IDC_FOLLOWTEXTEDITINGCHECK
,BM_SETCHECK
, wParam
,0);
465 SendDlgItemMessage(hDlg
,IDC_INVERTCOLORSCHECK
,BM_SETCHECK
, wParam
,0);
468 SendDlgItemMessage(hDlg
,IDC_STARTMINIMIZEDCHECK
,BM_SETCHECK
, wParam
,0);
471 SendDlgItemMessage(hDlg
,IDC_SHOWMAGNIFIERCHECK
,BM_SETCHECK
, wParam
,0);
473 return (INT_PTR
)TRUE
;
476 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
478 EndDialog(hDlg
, LOWORD(wParam
));
479 return (INT_PTR
)TRUE
;
481 if (LOWORD(wParam
) == IDOK
)
484 if (LOWORD(wParam
) == IDHELP
)
486 MessageBox(hDlg
, TEXT("Magnifier help not available yet!") , TEXT("Help") , MB_OK
);
488 switch(LOWORD(wParam
))
491 if(HIWORD(wParam
) == CBN_SELCHANGE
)
493 HWND hCombo
= GetDlgItem(hDlg
,IDC_ZOOM
);
495 /* Get index of current selection and the text of that selection. */
496 iZoom
= SendMessage( hCombo
, CB_GETCURSEL
, (WPARAM
) wParam
, (LPARAM
) lParam
) + 1;
498 //Update the magnigier UI
502 case IDC_INVERTCOLORSCHECK
:
503 bInvertColors
= IsDlgButtonChecked (hDlg
, IDC_INVERTCOLORSCHECK
);
506 case IDC_FOLLOWMOUSECHECK
:
507 bFollowMouse
= IsDlgButtonChecked (hDlg
, IDC_FOLLOWMOUSECHECK
);
509 case IDC_FOLLOWKEYBOARDCHECK
:
510 bFollowFocus
= IsDlgButtonChecked (hDlg
, IDC_FOLLOWKEYBOARDCHECK
);
512 case IDC_FOLLOWTEXTEDITINGCHECK
:
513 bFollowCaret
= IsDlgButtonChecked (hDlg
, IDC_FOLLOWTEXTEDITINGCHECK
);
515 case IDC_STARTMINIMIZEDCHECK
:
516 bStartMinimized
= IsDlgButtonChecked (hDlg
, IDC_STARTMINIMIZEDCHECK
);
518 case IDC_SHOWMAGNIFIER
:
519 bShowMagnifier
= IsDlgButtonChecked (hDlg
, IDC_SHOWMAGNIFIERCHECK
);
521 ShowWindow (hMainWnd
, SW_SHOW
);
523 ShowWindow (hMainWnd
, SW_HIDE
);
528 return (INT_PTR
)FALSE
;
531 // Message handler for warning box.
532 INT_PTR CALLBACK
WarningProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
534 UNREFERENCED_PARAMETER(lParam
);
539 return (INT_PTR
)TRUE
;
541 switch(LOWORD(wParam
))
543 case IDC_SHOWWARNINGCHECK
:
544 bShowWarning
= !IsDlgButtonChecked (hDlg
, IDC_SHOWWARNINGCHECK
);
547 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
549 EndDialog(hDlg
, LOWORD(wParam
));
550 return (INT_PTR
)TRUE
;
554 return (INT_PTR
)FALSE
;