* PURPOSE: Windows
* FILE: subsys/win32k/ntuser/window.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * Thomas Weidenmueller (w3seek@users.sourceforge.net)
* REVISION HISTORY:
* 06-06-2001 CSH Created
*/
#include <windows.h>
#include <user32.h>
#include <debug.h>
+#include <draw.h>
+#include <stdlib.h>
+#include <string.h>
/* GLOBAL VARIABLES **********************************************************/
/*
#define RIGHT_ARROW(flags,pressed) \
(((flags)&ESB_DISABLE_RIGHT) ? hRgArrowI : ((pressed) ? hRgArrowD:hRgArrow))
-#define SCROLL_ARROW_THUMB_OVERLAP 0 /* Overlap between arrows and thumb */
#define SCROLL_MIN_THUMB 6 /* Minimum size of the thumb in pixels */
#define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when holding the button down */
#define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */
#define SA_SSI_REFRESH 0x0004
#define SA_SSI_REPAINT_ARROWS 0x0008
- /* Scroll-bar hit testing */
-enum SCROLL_HITTEST
-{
- SCROLL_NOWHERE, /* Outside the scroll bar */
- SCROLL_TOP_ARROW, /* Top or left arrow */
- SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */
- SCROLL_THUMB, /* Thumb rectangle */
- SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */
- SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
-};
+/* Scroll-bar hit testing */
+#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? */
static INT SCROLL_TrackingBar = 0;
static INT SCROLL_TrackingPos = 0;
/* static INT SCROLL_TrackingVal = 0; */
-static enum SCROLL_HITTEST SCROLL_trackHitTest; /* Hit test code of the last button-down event */
+static DWORD SCROLL_trackHitTest; /* Hit test code of the last button-down event */
static BOOL SCROLL_trackVertical;
-/* FUNCTIONS
-*****************************************************************/
+/* INTERNAL FUNCTIONS *********************************************************/
HBRUSH DefWndControlColor (HDC hDC, UINT ctlType);
-HPEN STDCALL GetSysColorPen (int nIndex);
-
-
-
-WINBOOL STDCALL
-GetScrollBarInfo (HWND hwnd, LONG idObject, PSCROLLBARINFO psbi)
-{
- int ret = NtUserGetScrollBarInfo (hwnd, idObject, psbi);
-
- return ret;
-}
/* Ported from WINE20020904 */
/* Draw the scroll bar interior (everything except the arrows). */
arrowSize, PSCROLLBARINFO psbi)
{
INT thumbSize = psbi->xyThumbBottom - psbi->xyThumbTop;
+ RECT rc;
HPEN hSavePen;
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;
}
if ( nBar == SB_CTL )
{
hBrush = (HBRUSH) NtUserSendMessage (GetParent (hwnd), WM_CTLCOLORSCROLLBAR, (WPARAM) hdc, (LPARAM) hwnd);
+ if(!hBrush)
+ hBrush = GetSysColorBrush(COLOR_SCROLLBAR);
}
else
{
/* Calculate the scroll rectangle */
if (vertical)
{
- psbi->rcScrollBar.top += arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
- psbi->rcScrollBar.bottom -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
+ rc.top = psbi->rcScrollBar.top + arrowSize;
+ rc.bottom = psbi->rcScrollBar.bottom - arrowSize;
+ rc.left = psbi->rcScrollBar.left;
+ rc.right = psbi->rcScrollBar.right;
}
else
{
- psbi->rcScrollBar.left += arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
- psbi->rcScrollBar.right -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
+ rc.top = psbi->rcScrollBar.top;
+ rc.bottom = psbi->rcScrollBar.bottom;
+ rc.left = psbi->rcScrollBar.left + arrowSize;
+ rc.right = psbi->rcScrollBar.right - arrowSize;
}
/* Draw the scroll rectangles and thumb */
- if (!psbi->dxyLineButton) /* No thumb to draw */
+ if (!psbi->xyThumbBottom) /* No thumb to draw */
{
PatBlt (hdc,
- psbi->rcScrollBar.left,
- psbi->rcScrollBar.top,
- psbi->rcScrollBar.right - psbi->rcScrollBar.left,
- psbi->rcScrollBar.bottom - psbi->rcScrollBar.top,
+ rc.left,
+ rc.top,
+ rc.right - rc.left,
+ rc.bottom - rc.top,
PATCOPY);
/* cleanup and return */
SelectObject (hdc, hSaveBrush);
return;
}
+
+ psbi->xyThumbTop -= arrowSize;
if (vertical)
{
PatBlt (hdc,
- psbi->rcScrollBar.left,
- psbi->rcScrollBar.top,
- psbi->rcScrollBar.right - psbi->rcScrollBar.left,
- psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP),
+ rc.left,
+ rc.top,
+ rc.right - rc.left,
+ psbi->dxyLineButton,
top_selected ? 0x0f0000 : PATCOPY);
- psbi->rcScrollBar.top += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
+ rc.top += psbi->xyThumbTop;
PatBlt (hdc,
- psbi->rcScrollBar.left,
- psbi->rcScrollBar.top + thumbSize,
- psbi->rcScrollBar.right - psbi->rcScrollBar.left,
- psbi->rcScrollBar.bottom - psbi->rcScrollBar.top - thumbSize,
+ rc.left,
+ rc.top + thumbSize,
+ rc.right - rc.left,
+ rc.bottom - rc.top - thumbSize,
bottom_selected ? 0x0f0000 : PATCOPY);
- psbi->rcScrollBar.bottom = psbi->rcScrollBar.top + thumbSize;
+ rc.bottom = rc.top + thumbSize;
}
else
{
PatBlt (hdc,
- psbi->rcScrollBar.left,
- psbi->rcScrollBar.top,
- psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP),
- psbi->rcScrollBar.bottom - psbi->rcScrollBar.top,
+ rc.left,
+ rc.top,
+ psbi->xyThumbTop,
+ rc.bottom - rc.top,
top_selected ? 0x0f0000 : PATCOPY);
- psbi->rcScrollBar.left += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
+ rc.left += psbi->xyThumbTop;
PatBlt (hdc,
- psbi->rcScrollBar.left + thumbSize,
- psbi->rcScrollBar.top,
- psbi->rcScrollBar.right - psbi->rcScrollBar.left - thumbSize,
- psbi->rcScrollBar.bottom - psbi->rcScrollBar.top,
+ rc.left + thumbSize,
+ rc.top,
+ rc.right - rc.left - thumbSize,
+ rc.bottom - rc.top,
bottom_selected ? 0x0f0000 : PATCOPY);
- psbi->rcScrollBar.right = psbi->rcScrollBar.left + thumbSize;
+ rc.right = rc.left + thumbSize;
}
/* Draw the thumb */
- DrawEdge (hdc, &psbi->rcScrollBar, EDGE_RAISED, BF_RECT | BF_MIDDLE);
+ DrawEdge (hdc, &rc, EDGE_RAISED, BF_RECT | BF_MIDDLE);
/* cleanup */
SelectObject (hdc, hSavePen);
else
max_size = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
- max_size -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP) + thumbSize;
+ max_size -= arrowSize + thumbSize;
- if (pos < (arrowSize - SCROLL_ARROW_THUMB_OVERLAP))
- pos = (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
+ if (pos < arrowSize)
+ pos = arrowSize;
else if (pos > max_size)
pos = max_size;
BOOL vertical;
info.cbSize = sizeof(SCROLLBARINFO);
- GetScrollBarInfo (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 = (GetWindowLong(hwnd,GWL_STYLE)&SBS_VERT) != 0;
+ vertical = (GetWindowLongW(hwnd,GWL_STYLE)&SBS_VERT) != 0;
+ NtUserGetScrollBarInfo (hwnd, OBJID_CLIENT, &info);
break;
#ifdef DBG
default:
break;
#endif /* DBG */
}
+
+ thumbSize = info.xyThumbBottom - info.xyThumbTop;
if (vertical)
arrowSize = GetSystemMetrics(SM_CXVSCROLL);
/* 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
+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;
+
+ thumbPos = sbi.xyThumbTop;
+ thumbSize = sbi.xyThumbBottom - thumbPos;
+ arrowSize = sbi.dxyLineButton;
+
+ if (vertical)
+ {
+ 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 */
+ {
+ 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 ******************************************************************/
+
+
+/*
+ * @implemented
+ */
+WINBOOL STDCALL
+EnableScrollBar(HWND hWnd, UINT wSBflags, UINT wArrows)
+{
+ return NtUserEnableScrollBar(hWnd, wSBflags, wArrows);
+}
+
+
+/*
+ * @implemented
+ */
+WINBOOL STDCALL
+GetScrollBarInfo(HWND hwnd, LONG idObject, PSCROLLBARINFO psbi)
+{
+ SCROLLBARINFO sbi;
+ WINBOOL ret;
+
+ if(!psbi)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ RtlCopyMemory(&sbi, psbi, sizeof(SCROLLBARINFO));
+ ret = NtUserGetScrollBarInfo (hwnd, idObject, psbi);
+ if(ret)
+ {
+ RtlCopyMemory(psbi, &sbi, sizeof(SCROLLBARINFO));
+ }
+
+ return ret;
+}
+
+
+/*
+ * @implemented
+ */
WINBOOL STDCALL
GetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi)
{
- UNIMPLEMENTED;
- return FALSE;
+ WINBOOL res;
+ SCROLLINFO si;
+
+ if(!lpsi ||
+ ((lpsi->cbSize != sizeof(SCROLLINFO)) && (lpsi->cbSize != sizeof(SCROLLINFO) - sizeof(si.nTrackPos))))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ RtlZeroMemory(&si, sizeof(SCROLLINFO));
+ si.cbSize = lpsi->cbSize;
+ si.fMask = lpsi->fMask;
+
+ res = (WINBOOL)NtUserGetScrollInfo(hwnd, fnBar, &si);
+
+ if(res)
+ {
+ RtlCopyMemory(lpsi, &si, lpsi->cbSize);
+ }
+
+ return res;
}
+
+/*
+ * @implemented
+ */
int STDCALL
GetScrollPos (HWND hWnd, int nBar)
{
- UNIMPLEMENTED;
- return 0;
+ SCROLLINFO si;
+ BOOL ret;
+ int res = 0;
+
+ si.cbSize = sizeof(SCROLLINFO);
+ si.fMask = SIF_POS;
+ ret = NtUserGetScrollInfo(hWnd, nBar, &si);
+ if(ret)
+ res = si.nPos;
+ return res;
}
+
+/*
+ * @implemented
+ */
WINBOOL STDCALL
GetScrollRange (HWND hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos)
{
- UNIMPLEMENTED;
- return FALSE;
+ WINBOOL ret;
+ SCROLLINFO si;
+
+ if(!lpMinPos || !lpMaxPos)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ si.cbSize = sizeof(SCROLLINFO);
+ si.fMask = SIF_RANGE;
+ ret = NtUserGetScrollInfo(hWnd, nBar, &si);
+ if(ret)
+ {
+ *lpMinPos = si.nMin;
+ *lpMaxPos = si.nMax;
+ }
+
+ return ret;
}
+
+/*
+ * @implemented
+ */
int STDCALL
SetScrollInfo (HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, WINBOOL fRedraw)
{
- UNIMPLEMENTED;
- return 0;
+ SCROLLINFO si;
+
+ if(!lpsi ||
+ ((lpsi->cbSize != sizeof(SCROLLINFO)) && (lpsi->cbSize != sizeof(SCROLLINFO) - sizeof(si.nTrackPos))))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ RtlCopyMemory(&si, lpsi, lpsi->cbSize);
+ return (int)NtUserSetScrollInfo(hwnd, fnBar, &si, fRedraw);
}
+
+/*
+ * @implemented
+ */
int STDCALL
SetScrollPos (HWND hWnd, int nBar, int nPos, WINBOOL bRedraw)
{
- UNIMPLEMENTED;
- return 0;
+ int Res = 0;
+ BOOL ret;
+ SCROLLINFO si;
+
+ si.cbSize = sizeof(SCROLLINFO);
+ si.fMask = SIF_POS;
+
+ /* call NtUserGetScrollInfo() because we need to return the previous position */
+ ret = NtUserGetScrollInfo(hWnd, nBar, &si);
+
+ if(ret)
+ {
+ Res = si.nPos;
+
+ if(Res != nPos)
+ {
+ si.nPos = nPos;
+ /* finally set the new position */
+ NtUserSetScrollInfo(hWnd, nBar, &si, bRedraw);
+ }
+ }
+
+ return Res;
}
+
+/*
+ * @implemented
+ */
WINBOOL STDCALL
SetScrollRange (HWND hWnd,
int nBar, int nMinPos, int nMaxPos, WINBOOL bRedraw)
{
- UNIMPLEMENTED;
- return FALSE;
+ SCROLLINFO si;
+
+ si.cbSize = sizeof(SCROLLINFO);
+ si.fMask = SIF_RANGE;
+ si.nMin = nMinPos;
+ si.nMax = nMaxPos;
+
+ NtUserSetScrollInfo(hWnd, nBar, &si, bRedraw);
+ /* FIXME - check if called successfully */
+
+ return TRUE;
}
-/* Ported from WINE20020904 */
+
+/*
+ * @implemented
+ */
WINBOOL STDCALL
ShowScrollBar (HWND hWnd, int wBar, WINBOOL bShow)
{
- NtUserShowScrollBar (hWnd, wBar, bShow);
- return TRUE;
+ return (WINBOOL)NtUserShowScrollBar (hWnd, wBar, bShow);
}