From 19c18b7f2cdbbf2be2e4706daab9820f07f9059f Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Mon, 8 Sep 2003 02:14:20 +0000 Subject: [PATCH] added hittesting for scrollbars and fixed passing the cursor coordinates to NCL messages svn path=/trunk/; revision=6011 --- reactos/include/defines.h | 16 ++++ reactos/include/win32k/ntuser.h | 2 +- reactos/lib/user32/controls/scrollbar.c | 117 +++++++++++++++++------ reactos/lib/user32/include/window.h | 3 + reactos/lib/user32/windows/defwnd.c | 8 +- reactos/subsys/win32k/ntuser/msgqueue.c | 7 +- reactos/subsys/win32k/ntuser/scrollbar.c | 70 ++++++++++++-- 7 files changed, 184 insertions(+), 39 deletions(-) diff --git a/reactos/include/defines.h b/reactos/include/defines.h index 1011d297c22..0857bcf9ff1 100644 --- a/reactos/include/defines.h +++ b/reactos/include/defines.h @@ -4592,6 +4592,22 @@ extern "C" { /* GetFileCompressedSize */ #define INVALID_FILE_SIZE ((DWORD)-1) +/* system ids */ +#define OBJID_WINDOW ((LONG)0x00000000) +#define OBJID_SYSMENU ((LONG)0xFFFFFFFF) +#define OBJID_TITLEBAR ((LONG)0xFFFFFFFE) +#define OBJID_MENU ((LONG)0xFFFFFFFD) +#define OBJID_CLIENT ((LONG)0xFFFFFFFC) +#define OBJID_VSCROLL ((LONG)0xFFFFFFFB) +#define OBJID_HSCROLL ((LONG)0xFFFFFFFA) +#define OBJID_SIZEGRIP ((LONG)0xFFFFFFF9) +#define OBJID_CARET ((LONG)0xFFFFFFF8) +#define OBJID_CURSOR ((LONG)0xFFFFFFF7) +#define OBJID_ALERT ((LONG)0xFFFFFFF6) +#define OBJID_SOUND ((LONG)0xFFFFFFF5) +#define OBJID_QUERYCLASSNAMEIDX ((LONG)0xFFFFFFF4) +#define OBJID_NATIVEOM ((LONG)0xFFFFFFF0) + /* --------------------- old stuff, need to organize! --------------- */ /* BEGINNING of windowsx.h stuff from old headers: */ diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index e2069e3cdec..385f266a0c5 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -468,7 +468,7 @@ NtUserInsertMenuItem( LPCMENUITEMINFOW lpmii); -DWORD +BOOL STDCALL NtUserEnableScrollBar( HWND hWnd, diff --git a/reactos/lib/user32/controls/scrollbar.c b/reactos/lib/user32/controls/scrollbar.c index df7e0e4db77..7f6530f6448 100644 --- a/reactos/lib/user32/controls/scrollbar.c +++ b/reactos/lib/user32/controls/scrollbar.c @@ -1,4 +1,4 @@ -/* $Id: scrollbar.c,v 1.12 2003/09/07 09:55:52 weiden Exp $ +/* $Id: scrollbar.c,v 1.13 2003/09/08 02:14:20 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -54,12 +54,12 @@ static HBITMAP hRgArrowI; #define SA_SSI_REPAINT_ARROWS 0x0008 /* Scroll-bar hit testing */ -#define SCROLL_NOWHERE 0x01 /* Outside the scroll bar */ -#define SCROLL_TOP_ARROW 0x02 /* Top or left arrow */ -#define SCROLL_TOP_RECT 0x04 /* Rectangle between the top arrow and the thumb */ -#define SCROLL_THUMB 0x08 /* Thumb rectangle */ -#define SCROLL_BOTTOM_RECT 0x10 /* Rectangle between the thumb and the bottom arrow */ -#define SCROLL_BOTTOM_ARROW 0x20 /* Bottom or right arrow */ +#define SCROLL_NOWHERE 0x00 /* Outside the scroll bar */ +#define SCROLL_TOP_ARROW 0x01 /* Top or left arrow */ +#define SCROLL_TOP_RECT 0x02 /* Rectangle between the top arrow and the thumb */ +#define SCROLL_THUMB 0x03 /* Thumb rectangle */ +#define SCROLL_BOTTOM_RECT 0x04 /* Rectangle between the thumb and the bottom arrow */ +#define SCROLL_BOTTOM_ARROW 0x05 /* Bottom or right arrow */ static BOOL SCROLL_MovingThumb = FALSE; /* Is the moving thumb being displayed? */ @@ -75,21 +75,6 @@ static BOOL SCROLL_trackVertical; HBRUSH DefWndControlColor (HDC hDC, UINT ctlType); - -DWORD FASTCALL -SCROLL_HitTest(HWND hwnd, LONG idObject, POINT Point) -{ - RECT WindowRect; - - GetWindowRect(hwnd, &WindowRect); - if (!PtInRect(&WindowRect, Point)) - { - return(SCROLL_NOWHERE); - } - - return SCROLL_NOWHERE; -} - /* Ported from WINE20020904 */ /* Draw the scroll bar interior (everything except the arrows). */ static void @@ -101,11 +86,11 @@ arrowSize, PSCROLLBARINFO psbi) HBRUSH hSaveBrush, hBrush; BOOLEAN top_selected = FALSE, bottom_selected = FALSE; DbgPrint("[SCROLL_DrawInterior:%d]\n", nBar); - if(psbi->rgstate[2] & STATE_SYSTEM_PRESSED) + if(psbi->rgstate[SCROLL_TOP_RECT] & STATE_SYSTEM_PRESSED) { top_selected = TRUE; } - if(psbi->rgstate[4] & STATE_SYSTEM_PRESSED) + if(psbi->rgstate[SCROLL_BOTTOM_RECT] & STATE_SYSTEM_PRESSED) { bottom_selected = TRUE; } @@ -274,20 +259,20 @@ SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar, BOOL vertical; info.cbSize = sizeof(SCROLLBARINFO); - NtUserGetScrollBarInfo (hwnd, nBar, &info); - - thumbSize = info.xyThumbBottom - info.xyThumbTop; switch ( nBar ) { case SB_HORZ: vertical = FALSE; + NtUserGetScrollBarInfo (hwnd, OBJID_HSCROLL, &info); break; case SB_VERT: vertical = TRUE; + NtUserGetScrollBarInfo (hwnd, OBJID_VSCROLL, &info); break; case SB_CTL: vertical = (GetWindowLongW(hwnd,GWL_STYLE)&SBS_VERT) != 0; + NtUserGetScrollBarInfo (hwnd, OBJID_CLIENT, &info); break; #ifdef DBG default: @@ -295,6 +280,8 @@ SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar, break; #endif /* DBG */ } + + thumbSize = info.xyThumbBottom - info.xyThumbTop; if (vertical) arrowSize = GetSystemMetrics(SM_CXVSCROLL); @@ -348,6 +335,82 @@ END:; /* WIN_ReleaseWndPtr(wndPtr); */ } +static BOOL +SCROLL_PtInRectEx( LPRECT lpRect, POINT pt, BOOL vertical ) +{ + RECT rect = *lpRect; + + if (vertical) + { + rect.left -= lpRect->right - lpRect->left; + rect.right += lpRect->right - lpRect->left; + } + else + { + rect.top -= lpRect->bottom - lpRect->top; + rect.bottom += lpRect->bottom - lpRect->top; + } + return PtInRect( &rect, pt ); +} + +/* +DWORD FASTCALL +SCROLL_HitTest(HWND hwnd, LONG idObject, POINT Point) +{ + RECT WindowRect; + + GetWindowRect(hwnd, &WindowRect); + if (!PtInRect(&WindowRect, Point)) + { + return(SCROLL_NOWHERE); + } + + return SCROLL_NOWHERE; +} +*/ + +DWORD +SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging ) +{ + SCROLLBARINFO sbi; + RECT wndrect; + INT arrowSize, thumbSize, thumbPos; + BOOL vertical = (nBar == SB_VERT); /* FIXME - ((Window->Style & SBS_VERT) != 0) */ + + NtUserGetWindowRect(hwnd, &wndrect); + + sbi.cbSize = sizeof(SCROLLBARINFO); + NtUserGetScrollBarInfo(hwnd, vertical ? OBJID_VSCROLL : OBJID_HSCROLL, &sbi); + + OffsetRect(&sbi.rcScrollBar, wndrect.left, wndrect.top); + + if ( (bDragging && !SCROLL_PtInRectEx( &sbi.rcScrollBar, pt, vertical )) || + (!PtInRect( &sbi.rcScrollBar, pt )) ) return SCROLL_NOWHERE; + + + if (vertical) + { + arrowSize = GetSystemMetrics(SM_CYVSCROLL); + if (pt.y < sbi.rcScrollBar.top + arrowSize) return SCROLL_TOP_ARROW; + if (pt.y >= sbi.rcScrollBar.bottom - arrowSize) return SCROLL_BOTTOM_ARROW; + if (!thumbPos) return SCROLL_TOP_RECT; + pt.y -= sbi.rcScrollBar.top; + if (pt.y < thumbPos) return SCROLL_TOP_RECT; + if (pt.y >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT; + } + else /* horizontal */ + { + arrowSize = GetSystemMetrics(SM_CXHSCROLL); + if (pt.x < sbi.rcScrollBar.left + arrowSize) return SCROLL_TOP_ARROW; + if (pt.x >= sbi.rcScrollBar.right - arrowSize) return SCROLL_BOTTOM_ARROW; + if (!thumbPos) return SCROLL_TOP_RECT; + pt.x -= sbi.rcScrollBar.left; + if (pt.x < thumbPos) return SCROLL_TOP_RECT; + if (pt.x >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT; + } + return SCROLL_THUMB; +} + /* FUNCTIONS ******************************************************************/ diff --git a/reactos/lib/user32/include/window.h b/reactos/lib/user32/include/window.h index 66d657c14e5..a5e06ce4c42 100644 --- a/reactos/lib/user32/include/window.h +++ b/reactos/lib/user32/include/window.h @@ -19,3 +19,6 @@ ULONG UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle); ULONG UserHasThickFrameStyle(ULONG Style, ULONG ExStyle); + +DWORD +SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging ); diff --git a/reactos/lib/user32/windows/defwnd.c b/reactos/lib/user32/windows/defwnd.c index a01d606680b..5be85dc2d70 100644 --- a/reactos/lib/user32/windows/defwnd.c +++ b/reactos/lib/user32/windows/defwnd.c @@ -1,4 +1,4 @@ -/* $Id: defwnd.c,v 1.81 2003/09/07 17:35:15 ekohl Exp $ +/* $Id: defwnd.c,v 1.82 2003/09/08 02:14:20 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -933,9 +933,15 @@ VOID STATIC DefWndDoScrollBarDown(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { POINT Point; + DWORD hit; Point.x = SLOWORD(lParam); Point.y = SHIWORD(lParam); + hit = SCROLL_HitTest(hWnd, (wParam == HTHSCROLL) ? SB_HORZ : SB_VERT, Point, FALSE); + + if(hit) + DbgPrint("SCROLL_HitTest() == 0x%x\n", hit); + SendMessageA(hWnd, WM_SYSCOMMAND, Msg + (UINT)wParam, lParam); } diff --git a/reactos/subsys/win32k/ntuser/msgqueue.c b/reactos/subsys/win32k/ntuser/msgqueue.c index 01e2c3dea30..4dd8cc3abda 100644 --- a/reactos/subsys/win32k/ntuser/msgqueue.c +++ b/reactos/subsys/win32k/ntuser/msgqueue.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: msgqueue.c,v 1.21 2003/08/29 19:17:32 weiden Exp $ +/* $Id: msgqueue.c,v 1.22 2003/09/08 02:14:20 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -208,8 +208,7 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh, if (Msg == WM_LBUTTONDBLCLK || Msg == WM_RBUTTONDBLCLK || Msg == WM_MBUTTONDBLCLK) { - if (!(IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_DBLCLKS) && - ((*HitTest) == HTCLIENT)) + if (((*HitTest) != HTCLIENT) || !(IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_DBLCLKS)) { Msg -= (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN); /* FIXME set WindowStation's system cursor variables: @@ -224,6 +223,7 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh, } *ScreenPoint = Message->Msg.pt; + Point = Message->Msg.pt; if ((*HitTest) != HTCLIENT) { @@ -232,7 +232,6 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh, } else { - Point = Message->Msg.pt; Point.x -= Window->ClientRect.left; Point.y -= Window->ClientRect.top; } diff --git a/reactos/subsys/win32k/ntuser/scrollbar.c b/reactos/subsys/win32k/ntuser/scrollbar.c index 6f954b3a56f..f881e034963 100644 --- a/reactos/subsys/win32k/ntuser/scrollbar.c +++ b/reactos/subsys/win32k/ntuser/scrollbar.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: scrollbar.c,v 1.10 2003/09/07 11:52:54 weiden Exp $ +/* $Id: scrollbar.c,v 1.11 2003/09/08 02:14:20 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -187,12 +187,57 @@ IntDestroyScrollBar(PWINDOW_OBJECT Window, LONG idObject) return FALSE; } +#define CHANGERGSTATE(item, status) \ + if(Info->rgstate[(item)] != (status)) \ + Chg = TRUE; \ + Info->rgstate[(item)] = (status); + + +BOOL STDCALL +IntEnableScrollBar(BOOL Horz, PSCROLLBARINFO Info, UINT wArrows) +{ + BOOL Chg = FALSE; + switch(wArrows) + { + case ESB_DISABLE_BOTH: + CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE); + CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE); + break; + case ESB_DISABLE_RTDN: + if(Horz) + { + CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE); + } + else + { + CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE); + } + break; + case ESB_DISABLE_LTUP: + if(Horz) + { + CHANGERGSTATE(SBRG_TOPRIGHTBTN, STATE_SYSTEM_UNAVAILABLE); + } + else + { + CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, STATE_SYSTEM_UNAVAILABLE); + } + break; + case ESB_ENABLE_BOTH: + CHANGERGSTATE(SBRG_TOPRIGHTBTN, 0); + CHANGERGSTATE(SBRG_BOTTOMLEFTBTN, 0); + break; + } + return Chg; +} + BOOL STDCALL NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi) { PWINDOW_OBJECT Window; + INT Bar; if(!psbi || (psbi->cbSize != sizeof(SCROLLBARINFO))) { @@ -210,23 +255,26 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi) switch(idObject) { - case SB_HORZ: + case OBJID_HSCROLL: if(Window->pHScroll) { + Bar = SB_HORZ; memcpy(psbi, Window->pHScroll, sizeof(SCROLLBARINFO)); break; } /* fall through */ - case SB_VERT: + case OBJID_VSCROLL: if(Window->pVScroll) { + Bar = SB_VERT; memcpy(psbi, Window->pVScroll, sizeof(SCROLLBARINFO)); break; } /* fall through */ - case SB_CTL: + case OBJID_CLIENT: if(Window->wExtra) { + Bar = SB_CTL; memcpy(psbi, Window->wExtra, sizeof(SCROLLBARINFO)); break; } @@ -237,7 +285,7 @@ NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi) return FALSE; } - IntGetScrollBarRect (Window, idObject, &(psbi->rcScrollBar)); + IntGetScrollBarRect (Window, Bar, &(psbi->rcScrollBar)); IntReleaseWindowObject(Window); return TRUE; @@ -280,7 +328,7 @@ NtUserGetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi) } -DWORD +BOOL STDCALL NtUserEnableScrollBar( HWND hWnd, @@ -289,6 +337,7 @@ NtUserEnableScrollBar( { PWINDOW_OBJECT Window; PSCROLLBARINFO InfoV = NULL, InfoH = NULL; + BOOL Chg = FALSE; Window = IntGetWindowObject(hWnd); @@ -317,6 +366,15 @@ NtUserEnableScrollBar( return FALSE; } + if(InfoV) + Chg = IntEnableScrollBar(FALSE, InfoV, wArrows); + + if(InfoH) + Chg = (IntEnableScrollBar(TRUE, InfoH, wArrows) || Chg); + + if(Chg) + /* FIXME - repaint scrollbars */ + IntReleaseWindowObject(Window); return TRUE; }