SkinUI_ScrollBar.cpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807
  1. //////////////////////////////////////////////////////////////////////////////////
  2. #include "internal.h"
  3. #include "SkinUI_ScrollBar.h"
  4. #include <Shlwapi.h>
  5. #define WIN32_LEAN_AND_MEAN
  6. static TCHAR g_szPropSB[] = TEXT("PROP_SkinUI");
  7. //在这里规定滚动条的图片资源大小为110*110,并且按照以下的规格就行图片的划分
  8. static POINT ptArray[6][6] =
  9. {
  10. { {0, 0}, {19, 0}, {38, 0}, {57, 0}, {76, 0}, {95, 0} },
  11. { {0, 19}, {19, 19}, {38, 19}, {57, 19}, {76, 19}, {95, 19} },
  12. { {0, 38}, {19, 38}, {38, 38}, {57, 38}, {76, 38}, {95, 38} },
  13. { {0, 57}, {19, 57}, {38, 57}, {57, 57}, {76, 57}, {95, 57} },
  14. { {0, 76}, {19, 76}, {38, 76}, {57, 76}, {76, 76}, {95, 76} },
  15. { {0, 95}, {19, 95}, {38, 95}, {57, 95}, {76, 95}, {95, 95} }
  16. };
  17. // Public interfaces
  18. //----------------------------------------------------------
  19. // Name : SkinUI_Init()
  20. // Desc : Initialize the skin scrollbar library
  21. //----------------------------------------------------------
  22. BOOL WINAPI SkinUI_Init(HWND hwnd, HBITMAP hBmp)
  23. {
  24. LPSB psb;
  25. DWORD dwStyle;
  26. if( !IsWindow(hwnd) ) {
  27. SetLastError(ERROR_INVALID_HANDLE);
  28. return FALSE;
  29. }
  30. if( SkinUI_IsValid(hwnd) )
  31. return FALSE;
  32. // Allocates memory
  33. psb = (LPSB)LocalAlloc(LPTR, sizeof(SB));
  34. if( psb == NULL )
  35. return FALSE;
  36. ZeroMemory(psb, sizeof(SB));
  37. dwStyle = GetWindowLong(hwnd, GWL_STYLE);
  38. psb->Horz.cbSize = psb->Vert.cbSize = sizeof(SCROLLINFO);
  39. psb->Horz.fMask = psb->Vert.fMask = SIF_ALL;
  40. if( dwStyle & WS_HSCROLL )
  41. GetScrollInfo(hwnd, SB_HORZ, &psb->Horz);
  42. if( dwStyle & WS_VSCROLL )
  43. GetScrollInfo(hwnd, SB_VERT, &psb->Vert);
  44. // Is left scrollbar style
  45. if( GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LEFTSCROLLBAR )
  46. psb->fLeftScrollBar = TRUE;
  47. if( !hBmp ) {
  48. SetLastError(ERROR_INVALID_HANDLE);
  49. return FALSE;
  50. }
  51. psb->hBmp = hBmp;
  52. // Reaplace the window procedure
  53. psb->hwnd = hwnd;
  54. psb->pfnOldProc = (WNDPROC)(LONG_PTR)SetWindowLong(hwnd,
  55. GWL_WNDPROC, (LONG)(LONG_PTR)SkinUI_Proc);
  56. psb->fPreventStyleChange = FALSE;
  57. psb->fTracking = FALSE;
  58. // Whether richedit control
  59. TCHAR szClassName[255] = { 0 };
  60. GetClassName(hwnd, szClassName, sizeof(szClassName));
  61. if( StrCmpI(szClassName, TEXT("RichEdit20A")) == 0 ||
  62. StrCmpI(szClassName, TEXT("RichEdit20W")) == 0 ) {
  63. psb->fRichEdit = TRUE;
  64. }
  65. // Set the window property
  66. if( !SetProp(hwnd, g_szPropSB, (HANDLE)psb) )
  67. return FALSE;
  68. // Redraw the window noclient
  69. SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOZORDER |
  70. SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_DRAWFRAME);
  71. return TRUE;
  72. }
  73. //---------------------------------------------------------
  74. // Name : SkinUI_Uninit()
  75. // Desc : Finalize the skin scrollbar library
  76. //---------------------------------------------------------
  77. BOOL WINAPI SkinUI_Uninit(HWND hwnd)
  78. {
  79. LPSB psb;
  80. SCROLLINFO vsi;
  81. SCROLLINFO hsi;
  82. BOOL vValid, hValid;
  83. UINT vFlags, hFlags;
  84. if( (psb = SkinUI_GetSB(hwnd)) == NULL )
  85. return FALSE;
  86. vsi.cbSize = hsi.cbSize = sizeof(SCROLLINFO);
  87. vsi.fMask = hsi.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
  88. vValid = SkinUI_GetScrollInfo(hwnd, SB_VERT, &vsi);
  89. vFlags = SkinUI_GetDisableFlags(psb, TRUE);
  90. hValid = SkinUI_GetScrollInfo(hwnd, SB_HORZ, &hsi);
  91. hFlags = SkinUI_GetDisableFlags(psb, FALSE);
  92. // Remove the subclass procedure
  93. SetWindowLong(hwnd, GWL_WNDPROC, (LONG)(LONG_PTR)psb->pfnOldProc);
  94. RemoveProp(hwnd, g_szPropSB);
  95. LocalFree((HLOCAL)psb);
  96. // Restore system scroll parameters
  97. if( vValid ) {
  98. SetScrollInfo(hwnd, SB_VERT, &vsi, TRUE);
  99. EnableScrollBar(hwnd, SB_VERT, vFlags);
  100. }
  101. if( hValid ) {
  102. SetScrollInfo(hwnd, SB_HORZ, &hsi, TRUE);
  103. EnableScrollBar(hwnd, SB_HORZ, hFlags);
  104. }
  105. return TRUE;
  106. }
  107. //---------------------------------------------------------
  108. // Name : SkinUI_IsValid()
  109. // Desc : Is initialized ??
  110. //---------------------------------------------------------
  111. BOOL WINAPI SkinUI_IsValid(HWND hwnd)
  112. {
  113. return (SkinUI_GetSB(hwnd) != NULL);
  114. }
  115. //---------------------------------------------------------
  116. // Name : SkinUI_GetScrollInfo()
  117. // Desc : Overload API GetScrollInfo()
  118. //---------------------------------------------------------
  119. BOOL WINAPI SkinUI_GetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi)
  120. {
  121. LPSB psb;
  122. LPSCROLLINFO psi;
  123. BOOL fCopied = FALSE;
  124. if( !lpsi || lpsi->cbSize != sizeof(SCROLLINFO) )
  125. return FALSE;
  126. // Is initialized ?
  127. if( (psb = SkinUI_GetSB(hwnd)) == NULL )
  128. return FALSE;
  129. // If be scrollbar control then call failed
  130. if( fnBar == SB_HORZ )
  131. psi = &psb->Horz;
  132. else if( fnBar == SB_VERT )
  133. psi = &psb->Vert;
  134. else if( fnBar == SB_CTL )
  135. return FALSE;
  136. if( lpsi->fMask & SIF_PAGE ) {
  137. lpsi->nPage = psi->nPage;
  138. fCopied = TRUE;
  139. }
  140. if( lpsi->fMask & SIF_POS ) {
  141. lpsi->nPos = psi->nPos;
  142. fCopied = TRUE;
  143. }
  144. if( lpsi->fMask & SIF_TRACKPOS ) {
  145. lpsi->nTrackPos = psi->nTrackPos;
  146. fCopied = TRUE;
  147. }
  148. if( lpsi->fMask & SIF_RANGE ) {
  149. lpsi->nMin = psi->nMin;
  150. lpsi->nMax = psi->nMax;
  151. fCopied = TRUE;
  152. }
  153. return fCopied;
  154. }
  155. //---------------------------------------------------------
  156. // Name : SkinUI_SetScrollInfo()
  157. // Desc : Overload API SetScrollInfo()
  158. //---------------------------------------------------------
  159. int WINAPI SkinUI_SetScrollInfo(HWND hwnd, int fnBar, LPCSCROLLINFO psi, BOOL fRedraw)
  160. {
  161. LPSB psb;
  162. LPSCROLLINFO mysi;
  163. int nRet;
  164. DWORD dwStyle;
  165. BOOL fVert;
  166. UINT wScroll;
  167. BOOL fScroll;
  168. BOOL fOldScroll;
  169. BOOL bReturnOldPos;
  170. // if be scrollbar control the call failed
  171. if( fnBar == SB_CTL )
  172. return 0;
  173. if( (psb = SkinUI_GetSB(hwnd)) == NULL )
  174. return 0;
  175. if( fRedraw )
  176. fRedraw = IsWindowVisible(hwnd);
  177. fVert = (fnBar == SB_VERT);
  178. bReturnOldPos = (psi->fMask & SIF_POS);
  179. dwStyle = GetWindowLong(hwnd, GWL_STYLE);
  180. wScroll = fVert ? WS_VSCROLL : WS_HSCROLL;
  181. fScroll = fOldScroll = (dwStyle & wScroll) ? TRUE : FALSE;
  182. // Don't do anything if we're setting position of a nonexistent scroll bar.
  183. if( !(psi->fMask & SIF_RANGE) && !fOldScroll )
  184. return 0;
  185. mysi = (fVert ? &psb->Vert : &psb->Horz);
  186. if( !SkinUI_SetSBParms(mysi, *psi, &fScroll, &nRet, bReturnOldPos) &&
  187. !(psi->fMask & SIF_DISABLENOSCROLL) ) {
  188. if( fOldScroll && fRedraw )
  189. goto redrawAfterSet;
  190. return nRet;
  191. }
  192. if( fScroll )
  193. psb->style |= wScroll;
  194. else
  195. psb->style &= ~wScroll;
  196. // Keep the owner window scroll style
  197. SetWindowLong(hwnd, GWL_STYLE, dwStyle | wScroll);
  198. if( psi->fMask & SIF_DISABLENOSCROLL ) {
  199. if( fOldScroll ) {
  200. fScroll = ((int)mysi->nPage <= (mysi->nMax - mysi->nMin));
  201. psb->style |= wScroll;
  202. SetWindowLong(hwnd, GWL_STYLE, dwStyle | wScroll);
  203. SkinUI_EnableArrows(psb, fnBar, fScroll ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH);
  204. }
  205. }
  206. else if( fOldScroll ^ fScroll ) {
  207. SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOZORDER |
  208. SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_DRAWFRAME);
  209. return nRet;
  210. }
  211. if( fScroll && fRedraw ) {
  212. redrawAfterSet:
  213. if(dwStyle & wScroll) {
  214. HDC hDC = GetWindowDC(hwnd);
  215. SkinUI_DrawThumb(psb, hDC, fVert);
  216. ReleaseDC(hwnd, hDC);
  217. }
  218. else {
  219. if( SkinUI_IsScrollInfoActive(psi) )
  220. SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOZORDER |
  221. SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_DRAWFRAME);
  222. }
  223. }
  224. return mysi->nPos; //lres;
  225. }
  226. //---------------------------------------------------------
  227. // Name : SkinUI_GetScrollPos()
  228. // Desc : Overload API GetScrollPos()
  229. //---------------------------------------------------------
  230. int WINAPI SkinUI_GetScrollPos(HWND hwnd, int nBar)
  231. {
  232. LPSB psb;
  233. int nPos;
  234. if( !(psb = SkinUI_GetSB(hwnd)) )
  235. return FALSE;
  236. if( nBar == SB_HORZ )
  237. nPos = psb->Horz.nPos;
  238. else if( nBar == SB_VERT )
  239. nPos = psb->Vert.nPos;
  240. return nPos;
  241. }
  242. //---------------------------------------------------------
  243. // Name : SkinUI_SetScrollPos()
  244. // Desc : Overload API SetScrollPos()
  245. //---------------------------------------------------------
  246. int WINAPI SkinUI_SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw)
  247. {
  248. LPSB psb;
  249. LPSCROLLINFO psi;
  250. int nOldPos;
  251. if( (psb = SkinUI_GetSB(hwnd)) == NULL)
  252. return FALSE;
  253. if( nBar == SB_HORZ )
  254. psi = &psb->Horz;
  255. else if( nBar == SB_VERT )
  256. psi = &psb->Vert;
  257. else
  258. return FALSE;
  259. nOldPos = psi->nPos;
  260. psi->nPos = nPos;
  261. if( fRedraw ) {
  262. HDC hDC = GetWindowDC(hwnd);
  263. SkinUI_DrawScrollBar(psb, hDC, (nBar == SB_VERT) );
  264. ReleaseDC(hwnd, hDC);
  265. }
  266. return nOldPos;
  267. }
  268. //---------------------------------------------------------
  269. // Name : SkinUI_GetScrollRange()
  270. // Desc : Overload API GetScrollRange()
  271. //---------------------------------------------------------
  272. BOOL WINAPI SkinUI_GetScrollRange(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos)
  273. {
  274. LPSB psb;
  275. LPSCROLLINFO psi;
  276. if( !lpMinPos || !lpMaxPos )
  277. return FALSE;
  278. if( (psb = SkinUI_GetSB(hwnd)) == NULL )
  279. return FALSE;
  280. if( nBar == SB_HORZ )
  281. psi = &psb->Horz;
  282. else if( nBar == SB_VERT )
  283. psi = &psb->Vert;
  284. *lpMinPos = psi->nMin;
  285. *lpMaxPos = psi->nMax;
  286. return TRUE;
  287. }
  288. //---------------------------------------------------------
  289. // Name : SkinUI_SetScrollRange()
  290. // Desc : Overload API SetScrollRange()
  291. //---------------------------------------------------------
  292. BOOL WINAPI SkinUI_SetScrollRange(HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw)
  293. {
  294. LPSB psb;
  295. LPSCROLLINFO psi;
  296. if( !(psb = SkinUI_GetSB(hwnd)) )
  297. return FALSE;
  298. if( nBar == SB_HORZ )
  299. psi = &psb->Horz;
  300. else if( nBar == SB_VERT )
  301. psi = &psb->Vert;
  302. psi->nMin = nMinPos;
  303. psi->nMax = nMaxPos;
  304. if(nMinPos == 0 && nMaxPos == 0)
  305. SkinUI_ShowScrollBar(hwnd, nBar, FALSE);
  306. if( fRedraw ) {
  307. HDC hDC = GetWindowDC(hwnd);
  308. SkinUI_DrawScrollBar(psb, hDC, (nBar == SB_VERT) );
  309. ReleaseDC(hwnd, hDC);
  310. }
  311. return TRUE;
  312. }
  313. //---------------------------------------------------------
  314. // Name : SkinUI_ShowScrollBar()
  315. // Desc : Overload API ShowScrollBar()
  316. //---------------------------------------------------------
  317. BOOL WINAPI SkinUI_ShowScrollBar(HWND hwnd, int wBar, BOOL fShow)
  318. {
  319. BOOL fChanged = FALSE;
  320. DWORD dwStyle, dwNew;
  321. switch( wBar )
  322. {
  323. case SB_CTL:
  324. ShowWindow(hwnd, fShow ? SW_SHOW : SW_HIDE);
  325. break;
  326. case SB_HORZ:
  327. dwNew = WS_HSCROLL;
  328. break;
  329. case SB_VERT:
  330. dwNew = WS_VSCROLL;
  331. break;
  332. case SB_BOTH:
  333. dwNew = WS_HSCROLL | WS_VSCROLL;
  334. break;
  335. }
  336. dwStyle = GetWindowLong(hwnd, GWL_STYLE);
  337. if( !fShow ) {
  338. if( dwStyle & dwNew ) {
  339. fChanged = TRUE;
  340. dwStyle &= ~dwNew;
  341. }
  342. }
  343. else {
  344. if( (dwStyle & dwNew) != dwNew ) {
  345. fChanged = TRUE;
  346. dwStyle |= dwNew;
  347. }
  348. }
  349. if( fChanged ) {
  350. SetWindowLong(hwnd, GWL_STYLE, dwStyle);
  351. SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOZORDER |
  352. SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_DRAWFRAME);
  353. }
  354. return TRUE;
  355. }
  356. //---------------------------------------------------------
  357. // Name : SkinUI_EnableScrollBar()
  358. // Desc : Overload API EnableScrollBar()
  359. //---------------------------------------------------------
  360. BOOL WINAPI SkinUI_EnableScrollBar(HWND hwnd, UINT wSBflags, UINT wArrows)
  361. {
  362. LPSB psb;
  363. if( !(psb = SkinUI_GetSB(hwnd)) )
  364. return FALSE;
  365. if( wSBflags == SB_CTL )
  366. return FALSE;
  367. return SkinUI_EnableArrows(psb, wSBflags, wArrows);
  368. }
  369. // Internal Function
  370. //---------------------------------------------------------
  371. // Name : SkinUI_SetSBParms()
  372. // Desc : Set scroll parameters
  373. //---------------------------------------------------------
  374. BOOL SkinUI_SetSBParms(LPSCROLLINFO psi, SCROLLINFO si, BOOL* pfScroll, int* plres, BOOL bOldPos)
  375. {
  376. BOOL fChanged = FALSE;
  377. if( bOldPos )
  378. *plres = psi->nPos;
  379. if( si.fMask & SIF_RANGE ) {
  380. if( si.nMax < si.nMin )
  381. si.nMax = si.nMin;
  382. if( si.nMax != psi->nMax || si.nMin != psi->nMin ) {
  383. psi->nMax = si.nMax;
  384. psi->nMin = si.nMin;
  385. if( !(si.fMask & SIF_PAGE) ) {
  386. si.fMask |= SIF_PAGE;
  387. si.nPage = psi->nPage;
  388. }
  389. if( !(si.fMask & SIF_POS) ) {
  390. si.fMask |= SIF_POS;
  391. si.nPos = psi->nPos;
  392. }
  393. fChanged = TRUE;
  394. }
  395. }
  396. if( si.fMask & SIF_PAGE ) {
  397. UINT nMaxPage = abs( psi->nMax - psi->nMin ) + 1;
  398. if( si.nPage > nMaxPage )
  399. si.nPage = nMaxPage;
  400. if( psi->nPage != si.nPage ) {
  401. psi->nPage = si.nPage;
  402. if( !(si.fMask & SIF_POS) ) {
  403. si.fMask |= SIF_POS;
  404. si.nPos = psi->nPos;
  405. }
  406. fChanged = TRUE;
  407. }
  408. }
  409. if( si.fMask & SIF_POS ) {
  410. int nMaxPos = psi->nMax - ((psi->nPage) ? psi->nPage - 1 : 0);
  411. if( si.nPos < psi->nMin )
  412. si.nPos = psi->nMin;
  413. else if( si.nPos > nMaxPos )
  414. si.nPos = nMaxPos;
  415. if( psi->nPos != si.nPos ) {
  416. psi->nPos = si.nPos;
  417. fChanged = TRUE;
  418. }
  419. }
  420. if( si.fMask & SIF_TRACKPOS ) {
  421. if( psi->nTrackPos != si.nTrackPos ) {
  422. psi->nTrackPos = si.nTrackPos;
  423. fChanged = TRUE;
  424. }
  425. }
  426. if( !bOldPos )
  427. *plres = psi->nPos; // Return the new pos
  428. if( si.fMask & SIF_RANGE ) {
  429. if( *pfScroll = (psi->nMin != psi->nMax) )
  430. goto CheckPage;
  431. }
  432. else if( si.fMask & SIF_PAGE ) {
  433. CheckPage:
  434. *pfScroll = ( (int)psi->nPage <= (psi->nMax - psi->nMin) );
  435. }
  436. return fChanged;
  437. }
  438. //---------------------------------------------------------
  439. // Name : SkinUI_EnableArrows()
  440. // Desc : Enable or Disable scrollbar arrows
  441. //---------------------------------------------------------
  442. BOOL SkinUI_EnableArrows(LPSB psb, int nBar, UINT wArrows)
  443. {
  444. HDC hDC;
  445. UINT uOldFlags;
  446. BOOL bRetValue = FALSE;
  447. if( psb == NULL )
  448. return FALSE;
  449. uOldFlags = psb->flags;
  450. if( (hDC = GetWindowDC(psb->hwnd)) == NULL )
  451. return FALSE;
  452. // Enable or disable horizontal scrollbar
  453. if( nBar == SB_HORZ || nBar == SB_BOTH ) {
  454. if( wArrows == ESB_ENABLE_BOTH )
  455. psb->flags &= ~ESB_DISABLE_BOTH;
  456. else
  457. psb->flags |= wArrows;
  458. if( uOldFlags != psb->flags ) {
  459. bRetValue = TRUE;
  460. if( GetWindowLong(psb->hwnd, GWL_STYLE ) & WS_HSCROLL )
  461. SkinUI_DrawScrollBar(psb, hDC, FALSE);
  462. }
  463. }
  464. // Enable or disable vertical scrollbar
  465. if( nBar == SB_VERT || nBar == SB_BOTH ) {
  466. if( wArrows == ESB_ENABLE_BOTH )
  467. psb->flags &= ~(ESB_DISABLE_BOTH << 2);
  468. else
  469. psb->flags |= (wArrows << 2);
  470. if( uOldFlags != psb->flags ) {
  471. bRetValue = TRUE;
  472. if( GetWindowLong(psb->hwnd, GWL_STYLE ) & WS_VSCROLL )
  473. SkinUI_DrawScrollBar(psb, hDC, TRUE);
  474. }
  475. }
  476. ReleaseDC(psb->hwnd, hDC);
  477. return bRetValue;
  478. }
  479. //---------------------------------------------------------
  480. // Name : SkinUI_GetDisableFlags()
  481. // Desc : Get scrollbar disable flags
  482. //---------------------------------------------------------
  483. UINT SkinUI_GetDisableFlags(LPSB psb, BOOL fVert)
  484. {
  485. return (fVert ? (psb->flags & 0x000c) >> 2 : psb->flags & 0x0003);
  486. }
  487. //---------------------------------------------------------
  488. // Name : SkinUI_GetSB()
  489. // Desc : Get the skin scrollbar data structure
  490. //---------------------------------------------------------
  491. LPSB SkinUI_GetSB(HWND hwnd)
  492. {
  493. return (LPSB)GetProp(hwnd, g_szPropSB);
  494. }
  495. //---------------------------------------------------------
  496. // Name : SkinUI_IsScrollInfoActive()
  497. // Desc : Check scroll information whether active
  498. //---------------------------------------------------------
  499. BOOL SkinUI_IsScrollInfoActive(LPCSCROLLINFO lpsi)
  500. {
  501. if( lpsi->nPage > (UINT)lpsi->nMax || lpsi->nMax <= lpsi->nMin || lpsi->nMax == 0 )
  502. return FALSE;
  503. else
  504. return TRUE;
  505. }
  506. //----------------------------------------------------------
  507. // Name : SkinUI_GetSizeBoxRect()
  508. // Desc : Get the size box rect
  509. //----------------------------------------------------------
  510. BOOL SkinUI_GetSizeBoxRect(LPSB psb, LPRECT lprc)
  511. {
  512. DWORD dwStyle;
  513. RECT rect;
  514. SetRectEmpty(lprc);
  515. dwStyle = GetWindowLong(psb->hwnd, GWL_STYLE);
  516. if( (dwStyle & WS_HSCROLL) && (dwStyle & WS_VSCROLL) ) {
  517. GetClientRect(psb->hwnd, &rect);
  518. ClientToScreen(psb->hwnd, (LPPOINT)&rect);
  519. ClientToScreen(psb->hwnd, ((LPPOINT)&rect)+1);
  520. // calculate left scroll style of size box rect
  521. if( psb->fLeftScrollBar ) {
  522. lprc->left = rect.left - GetSystemMetrics(SM_CXVSCROLL);
  523. lprc->right = rect.left;
  524. }
  525. else {
  526. lprc->left = rect.right;
  527. lprc->right = rect.right + GetSystemMetrics(SM_CXVSCROLL);
  528. }
  529. lprc->top = rect.bottom;
  530. lprc->bottom= rect.bottom + GetSystemMetrics(SM_CYHSCROLL);
  531. return TRUE;
  532. }
  533. return FALSE;
  534. }
  535. //----------------------------------------------------------
  536. // Name : SkinUI_GetScrollBarRect()
  537. // Desc : Get the scrollbar rect
  538. //----------------------------------------------------------
  539. BOOL SkinUI_GetScrollBarRect(LPSB psb, BOOL fVert, LPRECT lprc)
  540. {
  541. RECT rect;
  542. DWORD dwStyle;
  543. if( !psb || !lprc )
  544. return FALSE;
  545. SetRectEmpty(lprc);
  546. GetClientRect(psb->hwnd, &rect);
  547. ClientToScreen(psb->hwnd, (LPPOINT)&rect);
  548. ClientToScreen(psb->hwnd, ((LPPOINT)&rect)+1);
  549. dwStyle = GetWindowLong(psb->hwnd, GWL_STYLE);
  550. if( fVert ) {
  551. if( psb->fLeftScrollBar ) {
  552. lprc->right = lprc->left = rect.left;
  553. if( dwStyle & WS_VSCROLL )
  554. lprc->left -= GetSystemMetrics(SM_CXVSCROLL);
  555. }
  556. else {
  557. lprc->right = lprc->left = rect.right;
  558. if( dwStyle & WS_VSCROLL )
  559. lprc->right += GetSystemMetrics(SM_CXVSCROLL);
  560. }
  561. lprc->top = rect.top;
  562. lprc->bottom = rect.bottom;
  563. }
  564. else {
  565. lprc->top = lprc->bottom = rect.bottom;
  566. if( dwStyle & WS_HSCROLL )
  567. lprc->bottom += GetSystemMetrics(SM_CYHSCROLL);
  568. lprc->left = rect.left;
  569. lprc->right = rect.right;
  570. }
  571. return TRUE;
  572. }
  573. //----------------------------------------------------------
  574. // Name : SkinUI_GetThumbRect()
  575. // Desc :
  576. //----------------------------------------------------------
  577. BOOL SkinUI_GetThumbRect(LPSB psb, LPRECT lprc, BOOL fVert)
  578. {
  579. if( !psb || !lprc )
  580. return FALSE;
  581. SBCALC sbc;
  582. RECT rect;
  583. SkinUI_SBCalc(psb, &sbc, fVert);
  584. GetWindowRect(psb->hwnd, &rect);
  585. if( fVert )
  586. SetRect(lprc, sbc.pxLeft, sbc.pxThumbTop, sbc.pxRight, sbc.pxThumbBottom);
  587. else
  588. SetRect(lprc, sbc.pxThumbLeft, sbc.pxTop, sbc.pxThumbRight, sbc.pxBottom);
  589. OffsetRect(lprc, -rect.left, -rect.top);
  590. return TRUE;
  591. }
  592. //----------------------------------------------------------
  593. // Name : SkinUI_GetGrooveRect()
  594. // Desc :
  595. //----------------------------------------------------------
  596. BOOL SkinUI_GetGrooveRect(LPSB psb, LPRECT lprc, BOOL fVert)
  597. {
  598. if( !psb || !lprc )
  599. return FALSE;
  600. SBCALC sbc;
  601. RECT rect;
  602. SkinUI_SBCalc(psb, &sbc, fVert);
  603. GetWindowRect(psb->hwnd, &rect);
  604. if( fVert )
  605. SetRect(lprc, sbc.pxLeft, sbc.pxUpArrow, sbc.pxRight, sbc.pxDownArrow);
  606. else
  607. SetRect(lprc, sbc.pxUpArrow, sbc.pxTop, sbc.pxDownArrow, sbc.pxBottom);
  608. OffsetRect(lprc, -rect.left, -rect.top);
  609. return TRUE;
  610. }
  611. //----------------------------------------------------------
  612. // Name : SkinUI_DrawSizeBox()
  613. // Desc : Draw the size box
  614. //----------------------------------------------------------
  615. BOOL SkinUI_DrawSizeBox(LPSB psb, HDC hDC)
  616. {
  617. HDC hMemDC;
  618. HBITMAP hOldBmp;
  619. RECT rect, rc;
  620. GetWindowRect(psb->hwnd, &rect);
  621. SkinUI_GetSizeBoxRect(psb, &rc);
  622. OffsetRect(&rc, -rect.left, -rect.top);
  623. hMemDC = CreateCompatibleDC(NULL);
  624. hOldBmp = (HBITMAP)SelectObject(hMemDC, psb->hBmp);
  625. BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 38, 57, SRCCOPY);
  626. // Release GDI object
  627. SelectObject(hMemDC, hOldBmp);
  628. DeleteDC(hMemDC);
  629. return TRUE;
  630. }
  631. //----------------------------------------------------------
  632. // Name : SkinUI_DrawGroove()
  633. // Desc :
  634. //----------------------------------------------------------
  635. BOOL SkinUI_DrawGroove(LPSB psb, HDC hdc, LPRECT lprc, BOOL fVert)
  636. {
  637. if( !hdc || !lprc || IsRectEmpty(lprc) )
  638. return FALSE;
  639. HDC hbmpDC;
  640. HBITMAP hOldBmp;
  641. POINT pt;
  642. int nMode;
  643. hbmpDC = CreateCompatibleDC(hdc);
  644. hOldBmp = (HBITMAP)SelectObject(hbmpDC, psb->hBmp);
  645. if( fVert )
  646. pt = ptArray[0][4];
  647. else
  648. pt = ptArray[3][4];
  649. nMode = SetStretchBltMode(hdc, HALFTONE);
  650. StretchBlt(hdc, lprc->left, lprc->top, lprc->right - lprc->left,
  651. lprc->bottom - lprc->top, hbmpDC, pt.x, pt.y, 16, 16, SRCCOPY);
  652. SetStretchBltMode(hdc, nMode);
  653. SelectObject(hbmpDC, hOldBmp);
  654. DeleteDC(hbmpDC);
  655. return TRUE;
  656. }
  657. //----------------------------------------------------------
  658. // Name : SkinUI_DrawScrollBar()
  659. // Desc : Draw the scrollbar
  660. //----------------------------------------------------------
  661. void SkinUI_DrawScrollBar(LPSB psb, HDC hDC, BOOL fVert)
  662. {
  663. RECT rcGroove;
  664. SkinUI_GetGrooveRect(psb, &rcGroove, fVert);
  665. SkinUI_DrawGroove(psb, hDC, &rcGroove, fVert);
  666. if( fVert ) {
  667. // Draw the arrow
  668. SkinUI_DrawArrow(psb, hDC, fVert, HTSCROLL_LINEUP, 0);
  669. SkinUI_DrawArrow(psb, hDC, fVert, HTSCROLL_LINEDOWN, 0);
  670. // Draw the thumb
  671. if( !SkinUI_IsScrollInfoActive(&psb->Vert) )
  672. return ;
  673. SkinUI_DrawThumb(psb, hDC, fVert);
  674. }
  675. else {
  676. SkinUI_DrawArrow(psb, hDC, fVert, HTSCROLL_LINEUP, 0);
  677. SkinUI_DrawArrow(psb, hDC, fVert, HTSCROLL_LINEDOWN, 0);
  678. if( !SkinUI_IsScrollInfoActive(&psb->Horz) )
  679. return ;
  680. SkinUI_DrawThumb(psb, hDC, fVert);
  681. }
  682. }
  683. //----------------------------------------------------------
  684. // Name : SkinUI_DrawArrow()
  685. // Desc : Draw the scrollbar arrow button
  686. //----------------------------------------------------------
  687. BOOL SkinUI_DrawArrow(LPSB psb, HDC hdc, BOOL fVert, int nArrow, UINT uState)
  688. {
  689. RECT rect, rc;
  690. SBCALC sbc;
  691. HDC hMemDC;
  692. HBITMAP hOldBmp;
  693. int x, y;
  694. POINT pt;
  695. GetWindowRect(psb->hwnd, &rect);
  696. SkinUI_SBCalc(psb, &sbc, fVert);
  697. if( uState == 0 )
  698. uState = SkinUI_GetState(psb, fVert, nArrow);
  699. hMemDC = CreateCompatibleDC(hdc);
  700. hOldBmp = (HBITMAP)SelectObject(hMemDC, psb->hBmp);
  701. switch( nArrow )
  702. {
  703. // up or left arrow
  704. case HTSCROLL_LINEUP:
  705. if( fVert ) {
  706. x = 0; y = 0;
  707. SetRect(&rc, sbc.pxLeft, sbc.pxTop, sbc.pxRight, sbc.pxUpArrow);
  708. }
  709. else {
  710. x = 3; y = 0;
  711. SetRect(&rc, sbc.pxLeft, sbc.pxTop, sbc.pxUpArrow, sbc.pxBottom);
  712. }
  713. break;
  714. // right or down arrow
  715. case HTSCROLL_LINEDOWN:
  716. if( fVert ) {
  717. x = 0; y = 1;
  718. SetRect(&rc, sbc.pxLeft, sbc.pxDownArrow, sbc.pxRight, sbc.pxBottom);
  719. }
  720. else {
  721. x = 3; y = 1;
  722. SetRect(&rc, sbc.pxDownArrow, sbc.pxTop, sbc.pxRight, sbc.pxBottom);
  723. }
  724. break;
  725. }
  726. OffsetRect(&rc, -rect.left, -rect.top);
  727. switch( uState )
  728. {
  729. case SB_STATE_NORMAL:
  730. break;
  731. case SB_STATE_HOTTRACKED:
  732. x += 1;
  733. break;
  734. case SB_STATE_PRESSED:
  735. x += 2;
  736. break;
  737. case SB_STATE_DISABLED:
  738. break;
  739. }
  740. pt = ptArray[x][y];
  741. BitBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
  742. hMemDC, pt.x, pt.y, SRCCOPY);
  743. SelectObject(hMemDC, hOldBmp);
  744. DeleteDC(hMemDC);
  745. return TRUE;
  746. }
  747. //----------------------------------------------------------
  748. // Name : SkinUI_DrawThumb()
  749. // Desc : Draw the thumb
  750. //----------------------------------------------------------
  751. void SkinUI_DrawThumb(LPSB psb, HDC hdc, BOOL fVert)
  752. {
  753. SBCALC sbc;
  754. RECT rc, rect;
  755. HDC hSrcDC;
  756. HDC memDC;
  757. HBITMAP hOldBmp;
  758. HBITMAP hMemBitmap, hOldBitmap;
  759. UINT uState;
  760. int cx, cy;
  761. POINT pt, pt1;
  762. uState = SkinUI_GetState(psb, fVert, HTSCROLL_THUMB);
  763. SkinUI_SBCalc(psb, &sbc, fVert);
  764. GetWindowRect(psb->hwnd, &rect);
  765. // Chack scrollbar of size whether valid
  766. if( sbc.pxTop >= sbc.pxBottom || sbc.pxLeft >= sbc.pxRight )
  767. return ;
  768. // Draw the groove only
  769. if( (sbc.pxDownArrow - sbc.pxUpArrow) < (sbc.pxThumbBottom - sbc.pxThumbTop) ||
  770. uState == SB_STATE_DISABLED ) {
  771. SkinUI_GetGrooveRect(psb, &rc, fVert);
  772. SkinUI_DrawGroove(psb, hdc, &rc, fVert);
  773. return ;
  774. }
  775. // Padding the groove part
  776. if( sbc.pxUpArrow < sbc.pxThumbTop ) {
  777. if( fVert )
  778. SetRect(&rc, sbc.pxLeft, sbc.pxUpArrow, sbc.pxRight, sbc.pxThumbTop);
  779. else
  780. SetRect(&rc, sbc.pxUpArrow, sbc.pxTop, sbc.pxThumbTop, sbc.pxBottom);
  781. OffsetRect(&rc, -rect.left, -rect.top);
  782. SkinUI_DrawGroove(psb, hdc, &rc, fVert);
  783. }
  784. if( sbc.pxThumbBottom < sbc.pxDownArrow ) {
  785. if( fVert )
  786. SetRect(&rc, sbc.pxLeft, sbc.pxThumbBottom, sbc.pxRight, sbc.pxDownArrow);
  787. else
  788. SetRect(&rc, sbc.pxThumbBottom, sbc.pxTop, sbc.pxDownArrow, sbc.pxBottom);
  789. OffsetRect(&rc, -rect.left, -rect.top);
  790. SkinUI_DrawGroove(psb, hdc, &rc, fVert);
  791. }
  792. // Draw the thumb use memory dc
  793. // Select scrollbar bitmap resource to dc
  794. hSrcDC = CreateCompatibleDC(hdc);
  795. hOldBmp = (HBITMAP)SelectObject(hSrcDC, psb->hBmp);
  796. // get the thumb rectangle
  797. SkinUI_GetThumbRect(psb, &rc, fVert);
  798. cx = rc.right - rc.left;
  799. cy = rc.bottom - rc.top;
  800. RECT rcMemDC = {0, 0, rc.right-rc.left, rc.bottom-rc.top};
  801. // create the memory dc
  802. memDC = CreateCompatibleDC(hdc);
  803. hMemBitmap = CreateCompatibleBitmap(hdc, cx, cy);
  804. hOldBitmap = (HBITMAP)SelectObject(memDC, hMemBitmap);
  805. SetBkColor(memDC, 0xFFFFFF);
  806. ExtTextOut(memDC, 0, 0, ETO_OPAQUE, &rcMemDC, NULL, 0, NULL);
  807. // Select state bitmap part
  808. switch( uState )
  809. {
  810. case SB_STATE_NORMAL:
  811. pt = fVert ? ptArray[0][2] : ptArray[3][2];
  812. pt1 = fVert ? ptArray[0][3] : ptArray[3][3];
  813. break;
  814. case SB_STATE_HOTTRACKED:
  815. pt = fVert ? ptArray[1][2] : ptArray[4][2];
  816. pt1 = fVert ? ptArray[1][3] : ptArray[4][3];
  817. break;
  818. case SB_STATE_PRESSED:
  819. pt = fVert ? ptArray[2][2] : ptArray[5][2];
  820. pt1 = fVert ? ptArray[2][3] : ptArray[5][3];
  821. break;
  822. case SB_STATE_DISABLED:
  823. break;
  824. }
  825. if ( fVert ) {
  826. for( int i= 4; i < cy - 4; i += 8 )
  827. BitBlt(memDC, 0, i, cx, 8, hSrcDC, pt.x, pt.y + 4, SRCCOPY);
  828. BitBlt(memDC, 0, 0, cx, 4, hSrcDC, pt.x, pt.y, SRCCOPY);
  829. BitBlt(memDC, 0, cy - 4, cx, 4, hSrcDC, pt.x, (pt.y + 16) - 4, SRCCOPY);
  830. if( cy > 16 + 8 ) {
  831. int y = (cy - 16) / 2;
  832. BitBlt(memDC, 0, y, cx, 16, hSrcDC, pt1.x, pt1.y, SRCCOPY);
  833. }
  834. }
  835. else {
  836. for( int i=4; i < cx - 4; i += 8 )
  837. BitBlt(memDC, i, 0, 8, cy, hSrcDC, pt.x + 4, pt.y, SRCCOPY);
  838. BitBlt(memDC, 0, 0, 4, cy, hSrcDC, pt.x, pt.y, SRCCOPY);
  839. BitBlt(memDC, cx - 4, 0, 4, cy, hSrcDC, (pt.x + 16) - 4, pt.y, SRCCOPY);
  840. if( cx > 16 + 8 ) {
  841. int x = (cx - 16) / 2;
  842. BitBlt(memDC, x, 0, 16, cy, hSrcDC, pt1.x, pt1.y, SRCCOPY);
  843. }
  844. }
  845. BitBlt(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, memDC, 0,0, SRCCOPY);
  846. // Release the memory DC
  847. SelectObject(memDC, hOldBitmap);
  848. DeleteDC(memDC);
  849. DeleteObject(hMemBitmap);
  850. SelectObject(hSrcDC, hOldBmp);
  851. DeleteDC(hSrcDC);
  852. }
  853. //----------------------------------------------------------
  854. // Name : SkinUI_HitTest()
  855. // Desc : HitTest scrollbar items
  856. //----------------------------------------------------------
  857. UINT SkinUI_HitTest(LPSB psb, BOOL fVert, POINT pt)
  858. {
  859. SBCALC sbc;
  860. UINT disFlags;
  861. int x;
  862. SkinUI_SBCalc(psb, &sbc, fVert);
  863. if( pt.x < sbc.pxLeft || pt.y < sbc.pxTop ||
  864. pt.x > sbc.pxRight || pt.y > sbc.pxBottom )
  865. return HTSCROLL_NONE;
  866. disFlags = SkinUI_GetDisableFlags(psb, fVert);
  867. x = fVert ? pt.y : pt.x;
  868. if( x < sbc.pxUpArrow ) {
  869. if( disFlags & ESB_DISABLE_BOTH || disFlags & ESB_DISABLE_LTUP )
  870. return HTSCROLL_NONE;
  871. else
  872. return HTSCROLL_LINEUP;
  873. }
  874. else if( x > sbc.pxUpArrow && x < sbc.pxThumbTop ) {
  875. if( disFlags & ESB_DISABLE_BOTH || disFlags & ESB_DISABLE_LTUP )
  876. return HTSCROLL_NONE;
  877. else
  878. return HTSCROLL_PAGEUP;
  879. }
  880. else if( (x >= sbc.pxThumbTop && x <= sbc.pxThumbBottom) &&
  881. (sbc.pxThumbTop > 0 && sbc.pxThumbBottom > sbc.pxThumbTop) ) {
  882. return HTSCROLL_THUMB;
  883. }
  884. else if( x > sbc.pxThumbBottom && x < sbc.pxDownArrow ) {
  885. if( disFlags & ESB_DISABLE_BOTH || disFlags & ESB_DISABLE_RTDN )
  886. return HTSCROLL_NONE;
  887. else
  888. return HTSCROLL_PAGEDOWN;
  889. }
  890. else if( x >= sbc.pxDownArrow ) {
  891. if( disFlags & ESB_DISABLE_BOTH || disFlags & ESB_DISABLE_RTDN )
  892. return HTSCROLL_NONE;
  893. else
  894. return HTSCROLL_LINEDOWN;
  895. }
  896. return HTSCROLL_NONE;
  897. }
  898. //----------------------------------------------------------
  899. // Name : SkinUI_SBCalc()
  900. // Desc : Calc the scrollbar items position and size
  901. //----------------------------------------------------------
  902. void SkinUI_SBCalc(LPSB psb, LPSBCALC lpcalc, BOOL fVert)
  903. {
  904. RECT rcBar; // the scrollbar rect
  905. int nRange; // the scroll range
  906. int nWorkingsize; // the scroll working size
  907. int nArrowsize; // the arrow button of size
  908. int nThumbsize; // the thumb of size
  909. int nStart; // the thumb of start position
  910. int nThumbpos; // the thumn of current position
  911. SCROLLINFO* psi;
  912. SkinUI_GetScrollBarRect(psb, fVert, &rcBar);
  913. lpcalc->pxLeft = rcBar.left;
  914. lpcalc->pxTop = rcBar.top;
  915. lpcalc->pxRight = rcBar.right;
  916. lpcalc->pxBottom = rcBar.bottom;
  917. if( fVert ) {
  918. psi = &psb->Vert;
  919. nArrowsize = GetSystemMetrics(SM_CYVSCROLL);
  920. nWorkingsize = (rcBar.bottom - rcBar.top) - nArrowsize * 2;
  921. nStart = rcBar.top + nArrowsize;
  922. lpcalc->pxUpArrow = rcBar.top + nArrowsize;
  923. lpcalc->pxDownArrow = rcBar.bottom - nArrowsize;
  924. }
  925. else {
  926. psi = &psb->Horz;
  927. nArrowsize = GetSystemMetrics(SM_CXHSCROLL);
  928. nWorkingsize = (rcBar.right - rcBar.left) - nArrowsize * 2;
  929. nStart = rcBar.left + nArrowsize;
  930. lpcalc->pxUpArrow = rcBar.left + nArrowsize;
  931. lpcalc->pxDownArrow = rcBar.right - nArrowsize;
  932. }
  933. nRange = (psi->nMax - psi->nMin) + 1;
  934. if( nRange > 0 && SkinUI_IsScrollInfoActive(psi)) {
  935. nThumbsize = MulDiv(psi->nPage, nWorkingsize, nRange);
  936. if( nThumbsize < SB_MINTHUMB_SIZE )
  937. nThumbsize = SB_MINTHUMB_SIZE;
  938. int pagesize = max(1, psi->nPage);
  939. nThumbpos = MulDiv(psi->nPos - psi->nMin, nWorkingsize - nThumbsize, nRange - pagesize);
  940. if( nThumbpos < 0 )
  941. nThumbpos = 0;
  942. if( nThumbpos >= nWorkingsize - nThumbsize )
  943. nThumbpos = nWorkingsize - nThumbsize;
  944. nThumbpos += nStart;
  945. lpcalc->pxThumbTop = nThumbpos;
  946. lpcalc->pxThumbBottom = nThumbpos + nThumbsize;
  947. }
  948. else {
  949. lpcalc->pxThumbTop = 0;
  950. lpcalc->pxThumbBottom = 0;
  951. }
  952. }
  953. //---------------------------------------------------------
  954. // Name : SkinUI_TrackThumb()
  955. // Desc : Track the scroll thumb
  956. //---------------------------------------------------------
  957. BOOL SkinUI_TrackThumb(LPSB psb, BOOL fVert, POINT pt)
  958. {
  959. SBCALC sbclc;
  960. int nPos;
  961. int nThumbpos;
  962. int nRange;
  963. int nThumbsize;
  964. int nWorksize;
  965. LPSCROLLINFO psi;
  966. SkinUI_SBCalc(psb, &sbclc, fVert);
  967. if( fVert ) {
  968. psi = &psb->Vert;
  969. nThumbpos = pt.y - psb->nOffsetPoint;
  970. }
  971. else {
  972. psi = &psb->Horz;
  973. nThumbpos = pt.x - psb->nOffsetPoint;
  974. }
  975. nPos = 0;
  976. nThumbpos -= sbclc.pxUpArrow;
  977. nThumbsize = sbclc.pxThumbBottom - sbclc.pxThumbTop;
  978. nWorksize = sbclc.pxDownArrow - sbclc.pxUpArrow;
  979. nRange = (psi->nMax - psi->nMin) + 1;
  980. if( nThumbpos < 0 )
  981. nThumbpos = 0;
  982. if( nThumbpos > nWorksize - nThumbsize)
  983. nThumbpos = nWorksize - nThumbsize;
  984. if( nRange > 0 )
  985. nPos = MulDiv(nThumbpos, nRange - psi->nPage, nWorksize - nThumbsize);
  986. // Send the scroll message to window !!!
  987. if( psi->nPos != nPos ) {
  988. psi->nTrackPos = nPos;
  989. psb->nTrackPos = nPos;
  990. // NOTE: 2008-12-24
  991. // Not use the SB_THUMBTRACK flag that because of
  992. // the RichEdit cannot receving the WM_MOUSEMOVE message
  993. if( psb->fRichEdit ) {
  994. DoScrollMsg(psb->hwnd, /*SB_THUMBTRACK*/SB_THUMBPOSITION, nPos, fVert);
  995. }
  996. else {
  997. DoScrollMsg(psb->hwnd, SB_THUMBTRACK, nPos, fVert);
  998. }
  999. }
  1000. return TRUE;
  1001. }
  1002. //---------------------------------------------------------
  1003. // Name : SkinUI_GetState()
  1004. // Desc :
  1005. //---------------------------------------------------------
  1006. UINT SkinUI_GetState(LPSB psb, BOOL fVert, UINT nHit)
  1007. {
  1008. BOOL fHotTracked;
  1009. BOOL fPressed;
  1010. BOOL fDisabled;
  1011. UINT disFlags;
  1012. UINT state;
  1013. if( nHit == HTSCROLL_NONE )
  1014. return 0;
  1015. fHotTracked = fPressed = fDisabled = FALSE;
  1016. disFlags = SkinUI_GetDisableFlags(psb, fVert);
  1017. switch( nHit ) {
  1018. case HTSCROLL_LINEUP:
  1019. fDisabled = (disFlags & ESB_DISABLE_BOTH || disFlags & ESB_DISABLE_UP);
  1020. break;
  1021. case HTSCROLL_LINEDOWN:
  1022. fDisabled = (disFlags & ESB_DISABLE_BOTH || disFlags & ESB_DISABLE_DOWN);
  1023. break;
  1024. case HTSCROLL_THUMB:
  1025. fDisabled = (disFlags & ESB_DISABLE_BOTH);
  1026. break;
  1027. }
  1028. if( nHit == psb->nLastCode && fVert == psb->fLastVert )
  1029. fHotTracked = TRUE;
  1030. if( !fDisabled && psb->fTracking && fHotTracked )
  1031. fPressed = TRUE;
  1032. if( fDisabled )
  1033. state = SB_STATE_DISABLED;
  1034. else if( fPressed )
  1035. state = SB_STATE_PRESSED;
  1036. else if( fHotTracked )
  1037. state = SB_STATE_HOTTRACKED;
  1038. else
  1039. state = SB_STATE_NORMAL;
  1040. return state;
  1041. }
  1042. //----------------------------------------------------------
  1043. // Name : SkinUI_Track()
  1044. // Desc :
  1045. //----------------------------------------------------------
  1046. void SkinUI_Track(LPSB psb, BOOL fVert, UINT nHit, POINT pt)
  1047. {
  1048. UINT disFlags;
  1049. LPSCROLLINFO psi;
  1050. WORD wSBCode;
  1051. psi = fVert ? &psb->Vert : &psb->Horz;
  1052. disFlags = SkinUI_GetDisableFlags(psb, fVert);
  1053. switch( nHit )
  1054. {
  1055. case HTSCROLL_THUMB:
  1056. SBCALC sbclc;
  1057. SkinUI_SBCalc(psb, &sbclc, fVert);
  1058. psi->nTrackPos = psi->nPos;
  1059. psb->nOffsetPoint = (fVert ? pt.y : pt.x) - sbclc.pxThumbTop;
  1060. break;
  1061. case HTSCROLL_LINEUP:
  1062. wSBCode = SB_LINEUP;
  1063. goto DoScroll;
  1064. case HTSCROLL_LINEDOWN:
  1065. wSBCode = SB_LINEDOWN;
  1066. goto DoScroll;
  1067. case HTSCROLL_PAGEDOWN:
  1068. wSBCode = SB_PAGEDOWN;
  1069. goto DoScroll;
  1070. case HTSCROLL_PAGEUP:
  1071. wSBCode = SB_PAGEUP;
  1072. DoScroll:
  1073. psb->nScrollTimerMsg = MAKELONG(fVert ? WM_VSCROLL : WM_HSCROLL, wSBCode);
  1074. DoScrollMsg(psb->hwnd, wSBCode, 0, fVert);
  1075. SetTimer(psb->hwnd, SB_TIMER_DELAY, SB_SCROLL_DELAY, NULL);
  1076. break;
  1077. default:
  1078. return;
  1079. }
  1080. psb->nTrackCode = nHit;
  1081. psb->fTrackVert = fVert;
  1082. psb->fTracking = TRUE;
  1083. SkinUI_HotTrack(psb, nHit, fVert, TRUE);
  1084. SetCapture(psb->hwnd);
  1085. //SkinUI_TrackLoop(psb);
  1086. }
  1087. /*
  1088. //----------------------------------------------------------
  1089. // Name : SkinUI_TrackLoop()
  1090. // Desc :
  1091. //----------------------------------------------------------
  1092. void SkinUI_TrackLoop(LPSB psb)
  1093. {
  1094. HWND hwnd;
  1095. MSG msg;
  1096. int cmd;
  1097. //POINT pt;
  1098. if( !psb->fTracking )
  1099. return;
  1100. hwnd = psb->hwnd;
  1101. while( GetCapture() == hwnd )
  1102. {
  1103. if( !GetMessage(&msg, hwnd, 0, 0) )
  1104. break;
  1105. if( !CallMsgFilter(&msg, MSGF_SCROLLBAR) )
  1106. {
  1107. cmd = msg.message;
  1108. if( msg.hwnd == hwnd &&
  1109. ((cmd >= WM_MOUSEFIRST && cmd <= WM_MOUSELAST) ||
  1110. (cmd >= WM_KEYFIRST && cmd <= WM_KEYLAST))
  1111. )
  1112. {
  1113. TRACE("message loop\n");
  1114. SkinUI_Proc(hwnd, cmd, msg.wParam, msg.lParam);
  1115. }
  1116. }
  1117. else
  1118. {
  1119. TranslateMessage(&msg);
  1120. DispatchMessage(&msg);
  1121. }
  1122. }
  1123. }*/
  1124. //----------------------------------------------------------
  1125. // Name : SkinUI_HotTrack()
  1126. // Desc : Hot scrollbar arrow and thumb items
  1127. //----------------------------------------------------------
  1128. BOOL SkinUI_HotTrack(LPSB psb, int nHitCode, BOOL fVert, BOOL fMouseDown)
  1129. {
  1130. HDC hDC;
  1131. UINT oldHit;
  1132. BOOL oldVert;
  1133. // Save old hittest code
  1134. oldHit = psb->nLastCode;
  1135. oldVert = psb->fLastVert;
  1136. psb->nLastCode = nHitCode;
  1137. psb->fLastVert = fVert;
  1138. if( (hDC = GetWindowDC(psb->hwnd)) == NULL )
  1139. return FALSE;
  1140. if( nHitCode != oldHit || fVert != oldVert || fMouseDown) {
  1141. // Restore old hittest item state
  1142. if( oldHit == HTSCROLL_LINEUP )
  1143. SkinUI_DrawArrow(psb, hDC, oldVert, HTSCROLL_LINEUP, SB_STATE_NORMAL);
  1144. else if( oldHit == HTSCROLL_LINEDOWN )
  1145. SkinUI_DrawArrow(psb, hDC, oldVert, HTSCROLL_LINEDOWN, SB_STATE_NORMAL);
  1146. else if( oldHit == HTSCROLL_THUMB )
  1147. SkinUI_DrawThumb(psb, hDC, oldVert);
  1148. // Draw new hittest item state
  1149. if( nHitCode == HTSCROLL_LINEUP )
  1150. SkinUI_DrawArrow(psb, hDC, fVert, HTSCROLL_LINEUP, fMouseDown ? SB_STATE_PRESSED : SB_STATE_HOTTRACKED);
  1151. else if( nHitCode == HTSCROLL_LINEDOWN )
  1152. SkinUI_DrawArrow(psb, hDC, fVert, HTSCROLL_LINEDOWN, fMouseDown ? SB_STATE_PRESSED : SB_STATE_HOTTRACKED);
  1153. else if( nHitCode == HTSCROLL_THUMB)
  1154. SkinUI_DrawThumb(psb, hDC, fVert);
  1155. }
  1156. ReleaseDC(psb->hwnd, hDC);
  1157. return TRUE;
  1158. }
  1159. // Message handle
  1160. //----------------------------------------------------------
  1161. // Name : SkinUI_OnStyleChanged()
  1162. // Desc :
  1163. //----------------------------------------------------------
  1164. LRESULT SkinUI_OnStyleChanged(LPSB psb, int nStyleType, LPSTYLESTRUCT lpStyleStruct)
  1165. {
  1166. if( psb->fPreventStyleChange )
  1167. return 0;
  1168. if( nStyleType == GWL_EXSTYLE ) {
  1169. BOOL fOld = psb->fLeftScrollBar;
  1170. if( lpStyleStruct->styleNew & WS_EX_LEFTSCROLLBAR )
  1171. psb->fLeftScrollBar = TRUE;
  1172. else
  1173. psb->fLeftScrollBar = FALSE;
  1174. if( fOld != psb->fLeftScrollBar )
  1175. SetWindowPos(psb->hwnd, NULL, 0, 0, 0, 0, SWP_NOZORDER |
  1176. SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_DRAWFRAME);
  1177. }
  1178. return CallWindowProc(psb->pfnOldProc, psb->hwnd, WM_STYLECHANGED, nStyleType, (LPARAM)lpStyleStruct);
  1179. }
  1180. //----------------------------------------------------------
  1181. // Name : SkinUI_OnNcCalcSize()
  1182. // Desc :
  1183. //----------------------------------------------------------
  1184. LRESULT SkinUI_OnNcCalcSize(LPSB psb, BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
  1185. {
  1186. LRESULT lr;
  1187. DWORD dwStyle;
  1188. RECT* lprc, rect;
  1189. lprc = &lpncsp->rgrc[0];
  1190. rect = *lprc;
  1191. dwStyle = GetWindowLong(psb->hwnd, GWL_STYLE);
  1192. if( dwStyle & (WS_VSCROLL | WS_HSCROLL) ) {
  1193. psb->fPreventStyleChange = TRUE;
  1194. SetWindowLong(psb->hwnd, GWL_STYLE, dwStyle & ~(WS_VSCROLL|WS_HSCROLL));
  1195. }
  1196. lr = CallWindowProc(psb->pfnOldProc, psb->hwnd,
  1197. WM_NCCALCSIZE, (WPARAM)bCalcValidRects, (LPARAM)lpncsp);
  1198. if( dwStyle & (WS_VSCROLL | WS_HSCROLL) ) {
  1199. SetWindowLong(psb->hwnd, GWL_STYLE, dwStyle);
  1200. psb->fPreventStyleChange = FALSE;
  1201. }
  1202. if( (dwStyle & WS_HSCROLL) &&
  1203. (lprc->bottom - lprc->top) > GetSystemMetrics(SM_CYHSCROLL) ) {
  1204. lprc->bottom -= GetSystemMetrics(SM_CYHSCROLL);
  1205. }
  1206. if( (dwStyle & WS_VSCROLL) &&
  1207. (lprc->right - lprc->left) > GetSystemMetrics(SM_CXVSCROLL) ) {
  1208. if( psb->fLeftScrollBar )
  1209. lprc->left += GetSystemMetrics(SM_CXVSCROLL);
  1210. else
  1211. lprc->right -= GetSystemMetrics(SM_CXVSCROLL);
  1212. }
  1213. return lr;
  1214. }
  1215. //----------------------------------------------------------
  1216. // Name : SkinUI_OnNcPaint()
  1217. // Desc :
  1218. //----------------------------------------------------------
  1219. LRESULT SkinUI_OnNcPaint(LPSB psb, HRGN hRgn)
  1220. {
  1221. LRESULT lr;
  1222. DWORD dwStyle;
  1223. HDC hDC;
  1224. dwStyle = GetWindowLong(psb->hwnd, GWL_STYLE);
  1225. if( dwStyle & (WS_VSCROLL | WS_HSCROLL) ) {
  1226. psb->fPreventStyleChange = TRUE;
  1227. SetWindowLong(psb->hwnd, GWL_STYLE, dwStyle & ~(WS_VSCROLL|WS_HSCROLL));
  1228. }
  1229. // draw frame border by system
  1230. lr = CallWindowProc(psb->pfnOldProc, psb->hwnd, WM_NCPAINT, (WPARAM)hRgn, 0);
  1231. if( dwStyle & (WS_VSCROLL | WS_HSCROLL) ) {
  1232. SetWindowLong(psb->hwnd, GWL_STYLE, dwStyle);
  1233. psb->fPreventStyleChange = FALSE;
  1234. }
  1235. //hDC = GetDCEx(psb->hwnd, hRgn, DCX_WINDOW|DCX_INTERSECTRGN|DCX_CACHE );
  1236. hDC = GetWindowDC(psb->hwnd);
  1237. // draw the size box
  1238. if( dwStyle & (WS_VSCROLL | WS_HSCROLL) )
  1239. SkinUI_DrawSizeBox(psb, hDC);
  1240. // Draw scrollbar
  1241. if( dwStyle & WS_VSCROLL )
  1242. SkinUI_DrawScrollBar(psb, hDC, TRUE);
  1243. if( dwStyle & WS_HSCROLL )
  1244. SkinUI_DrawScrollBar(psb, hDC, FALSE);
  1245. ReleaseDC(psb->hwnd, hDC);
  1246. return lr;
  1247. }
  1248. //----------------------------------------------------------
  1249. // Name : SkinUI_OnNcHitTest()
  1250. // Desc :
  1251. //----------------------------------------------------------
  1252. LRESULT SkinUI_OnNcHitTest(LPSB psb, WPARAM wParam, LPARAM lParam)
  1253. {
  1254. POINT pt;
  1255. RECT rcHorz, rcVert, rcSize;
  1256. pt.x = GET_X_LPARAM(lParam);
  1257. pt.y = GET_Y_LPARAM(lParam);
  1258. SkinUI_GetScrollBarRect(psb, TRUE, &rcVert);
  1259. SkinUI_GetScrollBarRect(psb, FALSE, &rcHorz);
  1260. SkinUI_GetSizeBoxRect(psb, &rcSize);
  1261. if( PtInRect(&rcVert, pt) )
  1262. return HTVSCROLL;
  1263. else if( PtInRect(&rcHorz, pt) )
  1264. return HTHSCROLL;
  1265. else if( PtInRect(&rcSize, pt) )
  1266. return HTSIZE;
  1267. return CallWindowProc(psb->pfnOldProc, psb->hwnd, WM_NCHITTEST, wParam, lParam);
  1268. }
  1269. //----------------------------------------------------------
  1270. // Name : SkinUI_OnNcMouseMove()
  1271. // Desc :
  1272. //----------------------------------------------------------
  1273. LRESULT SkinUI_OnNcMouseMove(LPSB psb, WPARAM wParam, LPARAM lParam)
  1274. {
  1275. if( wParam == HTHSCROLL || wParam == HTVSCROLL ) {
  1276. POINT pt;
  1277. BOOL fVert;
  1278. int nHitCode;
  1279. pt.x = GET_X_LPARAM(lParam);
  1280. pt.y = GET_Y_LPARAM(lParam);
  1281. fVert = ( wParam == HTVSCROLL );
  1282. nHitCode = SkinUI_HitTest(psb, fVert, pt);
  1283. SkinUI_HotTrack(psb, nHitCode, fVert, FALSE);
  1284. }
  1285. else if( wParam == HTSIZE ) {
  1286. SkinUI_HotTrack(psb, HTSCROLL_NONE, FALSE, FALSE);
  1287. }
  1288. return CallWindowProc(psb->pfnOldProc, psb->hwnd, WM_NCMOUSEMOVE, wParam, lParam);
  1289. }
  1290. //---------------------------------------------------------
  1291. // Name : SkinUI_OnNcMouseLeave()
  1292. // Desc :
  1293. //---------------------------------------------------------
  1294. LRESULT SkinUI_OnNcMouseLeave(LPSB psb, WPARAM wParam, LPARAM lParam)
  1295. {
  1296. psb->fMouseTracking = FALSE;
  1297. if( psb->fTracking )
  1298. return 0;
  1299. SkinUI_HotTrack(psb, HTSCROLL_NONE, FALSE, FALSE);
  1300. psb->nLastCode = HTSCROLL_NONE;
  1301. return 0;
  1302. }
  1303. //----------------------------------------------------------
  1304. // Name : SkinUI_OnNcLButtonDown()
  1305. // Desc :
  1306. //----------------------------------------------------------
  1307. LRESULT SkinUI_OnNcLButtonDown(LPSB psb, WPARAM wParam, LPARAM lParam)
  1308. {
  1309. if( wParam == HTHSCROLL || wParam == HTVSCROLL ) {
  1310. POINT pt;
  1311. BOOL fVert;
  1312. int nHitCode;
  1313. LPSCROLLINFO psi;
  1314. pt.x = GET_X_LPARAM(lParam);
  1315. pt.y = GET_Y_LPARAM(lParam);
  1316. fVert = (wParam == HTVSCROLL);
  1317. psi = (fVert ? &psb->Vert : &psb->Horz);
  1318. nHitCode = SkinUI_HitTest(psb, fVert, pt);
  1319. psb->nLastCode = nHitCode;
  1320. psb->fLastVert = fVert;
  1321. SkinUI_Track(psb, fVert, nHitCode, pt);
  1322. return 0;
  1323. }
  1324. return CallWindowProc(psb->pfnOldProc, psb->hwnd, WM_NCLBUTTONDOWN, wParam, lParam);
  1325. }
  1326. //----------------------------------------------------------
  1327. // Name : SkinUI_OnMouseMove()
  1328. // Desc :
  1329. //----------------------------------------------------------
  1330. LRESULT SkinUI_OnMouseMove(LPSB psb, WPARAM wParam, LPARAM lParam)
  1331. {
  1332. DWORD dwPos;
  1333. POINT pt;
  1334. UINT nHitCode, nHitTest;
  1335. dwPos = GetMessagePos();
  1336. pt.x = GET_X_LPARAM(dwPos);
  1337. pt.y = GET_Y_LPARAM(dwPos);
  1338. // Mouse left button down
  1339. if( psb->fTracking && wParam & MK_LBUTTON ) {
  1340. if( psb->nTrackCode == HTSCROLL_THUMB ) {
  1341. SkinUI_TrackThumb(psb, psb->fTrackVert, pt);
  1342. return 0;
  1343. }
  1344. nHitTest = (UINT)SkinUI_OnNcHitTest(psb, 0, dwPos);
  1345. if( nHitTest == HTHSCROLL || nHitTest == HTVSCROLL ) {
  1346. BOOL fVert = (nHitTest == HTVSCROLL);
  1347. nHitCode = SkinUI_HitTest(psb, fVert, pt);
  1348. if( nHitCode != psb->nTrackCode || fVert != psb->fTrackVert) {
  1349. // Unallowed hot-track other hittest item
  1350. SkinUI_HotTrack(psb, HTSCROLL_NONE, FALSE, FALSE);
  1351. }
  1352. else {
  1353. SkinUI_HotTrack(psb, psb->nTrackCode, psb->fTrackVert, TRUE);
  1354. }
  1355. }
  1356. else {
  1357. SkinUI_HotTrack(psb, HTSCROLL_NONE, FALSE, FALSE);
  1358. }
  1359. return 0;
  1360. }
  1361. return CallWindowProc(psb->pfnOldProc, psb->hwnd, WM_MOUSEMOVE, wParam, lParam);
  1362. }
  1363. //----------------------------------------------------------
  1364. // Name : SkinUI_OnLButtonUp()
  1365. // Desc :
  1366. //----------------------------------------------------------
  1367. LRESULT SkinUI_OnLButtonUp(LPSB psb, WPARAM wParam, LPARAM lParam)
  1368. {
  1369. if( psb->nTrackCode != HTSCROLL_NONE && psb->fTracking) {
  1370. // Release mouse capture
  1371. ReleaseCapture();
  1372. // End scroll
  1373. switch( psb->nTrackCode )
  1374. {
  1375. case HTSCROLL_LINEUP:
  1376. case HTSCROLL_LINEDOWN:
  1377. case HTSCROLL_PAGEUP:
  1378. case HTSCROLL_PAGEDOWN:
  1379. KillTimer(psb->hwnd, SB_TIMER_SCROLL);
  1380. DoScrollMsg(psb->hwnd, SB_ENDSCROLL, 0, psb->fTrackVert);
  1381. break;
  1382. case HTSCROLL_THUMB:
  1383. if( psb->fTracking ) {
  1384. DWORD dwPos;
  1385. POINT pt;
  1386. dwPos = GetMessagePos();
  1387. pt.x = GET_X_LPARAM(dwPos);
  1388. pt.y = GET_Y_LPARAM(dwPos);
  1389. DoScrollMsg(psb->hwnd, SB_THUMBPOSITION, psb->nTrackPos, psb->fTrackVert);
  1390. DoScrollMsg(psb->hwnd, SB_ENDSCROLL, 0, psb->fTrackVert);
  1391. psb->nLastCode = SkinUI_HitTest(psb, psb->fTrackVert, pt);
  1392. }
  1393. break;
  1394. }
  1395. // Clean the track parameters
  1396. psb->nOffsetPoint = 0;
  1397. psb->nScrollTimerMsg = MAKELONG(WM_NULL, 0);
  1398. psb->nTrackCode = HTSCROLL_NONE;
  1399. psb->fTracking = FALSE;
  1400. psb->nTrackPos = 0;
  1401. HDC hdc = GetWindowDC(psb->hwnd);
  1402. SkinUI_DrawThumb(psb, hdc, psb->fTrackVert);
  1403. ReleaseDC(psb->hwnd, hdc);
  1404. return 0;
  1405. }
  1406. return CallWindowProc(psb->pfnOldProc, psb->hwnd, WM_LBUTTONUP, wParam, lParam);
  1407. }
  1408. //----------------------------------------------------------
  1409. // Name : SkinUI_OnTimer()
  1410. // Desc :
  1411. //----------------------------------------------------------
  1412. LRESULT SkinUI_OnTimer(LPSB psb, WPARAM wParam, LPARAM lParam)
  1413. {
  1414. if(wParam == SB_TIMER_SCROLL) {
  1415. // if mouse left button released then close scroll timer
  1416. if( psb->nTrackCode == HTSCROLL_NONE ) {
  1417. KillTimer(psb->hwnd, SB_TIMER_SCROLL);
  1418. return 0;
  1419. }
  1420. // Timer send scroll message
  1421. if( psb->nTrackCode == psb->nLastCode && psb->fTrackVert == psb->fLastVert )
  1422. DoScrollMsg(psb->hwnd, HIWORD(psb->nScrollTimerMsg), 0, psb->fTrackVert);
  1423. return 0;
  1424. }
  1425. else if(wParam == SB_TIMER_DELAY) {
  1426. KillTimer(psb->hwnd, SB_TIMER_DELAY);
  1427. SetTimer(psb->hwnd, SB_TIMER_SCROLL, SB_SCROLL_INTERVAL, 0);
  1428. return 0;
  1429. }
  1430. return CallWindowProc(psb->pfnOldProc, psb->hwnd, WM_TIMER, wParam, lParam);
  1431. }
  1432. //----------------------------------------------------------
  1433. // Name : SkinUI_Proc()
  1434. // Desc :
  1435. //----------------------------------------------------------
  1436. LRESULT CALLBACK SkinUI_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1437. {
  1438. LPSB psb = SkinUI_GetSB(hwnd);
  1439. if( psb && uMsg == WM_NCMOUSEMOVE ) {
  1440. if(!psb->fMouseTracking && !psb->fTracking) {
  1441. TRACKMOUSEEVENT tme;
  1442. tme.cbSize = sizeof(tme);
  1443. tme.hwndTrack = psb->hwnd;
  1444. tme.dwFlags = TME_LEAVE|TME_NONCLIENT;
  1445. tme.dwHoverTime = 0;
  1446. psb->fMouseTracking = _TrackMouseEvent(&tme);
  1447. }
  1448. }
  1449. switch( uMsg )
  1450. {
  1451. case WM_NCPAINT:
  1452. return SkinUI_OnNcPaint(psb, (HRGN)wParam);
  1453. case WM_NCCALCSIZE:
  1454. return SkinUI_OnNcCalcSize(psb, (BOOL)wParam, (NCCALCSIZE_PARAMS*)lParam);
  1455. case WM_NCHITTEST:
  1456. return SkinUI_OnNcHitTest(psb, wParam, lParam);
  1457. case WM_STYLECHANGED:
  1458. return SkinUI_OnStyleChanged(psb, (int)wParam, (LPSTYLESTRUCT)lParam);
  1459. case WM_NCLBUTTONDOWN:
  1460. return SkinUI_OnNcLButtonDown(psb, wParam, lParam);
  1461. case WM_NCMOUSEMOVE:
  1462. return SkinUI_OnNcMouseMove(psb, wParam, lParam);
  1463. case WM_MOUSEMOVE:
  1464. return SkinUI_OnMouseMove(psb, wParam, lParam);
  1465. case WM_LBUTTONUP:
  1466. return SkinUI_OnLButtonUp(psb, wParam, lParam);
  1467. case WM_NCMOUSELEAVE:
  1468. return SkinUI_OnNcMouseLeave(psb, wParam, lParam);
  1469. case WM_NCLBUTTONDBLCLK:
  1470. case WM_NCRBUTTONDBLCLK:
  1471. return 0;
  1472. case WM_TIMER:
  1473. return SkinUI_OnTimer(psb, wParam, lParam);
  1474. case WM_NCDESTROY:
  1475. LRESULT lr = CallWindowProc(psb->pfnOldProc, hwnd, uMsg, wParam, lParam);
  1476. SkinUI_Uninit(hwnd);
  1477. return lr;
  1478. }
  1479. return CallWindowProc(psb->pfnOldProc, hwnd, uMsg, wParam, lParam);
  1480. }