mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 01:03:16 +00:00
[MAGNIFY]
* Use GetGUIThreadInfo instead of multiple separate "hacks" to obtain all the necessary data in one single call. * Keep the off-screen DC for later use, and only recreate when needed. * Restore caret follow back to default-on. More changes toward CORE-10691 svn path=/trunk/; revision=70337
This commit is contained in:
parent
4faf7c3ef3
commit
901e051b93
2 changed files with 94 additions and 70 deletions
|
@ -44,6 +44,13 @@ HMENU notifyMenu;
|
||||||
HWND hOptionsDialog;
|
HWND hOptionsDialog;
|
||||||
BOOL bOptionsDialog = FALSE;
|
BOOL bOptionsDialog = FALSE;
|
||||||
|
|
||||||
|
BOOL bRecreateOffscreenDC = TRUE;
|
||||||
|
LONG sourceWidth = 0;
|
||||||
|
LONG sourceHeight = 0;
|
||||||
|
HDC hdcOffscreen = NULL;
|
||||||
|
HANDLE hbmpOld;
|
||||||
|
HBITMAP hbmpOffscreen = NULL;
|
||||||
|
|
||||||
/* Current magnified area */
|
/* Current magnified area */
|
||||||
POINT cp;
|
POINT cp;
|
||||||
|
|
||||||
|
@ -51,6 +58,8 @@ POINT cp;
|
||||||
POINT pMouse;
|
POINT pMouse;
|
||||||
POINT pCaret;
|
POINT pCaret;
|
||||||
POINT pFocus;
|
POINT pFocus;
|
||||||
|
HWND pCaretWnd;
|
||||||
|
HWND pFocusWnd;
|
||||||
|
|
||||||
ATOM MyRegisterClass(HINSTANCE hInstance);
|
ATOM MyRegisterClass(HINSTANCE hInstance);
|
||||||
BOOL InitInstance(HINSTANCE, int);
|
BOOL InitInstance(HINSTANCE, int);
|
||||||
|
@ -97,6 +106,11 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SelectObject(hdcOffscreen, hbmpOld);
|
||||||
|
DeleteObject (hbmpOffscreen);
|
||||||
|
DeleteDC(hdcOffscreen);
|
||||||
|
|
||||||
return (int) msg.wParam;
|
return (int) msg.wParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,9 +215,6 @@ void GetBestOverlapWithMonitors(LPRECT rect)
|
||||||
void Draw(HDC aDc)
|
void Draw(HDC aDc)
|
||||||
{
|
{
|
||||||
HDC desktopHdc = NULL;
|
HDC desktopHdc = NULL;
|
||||||
HDC HdcStretch;
|
|
||||||
HANDLE hOld;
|
|
||||||
HBITMAP HbmpStrech;
|
|
||||||
|
|
||||||
RECT sourceRect, intersectedRect;
|
RECT sourceRect, intersectedRect;
|
||||||
RECT targetRect, appRect;
|
RECT targetRect, appRect;
|
||||||
|
@ -212,7 +223,6 @@ void Draw(HDC aDc)
|
||||||
ICONINFO iinfo;
|
ICONINFO iinfo;
|
||||||
|
|
||||||
int AppWidth, AppHeight;
|
int AppWidth, AppHeight;
|
||||||
LONG blitAreaWidth, blitAreaHeight;
|
|
||||||
|
|
||||||
if (bInvertColors)
|
if (bInvertColors)
|
||||||
rop = NOTSRCCOPY;
|
rop = NOTSRCCOPY;
|
||||||
|
@ -220,7 +230,8 @@ void Draw(HDC aDc)
|
||||||
desktopHdc = GetDC(0);
|
desktopHdc = GetDC(0);
|
||||||
|
|
||||||
GetClientRect(hMainWnd, &appRect);
|
GetClientRect(hMainWnd, &appRect);
|
||||||
GetWindowRect(hDesktopWindow, &sourceRect);
|
AppWidth = (appRect.right - appRect.left);
|
||||||
|
AppHeight = (appRect.bottom - appRect.top);
|
||||||
|
|
||||||
ZeroMemory(&cinfo, sizeof(cinfo));
|
ZeroMemory(&cinfo, sizeof(cinfo));
|
||||||
ZeroMemory(&iinfo, sizeof(iinfo));
|
ZeroMemory(&iinfo, sizeof(iinfo));
|
||||||
|
@ -232,38 +243,48 @@ void Draw(HDC aDc)
|
||||||
ClientToScreen(hMainWnd, (POINT*)&targetRect.left);
|
ClientToScreen(hMainWnd, (POINT*)&targetRect.left);
|
||||||
ClientToScreen(hMainWnd, (POINT*)&targetRect.right);
|
ClientToScreen(hMainWnd, (POINT*)&targetRect.right);
|
||||||
|
|
||||||
AppWidth = (appRect.right - appRect.left);
|
if (bRecreateOffscreenDC || !hdcOffscreen)
|
||||||
AppHeight = (appRect.bottom - appRect.top);
|
{
|
||||||
|
bRecreateOffscreenDC = FALSE;
|
||||||
|
|
||||||
blitAreaWidth = AppWidth / iZoom;
|
if(hdcOffscreen)
|
||||||
blitAreaHeight = AppHeight / iZoom;
|
{
|
||||||
|
SelectObject(hdcOffscreen, hbmpOld);
|
||||||
|
DeleteObject (hbmpOffscreen);
|
||||||
|
DeleteDC(hdcOffscreen);
|
||||||
|
}
|
||||||
|
|
||||||
sourceRect.left = (cp.x) - (blitAreaWidth /2);
|
sourceWidth = AppWidth / iZoom;
|
||||||
sourceRect.top = (cp.y) - (blitAreaHeight /2);
|
sourceHeight = AppHeight / iZoom;
|
||||||
sourceRect.right = sourceRect.left + blitAreaWidth;
|
|
||||||
sourceRect.bottom = sourceRect.top + blitAreaHeight;
|
/* 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);
|
GetBestOverlapWithMonitors(&sourceRect);
|
||||||
|
|
||||||
/* Create a memory DC compatible with client area DC */
|
|
||||||
HdcStretch = CreateCompatibleDC(desktopHdc);
|
|
||||||
|
|
||||||
/* Create a bitmap compatible with the client area DC */
|
|
||||||
HbmpStrech = CreateCompatibleBitmap(
|
|
||||||
desktopHdc,
|
|
||||||
blitAreaWidth,
|
|
||||||
blitAreaHeight);
|
|
||||||
|
|
||||||
/* Select our bitmap in memory DC and save the old one */
|
|
||||||
hOld = SelectObject(HdcStretch , HbmpStrech);
|
|
||||||
|
|
||||||
/* Paint the screen bitmap to our in memory DC */
|
/* Paint the screen bitmap to our in memory DC */
|
||||||
BitBlt(
|
BitBlt(
|
||||||
HdcStretch,
|
hdcOffscreen,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
blitAreaWidth,
|
sourceWidth,
|
||||||
blitAreaHeight,
|
sourceHeight,
|
||||||
desktopHdc,
|
desktopHdc,
|
||||||
sourceRect.left,
|
sourceRect.left,
|
||||||
sourceRect.top,
|
sourceRect.top,
|
||||||
|
@ -272,12 +293,12 @@ void Draw(HDC aDc)
|
||||||
if (IntersectRect(&intersectedRect, &sourceRect, &targetRect))
|
if (IntersectRect(&intersectedRect, &sourceRect, &targetRect))
|
||||||
{
|
{
|
||||||
OffsetRect(&intersectedRect, -sourceRect.left, -sourceRect.top);
|
OffsetRect(&intersectedRect, -sourceRect.left, -sourceRect.top);
|
||||||
FillRect(HdcStretch, &intersectedRect, GetStockObject(DC_BRUSH));
|
FillRect(hdcOffscreen, &intersectedRect, GetStockObject(DC_BRUSH));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw the mouse pointer in the right position */
|
/* Draw the mouse pointer in the right position */
|
||||||
DrawIcon(
|
DrawIcon(
|
||||||
HdcStretch ,
|
hdcOffscreen ,
|
||||||
pMouse.x - iinfo.xHotspot - sourceRect.left, // - 10,
|
pMouse.x - iinfo.xHotspot - sourceRect.left, // - 10,
|
||||||
pMouse.y - iinfo.yHotspot - sourceRect.top, // - 10,
|
pMouse.y - iinfo.yHotspot - sourceRect.top, // - 10,
|
||||||
cinfo.hCursor);
|
cinfo.hCursor);
|
||||||
|
@ -289,11 +310,11 @@ void Draw(HDC aDc)
|
||||||
0,
|
0,
|
||||||
AppWidth,
|
AppWidth,
|
||||||
AppHeight,
|
AppHeight,
|
||||||
HdcStretch,
|
hdcOffscreen,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
blitAreaWidth,
|
sourceWidth,
|
||||||
blitAreaHeight,
|
sourceHeight,
|
||||||
SRCCOPY | NOMIRRORBITMAP);
|
SRCCOPY | NOMIRRORBITMAP);
|
||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
|
@ -301,9 +322,6 @@ void Draw(HDC aDc)
|
||||||
DeleteObject(iinfo.hbmMask);
|
DeleteObject(iinfo.hbmMask);
|
||||||
if (iinfo.hbmColor)
|
if (iinfo.hbmColor)
|
||||||
DeleteObject(iinfo.hbmColor);
|
DeleteObject(iinfo.hbmColor);
|
||||||
SelectObject(HdcStretch, hOld);
|
|
||||||
DeleteObject (HbmpStrech);
|
|
||||||
DeleteDC(HdcStretch);
|
|
||||||
ReleaseDC(hDesktopWindow, desktopHdc);
|
ReleaseDC(hDesktopWindow, desktopHdc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,6 +350,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_TIMER:
|
case WM_TIMER:
|
||||||
{
|
{
|
||||||
BOOL hasMoved = FALSE;
|
BOOL hasMoved = FALSE;
|
||||||
|
HWND hwndForeground = GetForegroundWindow ();
|
||||||
|
DWORD threadId = GetWindowThreadProcessId(hwndForeground, NULL);
|
||||||
|
GUITHREADINFO guiInfo;
|
||||||
|
guiInfo.cbSize = sizeof(guiInfo);
|
||||||
|
|
||||||
|
GetGUIThreadInfo(threadId, &guiInfo);
|
||||||
|
|
||||||
if (bFollowMouse)
|
if (bFollowMouse)
|
||||||
{
|
{
|
||||||
|
@ -350,47 +374,43 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bFollowCaret && !hasMoved)
|
if (bFollowCaret && hwndForeground && guiInfo.hwndCaret)
|
||||||
{
|
{
|
||||||
POINT pNewCaret;
|
POINT ptCaret;
|
||||||
HWND hwnd2;
|
ptCaret.x = (guiInfo.rcCaret.left + guiInfo.rcCaret.right) / 2;
|
||||||
|
ptCaret.y = (guiInfo.rcCaret.top + guiInfo.rcCaret.bottom) / 2;
|
||||||
|
|
||||||
//Get caret position
|
if (guiInfo.hwndCaret && ((pCaretWnd != guiInfo.hwndCaret) || (pCaret.x != ptCaret.x) || (pCaret.y != ptCaret.y)))
|
||||||
HWND hwnd1 = GetForegroundWindow ();
|
|
||||||
DWORD a = GetWindowThreadProcessId(hwnd1, NULL);
|
|
||||||
DWORD b = GetCurrentThreadId();
|
|
||||||
AttachThreadInput (a, b, TRUE);
|
|
||||||
hwnd2 = GetFocus();
|
|
||||||
|
|
||||||
GetCaretPos( &pNewCaret);
|
|
||||||
ClientToScreen (hwnd2, (LPPOINT) &pNewCaret);
|
|
||||||
AttachThreadInput (a, b, FALSE);
|
|
||||||
|
|
||||||
if (((pCaret.x != pNewCaret.x) || (pCaret.y != pNewCaret.y)))
|
|
||||||
{
|
{
|
||||||
//Update to new position
|
//Update to new position
|
||||||
pCaret = pNewCaret;
|
pCaret = ptCaret;
|
||||||
cp = pNewCaret;
|
pCaretWnd = guiInfo.hwndCaret;
|
||||||
|
if(!hasMoved)
|
||||||
|
{
|
||||||
|
ClientToScreen (guiInfo.hwndCaret, (LPPOINT) &ptCaret);
|
||||||
|
cp = ptCaret;
|
||||||
|
}
|
||||||
hasMoved = TRUE;
|
hasMoved = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bFollowFocus && !hasMoved)
|
if (bFollowFocus && hwndForeground && guiInfo.hwndFocus)
|
||||||
{
|
{
|
||||||
POINT pNewFocus;
|
POINT ptFocus;
|
||||||
RECT controlRect;
|
RECT activeRect;
|
||||||
|
|
||||||
//Get current control focus
|
//Get current control focus
|
||||||
HWND hwnd3 = GetFocus ();
|
GetWindowRect (guiInfo.hwndFocus, &activeRect);
|
||||||
GetWindowRect (hwnd3 , &controlRect);
|
ptFocus.x = (activeRect.left + activeRect.right) / 2;
|
||||||
pNewFocus.x = controlRect.left;
|
ptFocus.y = (activeRect.top + activeRect.bottom) / 2;
|
||||||
pNewFocus.y = controlRect.top;
|
|
||||||
|
|
||||||
if(((pFocus.x != pNewFocus.x) || (pFocus.y != pNewFocus.y)))
|
if(guiInfo.hwndFocus && ((guiInfo.hwndFocus != pFocusWnd) || (pFocus.x != ptFocus.x) || (pFocus.y != ptFocus.y)))
|
||||||
{
|
{
|
||||||
//Update to new position
|
//Update to new position
|
||||||
pFocus = pNewFocus;
|
pFocus = ptFocus;
|
||||||
cp = pNewFocus;
|
pFocusWnd = guiInfo.hwndFocus;
|
||||||
|
if(!hasMoved)
|
||||||
|
cp = ptFocus;
|
||||||
hasMoved = TRUE;
|
hasMoved = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,6 +471,16 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
break;
|
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:
|
case WM_ERASEBKGND:
|
||||||
// handle WM_ERASEBKGND by simply returning non-zero because we did all the drawing in WM_PAINT.
|
// handle WM_ERASEBKGND by simply returning non-zero because we did all the drawing in WM_PAINT.
|
||||||
break;
|
break;
|
||||||
|
@ -511,12 +541,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_CONTEXTMENU:
|
|
||||||
{
|
|
||||||
TrackPopupMenu(notifyMenu, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, hWnd, NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ BOOL bShowWarning = TRUE;
|
||||||
|
|
||||||
BOOL bFollowMouse = TRUE;
|
BOOL bFollowMouse = TRUE;
|
||||||
BOOL bFollowFocus = TRUE;
|
BOOL bFollowFocus = TRUE;
|
||||||
BOOL bFollowCaret = FALSE; // FIXME: Default to false because AttachThreadInput seems to break.
|
BOOL bFollowCaret = TRUE;
|
||||||
|
|
||||||
BOOL bInvertColors = FALSE;
|
BOOL bInvertColors = FALSE;
|
||||||
BOOL bStartMinimized = FALSE;
|
BOOL bStartMinimized = FALSE;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue