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 * COPYRIGHT: Copyright 2007 Marc Piulachs <marc.piulachs@codexchange.net>
11 #include "magnifier.h"
20 const TCHAR szWindowClass
[] = TEXT("MAGNIFIER");
22 #define MAX_LOADSTRING 100
25 HINSTANCE hInst
; // current instance
28 TCHAR szTitle
[MAX_LOADSTRING
]; // The title bar text
30 #define REPAINT_SPEED 100
32 HWND hDesktopWindow
= NULL
;
34 //Current magnified area
42 // Forward declarations of functions included in this code module:
43 ATOM
MyRegisterClass(HINSTANCE hInstance
);
44 BOOL
InitInstance(HINSTANCE
, int);
45 LRESULT CALLBACK
WndProc(HWND
, UINT
, WPARAM
, LPARAM
);
46 INT_PTR CALLBACK
AboutProc(HWND
, UINT
, WPARAM
, LPARAM
);
47 INT_PTR CALLBACK
OptionsProc(HWND
, UINT
, WPARAM
, LPARAM
);
48 INT_PTR CALLBACK
WarningProc(HWND
, UINT
, WPARAM
, LPARAM
);
50 int WINAPI
WinMain( HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR lpCmdLine
, int nCmdShow
)
52 // TODO: Place code here.
56 UNREFERENCED_PARAMETER(hPrevInstance
);
57 UNREFERENCED_PARAMETER(lpCmdLine
);
59 switch (GetUserDefaultUILanguage())
61 case MAKELANGID(LANG_HEBREW
, SUBLANG_DEFAULT
):
62 SetProcessDefaultLayout(LAYOUT_RTL
);
69 // Initialize global strings
70 LoadString(hInstance
, IDS_APP_TITLE
, szTitle
, MAX_LOADSTRING
);
71 MyRegisterClass(hInstance
);
73 // Perform application initialization:
74 if (!InitInstance (hInstance
, nCmdShow
))
79 hAccelTable
= LoadAccelerators(hInstance
, MAKEINTRESOURCE(IDC_MAGNIFIER
));
82 while (GetMessage(&msg
, NULL
, 0, 0))
84 if (!TranslateAccelerator(msg
.hwnd
, hAccelTable
, &msg
))
86 TranslateMessage(&msg
);
87 DispatchMessage(&msg
);
91 return (int) msg
.wParam
;
97 * FUNCTION: MyRegisterClass()
99 * PURPOSE: Registers the window class.
103 * This function and its usage are only necessary if you want this code
104 * to be compatible with Win32 systems prior to the 'RegisterClassEx'
105 * function that was added to Windows 95. It is important to call this function
106 * so that the application will get 'well formed' small icons associated
109 ATOM
MyRegisterClass(HINSTANCE hInstance
)
113 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
114 wc
.lpfnWndProc
= WndProc
;
117 wc
.hInstance
= hInstance
;
118 wc
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_ICON
));
119 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
120 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+1);
121 wc
.lpszMenuName
= MAKEINTRESOURCE(IDC_MAGNIFIER
);
122 wc
.lpszClassName
= szWindowClass
;
124 return RegisterClass(&wc
);
128 * FUNCTION: InitInstance(HINSTANCE, int)
130 * PURPOSE: Saves instance handle and creates main window
134 * In this function, we save the instance handle in a global variable and
135 * create and display the main program window.
137 BOOL
InitInstance(HINSTANCE hInstance
, int nCmdShow
)
140 hInst
= hInstance
; // Store instance handle in our global variable
142 SystemParametersInfo(SPI_GETWORKAREA
, 0, &rcWorkArea
, 0);
144 /* Create the Window */
145 hMainWnd
= CreateWindowEx(
146 WS_EX_TOPMOST
| WS_EX_PALETTEWINDOW
,
152 (rcWorkArea
.right
- rcWorkArea
.left
) * 2 / 3,
164 ShowWindow(hMainWnd
, (bStartMinimized
) ? SW_MINIMIZE
: nCmdShow
);
165 UpdateWindow(hMainWnd
);
169 DialogBox (hInstance
, MAKEINTRESOURCE(IDD_WARNINGDIALOG
), hMainWnd
, WarningProc
);
177 if (!IsIconic(hMainWnd
))
179 // Invalidate the client area forcing a WM_PAINT message
180 InvalidateRgn(hMainWnd
, NULL
, TRUE
);
186 HDC desktopHdc
= NULL
;
197 int Width
, Height
, AppWidth
, AppHeight
;
198 LONG blitAreaWidth
, blitAreaHeight
, blitAreaX
, blitAreaY
;
200 desktopHdc
= GetWindowDC (hDesktopWindow
);
202 GetClientRect(hMainWnd
, &appRect
);
203 GetWindowRect(hDesktopWindow
, &R
);
205 ZeroMemory(&cinfo
, sizeof(CURSORINFO
));
206 ZeroMemory(&iinfo
, sizeof(ICONINFO
));
207 cinfo
.cbSize
= sizeof(cinfo
);
208 GetCursorInfo(&cinfo
);
209 GetIconInfo(cinfo
.hCursor
, &iinfo
);
211 /* Create a memory DC compatible with client area DC.*/
212 HdcStrech
= CreateCompatibleDC(desktopHdc
);
214 /* Create a bitmap compatible with the client area DC.*/
215 HbmpStrech
= CreateCompatibleBitmap(
220 /* Select our bitmap in memory DC and save the old one.*/
221 hOld
= SelectObject (HdcStrech
, HbmpStrech
);
223 /* Paint the screen bitmap to our in memory DC */
235 /* Draw the mouse pointer in the right position */
238 pMouse
.x
- iinfo
.xHotspot
, // - 10,
239 pMouse
.y
- iinfo
.yHotspot
, // - 10,
242 Width
= (R
.right
- R
.left
);
243 Height
= (R
.bottom
- R
.top
);
245 AppWidth
= (appRect
.right
- appRect
.left
);
246 AppHeight
= (appRect
.bottom
- appRect
.top
);
248 blitAreaWidth
= AppWidth
/ iZoom
;
249 blitAreaHeight
= AppHeight
/ iZoom
;
251 blitAreaX
= (cp
.x
) - (blitAreaWidth
/2);
252 blitAreaY
= (cp
.y
) - (blitAreaHeight
/2);
264 if (blitAreaX
> (Width
- blitAreaWidth
))
266 blitAreaX
= (Width
- blitAreaWidth
);
269 if (blitAreaY
> (Height
- blitAreaHeight
))
271 blitAreaY
= (Height
- blitAreaHeight
);
279 /* Blast the stretched image from memory DC to window DC.*/
291 rop
| NOMIRRORBITMAP
);
296 DeleteObject(iinfo
.hbmMask
);
298 DeleteObject(iinfo
.hbmColor
);
299 SelectObject (HdcStrech
, hOld
);
300 DeleteObject (HbmpStrech
);
301 DeleteDC (HdcStrech
);
302 ReleaseDC(hDesktopWindow
, desktopHdc
);
306 * FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
308 * PURPOSE: Processes messages for the main window.
310 * WM_COMMAND - process the application menu
311 * WM_PAINT - Paint the main window
312 * WM_DESTROY - post a quit message and return
315 LRESULT CALLBACK
WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
326 HWND hwnd1
, hwnd2
, hwnd3
;
330 //Get current mouse position
331 GetCursorPos (&pNewMouse
);
334 hwnd1
= GetForegroundWindow ();
335 a
= GetWindowThreadProcessId(hwnd1
, NULL
);
336 b
= GetCurrentThreadId();
337 AttachThreadInput (a
, b
, TRUE
);
340 GetCaretPos( &pNewCaret
);
341 ClientToScreen (hwnd2
, (LPPOINT
) &pNewCaret
);
342 AttachThreadInput (a
, b
, FALSE
);
344 //Get current control focus
346 GetWindowRect (hwnd3
, &controlRect
);
347 pNewFocus
.x
= controlRect
.left
;
348 pNewFocus
.y
= controlRect
.top
;
350 //If mouse has moved ....
351 if (((pMouse
.x
!= pNewMouse
.x
) || (pMouse
.y
!= pNewMouse
.y
)) && bFollowMouse
)
353 //Update to new position
357 else if (((pCaret
.x
!= pNewCaret
.x
) || (pCaret
.y
!= pNewCaret
.y
)) && bFollowCaret
)
359 //Update to new position
363 else if (((pFocus
.x
!= pNewFocus
.x
) || (pFocus
.y
!= pNewFocus
.y
)) && bFollowFocus
)
365 //Update to new position
373 wmId
= LOWORD(wParam
);
374 // Parse the menu selections:
378 DialogBox(hInst
, MAKEINTRESOURCE(IDD_DIALOGOPTIONS
), hWnd
, OptionsProc
);
381 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, AboutProc
);
387 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
392 PAINTSTRUCT PaintStruct
;
394 dc
= BeginPaint(hWnd
, &PaintStruct
);
396 EndPaint(hWnd
, &PaintStruct
);
400 //handle WM_ERASEBKGND by simply returning non-zero because we did all the drawing in WM_PAINT.
403 //Save settings to registry
405 KillTimer (hWnd
, 1);
409 //Load settings from registry
412 //Get the desktop window
413 hDesktopWindow
= GetDesktopWindow();
416 SetTimer (hWnd
, 1, REPAINT_SPEED
, NULL
);
419 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
424 // Message handler for about box.
425 INT_PTR CALLBACK
AboutProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
427 UNREFERENCED_PARAMETER(lParam
);
431 return (INT_PTR
)TRUE
;
434 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
436 EndDialog(hDlg
, LOWORD(wParam
));
437 return (INT_PTR
)TRUE
;
441 return (INT_PTR
)FALSE
;
444 // Message handler for options box.
445 INT_PTR CALLBACK
OptionsProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
447 UNREFERENCED_PARAMETER(lParam
);
452 //Add the zoom items....
453 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("1"));
454 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("2"));
455 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("3"));
456 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("4"));
457 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("5"));
458 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("6"));
459 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("7"));
460 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("8"));
463 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_SETCURSEL
, iZoom
- 1, 0);
466 SendDlgItemMessage(hDlg
,IDC_FOLLOWMOUSECHECK
,BM_SETCHECK
, wParam
,0);
469 SendDlgItemMessage(hDlg
,IDC_FOLLOWKEYBOARDCHECK
,BM_SETCHECK
, wParam
,0);
472 SendDlgItemMessage(hDlg
,IDC_FOLLOWTEXTEDITINGCHECK
,BM_SETCHECK
, wParam
,0);
475 SendDlgItemMessage(hDlg
,IDC_INVERTCOLORSCHECK
,BM_SETCHECK
, wParam
,0);
478 SendDlgItemMessage(hDlg
,IDC_STARTMINIMIZEDCHECK
,BM_SETCHECK
, wParam
,0);
481 SendDlgItemMessage(hDlg
,IDC_SHOWMAGNIFIERCHECK
,BM_SETCHECK
, wParam
,0);
483 return (INT_PTR
)TRUE
;
486 switch(LOWORD(wParam
))
490 EndDialog(hDlg
, LOWORD(wParam
));
491 return (INT_PTR
)TRUE
;
493 case IDC_BUTTON_HELP
:
495 MessageBox(hDlg
, TEXT("Magnifier help not available yet!") , TEXT("Help") , MB_OK
);
498 if(HIWORD(wParam
) == CBN_SELCHANGE
)
500 HWND hCombo
= GetDlgItem(hDlg
,IDC_ZOOM
);
502 /* Get index of current selection and the text of that selection. */
503 iZoom
= SendMessage( hCombo
, CB_GETCURSEL
, (WPARAM
) wParam
, (LPARAM
) lParam
) + 1;
505 //Update the magnigier UI
509 case IDC_INVERTCOLORSCHECK
:
510 bInvertColors
= IsDlgButtonChecked (hDlg
, IDC_INVERTCOLORSCHECK
);
513 case IDC_FOLLOWMOUSECHECK
:
514 bFollowMouse
= IsDlgButtonChecked (hDlg
, IDC_FOLLOWMOUSECHECK
);
516 case IDC_FOLLOWKEYBOARDCHECK
:
517 bFollowFocus
= IsDlgButtonChecked (hDlg
, IDC_FOLLOWKEYBOARDCHECK
);
519 case IDC_FOLLOWTEXTEDITINGCHECK
:
520 bFollowCaret
= IsDlgButtonChecked (hDlg
, IDC_FOLLOWTEXTEDITINGCHECK
);
522 case IDC_STARTMINIMIZEDCHECK
:
523 bStartMinimized
= IsDlgButtonChecked (hDlg
, IDC_STARTMINIMIZEDCHECK
);
525 case IDC_SHOWMAGNIFIER
:
526 bShowMagnifier
= IsDlgButtonChecked (hDlg
, IDC_SHOWMAGNIFIERCHECK
);
528 ShowWindow (hMainWnd
, SW_SHOW
);
530 ShowWindow (hMainWnd
, SW_HIDE
);
535 return (INT_PTR
)FALSE
;
538 // Message handler for warning box.
539 INT_PTR CALLBACK
WarningProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
541 UNREFERENCED_PARAMETER(lParam
);
546 return (INT_PTR
)TRUE
;
548 switch(LOWORD(wParam
))
550 case IDC_SHOWWARNINGCHECK
:
551 bShowWarning
= !IsDlgButtonChecked (hDlg
, IDC_SHOWWARNINGCHECK
);
554 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
556 EndDialog(hDlg
, LOWORD(wParam
));
557 return (INT_PTR
)TRUE
;
561 return (INT_PTR
)FALSE
;