Author: akhaldi
Date: Tue Dec 15 22:53:08 2015
New Revision: 70352
URL:
http://svn.reactos.org/svn/reactos?rev=70352&view=rev
Log:
[0.4.0] * Merge magnifier improvements by David Quintana in revisions 70335 => 70337.
CORE-10691
Modified:
branches/ros-branch-0_4_0/ (props changed)
branches/ros-branch-0_4_0/reactos/ (props changed)
branches/ros-branch-0_4_0/reactos/base/applications/magnify/lang/en-US.rc
branches/ros-branch-0_4_0/reactos/base/applications/magnify/lang/es-ES.rc
branches/ros-branch-0_4_0/reactos/base/applications/magnify/magnifier.c
Propchange: branches/ros-branch-0_4_0/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Dec 15 22:53:08 2015
@@ -1 +1 @@
-/trunk:70000-70321,70324
+/trunk:70000-70321,70324,70335-70337
Propchange: branches/ros-branch-0_4_0/reactos/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Dec 15 22:53:08 2015
@@ -20,4 +20,4 @@
/branches/usb-bringup:51335,51337,51341-51343,51348,51350,51353,51355,51365-51369,51372,51384-54388,54396-54398,54736-54737,54752-54754,54756-54760,54762,54764-54765,54767-54768,54772,54774-54777,54781,54787,54790-54792,54797-54798,54806,54808,54834-54838,54843,54850,54852,54856,54858-54859
/branches/usb-bringup-trunk:55019-55543,55548-55554,55556-55567
/branches/wlan-bringup:54809-54998
-/trunk/reactos:70000-70321,70324
+/trunk/reactos:70000-70321,70324,70335-70337
Modified: branches/ros-branch-0_4_0/reactos/base/applications/magnify/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/a…
==============================================================================
--- branches/ros-branch-0_4_0/reactos/base/applications/magnify/lang/en-US.rc [iso-8859-1]
(original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/magnify/lang/en-US.rc [iso-8859-1]
Tue Dec 15 22:53:08 2015
@@ -33,7 +33,7 @@
CAPTION "Magnifier Settings"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
- DEFPUSHBUTTON "Exit", IDOK, 96, 161, 50, 14
+ DEFPUSHBUTTON "Ok", IDOK, 96, 161, 50, 14
PUSHBUTTON "Help", IDC_BUTTON_HELP, 38, 161, 50, 14
LTEXT "Magnification level:", IDC_STATIC, 6, 8, 68, 8
COMBOBOX IDC_ZOOM, 72, 6, 63, 66, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL |
WS_TABSTOP
Modified: branches/ros-branch-0_4_0/reactos/base/applications/magnify/lang/es-ES.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/a…
==============================================================================
--- branches/ros-branch-0_4_0/reactos/base/applications/magnify/lang/es-ES.rc [iso-8859-1]
(original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/magnify/lang/es-ES.rc [iso-8859-1]
Tue Dec 15 22:53:08 2015
@@ -37,7 +37,7 @@
CAPTION "Configurar lupa"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
- DEFPUSHBUTTON "Salir", IDOK, 96, 161, 50, 14
+ DEFPUSHBUTTON "Aceptar", IDOK, 96, 161, 50, 14
PUSHBUTTON "Ayuda", IDC_BUTTON_HELP, 38, 161, 50, 14
LTEXT "Niveles de aumento:", IDC_STATIC, 6, 8, 68, 8
COMBOBOX IDC_ZOOM, 76, 6, 63, 66, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL |
WS_TABSTOP
Modified: branches/ros-branch-0_4_0/reactos/base/applications/magnify/magnifier.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_4_0/reactos/base/a…
==============================================================================
--- branches/ros-branch-0_4_0/reactos/base/applications/magnify/magnifier.c [iso-8859-1]
(original)
+++ branches/ros-branch-0_4_0/reactos/base/applications/magnify/magnifier.c [iso-8859-1]
Tue Dec 15 22:53:08 2015
@@ -3,8 +3,9 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/magnify/magnifier.c
* PURPOSE: Magnification of parts of the screen.
- * COPYRIGHT: Copyright 2007 Marc Piulachs <marc.piulachs(a)codexchange.net>
- *
+ * AUTHORS:
+ * Marc Piulachs <marc.piulachs(a)codexchange.net>
+ * David Quintana <gigaherz(a)gmail.com>
*/
/* TODO: AppBar */
@@ -14,6 +15,8 @@
#include <winuser.h>
#include <wingdi.h>
#include <winnls.h>
+#include <shellapi.h>
+#include <windowsx.h>
#include "resource.h"
@@ -27,9 +30,26 @@
TCHAR szTitle[MAX_LOADSTRING];
-#define REPAINT_SPEED 100
+#define TIMER_SPEED 1
+#define REPAINT_SPEED 100
+
+DWORD lastTicks = 0;
HWND hDesktopWindow = NULL;
+
+#define APPMSG_NOTIFYICON (WM_APP+1)
+HICON notifyIcon;
+NOTIFYICONDATA nid;
+HMENU notifyMenu;
+HWND hOptionsDialog;
+BOOL bOptionsDialog = FALSE;
+
+BOOL bRecreateOffscreenDC = TRUE;
+LONG sourceWidth = 0;
+LONG sourceHeight = 0;
+HDC hdcOffscreen = NULL;
+HANDLE hbmpOld;
+HBITMAP hbmpOffscreen = NULL;
/* Current magnified area */
POINT cp;
@@ -38,6 +58,8 @@
POINT pMouse;
POINT pCaret;
POINT pFocus;
+HWND pCaretWnd;
+HWND pFocusWnd;
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
@@ -83,6 +105,11 @@
DispatchMessage(&msg);
}
}
+
+
+ SelectObject(hdcOffscreen, hbmpOld);
+ DeleteObject (hbmpOffscreen);
+ DeleteDC(hdcOffscreen);
return (int) msg.wParam;
}
@@ -99,7 +126,7 @@
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wc.lpszMenuName = MAKEINTRESOURCE(IDC_MAGNIFIER);
+ wc.lpszMenuName = NULL; //MAKEINTRESOURCE(IDC_MAGNIFIER);
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
@@ -133,6 +160,10 @@
ShowWindow(hMainWnd, bStartMinimized ? SW_MINIMIZE : nCmdShow);
UpdateWindow(hMainWnd);
+ // Windows 2003's Magnifier always shows this dialog, and exits when the dialog
isclosed.
+ // Should we add a custom means to prevent opening it?
+ hOptionsDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOGOPTIONS),
hMainWnd, OptionsProc);
+
if (bShowWarning)
DialogBox(hInstance, MAKEINTRESOURCE(IDD_WARNINGDIALOG), hMainWnd, WarningProc);
@@ -148,26 +179,59 @@
}
}
+void GetBestOverlapWithMonitors(LPRECT rect)
+{
+ int rcLeft, rcTop;
+ int rcWidth, rcHeight;
+ RECT rcMon;
+ HMONITOR hMon = MonitorFromRect(rect, MONITOR_DEFAULTTONEAREST);
+ MONITORINFO info;
+ info.cbSize = sizeof(info);
+
+ GetMonitorInfo(hMon, &info);
+
+ rcMon = info.rcMonitor;
+
+ rcLeft = rect->left;
+ rcTop = rect->top;
+ rcWidth = (rect->right - rect->left);
+ rcHeight = (rect->bottom - rect->top);
+
+ if (rcLeft < rcMon.left)
+ rcLeft = rcMon.left;
+
+ if (rcTop < rcMon.top)
+ rcTop = rcMon.top;
+
+ if (rcLeft > (rcMon.right - rcWidth))
+ rcLeft = (rcMon.right - rcWidth);
+
+ if (rcTop > (rcMon.bottom - rcHeight))
+ rcTop = (rcMon.bottom - rcHeight);
+
+ OffsetRect(rect, (rcLeft-rect->left), (rcTop-rect->top));
+}
+
void Draw(HDC aDc)
{
HDC desktopHdc = NULL;
- HDC HdcStrech;
- HANDLE hOld;
- HBITMAP HbmpStrech;
-
- RECT R;
- RECT appRect;
+
+ RECT sourceRect, intersectedRect;
+ RECT targetRect, appRect;
DWORD rop = SRCCOPY;
CURSORINFO cinfo;
ICONINFO iinfo;
- int Width, Height, AppWidth, AppHeight;
- LONG blitAreaWidth, blitAreaHeight, blitAreaX, blitAreaY;
-
- desktopHdc = GetWindowDC(hDesktopWindow);
+ int AppWidth, AppHeight;
+
+ if (bInvertColors)
+ rop = NOTSRCCOPY;
+
+ desktopHdc = GetDC(0);
GetClientRect(hMainWnd, &appRect);
- GetWindowRect(hDesktopWindow, &R);
+ AppWidth = (appRect.right - appRect.left);
+ AppHeight = (appRect.bottom - appRect.top);
ZeroMemory(&cinfo, sizeof(cinfo));
ZeroMemory(&iinfo, sizeof(iinfo));
@@ -175,63 +239,69 @@
GetCursorInfo(&cinfo);
GetIconInfo(cinfo.hCursor, &iinfo);
- /* Create a memory DC compatible with client area DC */
- HdcStrech = CreateCompatibleDC(desktopHdc);
-
- /* Create a bitmap compatible with the client area DC */
- HbmpStrech = CreateCompatibleBitmap(
- desktopHdc,
- R.right,
- R.bottom);
-
- /* Select our bitmap in memory DC and save the old one */
- hOld = SelectObject(HdcStrech , HbmpStrech);
-
+ targetRect = appRect;
+ ClientToScreen(hMainWnd, (POINT*)&targetRect.left);
+ ClientToScreen(hMainWnd, (POINT*)&targetRect.right);
+
+ if (bRecreateOffscreenDC || !hdcOffscreen)
+ {
+ bRecreateOffscreenDC = FALSE;
+
+ if(hdcOffscreen)
+ {
+ SelectObject(hdcOffscreen, hbmpOld);
+ DeleteObject (hbmpOffscreen);
+ DeleteDC(hdcOffscreen);
+ }
+
+ sourceWidth = AppWidth / iZoom;
+ sourceHeight = AppHeight / iZoom;
+
+ /* Create a memory DC compatible with client area DC */
+ hdcOffscreen = CreateCompatibleDC(desktopHdc);
+
+ /* Create a bitmap compatible with the client area DC */
+ hbmpOffscreen = CreateCompatibleBitmap(
+ desktopHdc,
+ sourceWidth,
+ sourceHeight);
+
+ /* Select our bitmap in memory DC and save the old one */
+ hbmpOld = SelectObject(hdcOffscreen , hbmpOffscreen);
+ }
+
+ GetWindowRect(hDesktopWindow, &sourceRect);
+ sourceRect.left = (cp.x) - (sourceWidth /2);
+ sourceRect.top = (cp.y) - (sourceHeight /2);
+ sourceRect.right = sourceRect.left + sourceWidth;
+ sourceRect.bottom = sourceRect.top + sourceHeight;
+
+ GetBestOverlapWithMonitors(&sourceRect);
+
/* Paint the screen bitmap to our in memory DC */
BitBlt(
- HdcStrech,
+ hdcOffscreen,
0,
0,
- R.right,
- R.bottom,
+ sourceWidth,
+ sourceHeight,
desktopHdc,
- 0,
- 0,
- SRCCOPY);
-
+ sourceRect.left,
+ sourceRect.top,
+ rop);
+
+ if (IntersectRect(&intersectedRect, &sourceRect, &targetRect))
+ {
+ OffsetRect(&intersectedRect, -sourceRect.left, -sourceRect.top);
+ FillRect(hdcOffscreen, &intersectedRect, GetStockObject(DC_BRUSH));
+ }
+
/* Draw the mouse pointer in the right position */
DrawIcon(
- HdcStrech ,
- pMouse.x - iinfo.xHotspot, // - 10,
- pMouse.y - iinfo.yHotspot, // - 10,
+ hdcOffscreen ,
+ pMouse.x - iinfo.xHotspot - sourceRect.left, // - 10,
+ pMouse.y - iinfo.yHotspot - sourceRect.top, // - 10,
cinfo.hCursor);
-
- Width = (R.right - R.left);
- Height = (R.bottom - R.top);
-
- AppWidth = (appRect.right - appRect.left);
- AppHeight = (appRect.bottom - appRect.top);
-
- blitAreaWidth = AppWidth / iZoom;
- blitAreaHeight = AppHeight / iZoom;
-
- blitAreaX = (cp.x) - (blitAreaWidth /2);
- blitAreaY = (cp.y) - (blitAreaHeight /2);
-
- if (blitAreaX < 0)
- blitAreaX = 0;
-
- if (blitAreaY < 0)
- blitAreaY = 0;
-
- if (blitAreaX > (Width - blitAreaWidth))
- blitAreaX = (Width - blitAreaWidth);
-
- if (blitAreaY > (Height - blitAreaHeight))
- blitAreaY = (Height - blitAreaHeight);
-
- if (bInvertColors)
- rop = NOTSRCCOPY;
/* Blast the stretched image from memory DC to window DC */
StretchBlt(
@@ -240,25 +310,37 @@
0,
AppWidth,
AppHeight,
- HdcStrech,
- blitAreaX,
- blitAreaY,
- blitAreaWidth,
- blitAreaHeight,
- rop | NOMIRRORBITMAP);
-
-
+ hdcOffscreen,
+ 0,
+ 0,
+ sourceWidth,
+ sourceHeight,
+ SRCCOPY | NOMIRRORBITMAP);
+
/* Cleanup */
if (iinfo.hbmMask)
DeleteObject(iinfo.hbmMask);
if (iinfo.hbmColor)
DeleteObject(iinfo.hbmColor);
- SelectObject(HdcStrech, hOld);
- DeleteObject (HbmpStrech);
- DeleteDC(HdcStrech);
ReleaseDC(hDesktopWindow, desktopHdc);
}
+void HandleNotifyIconMessage(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+ POINT pt;
+
+ switch(lParam)
+ {
+ case WM_LBUTTONUP:
+ PostMessage(hMainWnd, WM_COMMAND, IDM_OPTIONS, 0);
+ break;
+ case WM_RBUTTONUP:
+ GetCursorPos (&pt);
+ TrackPopupMenu(notifyMenu, 0, pt.x, pt.y, 0, hWnd, NULL);
+ break;
+ }
+}
+
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId;
@@ -267,53 +349,87 @@
{
case WM_TIMER:
{
- POINT pNewMouse;
- POINT pNewCaret;
- POINT pNewFocus;
- HWND hwnd1, hwnd2, hwnd3;
- DWORD a, b;
- RECT controlRect;
-
- //Get current mouse position
- GetCursorPos (&pNewMouse);
-
- //Get caret position
- hwnd1 = GetForegroundWindow ();
- a = GetWindowThreadProcessId(hwnd1, NULL);
- b = GetCurrentThreadId();
- AttachThreadInput (a, b, TRUE);
- hwnd2 = GetFocus();
-
- GetCaretPos( &pNewCaret);
- ClientToScreen (hwnd2, (LPPOINT) &pNewCaret);
- AttachThreadInput (a, b, FALSE);
-
- //Get current control focus
- hwnd3 = GetFocus ();
- GetWindowRect (hwnd3 , &controlRect);
- pNewFocus.x = controlRect.left;
- pNewFocus.y = controlRect.top;
-
- //If mouse has moved ....
- if (((pMouse.x != pNewMouse.x) || (pMouse.y != pNewMouse.y)) &&
bFollowMouse)
- {
- //Update to new position
- pMouse = pNewMouse;
- cp = pNewMouse;
- }
- else if (((pCaret.x != pNewCaret.x) || (pCaret.y != pNewCaret.y)) &&
bFollowCaret)
- {
- //Update to new position
- pCaret = pNewCaret;
- cp = pNewCaret;
- }
- else if (((pFocus.x != pNewFocus.x) || (pFocus.y != pNewFocus.y)) &&
bFollowFocus)
- {
- //Update to new position
- pFocus = pNewFocus;
- cp = pNewFocus;
- }
- Refresh();
+ BOOL hasMoved = FALSE;
+ HWND hwndForeground = GetForegroundWindow ();
+ DWORD threadId = GetWindowThreadProcessId(hwndForeground, NULL);
+ GUITHREADINFO guiInfo;
+ guiInfo.cbSize = sizeof(guiInfo);
+
+ GetGUIThreadInfo(threadId, &guiInfo);
+
+ if (bFollowMouse)
+ {
+ POINT pNewMouse;
+
+ //Get current mouse position
+ GetCursorPos (&pNewMouse);
+
+ //If mouse has moved ...
+ if (((pMouse.x != pNewMouse.x) || (pMouse.y != pNewMouse.y)))
+ {
+ //Update to new position
+ pMouse = pNewMouse;
+ cp = pNewMouse;
+ hasMoved = TRUE;
+ }
+ }
+
+ if (bFollowCaret && hwndForeground && guiInfo.hwndCaret)
+ {
+ POINT ptCaret;
+ ptCaret.x = (guiInfo.rcCaret.left + guiInfo.rcCaret.right) / 2;
+ ptCaret.y = (guiInfo.rcCaret.top + guiInfo.rcCaret.bottom) / 2;
+
+ if (guiInfo.hwndCaret && ((pCaretWnd != guiInfo.hwndCaret) ||
(pCaret.x != ptCaret.x) || (pCaret.y != ptCaret.y)))
+ {
+ //Update to new position
+ pCaret = ptCaret;
+ pCaretWnd = guiInfo.hwndCaret;
+ if(!hasMoved)
+ {
+ ClientToScreen (guiInfo.hwndCaret, (LPPOINT) &ptCaret);
+ cp = ptCaret;
+ }
+ hasMoved = TRUE;
+ }
+ }
+
+ if (bFollowFocus && hwndForeground && guiInfo.hwndFocus)
+ {
+ POINT ptFocus;
+ RECT activeRect;
+
+ //Get current control focus
+ GetWindowRect (guiInfo.hwndFocus, &activeRect);
+ ptFocus.x = (activeRect.left + activeRect.right) / 2;
+ ptFocus.y = (activeRect.top + activeRect.bottom) / 2;
+
+ if(guiInfo.hwndFocus && ((guiInfo.hwndFocus != pFocusWnd) ||
(pFocus.x != ptFocus.x) || (pFocus.y != ptFocus.y)))
+ {
+ //Update to new position
+ pFocus = ptFocus;
+ pFocusWnd = guiInfo.hwndFocus;
+ if(!hasMoved)
+ cp = ptFocus;
+ hasMoved = TRUE;
+ }
+ }
+
+ if(!hasMoved)
+ {
+ DWORD newTicks = GetTickCount();
+ DWORD elapsed = (newTicks - lastTicks);
+ if(elapsed > REPAINT_SPEED)
+ {
+ hasMoved = TRUE;
+ }
+ }
+
+ if(hasMoved)
+ {
+ lastTicks = GetTickCount();
+ Refresh();
+ }
}
break;
@@ -324,7 +440,14 @@
switch (wmId)
{
case IDM_OPTIONS:
- DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOGOPTIONS), hWnd,
OptionsProc);
+ if(bOptionsDialog)
+ {
+ ShowWindow(hOptionsDialog, SW_HIDE);
+ }
+ else
+ {
+ ShowWindow(hOptionsDialog, SW_SHOW);
+ }
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutProc);
@@ -348,6 +471,16 @@
break;
}
+ case WM_CONTEXTMENU:
+ TrackPopupMenu(notifyMenu, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0,
hWnd, NULL);
+ break;
+
+ case WM_SIZE:
+ case WM_DISPLAYCHANGE:
+ bRecreateOffscreenDC = TRUE;
+ Refresh();
+ return DefWindowProc(hWnd, message, wParam, lParam);
+
case WM_ERASEBKGND:
// handle WM_ERASEBKGND by simply returning non-zero because we did all the
drawing in WM_PAINT.
break;
@@ -357,9 +490,24 @@
SaveSettings();
KillTimer(hWnd , 1);
PostQuitMessage(0);
+
+ /* Cleanup notification icon */
+ ZeroMemory(&nid, sizeof(nid));
+ nid.cbSize = sizeof(nid);
+ nid.uFlags = NIF_MESSAGE;
+ nid.hWnd = hWnd;
+ nid.uCallbackMessage = APPMSG_NOTIFYICON;
+ Shell_NotifyIcon(NIM_DELETE, &nid);
+
+ DestroyIcon(notifyIcon);
+
+ DestroyWindow(hOptionsDialog);
break;
case WM_CREATE:
+ {
+ HMENU tempMenu;
+
/* Load settings from registry */
LoadSettings();
@@ -367,7 +515,30 @@
hDesktopWindow = GetDesktopWindow();
/* Set the timer */
- SetTimer (hWnd , 1, REPAINT_SPEED , NULL);
+ SetTimer (hWnd , 1, TIMER_SPEED , NULL);
+
+ /* Notification icon */
+ notifyIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON,
16, 16, 0);
+
+ ZeroMemory(&nid, sizeof(nid));
+ nid.cbSize = sizeof(nid);
+ nid.uFlags = NIF_ICON | NIF_MESSAGE;
+ nid.hWnd = hWnd;
+ nid.uCallbackMessage = APPMSG_NOTIFYICON;
+ nid.hIcon = notifyIcon;
+ Shell_NotifyIcon(NIM_ADD, &nid);
+
+ tempMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDC_MAGNIFIER));
+ notifyMenu = GetSubMenu(tempMenu, 0);
+ RemoveMenu(tempMenu, 0, MF_BYPOSITION);
+ DestroyMenu(tempMenu);
+
+ break;
+ }
+
+ case APPMSG_NOTIFYICON:
+ HandleNotifyIconMessage(hWnd, wParam, lParam);
+
break;
default:
@@ -402,6 +573,9 @@
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
+ case WM_SHOWWINDOW:
+ bOptionsDialog = wParam;
+ break;
case WM_INITDIALOG:
{
// Add the zoom items...
@@ -442,7 +616,7 @@
{
case IDOK:
case IDCANCEL:
- EndDialog(hDlg, LOWORD(wParam));
+ ShowWindow(hDlg, SW_HIDE);
return (INT_PTR)TRUE;
case IDC_BUTTON_HELP: