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/ap... ============================================================================== --- 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/ap... ============================================================================== --- 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/ap... ============================================================================== --- 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@codexchange.net - * + * AUTHORS: + * Marc Piulachs marc.piulachs@codexchange.net + * David Quintana gigaherz@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: