reactos/lib/user32/windows
diff -u -r1.52 -r1.53
--- nonclient.c 15 Apr 2004 23:36:02 -0000 1.52
+++ nonclient.c 17 Apr 2004 11:00:13 -0000 1.53
@@ -67,6 +67,10 @@
(WindowRect.right - WindowRect.left == ParentClientRect.right) && \
(WindowRect.bottom - WindowRect.top == ParentClientRect.bottom)))
+#ifndef STATE_SYSTEM_OFFSCREEN
+#define STATE_SYSTEM_OFFSCREEN 0x00010000
+#endif
+
/*
* FIXME: This should be moved to a header
*/
@@ -84,6 +88,17 @@
/* PRIVATE FUNCTIONS **********************************************************/
BOOL
+IntIsScrollBarVisible(HWND hWnd, INT hBar)
+{
+ SCROLLBARINFO sbi;
+ sbi.cbSize = sizeof(SCROLLBARINFO);
+ if(!NtUserGetScrollBarInfo(hWnd, hBar, &sbi))
+ return FALSE;
+
+ return !(sbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN);
+}
+
+BOOL
UserHasWindowEdge(DWORD Style, DWORD ExStyle)
{
if (Style & WS_MINIMIZE)
@@ -459,7 +474,7 @@
/* Draw the scrollbars */
if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL) &&
- (CurrentRect.bottom - CurrentRect.top) > GetSystemMetrics(SM_CYHSCROLL))
+ IntIsScrollBarVisible(hWnd, OBJID_VSCROLL) && IntIsScrollBarVisible(hWnd, OBJID_HSCROLL))
{
RECT ParentClientRect;
@@ -469,7 +484,7 @@
else
TempRect.left = TempRect.right - GetSystemMetrics(SM_CXVSCROLL);
TempRect.top = TempRect.bottom - GetSystemMetrics(SM_CYHSCROLL);
- FillRect(hDC, &TempRect, GetSysColorBrush(COLOR_SCROLLBAR));
+ FillRect(hDC, &TempRect, GetSysColorBrush(COLOR_BTNFACE));
/* FIXME: Correct drawing of size-box with WS_EX_LEFTSCROLLBAR */
if(Parent)
GetClientRect(Parent, &ParentClientRect);
@@ -482,9 +497,9 @@
}
else
{
- if (Style & WS_VSCROLL)
+ if (Style & WS_VSCROLL && IntIsScrollBarVisible(hWnd, OBJID_VSCROLL))
IntDrawScrollBar(hWnd, hDC, SB_VERT);
- else if (Style & WS_HSCROLL)
+ else if (Style & WS_HSCROLL && IntIsScrollBarVisible(hWnd, OBJID_HSCROLL))
IntDrawScrollBar(hWnd, hDC, SB_HORZ);
}
}
@@ -561,9 +576,53 @@
InflateRect(Rect, -2 * GetSystemMetrics(SM_CXBORDER),
-2 * GetSystemMetrics(SM_CYBORDER));
}
+
+ if(Style & (WS_VSCROLL | WS_HSCROLL))
+ {
+ SCROLLBARINFO sbi;
+ SETSCROLLBARINFO ssbi;
+
+ sbi.cbSize = sizeof(SCROLLBARINFO);
+ if((Style & WS_VSCROLL) && NtUserGetScrollBarInfo(hWnd, OBJID_VSCROLL, &sbi))
+ {
+ int i;
+ LONG sx = Rect->right;
+
+ sx -= GetSystemMetrics(SM_CXVSCROLL);
+ for(i = 0; i <= CCHILDREN_SCROLLBAR; i++)
+ ssbi.rgstate[i] = sbi.rgstate[i];
+ if(sx <= Rect->left)
+ ssbi.rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
+ else
+ ssbi.rgstate[0] &= ~STATE_SYSTEM_OFFSCREEN;
+ NtUserSetScrollBarInfo(hWnd, OBJID_VSCROLL, &ssbi);
+ if(ssbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN)
+ Style &= ~WS_VSCROLL;
+ }
+ else
+ Style &= ~WS_VSCROLL;
+
+ if((Style & WS_HSCROLL) && NtUserGetScrollBarInfo(hWnd, OBJID_HSCROLL, &sbi))
+ {
+ int i;
+ LONG sy = Rect->bottom;
+
+ sy -= GetSystemMetrics(SM_CYHSCROLL);
+ for(i = 0; i <= CCHILDREN_SCROLLBAR; i++)
+ ssbi.rgstate[i] = sbi.rgstate[i];
+ if(sy <= Rect->top)
+ ssbi.rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
+ else
+ ssbi.rgstate[0] &= ~STATE_SYSTEM_OFFSCREEN;
+ NtUserSetScrollBarInfo(hWnd, OBJID_HSCROLL, &ssbi);
+ if(ssbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN)
+ Style &= ~WS_HSCROLL;
+ }
+ else
+ Style &= ~WS_HSCROLL;
+ }
- if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL) &&
- (Rect->bottom - Rect->top) > GetSystemMetrics(SM_CYHSCROLL))
+ if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL))
{
if ((ExStyle & WS_EX_LEFTSCROLLBAR) != 0)
Rect->left += GetSystemMetrics(SM_CXVSCROLL);
reactos/subsys/win32k/ntuser
diff -u -r1.29 -r1.30
--- scrollbar.c 9 Apr 2004 20:03:19 -0000 1.29
+++ scrollbar.c 17 Apr 2004 11:00:14 -0000 1.30
@@ -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.29 2004/04/09 20:03:19 navaraf Exp $
+/* $Id: scrollbar.c,v 1.30 2004/04/17 11:00:14 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -58,6 +58,11 @@
#define SBRG_PAGEDOWNLEFT 4 /* the page down or page left region */
#define SBRG_BOTTOMLEFTBTN 5 /* the bottom or left button */
+#define CHANGERGSTATE(item, status) \
+ if(Info->rgstate[(item)] != (status)) \
+ Chg = TRUE; \
+ Info->rgstate[(item)] = (status);
+
/* FUNCTIONS *****************************************************************/
/* Ported from WINE20020904 */
@@ -66,7 +71,7 @@
* 'thumbSize' returns the size of the thumb, and 'thumbPos' returns the position of the thumb relative to the left or to
* the top. Return TRUE if the scrollbar is vertical, FALSE if horizontal.
*/
-BOOL STDCALL
+BOOL FASTCALL
IntGetScrollBarRect (PWINDOW_OBJECT Window, INT nBar, PRECT lprect)
{
BOOL vertical;
@@ -180,43 +185,40 @@
return TRUE;
}
+static VOID FASTCALL
+IntUpdateSBInfo(PWINDOW_OBJECT Window, int wBar)
+{
+ PSCROLLBARINFO sbi;
+ LPSCROLLINFO psi;
+
+ ASSERT(Window);
+ ASSERT(Window->Scroll);
+
+ sbi = IntGetScrollbarInfoFromWindow(Window, wBar);
+ psi = IntGetScrollInfoFromWindow(Window, wBar);
+ IntGetScrollBarRect(Window, wBar, &(sbi->rcScrollBar));
+ IntCalculateThumb(Window, wBar, sbi, psi);
+}
+
static BOOL FASTCALL
IntGetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPSCROLLINFO lpsi)
{
UINT Mask;
LPSCROLLINFO psi;
- PSCROLLBARINFO Info;
- switch (nBar)
- {
- case SB_HORZ:
- Info = Window->pHScroll;
- break;
- case SB_VERT:
- Info = Window->pVScroll;
- break;
- case SB_CTL:
- if (Window->ExtraDataSize < sizeof(SCROLLBARINFO) + sizeof(SCROLLINFO))
- {
- Info = NULL;
- }
- else
- {
- Info = (PSCROLLBARINFO) Window->ExtraData;
- }
- break;
- default:
- DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d", nBar);
- return FALSE;
- }
+ if(!SBID_IS_VAILD(nBar))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d", nBar);
+ return FALSE;
+ }
- if (NULL == Info)
+ if(!IntCreateScrollBars(Window))
{
- DPRINT1("No scrollinfo available\n");
return FALSE;
}
- psi = (LPSCROLLINFO)(Info + 1);
+ psi = IntGetScrollInfoFromWindow(Window, nBar);
if (lpsi->fMask == SIF_ALL)
{
@@ -264,6 +266,18 @@
/* UINT new_flags;*/
BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */
+ if(!SBID_IS_VAILD(nBar))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", nBar);
+ return FALSE;
+ }
+
+ if(!IntCreateScrollBars(Window))
+ {
+ return FALSE;
+ }
+
if (lpsi->cbSize != sizeof(SCROLLINFO) &&
lpsi->cbSize != (sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos)))
{
@@ -275,38 +289,9 @@
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
- switch (nBar)
- {
- case SB_HORZ:
- if (NULL == Window->pHScroll)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
- psbi = Window->pHScroll;
- break;
- case SB_VERT:
- if (NULL == Window->pVScroll)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
- psbi = Window->pVScroll;
- break;
- case SB_CTL:
- if (Window->ExtraDataSize < sizeof(SCROLLBARINFO) + sizeof(SCROLLINFO))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
- psbi = (PSCROLLBARINFO) Window->ExtraData;
- break;
- default:
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- Info = (LPSCROLLINFO)(psbi + 1);
+
+ psbi = IntGetScrollbarInfoFromWindow(Window, nBar);
+ Info = IntGetScrollInfoFromWindow(Window, nBar);
/* Set the page size */
if (0 != (lpsi->fMask & SIF_PAGE))
@@ -430,39 +415,22 @@
PSCROLLBARINFO sbi;
LPSCROLLINFO psi;
- switch(idObject)
- {
- case OBJID_HSCROLL:
- Bar = SB_HORZ;
- sbi = Window->pHScroll;
- break;
- case OBJID_VSCROLL:
- Bar = SB_VERT;
- sbi = Window->pVScroll;
- break;
- case OBJID_CLIENT:
- Bar = SB_CTL;
- if (Window->ExtraDataSize < sizeof(SCROLLBARINFO) + sizeof(SCROLLINFO))
- {
- sbi = NULL;
- }
- else
- {
- sbi = (PSCROLLBARINFO) Window->ExtraData;
- }
- break;
- default:
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- if (NULL == sbi)
+ Bar = SBOBJ_TO_SBID(idObject);
+
+ if(!SBID_IS_VAILD(Bar))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d", Bar);
+ return FALSE;
+ }
+
+ if(!IntCreateScrollBars(Window))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
- psi = (LPSCROLLINFO)(sbi + 1);
+ sbi = IntGetScrollbarInfoFromWindow(Window, Bar);
+ psi = IntGetScrollInfoFromWindow(Window, Bar);
IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar));
IntCalculateThumb(Window, Bar, sbi, psi);
@@ -472,97 +440,65 @@
return TRUE;
}
-DWORD FASTCALL
-IntCreateScrollBar(PWINDOW_OBJECT Window, LONG idObject)
+BOOL FASTCALL
+IntCreateScrollBars(PWINDOW_OBJECT Window)
{
PSCROLLBARINFO psbi;
LPSCROLLINFO psi;
LRESULT Result;
+ ULONG Size, s;
INT i;
-
- psbi = ExAllocatePoolWithTag(PagedPool, sizeof(SCROLLBARINFO) + sizeof(SCROLLINFO), TAG_SBARINFO);
- if(!psbi)
+
+ if(Window->Scroll)
+ {
+ /* no need to create it anymore */
+ return TRUE;
+ }
+
+ /* allocate memory for all scrollbars (HORZ, VERT, CONTROL) */
+ Size = 2 * (sizeof(WINDOW_SCROLLINFO));
+ if(!(Window->Scroll = ExAllocatePoolWithTag(PagedPool, Size, TAG_SBARINFO)))
+ {
+ DPRINT1("Unable to allocate memory for scrollbar information for window 0x%x\n", Window->Self);
return FALSE;
-
- psi = (LPSCROLLINFO)((PSCROLLBARINFO)(psbi + 1));
+ }
- psi->cbSize = sizeof(LPSCROLLINFO);
- psi->nMin = 0;
- psi->nMax = 100;
- psi->nPage = 0;
- psi->nPos = 0;
- psi->nTrackPos = 0;
+ RtlZeroMemory(Window->Scroll, Size);
Result = WinPosGetNonClientSize(Window->Self,
&Window->WindowRect,
&Window->ClientRect);
-
- psbi->cbSize = sizeof(SCROLLBARINFO);
-
- for (i = 0; i < CCHILDREN_SCROLLBAR + 1; i++)
- psbi->rgstate[i] = 0;
-
- switch(idObject)
+
+ for(s = SB_HORZ; s <= SB_VERT; s++)
{
- case SB_HORZ:
- Window->pHScroll = psbi;
- break;
- case SB_VERT:
- Window->pVScroll = psbi;
- break;
- case SB_CTL:
- Window->wExtra = psbi;
- break;
- default:
- ExFreePool(psbi);
- return FALSE;
+ psbi = IntGetScrollbarInfoFromWindow(Window, s);
+ psbi->cbSize = sizeof(SCROLLBARINFO);
+ for (i = 0; i < CCHILDREN_SCROLLBAR + 1; i++)
+ psbi->rgstate[i] = 0;
+
+ psi = IntGetScrollInfoFromWindow(Window, s);
+ psi->cbSize = sizeof(LPSCROLLINFO);
+ psi->nMax = 100;
+
+ IntGetScrollBarRect(Window, s, &(psbi->rcScrollBar));
+ IntCalculateThumb(Window, s, psbi, psi);
}
- IntGetScrollBarRect(Window, idObject, &(psbi->rcScrollBar));
- IntCalculateThumb(Window, idObject, psbi, psi);
-
- return 0;
+ return TRUE;
}
BOOL FASTCALL
-IntDestroyScrollBar(PWINDOW_OBJECT Window, LONG idObject)
+IntDestroyScrollBars(PWINDOW_OBJECT Window)
{
- switch(idObject)
+ if(Window->Scroll)
{
- case SB_HORZ:
- if(Window->pHScroll)
- {
- ExFreePool(Window->pHScroll);
- Window->pHScroll = NULL;
- return TRUE;
- }
- return FALSE;
- case SB_VERT:
- if(Window->pVScroll)
- {
- ExFreePool(Window->pVScroll);
- Window->pVScroll = NULL;
- return TRUE;
- }
- return FALSE;
- case SB_CTL:
- if(Window->wExtra)
- {
- ExFreePool(Window->wExtra);
- Window->wExtra = NULL;
- return TRUE;
- }
- return FALSE;
+ ExFreePool(Window->Scroll);
+ Window->Scroll = NULL;
+ return TRUE;
}
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)
{
@@ -672,7 +608,13 @@
return FALSE;
}
- Ret = IntGetScrollInfo(Window, fnBar, &psi);
+ if(fnBar == SB_CTL)
+ {
+ IntSendMessage(Window->Self, SBM_GETSCROLLINFO, 0, (LPARAM)lpsi);
+ Ret = TRUE;
+ }
+ else
+ Ret = IntGetScrollInfo(Window, fnBar, &psi);
IntReleaseWindowObject(Window);
@@ -706,19 +648,37 @@
return FALSE;
}
+ if(wSBflags == SB_CTL)
+ {
+ /* FIXME */
+ IntReleaseWindowObject(Window);
+ return FALSE;
+ }
+
+ if(wSBflags != SB_BOTH && !SBID_IS_VAILD(wSBflags))
+ {
+ IntReleaseWindowObject(Window);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", wSBflags);
+ return FALSE;
+ }
+
+ if(!IntCreateScrollBars(Window))
+ {
+ IntReleaseWindowObject(Window);
+ return FALSE;
+ }
+
switch(wSBflags)
{
case SB_BOTH:
- InfoV = Window->pVScroll;
+ InfoV = IntGetScrollbarInfoFromWindow(Window, SB_VERT);
/* fall through */
case SB_HORZ:
- InfoH = Window->pHScroll;
+ InfoH = IntGetScrollbarInfoFromWindow(Window, SB_HORZ);
break;
case SB_VERT:
- InfoV = Window->pVScroll;
- break;
- case SB_CTL:
- InfoV = Window->wExtra;
+ InfoV = IntGetScrollbarInfoFromWindow(Window, SB_VERT);
break;
default:
IntReleaseWindowObject(Window);
@@ -747,9 +707,10 @@
{
PWINDOW_OBJECT Window;
SETSCROLLBARINFO Safeinfo;
- PSCROLLBARINFO sbi = NULL;
+ PSCROLLBARINFO sbi;
LPSCROLLINFO psi;
NTSTATUS Status;
+ LONG Obj;
Window = IntGetWindowObject(hwnd);
@@ -759,41 +720,31 @@
return FALSE;
}
- Status = MmCopyFromCaller(&Safeinfo, info, sizeof(SETSCROLLBARINFO));
- if(!NT_SUCCESS(Status))
+ Obj = SBOBJ_TO_SBID(idObject);
+ if(!SBID_IS_VAILD(Obj))
{
IntReleaseWindowObject(Window);
- SetLastNtError(Status);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Trying to set scrollinfo for unknown scrollbar type %d", Obj);
return FALSE;
}
-
- switch(idObject)
- {
- case OBJID_HSCROLL:
- sbi = Window->pHScroll;
- break;
- case OBJID_VSCROLL:
- sbi = Window->pVScroll;
- break;
- case OBJID_CLIENT:
- /* FIXME */
- IntReleaseWindowObject(Window);
- return FALSE;
- default:
+ if(!IntCreateScrollBars(Window))
+ {
IntReleaseWindowObject(Window);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
- }
+ }
- if(!sbi)
+ Status = MmCopyFromCaller(&Safeinfo, info, sizeof(SETSCROLLBARINFO));
+ if(!NT_SUCCESS(Status))
{
- DPRINT1("SCROLLBARINFO structure not allocated!\n");
IntReleaseWindowObject(Window);
+ SetLastNtError(Status);
return FALSE;
}
- psi = (LPSCROLLINFO)((PSCROLLBARINFO)(sbi + 1));
+ sbi = IntGetScrollbarInfoFromWindow(Window, Obj);
+ psi = IntGetScrollInfoFromWindow(Window, Obj);
psi->nTrackPos = Safeinfo.nTrackPos;
sbi->reserved = Safeinfo.reserved;
@@ -824,6 +775,13 @@
return 0;
}
+ if(fnBar == SB_CTL)
+ {
+ Ret = IntSendMessage(hwnd, SBM_SETSCROLLINFO, (WPARAM)bRedraw, (LPARAM)lpsi);
+ IntReleaseWindowObject(Window);
+ return Ret;
+ }
+
Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos));
if(!NT_SUCCESS(Status))
{
@@ -842,6 +800,7 @@
DWORD STDCALL
NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
{
+ DWORD Style, OldStyle;
PWINDOW_OBJECT Window = IntGetWindowObject(hWnd);
if (!Window)
@@ -849,46 +808,62 @@
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE;
}
+
+ switch(wBar)
+ {
+ case SB_HORZ:
+ Style = WS_HSCROLL;
+ break;
+ case SB_VERT:
+ Style = WS_VSCROLL;
+ break;
+ case SB_BOTH:
+ Style = WS_HSCROLL | WS_VSCROLL;
+ break;
+ case SB_CTL:
+ break;
+ default:
+ IntReleaseWindowObject(Window);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if(!IntCreateScrollBars(Window))
+ {
+ IntReleaseWindowObject(Window);
+ return FALSE;
+ }
if (wBar == SB_CTL)
{
+ IntUpdateSBInfo(Window, SB_CTL);
+
WinPosShowWindow(hWnd, bShow ? SW_SHOW : SW_HIDE);
IntReleaseWindowObject(Window);
return TRUE;
}
-
- if (wBar == SB_BOTH || wBar == SB_HORZ)
+
+ OldStyle = Window->Style;
+ if(bShow)
+ Window->Style |= Style;
+ else
+ Window->Style &= ~Style;
+
+ if(Window->Style != OldStyle)
{
- if (bShow)
- {
- Window->Style |= WS_HSCROLL;
- if (!Window->pHScroll)
- IntCreateScrollBar(Window, SB_HORZ);
- }
- else
- {
- Window->Style &= ~WS_HSCROLL;
- }
+ if(Window->Style & WS_HSCROLL)
+ IntUpdateSBInfo(Window, SB_HORZ);
+ if(Window->Style & WS_VSCROLL)
+ IntUpdateSBInfo(Window, SB_VERT);
+
+ if(Window->Style & WS_VISIBLE)
+ {
+ /* Frame has been changed, let the window redraw itself */
+ WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
+ }
}
-
- if (wBar == SB_BOTH || wBar == SB_VERT)
- {
- if (bShow)
- {
- Window->Style |= WS_VSCROLL;
- if (!Window->pVScroll)
- IntCreateScrollBar(Window, SB_VERT);
- }
- else
- {
- Window->Style &= ~WS_VSCROLL;
- }
- }
-
- /* Frame has been changed, let the window redraw itself */
- WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
- SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
-
+
IntReleaseWindowObject(Window);
return TRUE;
}