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
24 /* Global Variables */
28 TCHAR szTitle
[MAX_LOADSTRING
];
30 #define REPAINT_SPEED 100
32 HWND hDesktopWindow
= NULL
;
34 /* Current magnified area */
42 ATOM
MyRegisterClass(HINSTANCE hInstance
);
43 BOOL
InitInstance(HINSTANCE
, int);
44 LRESULT CALLBACK
WndProc(HWND
, UINT
, WPARAM
, LPARAM
);
45 INT_PTR CALLBACK
AboutProc(HWND
, UINT
, WPARAM
, LPARAM
);
46 INT_PTR CALLBACK
OptionsProc(HWND
, UINT
, WPARAM
, LPARAM
);
47 INT_PTR CALLBACK
WarningProc(HWND
, UINT
, WPARAM
, LPARAM
);
49 int WINAPI
WinMain( HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR lpCmdLine
, int nCmdShow
)
54 UNREFERENCED_PARAMETER(hPrevInstance
);
55 UNREFERENCED_PARAMETER(lpCmdLine
);
57 switch (GetUserDefaultUILanguage())
59 case MAKELANGID(LANG_HEBREW
, SUBLANG_DEFAULT
):
60 SetProcessDefaultLayout(LAYOUT_RTL
);
67 /* Initialize global strings */
68 LoadString(hInstance
, IDS_APP_TITLE
, szTitle
, MAX_LOADSTRING
);
69 MyRegisterClass(hInstance
);
71 /* Perform application initialization */
72 if (!InitInstance(hInstance
, nCmdShow
))
75 hAccelTable
= LoadAccelerators(hInstance
, MAKEINTRESOURCE(IDC_MAGNIFIER
));
77 /* Main message loop */
78 while (GetMessage(&msg
, NULL
, 0, 0))
80 if (!TranslateAccelerator(msg
.hwnd
, hAccelTable
, &msg
))
82 TranslateMessage(&msg
);
83 DispatchMessage(&msg
);
87 return (int) msg
.wParam
;
90 ATOM
MyRegisterClass(HINSTANCE hInstance
)
94 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
95 wc
.lpfnWndProc
= WndProc
;
98 wc
.hInstance
= hInstance
;
99 wc
.hIcon
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_ICON
));
100 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
101 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+1);
102 wc
.lpszMenuName
= MAKEINTRESOURCE(IDC_MAGNIFIER
);
103 wc
.lpszClassName
= szWindowClass
;
105 return RegisterClass(&wc
);
108 BOOL
InitInstance(HINSTANCE hInstance
, int nCmdShow
)
111 hInst
= hInstance
; // Store instance handle in our global variable
113 SystemParametersInfo(SPI_GETWORKAREA
, 0, &rcWorkArea
, 0);
115 /* Create the Window */
116 hMainWnd
= CreateWindowEx(
117 WS_EX_TOPMOST
| WS_EX_PALETTEWINDOW
,
123 (rcWorkArea
.right
- rcWorkArea
.left
) * 2 / 3,
133 ShowWindow(hMainWnd
, bStartMinimized
? SW_MINIMIZE
: nCmdShow
);
134 UpdateWindow(hMainWnd
);
137 DialogBox(hInstance
, MAKEINTRESOURCE(IDD_WARNINGDIALOG
), hMainWnd
, WarningProc
);
144 if (!IsIconic(hMainWnd
))
146 /* Invalidate the client area forcing a WM_PAINT message */
147 InvalidateRgn(hMainWnd
, NULL
, TRUE
);
153 HDC desktopHdc
= NULL
;
164 int Width
, Height
, AppWidth
, AppHeight
;
165 LONG blitAreaWidth
, blitAreaHeight
, blitAreaX
, blitAreaY
;
167 desktopHdc
= GetWindowDC(hDesktopWindow
);
169 GetClientRect(hMainWnd
, &appRect
);
170 GetWindowRect(hDesktopWindow
, &R
);
172 ZeroMemory(&cinfo
, sizeof(cinfo
));
173 ZeroMemory(&iinfo
, sizeof(iinfo
));
174 cinfo
.cbSize
= sizeof(cinfo
);
175 GetCursorInfo(&cinfo
);
176 GetIconInfo(cinfo
.hCursor
, &iinfo
);
178 /* Create a memory DC compatible with client area DC */
179 HdcStrech
= CreateCompatibleDC(desktopHdc
);
181 /* Create a bitmap compatible with the client area DC */
182 HbmpStrech
= CreateCompatibleBitmap(
187 /* Select our bitmap in memory DC and save the old one */
188 hOld
= SelectObject(HdcStrech
, HbmpStrech
);
190 /* Paint the screen bitmap to our in memory DC */
202 /* Draw the mouse pointer in the right position */
205 pMouse
.x
- iinfo
.xHotspot
, // - 10,
206 pMouse
.y
- iinfo
.yHotspot
, // - 10,
209 Width
= (R
.right
- R
.left
);
210 Height
= (R
.bottom
- R
.top
);
212 AppWidth
= (appRect
.right
- appRect
.left
);
213 AppHeight
= (appRect
.bottom
- appRect
.top
);
215 blitAreaWidth
= AppWidth
/ iZoom
;
216 blitAreaHeight
= AppHeight
/ iZoom
;
218 blitAreaX
= (cp
.x
) - (blitAreaWidth
/2);
219 blitAreaY
= (cp
.y
) - (blitAreaHeight
/2);
227 if (blitAreaX
> (Width
- blitAreaWidth
))
228 blitAreaX
= (Width
- blitAreaWidth
);
230 if (blitAreaY
> (Height
- blitAreaHeight
))
231 blitAreaY
= (Height
- blitAreaHeight
);
236 /* Blast the stretched image from memory DC to window DC */
248 rop
| NOMIRRORBITMAP
);
253 DeleteObject(iinfo
.hbmMask
);
255 DeleteObject(iinfo
.hbmColor
);
256 SelectObject(HdcStrech
, hOld
);
257 DeleteObject (HbmpStrech
);
259 ReleaseDC(hDesktopWindow
, desktopHdc
);
262 LRESULT CALLBACK
WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
273 HWND hwnd1
, hwnd2
, hwnd3
;
277 //Get current mouse position
278 GetCursorPos (&pNewMouse
);
281 hwnd1
= GetForegroundWindow ();
282 a
= GetWindowThreadProcessId(hwnd1
, NULL
);
283 b
= GetCurrentThreadId();
284 AttachThreadInput (a
, b
, TRUE
);
287 GetCaretPos( &pNewCaret
);
288 ClientToScreen (hwnd2
, (LPPOINT
) &pNewCaret
);
289 AttachThreadInput (a
, b
, FALSE
);
291 //Get current control focus
293 GetWindowRect (hwnd3
, &controlRect
);
294 pNewFocus
.x
= controlRect
.left
;
295 pNewFocus
.y
= controlRect
.top
;
297 //If mouse has moved ....
298 if (((pMouse
.x
!= pNewMouse
.x
) || (pMouse
.y
!= pNewMouse
.y
)) && bFollowMouse
)
300 //Update to new position
304 else if (((pCaret
.x
!= pNewCaret
.x
) || (pCaret
.y
!= pNewCaret
.y
)) && bFollowCaret
)
306 //Update to new position
310 else if (((pFocus
.x
!= pNewFocus
.x
) || (pFocus
.y
!= pNewFocus
.y
)) && bFollowFocus
)
312 //Update to new position
322 wmId
= LOWORD(wParam
);
323 /* Parse the menu selections */
327 DialogBox(hInst
, MAKEINTRESOURCE(IDD_DIALOGOPTIONS
), hWnd
, OptionsProc
);
330 DialogBox(hInst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hWnd
, AboutProc
);
336 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
343 PAINTSTRUCT PaintStruct
;
345 dc
= BeginPaint(hWnd
, &PaintStruct
);
347 EndPaint(hWnd
, &PaintStruct
);
352 // handle WM_ERASEBKGND by simply returning non-zero because we did all the drawing in WM_PAINT.
356 /* Save settings to registry */
363 /* Load settings from registry */
366 /* Get the desktop window */
367 hDesktopWindow
= GetDesktopWindow();
370 SetTimer (hWnd
, 1, REPAINT_SPEED
, NULL
);
374 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
380 INT_PTR CALLBACK
AboutProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
382 UNREFERENCED_PARAMETER(lParam
);
386 return (INT_PTR
)TRUE
;
389 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
391 EndDialog(hDlg
, LOWORD(wParam
));
392 return (INT_PTR
)TRUE
;
397 return (INT_PTR
)FALSE
;
400 INT_PTR CALLBACK
OptionsProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
402 UNREFERENCED_PARAMETER(lParam
);
407 // Add the zoom items...
408 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("1"));
409 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("2"));
410 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("3"));
411 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("4"));
412 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("5"));
413 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("6"));
414 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("7"));
415 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_ADDSTRING
, 0, (LPARAM
)("8"));
417 SendDlgItemMessage(hDlg
, IDC_ZOOM
, CB_SETCURSEL
, iZoom
- 1, 0);
420 SendDlgItemMessage(hDlg
,IDC_FOLLOWMOUSECHECK
,BM_SETCHECK
, wParam
,0);
423 SendDlgItemMessage(hDlg
,IDC_FOLLOWKEYBOARDCHECK
,BM_SETCHECK
, wParam
,0);
426 SendDlgItemMessage(hDlg
,IDC_FOLLOWTEXTEDITINGCHECK
,BM_SETCHECK
, wParam
,0);
429 SendDlgItemMessage(hDlg
,IDC_INVERTCOLORSCHECK
,BM_SETCHECK
, wParam
,0);
432 SendDlgItemMessage(hDlg
,IDC_STARTMINIMIZEDCHECK
,BM_SETCHECK
, wParam
,0);
435 SendDlgItemMessage(hDlg
,IDC_SHOWMAGNIFIERCHECK
,BM_SETCHECK
, wParam
,0);
437 return (INT_PTR
)TRUE
;
441 switch (LOWORD(wParam
))
445 EndDialog(hDlg
, LOWORD(wParam
));
446 return (INT_PTR
)TRUE
;
448 case IDC_BUTTON_HELP
:
450 MessageBox(hDlg
, TEXT("Magnifier help not available yet!") , TEXT("Help") , MB_OK
);
453 if (HIWORD(wParam
) == CBN_SELCHANGE
)
455 HWND hCombo
= GetDlgItem(hDlg
,IDC_ZOOM
);
457 /* Get index of current selection and the text of that selection */
458 iZoom
= SendMessage( hCombo
, CB_GETCURSEL
, (WPARAM
) wParam
, (LPARAM
) lParam
) + 1;
460 /* Update the magnifier UI */
464 case IDC_INVERTCOLORSCHECK
:
465 bInvertColors
= IsDlgButtonChecked(hDlg
, IDC_INVERTCOLORSCHECK
);
468 case IDC_FOLLOWMOUSECHECK
:
469 bFollowMouse
= IsDlgButtonChecked(hDlg
, IDC_FOLLOWMOUSECHECK
);
471 case IDC_FOLLOWKEYBOARDCHECK
:
472 bFollowFocus
= IsDlgButtonChecked(hDlg
, IDC_FOLLOWKEYBOARDCHECK
);
474 case IDC_FOLLOWTEXTEDITINGCHECK
:
475 bFollowCaret
= IsDlgButtonChecked(hDlg
, IDC_FOLLOWTEXTEDITINGCHECK
);
477 case IDC_STARTMINIMIZEDCHECK
:
478 bStartMinimized
= IsDlgButtonChecked(hDlg
, IDC_STARTMINIMIZEDCHECK
);
480 case IDC_SHOWMAGNIFIER
:
481 bShowMagnifier
= IsDlgButtonChecked(hDlg
, IDC_SHOWMAGNIFIERCHECK
);
483 ShowWindow (hMainWnd
, SW_SHOW
);
485 ShowWindow (hMainWnd
, SW_HIDE
);
490 return (INT_PTR
)FALSE
;
493 INT_PTR CALLBACK
WarningProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
495 UNREFERENCED_PARAMETER(lParam
);
500 return (INT_PTR
)TRUE
;
503 switch (LOWORD(wParam
))
505 case IDC_SHOWWARNINGCHECK
:
506 bShowWarning
= !IsDlgButtonChecked(hDlg
, IDC_SHOWWARNINGCHECK
);
509 if (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
)
511 EndDialog(hDlg
, LOWORD(wParam
));
512 return (INT_PTR
)TRUE
;
517 return (INT_PTR
)FALSE
;