coolsblib.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. /*
  2. Cool Scrollbar Library Version 1.2
  3. Module: coolsblib.c
  4. Copyright (c) J Brown 2001
  5. This code is freeware, however, you may not publish
  6. this code elsewhere or charge any money for it. This code
  7. is supplied as-is. I make no guarantees about the suitability
  8. of this code - use at your own risk.
  9. It would be nice if you credited me, in the event
  10. that you use this code in a product.
  11. VERSION HISTORY:
  12. V1.2: TreeView problem fixed by Diego Tartara
  13. Small problem in thumbsize calculation also fixed (thanks Diego!)
  14. V1.1: Added support for Right-left windows
  15. Changed calling convention of APIs to WINAPI (__stdcall)
  16. Completely standalone (no need for c-runtime)
  17. V1.0: Apr 2001: Initial Version CoolSB_SetStyle
  18. */
  19. #include "stdafx.h"
  20. #include <windows.h>
  21. #include <commctrl.h>
  22. #include <tchar.h>
  23. #include "coolscroll.h"
  24. #include "userdefs.h"
  25. #include "coolsb_internal.h"
  26. static TCHAR szPropStr[] = _T("CoolSBSubclassPtr");
  27. LRESULT CALLBACK CoolSBWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  28. SCROLLWND *GetScrollWndFromHwnd(HWND hwnd)
  29. {
  30. return (SCROLLWND *)GetProp(hwnd, szPropStr);
  31. }
  32. SCROLLBAR *GetScrollBarFromHwnd(HWND hwnd, UINT nBar)
  33. {
  34. SCROLLWND *sw = GetScrollWndFromHwnd(hwnd);
  35. if(!sw) return 0;
  36. if(nBar == SB_HORZ)
  37. return &sw->sbarHorz;
  38. else if(nBar == SB_VERT)
  39. return &sw->sbarVert;
  40. else
  41. return 0;
  42. }
  43. BOOL WINAPI CoolSB_IsCoolScrollEnabled(HWND hwnd)
  44. {
  45. if(GetScrollWndFromHwnd(hwnd))
  46. return TRUE;
  47. else
  48. return FALSE;
  49. }
  50. BOOL GetScrollRect(SCROLLWND *sw, UINT nBar, HWND hwnd, RECT *rect);
  51. //
  52. // Special support for USER32.DLL patching (using Detours library)
  53. // The only place we call a real scrollbar API is in InitializeCoolSB,
  54. // where we call EnableScrollbar.
  55. //
  56. // We HAVE to call the origial EnableScrollbar function,
  57. // so we need to be able to set a pointer to this func when using
  58. // using Detours (or any other LIB??)
  59. //
  60. static BOOL (WINAPI * pEnableScrollBar) (HWND, UINT, UINT) = 0;
  61. void WINAPI CoolSB_SetESBProc(void *proc)
  62. {
  63. // pEnableScrollBar = proc;
  64. }
  65. //
  66. //
  67. static void RedrawNonClient(HWND hwnd, BOOL fFrameChanged)
  68. {
  69. if(fFrameChanged == FALSE)
  70. {
  71. /*
  72. RECT rect;
  73. HRGN hrgn1, hrgn2;
  74. SCROLLWND *sw = GetScrollWndFromHwnd(hwnd);
  75. GetScrollRect(sw, SB_HORZ, hwnd, &rect);
  76. hrgn1 = CreateRectRgnIndirect(&rect);
  77. GetScrollRect(sw, SB_VERT, hwnd, &rect);
  78. hrgn2 = CreateRectRgnIndirect(&rect);
  79. CombineRgn(hrgn1, hrgn2, hrgn1, RGN_OR);
  80. SendMessage(hwnd, WM_NCPAINT, (WPARAM)hrgn1, 0);
  81. DeleteObject(hrgn1);
  82. DeleteObject(hrgn2);*/
  83. SendMessage(hwnd, WM_NCPAINT, (WPARAM)1, 0);
  84. }
  85. else
  86. {
  87. SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE
  88. | SWP_FRAMECHANGED | SWP_DRAWFRAME);
  89. }
  90. }
  91. //
  92. // return the default minimum size of a scrollbar thumb
  93. //
  94. int WINAPI CoolSB_GetDefaultMinThumbSize(void)
  95. {
  96. DWORD dwVersion = GetVersion();
  97. // set the minimum thumb size for a scrollbar. This
  98. // differs between NT4 and 2000, so need to check to see
  99. // which platform we are running under
  100. if(dwVersion < 0x80000000) // Windows NT/2000
  101. {
  102. if(LOBYTE(LOWORD(dwVersion)) >= 5)
  103. return MINTHUMBSIZE_2000;
  104. else
  105. return MINTHUMBSIZE_NT4;
  106. }
  107. else
  108. {
  109. return MINTHUMBSIZE_NT4;
  110. }
  111. }
  112. static SCROLLINFO *GetScrollInfoFromHwnd(HWND hwnd, int fnBar)
  113. {
  114. SCROLLBAR *sb = GetScrollBarFromHwnd(hwnd, fnBar);
  115. if(sb == 0)
  116. return FALSE;
  117. if(fnBar == SB_HORZ)
  118. {
  119. return &sb->scrollInfo;
  120. }
  121. else if(fnBar == SB_VERT)
  122. {
  123. return &sb->scrollInfo;
  124. }
  125. else
  126. return NULL;
  127. }
  128. //
  129. // Initialize the cool scrollbars for a window by subclassing it
  130. // and using the coolsb window procedure instead
  131. //
  132. BOOL WINAPI InitializeCoolSB(HWND hwnd)
  133. {
  134. SCROLLWND *sw;
  135. SCROLLINFO *si;
  136. RECT rect;
  137. DWORD dwCurStyle;
  138. if(pEnableScrollBar == 0)
  139. pEnableScrollBar = EnableScrollBar;
  140. GetClientRect(hwnd, &rect);
  141. //if we have already initialized Cool Scrollbars for this window,
  142. //then stop the user from doing it again
  143. if(GetScrollWndFromHwnd(hwnd) != 0)
  144. {
  145. return FALSE;
  146. }
  147. //allocate a private scrollbar structure which we
  148. //will use to keep track of the scrollbar data
  149. sw = (SCROLLWND *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SCROLLWND));
  150. si = &sw->sbarHorz.scrollInfo;
  151. si->cbSize = sizeof(SCROLLINFO);
  152. si->fMask = SIF_ALL;
  153. GetScrollInfo(hwnd, SB_HORZ, si);
  154. si = &sw->sbarVert.scrollInfo;
  155. si->cbSize = sizeof(SCROLLINFO);
  156. si->fMask = SIF_ALL;
  157. GetScrollInfo(hwnd, SB_VERT, si);
  158. //check to see if the window has left-aligned scrollbars
  159. if(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LEFTSCROLLBAR)
  160. sw->fLeftScrollbar = TRUE;
  161. else
  162. sw->fLeftScrollbar = FALSE;
  163. dwCurStyle = GetWindowLong(hwnd, GWL_STYLE);
  164. SetProp(hwnd, szPropStr, (HANDLE)sw);
  165. //try to enable the scrollbar arrows - if the return value is
  166. //non-zero, then the scrollbars were previously disabled
  167. //fDisabled = pEnableScrollBar(hwnd, SB_HORZ, ESB_ENABLE_BOTH);
  168. //scrollbars will automatically get enabled, even if
  169. //they aren't to start with....sorry, but there isn't an
  170. //easy alternative.
  171. if(dwCurStyle & WS_HSCROLL)
  172. sw->sbarHorz.fScrollFlags = CSBS_VISIBLE;
  173. if(dwCurStyle & WS_VSCROLL)
  174. sw->sbarVert.fScrollFlags = CSBS_VISIBLE;
  175. //need to be able to distinguish between horizontal and vertical
  176. //scrollbars in some instances
  177. sw->sbarHorz.nBarType = SB_HORZ;
  178. sw->sbarVert.nBarType = SB_VERT;
  179. sw->sbarHorz.fFlatScrollbar = CSBS_NORMAL;
  180. sw->sbarVert.fFlatScrollbar = CSBS_NORMAL;
  181. //set the default arrow sizes for the scrollbars
  182. sw->sbarHorz.nArrowLength = SYSTEM_METRIC;
  183. sw->sbarHorz.nArrowWidth = SYSTEM_METRIC;
  184. sw->sbarVert.nArrowLength = SYSTEM_METRIC;
  185. sw->sbarVert.nArrowWidth = SYSTEM_METRIC;
  186. sw->bPreventStyleChange = FALSE;
  187. sw->oldproc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)CoolSBWndProc);
  188. CoolSB_SetMinThumbSize(hwnd, SB_BOTH, CoolSB_GetDefaultMinThumbSize());
  189. //send the window a frame changed message to update the scrollbars
  190. RedrawNonClient(hwnd, TRUE);
  191. return TRUE;
  192. }
  193. BOOL WINAPI CoolSB_EnableScrollBar (HWND hwnd, int wSBflags, UINT wArrows)
  194. {
  195. SCROLLBAR *sbar;
  196. UINT oldstate;
  197. BOOL bFailed = FALSE;
  198. if(!CoolSB_IsCoolScrollEnabled(hwnd))
  199. return EnableScrollBar(hwnd, wSBflags, wArrows);
  200. if((wSBflags == SB_HORZ || wSBflags == SB_BOTH) &&
  201. (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
  202. {
  203. oldstate = sbar->fScrollFlags;
  204. //clear any existing state, and OR in the disabled flags
  205. sbar->fScrollFlags = (sbar->fScrollFlags & ~ESB_DISABLE_BOTH) | wArrows;
  206. if(oldstate == sbar->fScrollFlags)
  207. bFailed = TRUE;
  208. }
  209. if((wSBflags == SB_VERT || wSBflags == SB_BOTH) &&
  210. (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
  211. {
  212. oldstate = sbar->fScrollFlags;
  213. //clear any existing state, and OR in the disabled flags
  214. sbar->fScrollFlags = (sbar->fScrollFlags & ~ESB_DISABLE_BOTH) | wArrows;
  215. if(oldstate == sbar->fScrollFlags)
  216. bFailed = TRUE;
  217. }
  218. return !bFailed;
  219. }
  220. BOOL WINAPI CoolSB_GetScrollBarInfo(HWND hwnd)
  221. {
  222. // SCROLLBARINFO sbi; not defined in winuser.h
  223. return FALSE;
  224. }
  225. BOOL WINAPI CoolSB_GetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi)
  226. {
  227. SCROLLINFO *mysi;
  228. BOOL copied = FALSE;
  229. if(!lpsi)
  230. return FALSE;
  231. if(!(mysi = GetScrollInfoFromHwnd(hwnd, fnBar)))
  232. {
  233. return GetScrollInfo(hwnd, fnBar, lpsi);
  234. }
  235. if(lpsi->fMask & SIF_PAGE)
  236. {
  237. lpsi->nPage = mysi->nPage;
  238. copied = TRUE;
  239. }
  240. if(lpsi->fMask & SIF_POS)
  241. {
  242. lpsi->nPos = mysi->nPos;
  243. copied = TRUE;
  244. }
  245. if(lpsi->fMask & SIF_TRACKPOS)
  246. {
  247. lpsi->nTrackPos = mysi->nTrackPos;
  248. copied = TRUE;
  249. }
  250. if(lpsi->fMask & SIF_RANGE)
  251. {
  252. lpsi->nMin = mysi->nMin;
  253. lpsi->nMax = mysi->nMax;
  254. copied = TRUE;
  255. }
  256. return copied;
  257. }
  258. int WINAPI CoolSB_GetScrollPos (HWND hwnd, int nBar)
  259. {
  260. SCROLLINFO *mysi;
  261. if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar)))
  262. return GetScrollPos(hwnd, nBar);
  263. return mysi->nPos;
  264. }
  265. BOOL WINAPI CoolSB_GetScrollRange (HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos)
  266. {
  267. SCROLLINFO *mysi;
  268. if(!lpMinPos || !lpMaxPos)
  269. return FALSE;
  270. if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar)))
  271. return GetScrollRange(hwnd, nBar, lpMinPos, lpMaxPos);
  272. *lpMinPos = mysi->nMin;
  273. *lpMaxPos = mysi->nMax;
  274. return TRUE;
  275. }
  276. int WINAPI CoolSB_SetScrollInfo (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw)
  277. {
  278. SCROLLINFO *mysi;
  279. SCROLLBAR *sbar;
  280. BOOL fRecalcFrame = FALSE;
  281. if(!lpsi)
  282. return FALSE;
  283. if(!(mysi = GetScrollInfoFromHwnd(hwnd, fnBar)))
  284. return SetScrollInfo(hwnd, fnBar, lpsi, fRedraw);
  285. //if(CoolSB_IsThumbTracking(hwnd))
  286. // return mysi->nPos;
  287. if(lpsi->fMask & SIF_RANGE)
  288. {
  289. mysi->nMin = lpsi->nMin;
  290. mysi->nMax = lpsi->nMax;
  291. }
  292. //The nPage member must specify a value from 0 to nMax - nMin +1.
  293. if(lpsi->fMask & SIF_PAGE)
  294. {
  295. UINT t = (UINT)(mysi->nMax - mysi->nMin + 1);
  296. mysi->nPage = min(max(0, lpsi->nPage), t);
  297. }
  298. //The nPos member must specify a value between nMin and nMax - max(nPage - 1, 0).
  299. if(lpsi->fMask & SIF_POS)
  300. {
  301. mysi->nPos = max(lpsi->nPos, mysi->nMin);
  302. mysi->nPos = min((UINT)mysi->nPos, mysi->nMax - max(mysi->nPage - 1, 0));
  303. }
  304. sbar = GetScrollBarFromHwnd(hwnd, fnBar);
  305. if((lpsi->fMask & SIF_DISABLENOSCROLL) || (sbar->fScrollFlags & CSBS_THUMBALWAYS))
  306. {
  307. if(!sbar->fScrollVisible)
  308. {
  309. CoolSB_ShowScrollBar(hwnd, fnBar, TRUE);
  310. fRecalcFrame = TRUE;
  311. }
  312. }
  313. else
  314. {
  315. if( mysi->nPage > (UINT)mysi->nMax
  316. || mysi->nPage == (UINT)mysi->nMax && mysi->nMax == 0
  317. || mysi->nMax <= mysi->nMin)
  318. {
  319. if(sbar->fScrollVisible)
  320. {
  321. CoolSB_ShowScrollBar(hwnd, fnBar, FALSE);
  322. fRecalcFrame = TRUE;
  323. }
  324. }
  325. else
  326. {
  327. if(!sbar->fScrollVisible)
  328. {
  329. CoolSB_ShowScrollBar(hwnd, fnBar, TRUE);
  330. fRecalcFrame = TRUE;
  331. }
  332. }
  333. }
  334. if(fRedraw && !CoolSB_IsThumbTracking(hwnd))
  335. RedrawNonClient(hwnd, fRecalcFrame);
  336. return mysi->nPos;
  337. }
  338. int WINAPI CoolSB_SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw)
  339. {
  340. SCROLLINFO *mysi;
  341. int oldpos;
  342. if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar)))
  343. {
  344. return SetScrollPos(hwnd, nBar, nPos, fRedraw);
  345. }
  346. //this is what should happen, but real scrollbars don't work like this..
  347. //if(CoolSB_IsThumbTracking(hwnd))
  348. // return mysi->nPos;
  349. //validate and set the scollbar position
  350. oldpos = mysi->nPos;
  351. mysi->nPos = max(nPos, mysi->nMin);
  352. mysi->nPos = min((UINT)mysi->nPos, mysi->nMax - max(mysi->nPage - 1, 0));
  353. if(fRedraw && !CoolSB_IsThumbTracking(hwnd))
  354. RedrawNonClient(hwnd, FALSE);
  355. return oldpos;
  356. }
  357. int WINAPI CoolSB_SetScrollRange (HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw)
  358. {
  359. SCROLLINFO *mysi;
  360. if(!(mysi = GetScrollInfoFromHwnd(hwnd, nBar)))
  361. return SetScrollRange(hwnd, nBar, nMinPos, nMaxPos, fRedraw);
  362. if(CoolSB_IsThumbTracking(hwnd))
  363. return mysi->nPos;
  364. //hide the scrollbar if nMin == nMax
  365. //nMax-nMin must not be greater than MAXLONG
  366. mysi->nMin = nMinPos;
  367. mysi->nMax = nMaxPos;
  368. if(fRedraw)
  369. RedrawNonClient(hwnd, FALSE);
  370. return TRUE;
  371. }
  372. //
  373. // Show or hide the specified scrollbars
  374. //
  375. BOOL WINAPI CoolSB_ShowScrollBar (HWND hwnd, int wBar, BOOL fShow)
  376. {
  377. SCROLLBAR *sbar;
  378. BOOL bFailed = FALSE;
  379. DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE);
  380. if(!CoolSB_IsCoolScrollEnabled(hwnd))
  381. return ShowScrollBar(hwnd, wBar, fShow);
  382. if((wBar == SB_HORZ || wBar == SB_BOTH) &&
  383. (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
  384. {
  385. sbar->fScrollFlags = sbar->fScrollFlags & ~CSBS_VISIBLE;
  386. sbar->fScrollFlags |= (fShow == TRUE ? CSBS_VISIBLE : 0);
  387. //bFailed = TRUE;
  388. if(fShow) SetWindowLong(hwnd, GWL_STYLE, dwStyle | WS_HSCROLL);
  389. else SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_HSCROLL);
  390. }
  391. if((wBar == SB_VERT || wBar == SB_BOTH) &&
  392. (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
  393. {
  394. sbar->fScrollFlags = sbar->fScrollFlags & ~CSBS_VISIBLE;
  395. sbar->fScrollFlags |= (fShow == TRUE ? CSBS_VISIBLE : 0);
  396. //bFailed = TRUE;
  397. if(fShow) SetWindowLong(hwnd, GWL_STYLE, dwStyle | WS_VSCROLL);
  398. else SetWindowLong(hwnd, GWL_STYLE, dwStyle & ~WS_VSCROLL);
  399. }
  400. if(bFailed)
  401. {
  402. return FALSE;
  403. }
  404. else
  405. {
  406. //DWORD style = GetWindowLong(hwnd, GWL_STYLE);
  407. //style |= WS_VSCROLL;
  408. //if(s
  409. //SetWindowLong(hwnd, GWL_STYLE, style);
  410. SetWindowPos(hwnd, 0, 0, 0, 0, 0,
  411. SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
  412. SWP_NOACTIVATE | SWP_FRAMECHANGED);
  413. return TRUE;
  414. }
  415. }
  416. //
  417. // Remove cool scrollbars from the specified window.
  418. //
  419. HRESULT WINAPI UninitializeCoolSB(HWND hwnd)
  420. {
  421. int i = 0;
  422. SCROLLWND *sw = GetScrollWndFromHwnd(hwnd);
  423. if(!sw) return E_FAIL;
  424. //restore the window procedure with the original one
  425. SetWindowLong(hwnd, GWL_WNDPROC, (LONG)sw->oldproc);
  426. RemoveProp(hwnd, szPropStr);
  427. //SetWindowLong(hwnd, GWL_USERDATA, 0);
  428. //finally, release the memory needed for the cool scrollbars
  429. HeapFree(GetProcessHeap(), 0, sw);
  430. //Force WM_NCCALCSIZE and WM_NCPAINT so the original scrollbars can kick in
  431. RedrawNonClient(hwnd, TRUE);
  432. return S_OK;
  433. }
  434. //
  435. // Set the size of the scrollbars
  436. //
  437. BOOL WINAPI CoolSB_SetSize (HWND hwnd, int wBar, int nLength, int nWidth)
  438. {
  439. SCROLLBAR *sbar;
  440. if(nLength == 0 || nWidth == 0)
  441. return FALSE;
  442. if(nLength < -8 || nWidth < -8)
  443. return FALSE;
  444. if(nLength > 256 || nWidth > 256)
  445. return FALSE;
  446. if(!GetScrollWndFromHwnd(hwnd))
  447. return FALSE;
  448. if((wBar == SB_HORZ || wBar == SB_BOTH) &&
  449. (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
  450. {
  451. sbar->nArrowLength = nLength;
  452. sbar->nArrowWidth = nWidth;
  453. }
  454. if((wBar == SB_VERT || wBar == SB_BOTH) &&
  455. (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
  456. {
  457. sbar->nArrowLength = nLength;
  458. sbar->nArrowWidth = nWidth;
  459. }
  460. RedrawNonClient(hwnd, TRUE);
  461. return TRUE;
  462. }
  463. //
  464. // Alter the display mode of the scrollbars
  465. // wBar - SB_HORZ / SB_VERT / SB_BOTH
  466. // nStyle - CSBF_NORMAL / CSBF_FLAT / CSBF_HOTTRACKED
  467. //
  468. BOOL WINAPI CoolSB_SetStyle(HWND hwnd, int wBar, UINT nStyle)
  469. {
  470. SCROLLBAR *sbar;
  471. if(!GetScrollWndFromHwnd(hwnd))
  472. return FALSE;
  473. if((wBar == SB_HORZ || wBar == SB_BOTH) &&
  474. (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
  475. {
  476. sbar->fFlatScrollbar = nStyle;
  477. }
  478. if((wBar == SB_VERT || wBar == SB_BOTH) &&
  479. (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
  480. {
  481. sbar->fFlatScrollbar = nStyle;
  482. }
  483. RedrawNonClient(hwnd, FALSE);
  484. return TRUE;
  485. }
  486. //
  487. // Set if the thumb is always visible, even if there is no data to
  488. // scroll. Setting this keeps the scrollbar enabled, but the thumb
  489. // covers the whole area
  490. //
  491. BOOL WINAPI CoolSB_SetThumbAlways(HWND hwnd, int wBar, BOOL fThumbAlways)
  492. {
  493. SCROLLBAR *sbar;
  494. if(!GetScrollWndFromHwnd(hwnd))
  495. return FALSE;
  496. if((wBar == SB_HORZ || wBar == SB_BOTH) &&
  497. (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
  498. {
  499. if(fThumbAlways)
  500. sbar->fScrollFlags |= CSBS_THUMBALWAYS;
  501. else
  502. sbar->fScrollFlags &= ~CSBS_THUMBALWAYS;
  503. }
  504. if((wBar == SB_VERT || wBar == SB_BOTH) &&
  505. (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
  506. {
  507. if(fThumbAlways)
  508. sbar->fScrollFlags |= CSBS_THUMBALWAYS;
  509. else
  510. sbar->fScrollFlags &= ~CSBS_THUMBALWAYS;
  511. }
  512. RedrawNonClient(hwnd, FALSE);
  513. return TRUE;
  514. }
  515. //
  516. // Set the minimum size, in pixels, that the thumb box will shrink to.
  517. //
  518. BOOL WINAPI CoolSB_SetMinThumbSize(HWND hwnd, UINT wBar, UINT size)
  519. {
  520. SCROLLBAR *sbar;
  521. if(!GetScrollWndFromHwnd(hwnd))
  522. return FALSE;
  523. if(size == -1)
  524. size = CoolSB_GetDefaultMinThumbSize();
  525. if((wBar == SB_HORZ || wBar == SB_BOTH) &&
  526. (sbar = GetScrollBarFromHwnd(hwnd, SB_HORZ)))
  527. {
  528. sbar->nMinThumbSize = size;
  529. }
  530. if((wBar == SB_VERT || wBar == SB_BOTH) &&
  531. (sbar = GetScrollBarFromHwnd(hwnd, SB_VERT)))
  532. {
  533. sbar->nMinThumbSize = size;
  534. }
  535. return TRUE;
  536. }