Commit 8eaca69b authored by Michael Kaufmann's avatar Michael Kaufmann Committed by Alexandre Julliard

ScrollWindowEx: Don't move the caret of child windows and hide it only

if it's in the source or in the destination rectangle.
parent 055d96b7
...@@ -346,30 +346,75 @@ static void update_now( HWND hwnd, UINT rdw_flags ) ...@@ -346,30 +346,75 @@ static void update_now( HWND hwnd, UINT rdw_flags )
/************************************************************************* /*************************************************************************
* fix_caret * fix_caret
* *
* Helper for ScrollWindowEx. * Helper for ScrollWindowEx:
* If the return value is 0, no special caret handling is necessary.
* Otherwise the return value is the handle of the window that owns the
* caret. Its caret needs to be hidden during the scroll operation and
* moved to new_caret_pos if move_caret is TRUE.
*/ */
static HWND fix_caret(HWND hWnd, LPRECT lprc, UINT flags) static HWND fix_caret(HWND hWnd, const LPRECT scroll_rect, INT dx, INT dy,
UINT flags, LPBOOL move_caret, LPPOINT new_caret_pos)
{ {
GUITHREADINFO info; GUITHREADINFO info;
RECT rect, mapped_rcCaret;
BOOL hide_caret = FALSE;
if (!GetGUIThreadInfo( GetCurrentThreadId(), &info )) return 0; if (!GetGUIThreadInfo( GetCurrentThreadId(), &info )) return 0;
if (!info.hwndCaret) return 0; if (!info.hwndCaret) return 0;
if (info.hwndCaret == hWnd ||
((flags & SW_SCROLLCHILDREN) && IsChild(hWnd, info.hwndCaret))) if (info.hwndCaret == hWnd)
{ {
POINT pt; /* Move the caret if it's (partially) in the source rectangle */
pt.x = info.rcCaret.left; if (IntersectRect(&rect, scroll_rect, &info.rcCaret))
pt.y = info.rcCaret.top;
MapWindowPoints( info.hwndCaret, hWnd, (LPPOINT)&info.rcCaret, 2 );
if( IntersectRect(lprc, lprc, &info.rcCaret) )
{ {
HideCaret(0); *move_caret = TRUE;
lprc->left = pt.x; hide_caret = TRUE;
lprc->top = pt.y; new_caret_pos->x = info.rcCaret.left + dx;
return info.hwndCaret; new_caret_pos->y = info.rcCaret.top + dy;
}
else
{
*move_caret = FALSE;
/* Hide the caret if it's in the destination rectangle */
rect = *scroll_rect;
OffsetRect(&rect, dx, dy);
hide_caret = IntersectRect(&rect, &rect, &info.rcCaret);
} }
} }
return 0; else
{
if ((flags & SW_SCROLLCHILDREN) && IsChild(hWnd, info.hwndCaret))
{
*move_caret = FALSE;
/* Hide the caret if it's in the source or in the destination
rectangle */
mapped_rcCaret = info.rcCaret;
MapWindowPoints(info.hwndCaret, hWnd, (LPPOINT)&mapped_rcCaret, 2);
if (IntersectRect(&rect, scroll_rect, &mapped_rcCaret))
{
hide_caret = TRUE;
}
else
{
rect = *scroll_rect;
OffsetRect(&rect, dx, dy);
hide_caret = IntersectRect(&rect, &rect, &mapped_rcCaret);
}
}
else
return 0;
}
if (hide_caret)
{
HideCaret(info.hwndCaret);
return info.hwndCaret;
}
else
return 0;
} }
...@@ -756,8 +801,9 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, ...@@ -756,8 +801,9 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy,
HRGN hrgnWinupd = 0; HRGN hrgnWinupd = 0;
HDC hDC; HDC hDC;
RECT rc, cliprc; RECT rc, cliprc;
RECT caretrc;
HWND hwndCaret = NULL; HWND hwndCaret = NULL;
BOOL moveCaret = FALSE;
POINT newCaretPos;
TRACE( "%p, %d,%d hrgnUpdate=%p rcUpdate = %p %s %04x\n", TRACE( "%p, %d,%d hrgnUpdate=%p rcUpdate = %p %s %04x\n",
hwnd, dx, dy, hrgnUpdate, rcUpdate, wine_dbgstr_rect(rect), flags ); hwnd, dx, dy, hrgnUpdate, rcUpdate, wine_dbgstr_rect(rect), flags );
...@@ -780,11 +826,13 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, ...@@ -780,11 +826,13 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy,
if( hrgnUpdate ) bOwnRgn = FALSE; if( hrgnUpdate ) bOwnRgn = FALSE;
else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ); else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
newCaretPos.x = newCaretPos.y = 0;
if( !IsRectEmpty(&cliprc) && (dx || dy)) { if( !IsRectEmpty(&cliprc) && (dx || dy)) {
DWORD dcxflags = DCX_CACHE; DWORD dcxflags = DCX_CACHE;
DWORD style = GetWindowLongW( hwnd, GWL_STYLE ); DWORD style = GetWindowLongW( hwnd, GWL_STYLE );
caretrc = rc;
hwndCaret = fix_caret(hwnd, &caretrc, flags); hwndCaret = fix_caret(hwnd, &rc, dx, dy, flags, &moveCaret, &newCaretPos);
if( style & WS_CLIPSIBLINGS) dcxflags |= DCX_CLIPSIBLINGS; if( style & WS_CLIPSIBLINGS) dcxflags |= DCX_CLIPSIBLINGS;
if( GetClassLongW( hwnd, GCL_STYLE ) & CS_PARENTDC) if( GetClassLongW( hwnd, GCL_STYLE ) & CS_PARENTDC)
...@@ -859,7 +907,7 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, ...@@ -859,7 +907,7 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy,
} }
if( hwndCaret ) { if( hwndCaret ) {
SetCaretPos( caretrc.left + dx, caretrc.top + dy ); if ( moveCaret ) SetCaretPos( newCaretPos.x, newCaretPos.y );
ShowCaret(hwndCaret); ShowCaret(hwndCaret);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment