00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdlib.h>
00017 #include <os2win.h>
00018 #include "controls.h"
00019 #include "scroll.h"
00020 #include "win32wbase.h"
00021 #include "oslibwin.h"
00022 #include "initterm.h"
00023 #include "pmwindow.h"
00024
00025 #define DBG_LOCALLOG DBG_scroll
00026 #include "dbglocal.h"
00027
00028 #define SCROLL_MIN_RECT 4
00029 #define SCROLL_MIN_THUMB 6
00030
00031 #define SCROLL_ARROW_THUMB_OVERLAP 0
00032
00033 #define SCROLL_FIRST_DELAY 200
00034 #define SCROLL_REPEAT_DELAY 50
00035 #define SCROLL_BLINK_DELAY 1000
00036
00037 #define SCROLL_TIMER 0
00038 #define BLINK_TIMER 1
00039
00040
00041 enum SCROLL_HITTEST
00042 {
00043 SCROLL_NOWHERE,
00044 SCROLL_TOP_ARROW,
00045 SCROLL_TOP_RECT,
00046 SCROLL_THUMB,
00047 SCROLL_BOTTOM_RECT,
00048 SCROLL_BOTTOM_ARROW
00049 };
00050
00051
00052 #define SA_SSI_HIDE 0x0001
00053 #define SA_SSI_SHOW 0x0002
00054 #define SA_SSI_REPAINT_INTERIOR 0x0004
00055 #define SA_SSI_REPAINT_ARROWS 0x0008
00056 #define SA_SSI_MOVE_THUMB 0x0010
00057 #define SA_SSI_REFRESH 0x0020
00058
00059
00060 static HWND SCROLL_TrackingWin = 0;
00061 static INT SCROLL_TrackingBar = 0;
00062 static INT SCROLL_TrackingPos = 0;
00063 static INT SCROLL_TrackingVal = 0;
00064
00065 static HWND SCROLL_FocusWin = 0;
00066 static BOOL SCROLL_HasFocus = FALSE;
00067 static BOOL SCROLL_Highlighted = FALSE;
00068 static BOOL SCROLL_Scrolling = FALSE;
00069
00070
00071 static enum SCROLL_HITTEST SCROLL_trackHitTest;
00072 static enum SCROLL_HITTEST SCROLL_lastHitTest;
00073 static BOOL SCROLL_trackVertical;
00074
00075
00076 static BOOL SCROLL_MovingThumb = FALSE;
00077
00078 static SCROLLBAR_INFO *SCROLL_GetInfoPtr( HWND hwnd, INT nBar )
00079 {
00080 Win32BaseWindow *win32wnd;
00081
00082 switch(nBar)
00083 {
00084 case SB_HORZ:
00085 case SB_VERT:
00086 {
00087 SCROLLBAR_INFO *pInfo;
00088 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
00089
00090 if (!win32wnd) return NULL;
00091 pInfo = win32wnd->getScrollInfo(nBar);
00092 RELEASE_WNDOBJ(win32wnd);
00093 return pInfo;
00094 }
00095
00096 case SB_CTL:
00097 return (SCROLLBAR_INFO*)GetInfoPtr(hwnd);
00098 }
00099
00100 return NULL;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 static BOOL SCROLL_GetScrollBarRect( HWND hwnd, INT nBar, RECT *lprect,
00117 INT *arrowSize, INT *thumbSize,
00118 INT *thumbPos )
00119 {
00120 INT pixels;
00121 BOOL vertical;
00122 RECT rectClient;
00123
00124 switch(nBar)
00125 {
00126 case SB_HORZ:
00127 {
00128 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
00129 RECT rectClient;
00130
00131 if (!win32wnd) return FALSE;
00132 rectClient = *win32wnd->getClientRectPtr();
00133 lprect->left = rectClient.left;
00134 lprect->top = rectClient.bottom;
00135 lprect->right = rectClient.right;
00136 lprect->bottom = lprect->top+GetSystemMetrics(SM_CYHSCROLL);
00137 if (win32wnd->getStyle() & WS_BORDER)
00138 {
00139 lprect->left--;
00140 lprect->right++;
00141 }
00142 else
00143 if (win32wnd->getStyle() & WS_VSCROLL)
00144 lprect->right++;
00145 RELEASE_WNDOBJ(win32wnd);
00146 vertical = FALSE;
00147 break;
00148 }
00149
00150 case SB_VERT:
00151 {
00152 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
00153 RECT rectClient;
00154
00155 if (!win32wnd) return FALSE;
00156 rectClient = *win32wnd->getClientRectPtr();
00157 lprect->left = rectClient.right;
00158 lprect->top = rectClient.top;
00159 lprect->right = lprect->left+GetSystemMetrics(SM_CXVSCROLL);
00160 lprect->bottom = rectClient.bottom;
00161 if(win32wnd->getStyle() & WS_BORDER)
00162 {
00163 lprect->top--;
00164 lprect->bottom++;
00165 }
00166 else
00167 if (win32wnd->getStyle() & WS_HSCROLL)
00168 lprect->bottom++;
00169 RELEASE_WNDOBJ(win32wnd);
00170 vertical = TRUE;
00171 break;
00172 }
00173
00174 case SB_CTL:
00175 {
00176 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00177
00178 GetClientRect( hwnd, lprect );
00179 vertical = ((dwStyle & SBS_VERT) != 0);
00180 break;
00181 }
00182
00183 default:
00184 return FALSE;
00185 }
00186
00187 if (vertical) pixels = lprect->bottom - lprect->top;
00188 else pixels = lprect->right - lprect->left;
00189
00190 if (pixels <= 2*GetSystemMetrics(SM_CXVSCROLL) + SCROLL_MIN_RECT)
00191 {
00192 if (pixels > SCROLL_MIN_RECT)
00193 *arrowSize = (pixels - SCROLL_MIN_RECT) / 2;
00194 else
00195 *arrowSize = 0;
00196 *thumbPos = *thumbSize = 0;
00197 }
00198 else
00199 {
00200 SCROLLBAR_INFO *info = SCROLL_GetInfoPtr( hwnd, nBar );
00201
00202 *arrowSize = GetSystemMetrics(SM_CXVSCROLL);
00203 pixels -= (2 * (GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP));
00204
00205 if (info->Page)
00206 {
00207 *thumbSize = pixels * info->Page / (info->MaxVal-info->MinVal+1);
00208 if (*thumbSize < SCROLL_MIN_THUMB) *thumbSize = SCROLL_MIN_THUMB;
00209 }
00210 else *thumbSize = GetSystemMetrics(SM_CXVSCROLL);
00211
00212 if (((pixels -= *thumbSize ) < 0) ||
00213 ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
00214 {
00215
00216 *thumbPos = *thumbSize = 0;
00217 }
00218 else
00219 {
00220 INT max = info->MaxVal - MAX( info->Page-1, 0 );
00221 if (info->MinVal >= max)
00222 *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
00223 else
00224 *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP
00225 + pixels * (info->CurVal-info->MinVal) / (max - info->MinVal);
00226 }
00227 }
00228
00229 dprintf(("SCROLL_GetScrollBarRect: thumbPos %d thumbSize %d", *thumbPos, *thumbSize));
00230 return vertical;
00231 }
00232
00233
00234
00235
00236 static BOOL SCROLL_PtInRectEx( LPRECT lpRect, POINT pt, BOOL vertical )
00237 {
00238 RECT rect = *lpRect;
00239
00240 if (vertical)
00241 {
00242 INT w = lpRect->right-lpRect->left;
00243
00244 rect.left -= w;
00245 rect.right += w;
00246 rect.top -= w;
00247 rect.bottom += w;
00248 } else
00249 {
00250 INT h = lpRect->bottom-lpRect->top;
00251
00252 rect.top -= h;
00253 rect.bottom += h;
00254 rect.left -= h;
00255 rect.right += h;
00256 }
00257
00258 return PtInRect( &rect, pt );
00259 }
00260
00261
00262
00263
00264
00265
00266 static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, INT nBar,
00267 POINT pt, BOOL bDragging )
00268 {
00269 INT arrowSize, thumbSize, thumbPos;
00270 RECT rect;
00271 SCROLLBAR_INFO *infoPtr = SCROLL_GetInfoPtr(hwnd,nBar);
00272
00273 if (!infoPtr) return SCROLL_NOWHERE;
00274
00275 BOOL vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
00276 &arrowSize, &thumbSize, &thumbPos );
00277
00278 if ( (bDragging && !SCROLL_PtInRectEx( &rect, pt, vertical )) ||
00279 (!PtInRect( &rect, pt )) ) return SCROLL_NOWHERE;
00280
00281 if (vertical)
00282 {
00283 if (pt.y < rect.top + arrowSize) return (infoPtr->flags & ESB_DISABLE_LTUP) ? SCROLL_NOWHERE:SCROLL_TOP_ARROW;
00284 if (pt.y >= rect.bottom - arrowSize) return (infoPtr->flags & ESB_DISABLE_RTDN) ? SCROLL_NOWHERE:SCROLL_BOTTOM_ARROW;
00285 if (!thumbPos) return ((infoPtr->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH) ? SCROLL_NOWHERE:SCROLL_TOP_RECT;
00286 pt.y -= rect.top;
00287 if (pt.y < thumbPos) return SCROLL_TOP_RECT;
00288 if (pt.y >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
00289 }
00290 else
00291 {
00292 if (pt.x < rect.left + arrowSize) return (infoPtr->flags & ESB_DISABLE_LTUP) ? SCROLL_NOWHERE:SCROLL_TOP_ARROW;
00293 if (pt.x >= rect.right - arrowSize) return (infoPtr->flags & ESB_DISABLE_RTDN) ? SCROLL_NOWHERE:SCROLL_BOTTOM_ARROW;
00294 if (!thumbPos) return ((infoPtr->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH) ? SCROLL_NOWHERE:SCROLL_TOP_RECT;
00295 pt.x -= rect.left;
00296 if (pt.x < thumbPos) return SCROLL_TOP_RECT;
00297 if (pt.x >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
00298 }
00299 return SCROLL_THUMB;
00300 }
00301
00302 static void SCROLL_DrawTopArrow(HDC hdc,SCROLLBAR_INFO *infoPtr,RECT *rect,INT arrowSize,BOOL vertical,BOOL top_pressed)
00303 {
00304 RECT r;
00305
00306 r = *rect;
00307 if( vertical )
00308 r.bottom = r.top + arrowSize;
00309 else
00310 r.right = r.left + arrowSize;
00311
00312 DrawFrameControl( hdc, &r, DFC_SCROLL,
00313 (vertical ? DFCS_SCROLLUP : DFCS_SCROLLLEFT)
00314 | (top_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0 )
00315 | (infoPtr->flags&ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0 ) );
00316 }
00317
00318 static void SCROLL_DrawBottomArrow(HDC hdc,SCROLLBAR_INFO *infoPtr,RECT *rect,INT arrowSize,BOOL vertical,BOOL bottom_pressed)
00319 {
00320 RECT r;
00321
00322 r = *rect;
00323 if( vertical )
00324 r.top = r.bottom-arrowSize;
00325 else
00326 r.left = r.right-arrowSize;
00327
00328 DrawFrameControl( hdc, &r, DFC_SCROLL,
00329 (vertical ? DFCS_SCROLLDOWN : DFCS_SCROLLRIGHT)
00330 | (bottom_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0 )
00331 | (infoPtr->flags&ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) );
00332 }
00333
00334
00335
00336
00337
00338
00339 static void SCROLL_DrawArrows( HDC hdc, SCROLLBAR_INFO *infoPtr,
00340 RECT *rect, INT arrowSize, BOOL vertical,
00341 BOOL top_pressed, BOOL bottom_pressed )
00342 {
00343 SCROLL_DrawTopArrow(hdc,infoPtr,rect,arrowSize,vertical,top_pressed);
00344 SCROLL_DrawBottomArrow(hdc,infoPtr,rect,arrowSize,vertical,bottom_pressed);
00345 }
00346
00347 static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, INT nBar,
00348 RECT *rect, INT arrowSize,
00349 INT thumbSize, INT thumbPos,
00350 UINT flags, BOOL vertical,
00351 BOOL top_selected, BOOL bottom_selected )
00352 {
00353 RECT r;
00354 HPEN hSavePen;
00355 HBRUSH hSaveBrush,hBrush;
00356
00357
00358
00359
00360
00361
00362
00363 if (nBar == SB_CTL) {
00364 hBrush = (HBRUSH)SendMessageA( GetParent(hwnd), WM_CTLCOLORSCROLLBAR,
00365 (WPARAM)hdc,(LPARAM)hwnd);
00366 } else {
00367 hBrush = (HBRUSH)SendMessageA( hwnd, WM_CTLCOLORSCROLLBAR,
00368 (WPARAM)hdc,(LPARAM)hwnd);
00369
00370 }
00371
00372 hSavePen = SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
00373 hSaveBrush = SelectObject( hdc, hBrush );
00374
00375
00376
00377 r = *rect;
00378 if (vertical)
00379 {
00380 r.top += arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
00381 r.bottom -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
00382 }
00383 else
00384 {
00385 r.left += arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
00386 r.right -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
00387 }
00388
00389
00390 if (!thumbPos)
00391 {
00392 PatBlt( hdc, r.left, r.top,
00393 r.right - r.left, r.bottom - r.top,
00394 PATCOPY );
00395
00396
00397 SelectObject( hdc, hSavePen );
00398 SelectObject( hdc, hSaveBrush );
00399 return;
00400 }
00401
00402 if (vertical)
00403 {
00404 PatBlt( hdc, r.left, r.top,
00405 r.right - r.left,
00406 thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP),
00407 top_selected ? 0x0f0000 : PATCOPY );
00408 r.top += thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
00409 PatBlt( hdc, r.left, r.top + thumbSize,
00410 r.right - r.left,
00411 r.bottom - r.top - thumbSize,
00412 bottom_selected ? 0x0f0000 : PATCOPY );
00413 r.bottom = r.top + thumbSize;
00414 }
00415 else
00416 {
00417 PatBlt( hdc, r.left, r.top,
00418 thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP),
00419 r.bottom - r.top,
00420 top_selected ? 0x0f0000 : PATCOPY );
00421 r.left += thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
00422 PatBlt( hdc, r.left + thumbSize, r.top,
00423 r.right - r.left - thumbSize,
00424 r.bottom - r.top,
00425 bottom_selected ? 0x0f0000 : PATCOPY );
00426 r.right = r.left + thumbSize;
00427 }
00428
00429
00430
00431 DrawEdge(hdc,&r,EDGE_RAISED,BF_RECT | BF_ADJUST);
00432 FillRect(hdc,&r,(SCROLL_FocusWin == hwnd && SCROLL_Highlighted && !SCROLL_Scrolling) ? GetSysColorBrush(COLOR_3DSHADOW):GetSysColorBrush(COLOR_BTNFACE));
00433
00434
00435 SelectObject( hdc, hSavePen );
00436 SelectObject( hdc, hSaveBrush );
00437 }
00438
00439
00440
00441
00442
00443
00444 static void SCROLL_DrawMovingThumb( HDC hdc, RECT *rect, BOOL vertical,
00445 INT arrowSize, INT thumbSize )
00446 {
00447 INT pos = SCROLL_TrackingPos;
00448 INT max_size;
00449
00450 if( vertical )
00451 max_size = rect->bottom - rect->top;
00452 else
00453 max_size = rect->right - rect->left;
00454
00455 max_size -= (arrowSize-SCROLL_ARROW_THUMB_OVERLAP) + thumbSize;
00456
00457 if( pos < (arrowSize-SCROLL_ARROW_THUMB_OVERLAP) )
00458 pos = (arrowSize-SCROLL_ARROW_THUMB_OVERLAP);
00459 else if( pos > max_size )
00460 pos = max_size;
00461
00462 SCROLL_DrawInterior( SCROLL_TrackingWin, hdc, SCROLL_TrackingBar,
00463 rect, arrowSize, thumbSize, pos,
00464 0, vertical, FALSE, FALSE );
00465 }
00466
00467
00468
00469
00470 static POINT SCROLL_ClipPos( LPRECT lpRect, POINT pt )
00471 {
00472 if( pt.x < lpRect->left )
00473 pt.x = lpRect->left;
00474 else
00475 if( pt.x >= lpRect->right )
00476 pt.x = lpRect->right-1;
00477
00478 if( pt.y < lpRect->top )
00479 pt.y = lpRect->top;
00480 else
00481 if( pt.y >= lpRect->bottom )
00482 pt.y = lpRect->bottom-1;
00483
00484 return pt;
00485 }
00486
00487
00488
00489
00490
00491
00492
00493 static UINT SCROLL_GetThumbVal( SCROLLBAR_INFO *infoPtr, RECT *rect,
00494 BOOL vertical, INT pos )
00495 {
00496 INT thumbSize;
00497 INT pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
00498
00499 if ((pixels -= 2*(GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP)) <= 0)
00500 return infoPtr->MinVal;
00501
00502 if (infoPtr->Page)
00503 {
00504 thumbSize = pixels * infoPtr->Page/(infoPtr->MaxVal-infoPtr->MinVal+1);
00505 if (thumbSize < SCROLL_MIN_THUMB) thumbSize = SCROLL_MIN_THUMB;
00506 }
00507 else thumbSize = GetSystemMetrics(SM_CXVSCROLL);
00508
00509 if ((pixels -= thumbSize) <= 0) return infoPtr->MinVal;
00510
00511 pos = MAX( 0, pos - (GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP) );
00512 if (pos > pixels) pos = pixels;
00513
00514 if (!infoPtr->Page) pos *= infoPtr->MaxVal - infoPtr->MinVal;
00515 else pos *= infoPtr->MaxVal - infoPtr->MinVal - infoPtr->Page + 1;
00516 return infoPtr->MinVal + ((pos + pixels / 2) / pixels);
00517 }
00518
00519 void SCROLL_GetSizeBox(HWND hwnd,DWORD dwStyle,PRECT rect)
00520 {
00521 RECT clientRect;
00522 INT cx = GetSystemMetrics(SM_CXVSCROLL);
00523 INT cy = GetSystemMetrics(SM_CYHSCROLL);
00524
00525 GetClientRect(hwnd,&clientRect);
00526
00527 if (dwStyle & SBS_SIZEBOXTOPLEFTALIGN)
00528 {
00529 rect->left = 0;
00530 rect->right = cx;
00531 rect->bottom = cy;
00532 rect->top = 0;
00533 } else
00534 {
00535 rect->left = clientRect.right-cx;
00536 rect->right = clientRect.right;
00537 rect->bottom = clientRect.bottom;
00538 rect->top = clientRect.bottom-cy;
00539 }
00540 }
00541
00542 void SCROLL_DrawSizeBox(HDC hdc,RECT rect)
00543 {
00544 POINT p1,p2;
00545 HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
00546 HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
00547 HPEN oldPen = SelectObject(hdc,penDark);
00548 INT x;
00549
00550 p1.x = rect.right-1;
00551 p1.y = rect.bottom;
00552 p2.x = rect.right;
00553 p2.y = rect.bottom-1;
00554 for (x = 0;x < 3;x++)
00555 {
00556 SelectObject(hdc,penDark);
00557 MoveToEx(hdc,p1.x,p1.y,NULL);
00558 LineTo(hdc,p2.x,p2.y);
00559 p1.x--;
00560 p2.y--;
00561 MoveToEx(hdc,p1.x,p1.y,NULL);
00562 LineTo(hdc,p2.x,p2.y);
00563 SelectObject(hdc,penWhite);
00564 p1.x--;
00565 p2.y--;
00566 MoveToEx(hdc,p1.x,p1.y,NULL);
00567 LineTo(hdc,p2.x,p2.y);
00568 p1.x -= 2;
00569 p2.y -= 2;
00570 }
00571
00572 SelectObject(hdc,oldPen);
00573 }
00574
00575
00576
00577
00578
00579
00580 void SCROLL_DrawScrollBar(HWND hwnd,HDC hdc,INT nBar,BOOL arrows,BOOL interior)
00581 {
00582 INT arrowSize, thumbSize, thumbPos;
00583 RECT rect;
00584 BOOL vertical;
00585 SCROLLBAR_INFO *infoPtr = SCROLL_GetInfoPtr( hwnd, nBar );
00586
00587 if (!infoPtr) return;
00588 if (nBar == SB_CTL)
00589 {
00590 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00591
00592 if (dwStyle & (SBS_SIZEBOX | SBS_SIZEGRIP))
00593 {
00594 RECT rect;
00595 HBRUSH hBrush;
00596
00597 hdc = GetDCEx(hwnd,0,DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW));
00598 hBrush = GetSysColorBrush(COLOR_3DFACE);
00599 GetClientRect(hwnd,&rect);
00600 FillRect(hdc,&rect,hBrush);
00601
00602 if (dwStyle & SBS_SIZEGRIP)
00603 {
00604 SCROLL_GetSizeBox(hwnd,dwStyle,&rect);
00605 SCROLL_DrawSizeBox(hdc,rect);
00606 }
00607
00608 ReleaseDC(hwnd,hdc);
00609
00610 return;
00611 }
00612 }
00613
00614 vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
00615 &arrowSize, &thumbSize, &thumbPos );
00616
00617
00618
00619 if (arrows && arrowSize)
00620 {
00621 if( vertical == SCROLL_trackVertical && GetCapture() == hwnd )
00622 SCROLL_DrawArrows( hdc, infoPtr, &rect, arrowSize, vertical,
00623 (SCROLL_trackHitTest == SCROLL_TOP_ARROW),
00624 (SCROLL_trackHitTest == SCROLL_BOTTOM_ARROW) );
00625 else
00626 SCROLL_DrawArrows( hdc, infoPtr, &rect, arrowSize, vertical,
00627 FALSE, FALSE );
00628 }
00629
00630 if (SCROLL_MovingThumb &&
00631 (SCROLL_TrackingWin == hwnd) &&
00632 (SCROLL_TrackingBar == nBar))
00633 SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize, thumbSize );
00634 else if( interior )
00635 SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
00636 thumbPos, infoPtr->flags, vertical, SCROLL_trackHitTest == SCROLL_TOP_RECT && SCROLL_lastHitTest == SCROLL_TOP_RECT,SCROLL_trackHitTest == SCROLL_BOTTOM_RECT && SCROLL_lastHitTest == SCROLL_BOTTOM_RECT);
00637 }
00638
00639
00640
00641
00642
00643
00644
00645 static void SCROLL_RefreshScrollBar( HWND hwnd, INT nBar,
00646 BOOL arrows, BOOL interior )
00647 {
00648 HDC hdc = GetDCEx(hwnd,0,DCX_CACHE | ((nBar == SB_CTL) ? 0:DCX_WINDOW));
00649
00650 if (!hdc) return;
00651
00652 SCROLL_DrawScrollBar( hwnd, hdc, nBar, arrows, interior );
00653 ReleaseDC( hwnd, hdc );
00654 }
00655
00656
00657
00658 LRESULT SCROLL_NCCreate(HWND hwnd,WPARAM wParam,LPARAM lParam)
00659 {
00660 SCROLLBAR_INFO *infoPtr = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
00661
00662 infoPtr->MinVal = infoPtr->CurVal = infoPtr->Page = 0;
00663 infoPtr->MaxVal = 100;
00664 infoPtr->flags = ESB_ENABLE_BOTH;
00665
00666 SetInfoPtr(hwnd,(DWORD)infoPtr);
00667
00668 return TRUE;
00669 }
00670
00671 LRESULT SCROLL_Create(HWND hwnd,WPARAM wParam,LPARAM lParam)
00672 {
00673 CREATESTRUCTA *lpCreat = (CREATESTRUCTA *)lParam;
00674
00675 #ifdef __WIN32OS2__
00676 if (!((lpCreat->style & (SBS_SIZEBOX | SBS_SIZEGRIP)) && !(lpCreat->style & (SBS_SIZEBOXTOPLEFTALIGN | SBS_SIZEBOXBOTTOMRIGHTALIGN))))
00677 #endif
00678 {
00679 if (lpCreat->style & SBS_VERT)
00680 {
00681 INT w,h;
00682
00683 w = GetSystemMetrics(SM_CXVSCROLL);
00684 #ifdef __WIN32OS2__
00685 if(lpCreat->style & (SBS_SIZEBOX | SBS_SIZEGRIP)) {
00686 h = GetSystemMetrics(SM_CYHSCROLL);
00687 }
00688 else h = lpCreat->cy;
00689 #else
00690 h = lpCreat->cy;
00691 #endif
00692 if (lpCreat->style & SBS_LEFTALIGN)
00693 MoveWindow(hwnd,lpCreat->x,lpCreat->y,w,h,FALSE);
00694 else if (lpCreat->style & SBS_RIGHTALIGN)
00695 MoveWindow(hwnd,lpCreat->x+lpCreat->cx-w,lpCreat->y,w,h,FALSE);
00696 } else
00697 {
00698 INT w,h;
00699
00700 #ifdef __WIN32OS2__
00701 if(lpCreat->style & (SBS_SIZEBOX | SBS_SIZEGRIP)) {
00702 w = GetSystemMetrics(SM_CXVSCROLL);
00703 }
00704 else w = lpCreat->cx;
00705 #else
00706 w = lpCreat->cx;
00707 #endif
00708
00709 h = GetSystemMetrics(SM_CYHSCROLL);
00710
00711 if (lpCreat->style & SBS_TOPALIGN)
00712 MoveWindow(hwnd,lpCreat->x,lpCreat->y,w,h,FALSE);
00713 else if (lpCreat->style & SBS_BOTTOMALIGN)
00714 MoveWindow(hwnd,lpCreat->x,lpCreat->y+lpCreat->cy-h,w,h,FALSE);
00715 }
00716 }
00717
00718 return 0;
00719 }
00720
00721 static LRESULT SCROLL_Destroy(HWND hwnd,WPARAM wParam,LPARAM lParam)
00722 {
00723 SCROLLBAR_INFO* infoPtr = (SCROLLBAR_INFO*)GetInfoPtr(hwnd);
00724
00725 free(infoPtr);
00726
00727 return 0;
00728 }
00729
00730 #ifdef __WIN32OS2__
00731 static LRESULT SCROLL_Enable(HWND hwnd, WPARAM wParam)
00732 {
00733 SCROLLBAR_INFO* infoPtr = (SCROLLBAR_INFO*)GetInfoPtr(hwnd);
00734
00735 if (!infoPtr) return 0;
00736
00737 EnableScrollBar(hwnd, SB_CTL, ESB_DISABLE_BOTH);
00738
00739 return 0;
00740 }
00741 #endif
00742
00743
00744
00745
00746
00747
00748
00749
00750 LRESULT SCROLL_HandleScrollEvent(HWND hwnd,WPARAM wParam,LPARAM lParam,INT nBar,UINT msg)
00751 {
00752 static POINT prevPt;
00753 static UINT trackThumbPos;
00754 static BOOL thumbTrackSent;
00755 static INT lastClickPos;
00756 static INT lastMousePos;
00757 static BOOL timerRunning;
00758
00759 enum SCROLL_HITTEST hittest;
00760 HWND hwndOwner, hwndCtl;
00761 BOOL vertical;
00762 INT arrowSize, thumbSize, thumbPos;
00763 RECT rect;
00764 HDC hdc;
00765 POINT pt;
00766 LRESULT res = 0;
00767
00768 SCROLLBAR_INFO *infoPtr = SCROLL_GetInfoPtr(hwnd,nBar);
00769 if (!infoPtr) return res;
00770
00771 if (nBar == SB_CTL)
00772 {
00773 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00774
00775 if ((dwStyle & (SBS_SIZEBOX | SBS_SIZEGRIP)))
00776 {
00777 if (!(dwStyle & SBS_SIZEGRIP)) return res;
00778
00779 if (msg == WM_NCHITTEST)
00780 {
00781 if (dwStyle & SBS_SIZEGRIP)
00782 {
00783 RECT rect;
00784
00785 pt.x = (SHORT)LOWORD(lParam);
00786 pt.y = (SHORT)HIWORD(lParam);
00787 ScreenToClient(hwnd,&pt);
00788 SCROLL_GetSizeBox(hwnd,dwStyle,&rect);
00789 if (PtInRect(&rect,pt))
00790 {
00791 if (dwStyle & SBS_SIZEBOXTOPLEFTALIGN)
00792 return HTTOPLEFT;
00793 else
00794 return HTBOTTOMRIGHT;
00795 }
00796 }
00797 return DefWindowProcA(hwnd,WM_NCHITTEST,wParam,lParam);
00798 } else if (msg == WM_LBUTTONDOWN)
00799 {
00800 return DefWindowProcA(hwnd,WM_LBUTTONDOWN,wParam,lParam);
00801 }
00802
00803 return res;
00804 }
00805 }
00806
00807 if (msg == WM_NCHITTEST) return DefWindowProcA(hwnd,WM_NCHITTEST,wParam,lParam);
00808
00809 vertical = SCROLL_GetScrollBarRect(hwnd,nBar,&rect,&arrowSize,&thumbSize,&thumbPos);
00810 hwndOwner = (nBar == SB_CTL) ? GetParent(hwnd):hwnd;
00811
00812 hwndCtl = (nBar == SB_CTL) ? hwnd:0;
00813
00814 switch (msg)
00815 {
00816 case WM_LBUTTONDOWN:
00817 pt.x = (SHORT)LOWORD(lParam);
00818 pt.y = (SHORT)HIWORD(lParam);
00819 SCROLL_trackVertical = vertical;
00820 SCROLL_trackHitTest = hittest = SCROLL_HitTest(hwnd,nBar,pt,FALSE);
00821 if (SCROLL_trackHitTest == SCROLL_NOWHERE)
00822 {
00823 MessageBeep(MB_ICONEXCLAMATION);
00824
00825 return res;
00826 }
00827 SCROLL_Scrolling = TRUE;
00828 timerRunning = FALSE;
00829 if ((SCROLL_FocusWin == hwnd) && SCROLL_Highlighted)
00830 {
00831 hdc = GetDCEx(hwnd,0,DCX_CACHE | ((nBar == SB_CTL) ? 0:DCX_WINDOW));
00832 SCROLL_DrawScrollBar(hwnd,hdc,nBar,FALSE,TRUE);
00833 ReleaseDC(hwnd,hdc);
00834 }
00835 lastClickPos = vertical ? pt.y:pt.x;
00836 lastMousePos = lastClickPos;
00837 trackThumbPos = thumbPos;
00838 prevPt = pt;
00839 if (nBar == SB_CTL && (GetWindowLongA(hwnd, GWL_STYLE) & WS_TABSTOP)) SetFocus( hwnd );
00840 SetCapture(hwnd);
00841 break;
00842
00843 case WM_MOUSEMOVE:
00844 if (SCROLL_Scrolling)
00845 {
00846 pt.x = (SHORT)LOWORD(lParam);
00847 pt.y = (SHORT)HIWORD(lParam);
00848 hittest = SCROLL_HitTest(hwnd,nBar,pt,TRUE);
00849 prevPt = pt;
00850 } else return res;
00851 break;
00852
00853 case WM_LBUTTONUP:
00854 if (SCROLL_Scrolling)
00855 {
00856 pt.x = (SHORT)LOWORD(lParam);
00857 pt.y = (SHORT)HIWORD(lParam);
00858 hittest = SCROLL_NOWHERE;
00859 ReleaseCapture();
00860 SCROLL_Scrolling = FALSE;
00861 } else return res;
00862 break;
00863
00864 case WM_CAPTURECHANGED:
00865 if (SCROLL_Scrolling)
00866 {
00867 hittest = SCROLL_NOWHERE;
00868 SCROLL_Scrolling = FALSE;
00869 } else return res;
00870 break;
00871
00872 case WM_SETFOCUS:
00873 if (nBar == SB_CTL)
00874 {
00875 SCROLL_FocusWin = hwnd;
00876 SCROLL_HasFocus = TRUE;
00877 SCROLL_Highlighted = FALSE;
00878 SetSystemTimer(hwnd,BLINK_TIMER,SCROLL_BLINK_DELAY,(TIMERPROC)0);
00879 }
00880 return res;
00881
00882 case WM_KILLFOCUS:
00883 if (SCROLL_FocusWin == hwnd)
00884 {
00885 SCROLL_FocusWin = 0;
00886 SCROLL_HasFocus = FALSE;
00887 if (SCROLL_Highlighted)
00888 {
00889 SCROLL_Highlighted = FALSE;
00890 hdc = GetDCEx(hwnd,0,DCX_CACHE | ((nBar == SB_CTL) ? 0:DCX_WINDOW));
00891 SCROLL_DrawScrollBar(hwnd,hdc,nBar,FALSE,TRUE);
00892 ReleaseDC(hwnd,hdc);
00893 }
00894 KillSystemTimer(hwnd,BLINK_TIMER);
00895 }
00896 return res;
00897
00898 case WM_SYSTIMER:
00899 if (wParam == SCROLL_TIMER)
00900 {
00901 pt = prevPt;
00902 hittest = SCROLL_HitTest( hwnd, nBar, pt, FALSE );
00903 break;
00904 } else if (wParam == BLINK_TIMER)
00905 {
00906 SCROLL_Highlighted = ~SCROLL_Highlighted;
00907 if (!SCROLL_Scrolling)
00908 {
00909 hdc = GetDCEx(hwnd,0,DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW));
00910 SCROLL_DrawScrollBar(hwnd,hdc,nBar,FALSE,TRUE);
00911 ReleaseDC(hwnd,hdc);
00912 }
00913 return res;
00914 } else return res;
00915
00916 default:
00917 return res;
00918 }
00919
00920 hdc = GetDCEx(hwnd,0,DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW));
00921
00922 switch(SCROLL_trackHitTest)
00923 {
00924 case SCROLL_NOWHERE:
00925 break;
00926
00927 case SCROLL_TOP_ARROW:
00928 if ((msg == WM_LBUTTONUP) || (msg == WM_CAPTURECHANGED))
00929 KillSystemTimer(hwnd,SCROLL_TIMER);
00930 else if ((msg == WM_LBUTTONDOWN) || (!timerRunning && msg == WM_SYSTIMER))
00931 {
00932 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
00933 SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
00934 (TIMERPROC)0 );
00935 if (msg != WM_LBUTTONDOWN) timerRunning = TRUE;
00936 }
00937
00938 if ((msg == WM_LBUTTONDOWN) || (SCROLL_lastHitTest != hittest))
00939 {
00940 SCROLL_DrawTopArrow(hdc,infoPtr,&rect,arrowSize,vertical,(hittest == SCROLL_trackHitTest));
00941 SCROLL_lastHitTest = hittest;
00942 }
00943 if ((hittest == SCROLL_trackHitTest) && ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)))
00944 SendMessageA(hwndOwner,vertical ? WM_VSCROLL:WM_HSCROLL,SB_LINEUP,hwndCtl);
00945
00946 break;
00947
00948 case SCROLL_TOP_RECT:
00949 if ((msg == WM_LBUTTONUP) || (msg == WM_CAPTURECHANGED))
00950 KillSystemTimer(hwnd,SCROLL_TIMER);
00951 else if ((msg == WM_LBUTTONDOWN) || (!timerRunning && (msg == WM_SYSTIMER)))
00952 {
00953 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
00954 SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
00955 (TIMERPROC)0 );
00956 if (msg != WM_LBUTTONDOWN) timerRunning = TRUE;
00957 }
00958
00959 if ((msg == WM_LBUTTONDOWN) || (SCROLL_lastHitTest != hittest))
00960 {
00961 SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
00962 thumbPos, infoPtr->flags, vertical,
00963 (hittest == SCROLL_trackHitTest), FALSE );
00964 SCROLL_lastHitTest = hittest;
00965 }
00966
00967 if ((hittest == SCROLL_trackHitTest) && ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)))
00968 SendMessageA(hwndOwner,vertical ? WM_VSCROLL:WM_HSCROLL,SB_PAGEUP,hwndCtl);
00969
00970 break;
00971
00972 case SCROLL_THUMB:
00973 if (msg == WM_LBUTTONDOWN)
00974 {
00975 SCROLL_TrackingWin = hwnd;
00976 SCROLL_TrackingBar = nBar;
00977 SCROLL_TrackingPos = trackThumbPos + lastMousePos - lastClickPos;
00978 SCROLL_TrackingVal = infoPtr->CurVal;
00979 SCROLL_MovingThumb = TRUE;
00980 thumbTrackSent = FALSE;
00981 SCROLL_DrawMovingThumb(hdc, &rect, vertical, arrowSize, thumbSize);
00982 } else if ((msg == WM_LBUTTONUP) || (msg == WM_CAPTURECHANGED))
00983 {
00984 UINT val;
00985 INT oldPos = infoPtr->CurVal;
00986
00987 SCROLL_MovingThumb = FALSE;
00988 SCROLL_TrackingWin = 0;
00989 SCROLL_trackHitTest = SCROLL_NOWHERE;
00990 val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
00991 trackThumbPos + lastMousePos - lastClickPos );
00992
00993 if ((val != infoPtr->CurVal) || thumbTrackSent)
00994 SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
00995 MAKEWPARAM( SB_THUMBPOSITION, val ), hwndCtl );
00996
00997 if (oldPos == infoPtr->CurVal)
00998 {
00999 vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
01000 &arrowSize, &thumbSize, &thumbPos );
01001 SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
01002 thumbPos, infoPtr->flags, vertical,
01003 FALSE, FALSE );
01004 }
01005
01006 ReleaseDC(hwnd,hdc);
01007 return res;
01008 } else if (msg == WM_MOUSEMOVE)
01009 {
01010 UINT pos;
01011
01012 #ifdef __WIN32OS2__
01013 if (!SCROLL_PtInRectEx( &rect, pt, vertical ) && !fOS2Look) pos = lastClickPos;
01014 #else
01015 if (!SCROLL_PtInRectEx( &rect, pt, vertical )) pos = lastClickPos;
01016 #endif
01017 else
01018 {
01019 pt = SCROLL_ClipPos( &rect, pt );
01020 pos = vertical ? pt.y:pt.x;
01021 }
01022 if (pos != lastMousePos)
01023 {
01024 lastMousePos = pos;
01025 SCROLL_TrackingPos = trackThumbPos + pos - lastClickPos;
01026 SCROLL_TrackingVal = SCROLL_GetThumbVal( infoPtr, &rect,
01027 vertical,
01028 SCROLL_TrackingPos );
01029 SCROLL_DrawMovingThumb( hdc, &rect, vertical,
01030 arrowSize, thumbSize );
01031 SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
01032 MAKEWPARAM( SB_THUMBTRACK, SCROLL_TrackingVal),
01033 hwndCtl );
01034 thumbTrackSent = TRUE;
01035 }
01036 }
01037 break;
01038
01039 case SCROLL_BOTTOM_RECT:
01040 if ((msg == WM_LBUTTONUP) || (msg == WM_CAPTURECHANGED))
01041 KillSystemTimer(hwnd,SCROLL_TIMER);
01042 else if ((msg == WM_LBUTTONDOWN) || (!timerRunning && (msg == WM_SYSTIMER)))
01043 {
01044 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
01045 SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
01046 (TIMERPROC)0 );
01047 if (msg != WM_LBUTTONDOWN) timerRunning = TRUE;
01048 }
01049
01050 if ((msg == WM_LBUTTONDOWN) || (SCROLL_lastHitTest != hittest))
01051 {
01052 SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
01053 thumbPos, infoPtr->flags, vertical,
01054 FALSE, (hittest == SCROLL_trackHitTest) );
01055 SCROLL_lastHitTest = hittest;
01056 }
01057
01058 if ((hittest == SCROLL_trackHitTest) && ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)))
01059 SendMessageA(hwndOwner,vertical ? WM_VSCROLL:WM_HSCROLL,SB_PAGEDOWN,hwndCtl);
01060
01061 break;
01062
01063 case SCROLL_BOTTOM_ARROW:
01064 if ((msg == WM_LBUTTONUP) || (msg == WM_CAPTURECHANGED))
01065 KillSystemTimer(hwnd,SCROLL_TIMER);
01066 else if ((msg == WM_LBUTTONDOWN) || (!timerRunning && (msg == WM_SYSTIMER)))
01067 {
01068 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
01069 SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
01070 (TIMERPROC)0 );
01071 if (msg != WM_LBUTTONDOWN) timerRunning = TRUE;
01072 }
01073
01074 if ((msg == WM_LBUTTONDOWN) || (SCROLL_lastHitTest != hittest))
01075 {
01076 SCROLL_DrawBottomArrow(hdc,infoPtr,&rect,arrowSize,vertical,(hittest == SCROLL_trackHitTest));
01077 SCROLL_lastHitTest = hittest;
01078 }
01079 if ((hittest == SCROLL_trackHitTest) && ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER)))
01080 SendMessageA(hwndOwner,vertical ? WM_VSCROLL:WM_HSCROLL,SB_LINEDOWN,hwndCtl);
01081
01082 break;
01083 }
01084
01085 if ((msg == WM_LBUTTONUP) || (msg == WM_CAPTURECHANGED))
01086 {
01087 SCROLL_trackHitTest = SCROLL_NOWHERE;
01088
01089 SendMessageA(hwndOwner,vertical ? WM_VSCROLL:WM_HSCROLL,SB_ENDSCROLL,hwndCtl);
01090 }
01091
01092 ReleaseDC( hwnd, hdc );
01093
01094 return res;
01095 }
01096
01097
01098
01099
01100
01101
01102 LRESULT SCROLL_KeyDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
01103 {
01104 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
01105 UINT msg;
01106
01107 if (dwStyle & (SBS_SIZEBOX | SBS_SIZEGRIP)) return 0;
01108
01109 switch(wParam)
01110 {
01111 case VK_PRIOR: msg = SB_PAGEUP; break;
01112 case VK_NEXT: msg = SB_PAGEDOWN; break;
01113 case VK_HOME: msg = SB_TOP; break;
01114 case VK_END: msg = SB_BOTTOM; break;
01115 case VK_UP: msg = SB_LINEUP; break;
01116 case VK_DOWN: msg = SB_LINEDOWN; break;
01117 default:
01118 return 0;
01119 }
01120 SendMessageA( GetParent(hwnd),
01121 (dwStyle & SBS_VERT) ? WM_VSCROLL : WM_HSCROLL,
01122 msg, hwnd );
01123
01124 return 0;
01125 }
01126
01127 LRESULT SCROLL_Paint(HWND hwnd,WPARAM wParam,LPARAM lParam,INT nBar)
01128 {
01129 PAINTSTRUCT ps;
01130 HDC hdc = wParam ? (HDC)wParam:BeginPaint( hwnd, &ps );
01131
01132 SCROLL_DrawScrollBar( hwnd, hdc, nBar, TRUE, TRUE );
01133 if (!wParam) EndPaint( hwnd, &ps );
01134
01135 return 0;
01136 }
01137
01138 LRESULT SCROLL_SetRange(HWND hwnd,WPARAM wParam,LPARAM lParam,INT nBar,BOOL redraw)
01139 {
01140 SCROLLBAR_INFO *infoPtr = SCROLL_GetInfoPtr(hwnd,nBar);
01141 INT oldPos = infoPtr->CurVal;
01142
01143 SetScrollRange(hwnd,nBar,wParam,lParam,redraw);
01144 return (oldPos != infoPtr->CurVal) ? infoPtr->CurVal:0;
01145 }
01146
01147
01148
01149
01150
01151
01152 LRESULT WINAPI ScrollBarWndProc( HWND hwnd, UINT message, WPARAM wParam,
01153 LPARAM lParam )
01154 {
01155 switch(message)
01156 {
01157 case WM_NCCREATE:
01158 return SCROLL_NCCreate(hwnd,wParam,lParam);
01159
01160 case WM_CREATE:
01161 return SCROLL_Create(hwnd,wParam,lParam);
01162
01163 case WM_DESTROY:
01164 return SCROLL_Destroy(hwnd,wParam,lParam);
01165
01166 case WM_LBUTTONDOWN:
01167 case WM_LBUTTONUP:
01168 case WM_NCHITTEST:
01169 case WM_CAPTURECHANGED:
01170 case WM_MOUSEMOVE:
01171 case WM_SYSTIMER:
01172 case WM_SETFOCUS:
01173 case WM_KILLFOCUS:
01174 return SCROLL_HandleScrollEvent(hwnd,wParam,lParam,SB_CTL,message);
01175
01176 case WM_KEYDOWN:
01177 return SCROLL_KeyDown(hwnd,wParam,lParam);
01178
01179 #ifdef __WIN32OS2__
01180 case WM_ENABLE:
01181 return SCROLL_Enable(hwnd, wParam);
01182
01183 case WM_SYSCOMMAND:
01184
01185
01186
01187 return SendMessageA(GetParent(hwnd), message, wParam, lParam);
01188 #endif
01189
01190 case WM_ERASEBKGND:
01191 return 1;
01192
01193 case WM_GETDLGCODE:
01194 return DLGC_WANTARROWS;
01195
01196 case WM_PAINT:
01197 return SCROLL_Paint(hwnd,wParam,lParam,SB_CTL);
01198
01199 case SBM_SETPOS:
01200 return SetScrollPos( hwnd, SB_CTL, wParam, (BOOL)lParam );
01201
01202 case SBM_GETPOS:
01203 return GetScrollPos( hwnd, SB_CTL );
01204
01205 case SBM_SETRANGE:
01206 return SCROLL_SetRange(hwnd,wParam,lParam,SB_CTL,FALSE);
01207
01208 case SBM_GETRANGE:
01209 GetScrollRange( hwnd, SB_CTL, (LPINT)wParam, (LPINT)lParam );
01210 return 0;
01211
01212 case SBM_ENABLE_ARROWS:
01213 return EnableScrollBar( hwnd, SB_CTL, wParam );
01214
01215 case SBM_SETRANGEREDRAW:
01216 return SCROLL_SetRange(hwnd,wParam,lParam,SB_CTL,TRUE);
01217
01218 case SBM_SETSCROLLINFO:
01219 return SetScrollInfo(hwnd,SB_CTL,(SCROLLINFO*)lParam,wParam);
01220
01221 case SBM_GETSCROLLINFO:
01222 return GetScrollInfo( hwnd, SB_CTL, (SCROLLINFO *)lParam );
01223
01224 case 0x00e5:
01225 case 0x00e7:
01226 case 0x00e8:
01227 case 0x00eb:
01228 case 0x00ec:
01229 case 0x00ed:
01230 case 0x00ee:
01231 case 0x00ef:
01232
01233
01234 break;
01235
01236 default:
01237 return DefWindowProcA( hwnd, message, wParam, lParam );
01238 }
01239
01240 return 0;
01241 }
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259 INT WINAPI SetScrollInfo(HWND hwnd,INT nBar,const SCROLLINFO *info,BOOL bRedraw)
01260 {
01261
01262
01263
01264 SCROLLBAR_INFO *infoPtr;
01265 UINT new_flags;
01266 INT action = 0;
01267 BOOL bChangeParams = FALSE;
01268
01269 dprintf(("USER32: SetScrollInfo %x %d",hwnd,nBar));
01270
01271 if(info == NULL) return 0;
01272
01273 if (!(infoPtr = SCROLL_GetInfoPtr(hwnd,nBar))) return 0;
01274 if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return 0;
01275 if ((info->cbSize != sizeof(*info)) &&
01276 (info->cbSize != sizeof(*info)-sizeof(info->nTrackPos))) return 0;
01277
01278
01279 if (info->fMask & SIF_PAGE)
01280 {
01281 if( infoPtr->Page != info->nPage )
01282 {
01283 infoPtr->Page = info->nPage;
01284 action |= SA_SSI_REPAINT_INTERIOR;
01285 bChangeParams = TRUE;
01286 }
01287 }
01288
01289
01290 if (info->fMask & SIF_POS)
01291 {
01292
01293 if( infoPtr->CurVal != info->nPos )
01294 {
01295 infoPtr->CurVal = info->nPos;
01296 action |= SA_SSI_MOVE_THUMB;
01297 }
01298 }
01299
01300
01301 if (info->fMask & SIF_RANGE)
01302 {
01303
01304 if ((info->nMin > info->nMax) ||
01305 ((UINT)(info->nMax - info->nMin) >= 0x80000000))
01306 {
01307
01308 infoPtr->MinVal = 0;
01309 infoPtr->MaxVal = 0;
01310 bChangeParams = TRUE;
01311 }
01312 else
01313 {
01314 if( infoPtr->MinVal != info->nMin ||
01315 infoPtr->MaxVal != info->nMax )
01316 {
01317 action |= SA_SSI_REPAINT_INTERIOR;
01318 infoPtr->MinVal = info->nMin;
01319 infoPtr->MaxVal = info->nMax;
01320 bChangeParams = TRUE;
01321 }
01322 }
01323 }
01324
01325
01326 if (infoPtr->Page < 0) infoPtr->Page = 0;
01327 else if (infoPtr->Page > infoPtr->MaxVal - infoPtr->MinVal + 1 )
01328 infoPtr->Page = infoPtr->MaxVal - infoPtr->MinVal + 1;
01329
01330
01331
01332 if (infoPtr->CurVal < infoPtr->MinVal)
01333 infoPtr->CurVal = infoPtr->MinVal;
01334 else if (infoPtr->CurVal > infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
01335 infoPtr->CurVal = infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 );
01336
01337
01338 dprintf(("new values: page=%d pos=%d min=%d max=%d\n",
01339 infoPtr->Page, infoPtr->CurVal,
01340 infoPtr->MinVal, infoPtr->MaxVal ));
01341
01342
01343
01344
01345 if(!(info->fMask & SIF_ALL)) goto done;
01346
01347
01348 if (info->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL))
01349 {
01350 new_flags = infoPtr->flags;
01351 if (infoPtr->MinVal >= infoPtr->MaxVal - MAX( infoPtr->Page-1, 0))
01352 {
01353
01354 if (info->fMask & SIF_DISABLENOSCROLL)
01355 {
01356 new_flags = ESB_DISABLE_BOTH;
01357 action |= SA_SSI_REFRESH;
01358 }
01359 else
01360 if (nBar != SB_CTL && bChangeParams)
01361 {
01362 action = SA_SSI_HIDE;
01363 infoPtr->flags = 0;
01364 goto done;
01365 }
01366 }
01367 else
01368 {
01369 new_flags = 0;
01370 if (nBar != SB_CTL && bChangeParams) action |= SA_SSI_SHOW;
01371 if (infoPtr->flags) action |= SA_SSI_REFRESH;
01372 }
01373
01374 if (infoPtr->flags != new_flags)
01375 {
01376 infoPtr->flags = new_flags;
01377 action |= SA_SSI_REPAINT_ARROWS;
01378 }
01379 }
01380
01381 done:
01382
01383
01384 if( action & SA_SSI_HIDE )
01385 ShowScrollBar(hwnd,nBar,FALSE);
01386 else
01387 {
01388 if(action & SA_SSI_SHOW)
01389 ShowScrollBar(hwnd,nBar,TRUE);
01390
01391 if (bRedraw)
01392 {
01393 if (action & SA_SSI_REFRESH)
01394 SCROLL_RefreshScrollBar(hwnd,nBar,TRUE,TRUE);
01395 else
01396 {
01397 if (action & (SA_SSI_REPAINT_INTERIOR | SA_SSI_MOVE_THUMB))
01398 SCROLL_RefreshScrollBar(hwnd,nBar,FALSE,TRUE);
01399 if (action & SA_SSI_REPAINT_ARROWS)
01400 SCROLL_RefreshScrollBar(hwnd,nBar,TRUE,FALSE);
01401 }
01402 }
01403 }
01404
01405
01406
01407 return infoPtr->CurVal;
01408 }
01409
01410
01411
01412
01413
01414
01415
01416 BOOL WINAPI GetScrollInfo(
01417 HWND hwnd ,
01418 INT nBar ,
01419 LPSCROLLINFO info )
01420 {
01421 SCROLLBAR_INFO *infoPtr;
01422
01423 dprintf(("USER32: GetScrollInfo"));
01424
01425 if (!(infoPtr = SCROLL_GetInfoPtr(hwnd,nBar))) return FALSE;
01426 if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return FALSE;
01427 if ((info->cbSize != sizeof(*info)) &&
01428 (info->cbSize != sizeof(*info)-sizeof(info->nTrackPos))) return FALSE;
01429
01430 if (info->fMask & SIF_PAGE) info->nPage = infoPtr->Page;
01431 if (info->fMask & SIF_POS) info->nPos = infoPtr->CurVal;
01432 if ((info->fMask & SIF_TRACKPOS) && (info->cbSize == sizeof(*info)))
01433 info->nTrackPos = (SCROLL_MovingThumb && SCROLL_TrackingWin == hwnd && SCROLL_TrackingBar == nBar) ? SCROLL_TrackingVal:infoPtr->CurVal;
01434
01435 if (info->fMask & SIF_RANGE)
01436 {
01437 info->nMin = infoPtr->MinVal;
01438 info->nMax = infoPtr->MaxVal;
01439 }
01440 return (info->fMask & SIF_ALL) != 0;
01441 }
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453 INT WINAPI SetScrollPos(
01454 HWND hwnd ,
01455 INT nBar ,
01456 INT nPos ,
01457 BOOL bRedraw )
01458 {
01459 SCROLLINFO info;
01460 SCROLLBAR_INFO *infoPtr;
01461 INT oldPos;
01462
01463 dprintf(("SetScrollPos %x %d %d %d", hwnd, nBar, nPos, bRedraw));
01464 if (!(infoPtr = SCROLL_GetInfoPtr(hwnd,nBar))) return 0;
01465 oldPos = infoPtr->CurVal;
01466 info.cbSize = sizeof(info);
01467 info.nPos = nPos;
01468 info.fMask = SIF_POS;
01469 SetScrollInfo( hwnd, nBar, &info, bRedraw );
01470 return oldPos;
01471 }
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483 INT WINAPI GetScrollPos(
01484 HWND hwnd,
01485 INT nBar )
01486 {
01487 SCROLLBAR_INFO *infoPtr;
01488
01489 dprintf(("GetScrollPos %x %d", hwnd, nBar));
01490
01491 infoPtr = SCROLL_GetInfoPtr(hwnd,nBar);
01492 if (!infoPtr) return 0;
01493
01494 return infoPtr->CurVal;
01495 }
01496
01497
01498
01499
01500
01501
01502 BOOL WINAPI SetScrollRange(
01503 HWND hwnd,
01504 INT nBar,
01505 INT MinVal,
01506 INT MaxVal,
01507 BOOL bRedraw )
01508 {
01509 SCROLLINFO info;
01510
01511 dprintf(("SetScrollRange %x %x %d %d %d", hwnd, nBar, MinVal, MaxVal, bRedraw));
01512
01513
01514 if ((MinVal > MaxVal) ||
01515 ((UINT)(MaxVal - MinVal) >= 0x80000000))
01516 {
01517 dprintf(("Invalid range"));
01518 SetLastError(ERROR_INVALID_SCROLLBAR_RANGE);
01519 return FALSE;
01520 }
01521
01522 info.cbSize = sizeof(info);
01523 info.nMin = MinVal;
01524 info.nMax = MaxVal;
01525 info.fMask = SIF_RANGE;
01526
01527 static int nestlevel = 0;
01528
01529
01530
01531 if(++nestlevel == 1)
01532 SetScrollInfo( hwnd, nBar, &info, bRedraw );
01533 nestlevel--;
01534
01535 return TRUE;
01536 }
01537
01538
01539
01540
01541
01542
01543 BOOL WINAPI GetScrollRange(
01544 HWND hwnd,
01545 INT nBar,
01546 LPINT lpMin,
01547 LPINT lpMax )
01548 {
01549 SCROLLBAR_INFO *infoPtr;
01550
01551 dprintf(("GetScrollRange %x %d %x %x", hwnd, nBar, lpMin, lpMax));
01552 infoPtr = SCROLL_GetInfoPtr(hwnd,nBar);
01553 if (!infoPtr)
01554 {
01555 if (lpMin) lpMin = 0;
01556 if (lpMax) lpMax = 0;
01557 return FALSE;
01558 }
01559 if (lpMin) *lpMin = infoPtr->MinVal;
01560 if (lpMax) *lpMax = infoPtr->MaxVal;
01561 return TRUE;
01562 }
01563
01564
01565
01566
01567
01568
01569 BOOL WINAPI ShowScrollBar(
01570 HWND hwnd,
01571 INT nBar,
01572 BOOL fShow )
01573 {
01574 BOOL fShowH = (nBar == SB_HORZ) ? fShow : 0;
01575 BOOL fShowV = (nBar == SB_VERT) ? fShow : 0;
01576 DWORD dwStyle;
01577
01578 dprintf(("ShowScrollBar %04x %d %d\n", hwnd, nBar, fShow));
01579 if (!IsWindow(hwnd)) return FALSE;
01580
01581 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
01582
01583
01584 switch(nBar)
01585 {
01586 case SB_CTL:
01587 ShowWindow(hwnd,fShow ? SW_SHOW:SW_HIDE);
01588 return TRUE;
01589
01590 case SB_BOTH:
01591 case SB_HORZ:
01592 if (fShow)
01593 {
01594 fShowH = !(dwStyle & WS_HSCROLL);
01595 SetWindowLongA(hwnd, GWL_STYLE, dwStyle | WS_HSCROLL);
01596 }
01597 else
01598 {
01599 fShowH = (dwStyle & WS_HSCROLL);
01600 SetWindowLongA(hwnd, GWL_STYLE, dwStyle & ~WS_HSCROLL);
01601 }
01602 if( nBar == SB_HORZ )
01603 {
01604 fShowV = FALSE;
01605 break;
01606 }
01607
01608
01609 case SB_VERT:
01610 if (fShow)
01611 {
01612 fShowV = !(dwStyle & WS_VSCROLL);
01613 SetWindowLongA(hwnd, GWL_STYLE, dwStyle | WS_VSCROLL);
01614 }
01615 else
01616 {
01617 fShowV = (dwStyle & WS_VSCROLL);
01618 SetWindowLongA(hwnd, GWL_STYLE, dwStyle & ~WS_VSCROLL);
01619 }
01620 if ( nBar == SB_VERT )
01621 fShowH = FALSE;
01622 break;
01623
01624 default:
01625 return TRUE;
01626 }
01627
01628 if( fShowH || fShowV )
01629 {
01630 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE
01631 | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
01632 }
01633
01634 return TRUE;
01635 }
01636
01637
01638
01639
01640 BOOL WINAPI EnableScrollBar( HWND hwnd, INT nBar, UINT flags)
01641 {
01642 BOOL bFineWithMe;
01643 SCROLLBAR_INFO *infoPtr;
01644
01645 dprintf(("EnableScrollBar %04x %d %d\n", hwnd, nBar, flags));
01646
01647 flags &= ESB_DISABLE_BOTH;
01648
01649 if (nBar == SB_BOTH)
01650 {
01651 if (!(infoPtr = SCROLL_GetInfoPtr( hwnd, SB_VERT ))) return FALSE;
01652 if (!(bFineWithMe = (infoPtr->flags == flags)) )
01653 {
01654 infoPtr->flags = flags;
01655 SCROLL_RefreshScrollBar( hwnd, SB_VERT, TRUE, TRUE );
01656 }
01657 nBar = SB_HORZ;
01658 }
01659 else
01660 bFineWithMe = TRUE;
01661
01662 if (!(infoPtr = SCROLL_GetInfoPtr( hwnd, nBar ))) return FALSE;
01663 if (bFineWithMe && infoPtr->flags == flags) return FALSE;
01664 infoPtr->flags = flags;
01665
01666 SCROLL_RefreshScrollBar( hwnd, nBar, TRUE, TRUE );
01667 return TRUE;
01668 }
01669
01670 BOOL WINAPI GetScrollBarInfo(HWND hwnd,LONG idObject,PSCROLLBARINFO psbi)
01671 {
01672 if (!psbi || (psbi->cbSize != sizeof(SCROLLBARINFO)))
01673 {
01674 SetLastError(ERROR_INVALID_PARAMETER);
01675
01676 return FALSE;
01677 }
01678
01679 dprintf(("GetScrollBarInfo %x %d %x", hwnd, idObject, psbi));
01680
01681 INT nBar,arrowSize;
01682
01683 switch (idObject)
01684 {
01685 case OBJID_CLIENT:
01686 nBar = SB_CTL;
01687 break;
01688
01689 case OBJID_HSCROLL:
01690 nBar = SB_HORZ;
01691 break;
01692
01693 case OBJID_VSCROLL:
01694 nBar = SB_VERT;
01695 break;
01696
01697 default:
01698 return FALSE;
01699 }
01700
01701 SCROLL_GetScrollBarRect(hwnd,nBar,&psbi->rcScrollBar,&arrowSize,&psbi->dxyLineButton,&psbi->xyThumbTop);
01702 psbi->xyThumbBottom = psbi->xyThumbTop+psbi->dxyLineButton;
01703 psbi->bogus = 0;
01704 psbi->rgstate[0] = IsWindowVisible(hwnd) ? STATE_SYSTEM_INVISIBLE:0;
01705 psbi->rgstate[1] = psbi->rgstate[2] = psbi->rgstate[3] = psbi->rgstate[4] = psbi->rgstate[5] = psbi->rgstate[0];
01706
01707 return TRUE;
01708 }
01709
01710
01711 BOOL SCROLLBAR_Register()
01712 {
01713 WNDCLASSA wndClass;
01714
01715
01716
01717
01718 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
01719 wndClass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW | CS_PARENTDC;
01720 wndClass.lpfnWndProc = (WNDPROC)ScrollBarWndProc;
01721 wndClass.cbClsExtra = 0;
01722 wndClass.cbWndExtra = sizeof(SCROLLBAR_INFO);
01723 wndClass.hCursor = LoadCursorA(0,IDC_ARROWA);
01724 wndClass.hbrBackground = (HBRUSH)0;
01725 wndClass.lpszClassName = SCROLLBARCLASSNAME;
01726
01727 return RegisterClassA(&wndClass);
01728 }
01729
01730
01731 BOOL SCROLLBAR_Unregister()
01732 {
01733 if (GlobalFindAtomA(SCROLLBARCLASSNAME))
01734 return UnregisterClassA(SCROLLBARCLASSNAME,(HINSTANCE)NULL);
01735 else return FALSE;
01736 }
01737
01738
01739