"README.md" did not exist on "7c425976069ebfac09ed3a7c6d6dd9cad1bb69fc"
Newer
Older
* Copyright 1993 Martin Ayotte
* Copyright 1994, 1996 Alexandre Julliard
#define NO_TRANSITION_TYPES /* This file is Win32-clean */
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
static HBITMAP32 hUpArrow = 0;
static HBITMAP32 hDnArrow = 0;
static HBITMAP32 hLfArrow = 0;
static HBITMAP32 hRgArrow = 0;
static HBITMAP32 hUpArrowD = 0;
static HBITMAP32 hDnArrowD = 0;
static HBITMAP32 hLfArrowD = 0;
static HBITMAP32 hRgArrowD = 0;
static HBITMAP32 hUpArrowI = 0;
static HBITMAP32 hDnArrowI = 0;
static HBITMAP32 hLfArrowI = 0;
static HBITMAP32 hRgArrowI = 0;
#define TOP_ARROW(flags,pressed) \
(((flags)&ESB_DISABLE_UP) ? hUpArrowI : ((pressed) ? hUpArrowD:hUpArrow))
#define BOTTOM_ARROW(flags,pressed) \
(((flags)&ESB_DISABLE_DOWN) ? hDnArrowI : ((pressed) ? hDnArrowD:hDnArrow))
#define LEFT_ARROW(flags,pressed) \
(((flags)&ESB_DISABLE_LEFT) ? hLfArrowI : ((pressed) ? hLfArrowD:hLfArrow))
#define RIGHT_ARROW(flags,pressed) \
(((flags)&ESB_DISABLE_RIGHT) ? hRgArrowI : ((pressed) ? hRgArrowD:hRgArrow))
/* Minimum size of the rectangle between the arrows */
#define SCROLL_MIN_RECT 4
/* Minimum size of the thumb in pixels */
#define SCROLL_MIN_THUMB 4
/* Delay (in ms) before first repetition when holding the button down */
#define SCROLL_FIRST_DELAY 200
/* Delay (in ms) between scroll repetitions */
#define SCROLL_REPEAT_DELAY 100
/* Scroll timer id */
#define SCROLL_TIMER 0
/* 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 */
};
static HWND32 SCROLL_TrackingWin = 0;
static INT32 SCROLL_TrackingBar = 0;
static INT32 SCROLL_TrackingPos = 0;
static INT32 SCROLL_TrackingVal = 0;
/* Is the moving thumb being displayed? */
static BOOL32 SCROLL_MovingThumb = FALSE;
/***********************************************************************
hUpArrow = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_UPARROW) );
hDnArrow = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_DNARROW) );
hLfArrow = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_LFARROW) );
hRgArrow = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RGARROW) );
hUpArrowD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_UPARROWD) );
hDnArrowD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_DNARROWD) );
hLfArrowD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_LFARROWD) );
hRgArrowD = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RGARROWD) );
hUpArrowI = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_UPARROWI) );
hDnArrowI = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_DNARROWI) );
hLfArrowI = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_LFARROWI) );
hRgArrowI = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_RGARROWI) );
/***********************************************************************
static SCROLLBAR_INFO *SCROLL_GetPtrScrollInfo( WND* wndPtr, INT32 nBar )
case SB_HORZ: infoPtr = (SCROLLBAR_INFO *)wndPtr->pHScroll; break;
case SB_VERT: infoPtr = (SCROLLBAR_INFO *)wndPtr->pVScroll; break;
case SB_CTL: infoPtr = (SCROLLBAR_INFO *)wndPtr->wExtra; break;
if (!infoPtr) /* Create the info structure if needed */
if ((infoPtr = HeapAlloc( SystemHeap, 0, sizeof(SCROLLBAR_INFO) )))
infoPtr->MinVal = infoPtr->CurVal = infoPtr->Page = 0;
infoPtr->MaxVal = 100;
infoPtr->flags = ESB_ENABLE_BOTH;
if (nBar == SB_HORZ) wndPtr->pHScroll = infoPtr;
else wndPtr->pVScroll = infoPtr;
/***********************************************************************
* SCROLL_GetScrollInfo
*/
static SCROLLBAR_INFO *SCROLL_GetScrollInfo( HWND32 hwnd, INT32 nBar )
{
WND *wndPtr = WIN_FindWndPtr( hwnd );
return SCROLL_GetPtrScrollInfo( wndPtr, nBar );
}
/***********************************************************************
* SCROLL_GetScrollBarRect
*
* Compute the scroll bar rectangle, in drawing coordinates (i.e. client
* coords for SB_CTL, window coords for SB_VERT and SB_HORZ).
* 'arrowSize' returns the width or height of an arrow (depending on
* the orientation of the scrollbar), '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.
*/
static BOOL32 SCROLL_GetScrollBarRect( HWND32 hwnd, INT32 nBar, RECT32 *lprect,
INT32 *arrowSize, INT32 *thumbSize,
INT32 *thumbPos )
WND *wndPtr = WIN_FindWndPtr( hwnd );
switch(nBar)
{
case SB_HORZ:
lprect->left = wndPtr->rectClient.left - wndPtr->rectWindow.left - 1;
lprect->top = wndPtr->rectClient.bottom - wndPtr->rectWindow.top;
lprect->right = wndPtr->rectClient.right - wndPtr->rectWindow.left +1;
lprect->bottom = lprect->top + SYSMETRICS_CYHSCROLL + 1;
vertical = FALSE;
break;
case SB_VERT:
lprect->left = wndPtr->rectClient.right - wndPtr->rectWindow.left;
lprect->top = wndPtr->rectClient.top - wndPtr->rectWindow.top - 1;
lprect->right = lprect->left + SYSMETRICS_CXVSCROLL + 1;
lprect->bottom = wndPtr->rectClient.bottom - wndPtr->rectWindow.top +1;
vertical = TRUE;
break;
case SB_CTL:
vertical = ((wndPtr->dwStyle & SBS_VERT) != 0);
break;
}
if (vertical) pixels = lprect->bottom - lprect->top;
else pixels = lprect->right - lprect->left;
if (pixels <= 2*SYSMETRICS_CXVSCROLL + SCROLL_MIN_RECT)
if (pixels > SCROLL_MIN_RECT)
*arrowSize = (pixels - SCROLL_MIN_RECT) / 2;
else
*arrowSize = 0;
*thumbPos = *thumbSize = 0;
SCROLLBAR_INFO *info = SCROLL_GetPtrScrollInfo( wndPtr, nBar );
*arrowSize = SYSMETRICS_CXVSCROLL;
pixels -= 2 * SYSMETRICS_CXVSCROLL;
if (info->Page)
{
*thumbSize = pixels * info->Page / (info->MaxVal-info->MinVal+1);
if (*thumbSize < SCROLL_MIN_THUMB) *thumbSize = SCROLL_MIN_THUMB;
}
else *thumbSize = SYSMETRICS_CXVSCROLL;
if (((pixels -= *thumbSize + 1) < 0) ||
((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
{
/* Rectangle too small or scrollbar disabled -> no thumb */
*thumbPos = *thumbSize = 0;
}
{
INT32 max = info->MaxVal - MAX( info->Page-1, 0 );
if (info->MinVal >= max)
*thumbPos = *arrowSize;
else
*thumbPos = *arrowSize + pixels * (info->CurVal-info->MinVal) /
(max - info->MinVal);
}
/***********************************************************************
* SCROLL_GetThumbVal
*
* Compute the current scroll position based on the thumb position in pixels
* from the top of the scroll-bar.
*/
static UINT32 SCROLL_GetThumbVal( SCROLLBAR_INFO *infoPtr, RECT32 *rect,
BOOL32 vertical, INT32 pos )
INT32 thumbSize;
INT32 pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
if ((pixels -= 2*SYSMETRICS_CXVSCROLL) <= 0) return infoPtr->MinVal;
if (infoPtr->Page)
{
thumbSize = pixels * infoPtr->Page/(infoPtr->MaxVal-infoPtr->MinVal+1);
if (thumbSize < SCROLL_MIN_THUMB) thumbSize = SCROLL_MIN_THUMB;
}
else thumbSize = SYSMETRICS_CXVSCROLL;
if ((pixels -= thumbSize + 1) <= 0) return infoPtr->MinVal;
if (!infoPtr->Page) pos *= infoPtr->MaxVal - infoPtr->MinVal;
else pos *= infoPtr->MaxVal - infoPtr->MinVal - infoPtr->Page + 1;
return infoPtr->MinVal + ((pos + pixels / 2) / pixels);
/***********************************************************************
* SCROLL_HitTest
*
* Scroll-bar hit testing (don't confuse this with WM_NCHITTEST!).
*/
static enum SCROLL_HITTEST SCROLL_HitTest( HWND32 hwnd, INT32 nBar,
POINT32 pt )
INT32 arrowSize, thumbSize, thumbPos;
RECT32 rect;
BOOL32 vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
&arrowSize, &thumbSize, &thumbPos );
if (!PtInRect32( &rect, pt )) return SCROLL_NOWHERE;
if (vertical)
{
if (pt.y <= rect.top + arrowSize + 1) return SCROLL_TOP_ARROW;
if (pt.y >= rect.bottom - arrowSize) return SCROLL_BOTTOM_ARROW;
if (!thumbPos) return SCROLL_TOP_RECT;
pt.y -= rect.top;
if (pt.y < thumbPos) return SCROLL_TOP_RECT;
if (pt.y > thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
return SCROLL_THUMB;
}
else /* horizontal */
{
if (pt.x <= rect.left + arrowSize) return SCROLL_TOP_ARROW;
if (pt.x >= rect.right - arrowSize) return SCROLL_BOTTOM_ARROW;
if (!thumbPos) return SCROLL_TOP_RECT;
pt.x -= rect.left;
if (pt.x < thumbPos) return SCROLL_TOP_RECT;
if (pt.x > thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
/***********************************************************************
* SCROLL_DrawArrows
*
* Draw the scroll bar arrows.
*/
static void SCROLL_DrawArrows( HDC32 hdc, SCROLLBAR_INFO *infoPtr,
RECT32 *rect, INT32 arrowSize, BOOL32 vertical,
BOOL32 top_pressed, BOOL32 bottom_pressed )
HDC32 hdcMem = CreateCompatibleDC( hdc );
HBITMAP32 hbmpPrev = SelectObject( hdcMem, vertical ?
TOP_ARROW(infoPtr->flags, top_pressed)
: LEFT_ARROW(infoPtr->flags, top_pressed));
StretchBlt( hdc, rect->left, rect->top,
vertical ? rect->right-rect->left : arrowSize+1,
vertical ? arrowSize+1 : rect->bottom-rect->top,
hdcMem, 0, 0,
SYSMETRICS_CXVSCROLL + 1, SYSMETRICS_CYHSCROLL + 1,
SRCCOPY );
SelectObject( hdcMem, vertical ?
BOTTOM_ARROW( infoPtr->flags, bottom_pressed )
: RIGHT_ARROW( infoPtr->flags, bottom_pressed ) );
if (vertical)
StretchBlt( hdc, rect->left, rect->bottom - arrowSize - 1,
rect->right - rect->left, arrowSize + 1,
hdcMem, 0, 0,
SYSMETRICS_CXVSCROLL + 1, SYSMETRICS_CYHSCROLL + 1,
SRCCOPY );
else
StretchBlt( hdc, rect->right - arrowSize - 1, rect->top,
arrowSize + 1, rect->bottom - rect->top,
hdcMem, 0, 0,
SYSMETRICS_CXVSCROLL + 1, SYSMETRICS_CYHSCROLL + 1,
SRCCOPY );
SelectObject( hdcMem, hbmpPrev );
DeleteDC( hdcMem );
/***********************************************************************
* SCROLL_DrawMovingThumb
*
* Draw the moving thumb rectangle.
*/
static void SCROLL_DrawMovingThumb( HDC32 hdc, RECT32 *rect, BOOL32 vertical,
INT32 arrowSize, INT32 thumbSize )
if (r.top < rect->top + arrowSize) r.top = rect->top + arrowSize;
if (r.top + thumbSize >= rect->bottom - arrowSize)
r.top = rect->bottom - arrowSize - thumbSize - 1;
r.bottom = r.top + thumbSize + 1;
if (r.left < rect->left + arrowSize) r.left = rect->left + arrowSize;
if (r.left + thumbSize >= rect->right - arrowSize)
r.left = rect->right - arrowSize - thumbSize - 1;
r.right = r.left + thumbSize + 1;
InflateRect32( &r, -1, -1 );
DrawFocusRect32( hdc, &r );
SCROLL_MovingThumb = !SCROLL_MovingThumb;
/***********************************************************************
* SCROLL_DrawInterior
*
* Draw the scroll bar interior (everything except the arrows).
*/
static void SCROLL_DrawInterior( HWND32 hwnd, HDC32 hdc, INT32 nBar,
RECT32 *rect, INT32 arrowSize,
INT32 thumbSize, INT32 thumbPos,
UINT32 flags, BOOL32 vertical,
BOOL32 top_selected, BOOL32 bottom_selected )
/* Select the correct brush and pen */
SelectObject( hdc, sysColorObjects.hpenWindowFrame );
if ((flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH)
{
/* This ought to be the color of the parent window */
SelectObject( hdc, sysColorObjects.hbrushWindow );
}
{
if (nBar == SB_CTL) /* Only scrollbar controls send WM_CTLCOLOR */
{
HBRUSH32 hbrush = SendMessage32A(GetParent32(hwnd),
WM_CTLCOLORSCROLLBAR, hdc, hwnd );
SelectObject( hdc, hbrush );
}
else SelectObject( hdc, sysColorObjects.hbrushScrollbar );
}
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
/* Calculate the scroll rectangle */
r = *rect;
if (vertical)
{
r.top += arrowSize;
r.bottom -= arrowSize;
}
else
{
r.left += arrowSize;
r.right -= arrowSize;
}
/* Draw the scroll bar frame */
MoveTo( hdc, r.left, r.top );
LineTo( hdc, r.right-1, r.top );
LineTo( hdc, r.right-1, r.bottom-1 );
LineTo( hdc, r.left, r.bottom-1 );
LineTo( hdc, r.left, r.top );
/* Draw the scroll rectangles and thumb */
if (!thumbPos) /* No thumb to draw */
{
PatBlt( hdc, r.left+1, r.top+1, r.right - r.left - 2,
return;
}
if (vertical)
{
PatBlt( hdc, r.left + 1, r.top + 1,
r.right - r.left - 2,
thumbPos - arrowSize,
}
else /* horizontal */
{
PatBlt( hdc, r.left + 1, r.top + 1,
thumbPos - arrowSize,
r.bottom - r.top - 2,
PatBlt( hdc, r.left + thumbSize + 1, r.top + 1,
r.right - r.left - thumbSize - 2,
}
/* Draw the thumb */
SelectObject( hdc, sysColorObjects.hbrushBtnFace );
Rectangle( hdc, r.left, r.top, r.right, r.bottom );
if (SCROLL_MovingThumb &&
(SCROLL_TrackingWin == hwnd) &&
(SCROLL_TrackingBar == nBar))
{
SCROLL_DrawMovingThumb( hdc, rect, vertical, arrowSize, thumbSize );
SCROLL_MovingThumb = TRUE;
}
/***********************************************************************
* SCROLL_DrawScrollBar
*
* Redraw the whole scrollbar.
*/
void SCROLL_DrawScrollBar( HWND32 hwnd, HDC32 hdc, INT32 nBar, BOOL32 arrows )
INT32 arrowSize, thumbSize, thumbPos;
RECT32 rect;
BOOL32 vertical;
SCROLLBAR_INFO *infoPtr = SCROLL_GetPtrScrollInfo( wndPtr, nBar );
if (!wndPtr || !infoPtr ||
((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL)) ||
((nBar == SB_HORZ) && !(wndPtr->dwStyle & WS_HSCROLL))) return;
vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
if (arrows && arrowSize) SCROLL_DrawArrows( hdc, infoPtr, &rect, arrowSize,
vertical, FALSE, FALSE );
SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
thumbPos, infoPtr->flags, vertical, FALSE, FALSE );
/***********************************************************************
* SCROLL_RefreshScrollBar
*
* Repaint the scroll bar interior after a SetScrollRange() or
* SetScrollPos() call.
*/
static void SCROLL_RefreshScrollBar( HWND32 hwnd, INT32 nBar, BOOL32 arrows )
HDC32 hdc = GetDCEx32( hwnd, 0,
DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW) );
SCROLL_DrawScrollBar( hwnd, hdc, nBar, arrows );
ReleaseDC32( hwnd, hdc );
/***********************************************************************
* SCROLL_HandleKbdEvent
*
* Handle a keyboard event (only for SB_CTL scrollbars).
static void SCROLL_HandleKbdEvent( HWND32 hwnd, WPARAM32 wParam )
switch(wParam)
{
case VK_PRIOR: msg = SB_PAGEUP; break;
case VK_NEXT: msg = SB_PAGEDOWN; break;
case VK_HOME: msg = SB_TOP; break;
case VK_END: msg = SB_BOTTOM; break;
case VK_UP: msg = SB_LINEUP; break;
case VK_DOWN: msg = SB_LINEDOWN; break;
default:
return;
}
(wndPtr->dwStyle & SBS_VERT) ? WM_VSCROLL : WM_HSCROLL,
msg, hwnd );
/***********************************************************************
* SCROLL_HandleScrollEvent
*
* Handle a mouse or timer event for the scrollbar.
* 'pt' is the location of the mouse event in client (for SB_CTL) or
* windows coordinates.
void SCROLL_HandleScrollEvent( HWND32 hwnd, INT32 nBar, UINT32 msg, POINT32 pt)
/* Hit test code of the last button-down event */
static enum SCROLL_HITTEST trackHitTest;
/* Thumb position when tracking started. */
/* Position in the scroll-bar of the last button-down event. */
/* Position in the scroll-bar of the last mouse event. */
HWND32 hwndOwner, hwndCtl;
BOOL32 vertical;
INT32 arrowSize, thumbSize, thumbPos;
RECT32 rect;
HDC32 hdc;
SCROLLBAR_INFO *infoPtr = SCROLL_GetScrollInfo( hwnd, nBar );
if (!infoPtr) return;
if ((trackHitTest == SCROLL_NOWHERE) && (msg != WM_LBUTTONDOWN)) return;
hdc = GetDCEx32( hwnd, 0, DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW));
vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
hwndOwner = (nBar == SB_CTL) ? GetParent32(hwnd) : hwnd;
hwndCtl = (nBar == SB_CTL) ? hwnd : 0;
switch(msg)
{
case WM_LBUTTONDOWN: /* Initialise mouse tracking */
trackHitTest = hittest = SCROLL_HitTest( hwnd, nBar, pt );
lastClickPos = vertical ? (pt.y - rect.top) : (pt.x - rect.left);
lastMousePos = lastClickPos;
trackThumbPos = thumbPos;
prevPt = pt;
break;
case WM_MOUSEMOVE:
hittest = SCROLL_HitTest( hwnd, nBar, pt );
prevPt = pt;
break;
case WM_LBUTTONUP:
hittest = SCROLL_NOWHERE;
ReleaseCapture();
break;
case WM_SYSTIMER:
pt = prevPt;
hittest = SCROLL_HitTest( hwnd, nBar, pt );
break;
default:
return; /* Should never happen */
}
dprintf_scroll( stddeb, "ScrollBar Event: hwnd=%04x bar=%d msg=%x pt=%d,%d hit=%d\n",
hwnd, nBar, msg, pt.x, pt.y, hittest );
switch(trackHitTest)
{
case SCROLL_NOWHERE: /* No tracking in progress */
break;
case SCROLL_TOP_ARROW:
SCROLL_DrawArrows( hdc, infoPtr, &rect, arrowSize, vertical,
(hittest == trackHitTest), FALSE );
if (hittest == trackHitTest)
{
if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
SB_LINEUP, hwndCtl );
SetSystemTimer32( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
(TIMERPROC32)0 );
SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
thumbPos, infoPtr->flags, vertical,
(hittest == trackHitTest), FALSE );
if (hittest == trackHitTest)
{
if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
SB_PAGEUP, hwndCtl );
SetSystemTimer32( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
(TIMERPROC32)0 );
break;
case SCROLL_THUMB:
if (msg == WM_LBUTTONDOWN)
SCROLL_TrackingWin = hwnd;
SCROLL_TrackingBar = nBar;
SCROLL_TrackingPos = trackThumbPos + lastMousePos - lastClickPos;
SCROLL_DrawMovingThumb(hdc, &rect, vertical, arrowSize, thumbSize);
SCROLL_TrackingWin = 0;
SCROLL_MovingThumb = FALSE;
SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
thumbPos, infoPtr->flags, vertical,
FALSE, FALSE );
else pos = vertical ? (pt.y - rect.top) : (pt.x - rect.left);
if (pos != lastMousePos)
{
SCROLL_DrawMovingThumb( hdc, &rect, vertical,
arrowSize, thumbSize );
SCROLL_TrackingPos = trackThumbPos + pos - lastClickPos;
SCROLL_TrackingVal = SCROLL_GetThumbVal( infoPtr, &rect,
vertical,
SCROLL_TrackingPos );
SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
MAKEWPARAM( SB_THUMBTRACK, SCROLL_TrackingVal),
hwndCtl );
SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
thumbPos, infoPtr->flags, vertical,
FALSE, (hittest == trackHitTest) );
if (hittest == trackHitTest)
{
if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
SB_PAGEDOWN, hwndCtl );
SetSystemTimer32( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
(TIMERPROC32)0 );
break;
case SCROLL_BOTTOM_ARROW:
SCROLL_DrawArrows( hdc, infoPtr, &rect, arrowSize, vertical,
FALSE, (hittest == trackHitTest) );
if (hittest == trackHitTest)
{
if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
SB_LINEDOWN, hwndCtl );
SetSystemTimer32( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
(TIMERPROC32)0 );
break;
}
if (msg == WM_LBUTTONUP)
{
if (trackHitTest == SCROLL_THUMB)
{
UINT32 val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
SendMessage32A( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
trackHitTest = SCROLL_NOWHERE; /* Terminate tracking */
}
/***********************************************************************
* ScrollBarWndProc
*/
LRESULT ScrollBarWndProc( HWND32 hwnd, UINT32 message, WPARAM32 wParam,
LPARAM lParam )
CREATESTRUCT32A *lpCreat = (CREATESTRUCT32A *)lParam;
if (lpCreat->style & SBS_SIZEBOX)
{
fprintf( stdnimp, "Unimplemented style SBS_SIZEBOX.\n" );
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
}
if (lpCreat->style & SBS_VERT)
{
if (lpCreat->style & SBS_LEFTALIGN)
MoveWindow( hwnd, lpCreat->x, lpCreat->y,
SYSMETRICS_CXVSCROLL+1, lpCreat->cy, FALSE );
else if (lpCreat->style & SBS_RIGHTALIGN)
MoveWindow( hwnd,
lpCreat->x+lpCreat->cx-SYSMETRICS_CXVSCROLL-1,
lpCreat->y,
SYSMETRICS_CXVSCROLL + 1, lpCreat->cy, FALSE );
}
else /* SBS_HORZ */
{
if (lpCreat->style & SBS_TOPALIGN)
MoveWindow( hwnd, lpCreat->x, lpCreat->y,
lpCreat->cx, SYSMETRICS_CYHSCROLL+1, FALSE );
else if (lpCreat->style & SBS_BOTTOMALIGN)
MoveWindow( hwnd,
lpCreat->x,
lpCreat->y+lpCreat->cy-SYSMETRICS_CYHSCROLL-1,
lpCreat->cx, SYSMETRICS_CYHSCROLL+1, FALSE );
}
}
if (!hUpArrow) SCROLL_LoadBitmaps();
dprintf_scroll( stddeb, "ScrollBar creation, hwnd=%04x\n", hwnd );
return 0;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
case WM_SYSTIMER:
{
POINT32 pt;
CONV_POINT16TO32( (POINT16 *)&lParam, &pt );
SCROLL_HandleScrollEvent( hwnd, SB_CTL, message, pt );
}
break;
case WM_KEYDOWN:
SCROLL_HandleKbdEvent( hwnd, wParam );
break;
case WM_ERASEBKGND:
return 1;
case WM_GETDLGCODE:
return DLGC_WANTARROWS; /* Windows returns this value */
PAINTSTRUCT32 ps;
HDC32 hdc = BeginPaint32( hwnd, &ps );
SCROLL_DrawScrollBar( hwnd, hdc, SB_CTL, TRUE );
EndPaint32( hwnd, &ps );
case SBM_SETPOS16:
case SBM_SETPOS32:
return SetScrollPos32( hwnd, SB_CTL, wParam, (BOOL32)lParam );
case SBM_GETPOS16:
case SBM_GETPOS32:
return GetScrollPos32( hwnd, SB_CTL );
case SBM_SETRANGE16:
SetScrollRange32( hwnd, SB_CTL, LOWORD(lParam), HIWORD(lParam),
wParam /* FIXME: Is this correct? */ );
case SBM_SETRANGE32:
SetScrollRange32( hwnd, SB_CTL, wParam, lParam, FALSE );
return 0; /* FIXME: return previous position */
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
case SBM_GETRANGE16:
/* FIXME */
fprintf( stderr, "ScrollBar: don't know how to handle SBM_GETRANGE16 (wp=%04x,lp=%08lx)\n",
wParam, lParam );
return 0;
case SBM_GETRANGE32:
GetScrollRange32( hwnd, SB_CTL, (LPINT32)wParam, (LPINT32)lParam );
return 0;
case SBM_ENABLE_ARROWS16:
case SBM_ENABLE_ARROWS32:
return EnableScrollBar32( hwnd, SB_CTL, wParam );
case SBM_SETRANGEREDRAW32:
SetScrollRange32( hwnd, SB_CTL, wParam, lParam, TRUE );
return 0; /* FIXME: return previous position */
case SBM_SETSCROLLINFO32:
return SetScrollInfo32( hwnd, SB_CTL, (SCROLLINFO *)lParam, wParam );
case SBM_GETSCROLLINFO32:
return GetScrollInfo32( hwnd, SB_CTL, (SCROLLINFO *)lParam );
case 0x00e5:
case 0x00e7:
case 0x00e8:
case 0x00eb:
case 0x00ec:
case 0x00ed:
case 0x00ee:
case 0x00ef:
fprintf(stderr, "ScrollBar: unknown Win32 msg %04x wp=%08x lp=%08lx\n",
message, wParam, lParam );
if (message >= WM_USER)
fprintf( stderr, "ScrollBar: unknown msg %04x wp=%04x lp=%08lx\n",
message, wParam, lParam );
return DefWindowProc32A( hwnd, message, wParam, lParam );
/*************************************************************************
INT16 SetScrollInfo16( HWND16 hwnd, INT16 nBar, const SCROLLINFO *info,
BOOL16 bRedraw )
{
return (INT16)SetScrollInfo32( hwnd, nBar, info, bRedraw );
}
/*************************************************************************
* SetScrollInfo32 (USER32.500)
*/
INT32 SetScrollInfo32( HWND32 hwnd, INT32 nBar, const SCROLLINFO *info,
BOOL32 bRedraw )
UINT32 new_flags;
BOOL32 repaint_arrows = FALSE;
if (!(infoPtr = SCROLL_GetScrollInfo(hwnd, nBar))) return 0;
if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return 0;
if ((info->cbSize != sizeof(*info)) &&
(info->cbSize != sizeof(*info)-sizeof(info->nTrackPos))) return 0;
dprintf_scroll( stddeb, "SetScrollInfo: hwnd=%04x bar=%d", hwnd, nBar );
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* Set the page size */
if (info->fMask & SIF_PAGE)
{
dprintf_scroll( stddeb, " page=%d", info->nPage );
infoPtr->Page = info->nPage;
}
/* Set the scroll pos */
if (info->fMask & SIF_POS)
{
dprintf_scroll( stddeb, " pos=%d", info->nPos );
infoPtr->CurVal = info->nPos;
}
/* Set the scroll range */
if (info->fMask & SIF_RANGE)
{
dprintf_scroll( stddeb, " min=%d max=%d", info->nMin, info->nMax );
/* Invalid range -> range is set to (0,0) */
if ((info->nMin > info->nMax) ||
((UINT32)(info->nMax - info->nMin) >= 0x80000000))
{
infoPtr->MinVal = 0;
infoPtr->MaxVal = 0;
}
else
{
infoPtr->MinVal = info->nMin;
infoPtr->MaxVal = info->nMax;
}
}
/* Make sure the page size is valid */
if (infoPtr->Page < 0) infoPtr->Page = 0;
else if (infoPtr->Page > infoPtr->MaxVal - infoPtr->MinVal + 1 )
infoPtr->Page = infoPtr->MaxVal - infoPtr->MinVal + 1;
/* Make sure the pos is inside the range */
if (infoPtr->CurVal < infoPtr->MinVal)
infoPtr->CurVal = infoPtr->MinVal;
else if (infoPtr->CurVal > infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
infoPtr->CurVal = infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 );
dprintf_scroll( stddeb, "\n new values: page=%d pos=%d min=%d max=%d\n",
infoPtr->Page, infoPtr->CurVal,
infoPtr->MinVal, infoPtr->MaxVal );
/* Check if the scrollbar should be hidden or disabled */
new_flags = infoPtr->flags;
if (infoPtr->MinVal >= infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
{
/* Hide or disable scroll-bar */
if (info->fMask & SIF_DISABLENOSCROLL) new_flags = ESB_DISABLE_BOTH;
else if (nBar != SB_CTL)
{
ShowScrollBar32( hwnd, nBar, FALSE );
bRedraw = FALSE; /* No need to repaint anything */
}
}
else /* Show and enable scroll-bar */
{
new_flags = 0;
if (nBar != SB_CTL) ShowScrollBar32( hwnd, nBar, TRUE );
}
if (infoPtr->flags != new_flags)
{
infoPtr->flags = new_flags;
repaint_arrows = TRUE;