SkinScrollBar.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. //////////////////////////////////////////////////////////////////////////
  2. #include "stdafx.h"
  3. #include "SkinScrollBar.h"
  4. #define TIMERID_NOTIFY 100
  5. #define TIMERID_DELAY 200
  6. #define TIME_DELAY 500
  7. #define TIME_INTER 100
  8. #define THUMB_BORDER 3
  9. #define THUMB_MINSIZE (THUMB_BORDER*2)
  10. /////////////////////////////////////////////////////////////////////////////
  11. // CSkinScrollBar
  12. CSkinScrollBar::CSkinScrollBar()
  13. {
  14. m_hBmp=NULL;
  15. m_bDrag=FALSE;
  16. memset(&m_si,0,sizeof(SCROLLINFO));
  17. m_si.nTrackPos=-1;
  18. m_uClicked=-1;
  19. m_bNotify=FALSE;
  20. m_uHtPrev=-1;
  21. m_bPause=FALSE;
  22. m_bTrace=FALSE;
  23. }
  24. CSkinScrollBar::~CSkinScrollBar()
  25. {
  26. }
  27. BEGIN_MESSAGE_MAP(CSkinScrollBar, CScrollBar)
  28. ON_WM_SIZE()
  29. ON_WM_PAINT()
  30. ON_WM_LBUTTONDOWN()
  31. ON_WM_MOUSEMOVE()
  32. ON_WM_LBUTTONUP()
  33. ON_WM_TIMER()
  34. ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
  35. ON_WM_DESTROY()
  36. END_MESSAGE_MAP()
  37. /////////////////////////////////////////////////////////////////////////////
  38. BOOL CSkinScrollBar::IsVertical()
  39. {
  40. DWORD dwStyle=GetStyle();
  41. return dwStyle&SBS_VERT;
  42. }
  43. UINT CSkinScrollBar::HitTest(CPoint pt)
  44. {
  45. int nTestPos=pt.y;
  46. if(!IsVertical()) nTestPos=pt.x;
  47. if(nTestPos<0) return -1;
  48. SCROLLINFO si=m_si;
  49. int nInterHei=m_nHei-2*m_nWid;
  50. if(nInterHei<0) nInterHei=0;
  51. int nSlideHei=si.nPage*nInterHei/(si.nMax-si.nMin+1);
  52. if(nSlideHei<THUMB_MINSIZE) nSlideHei=THUMB_MINSIZE;
  53. if(nInterHei<THUMB_MINSIZE) nSlideHei=0;
  54. int nEmptyHei=nInterHei-nSlideHei;
  55. int nArrowHei=(nInterHei==0)?(m_nHei/2):m_nWid;
  56. int nBottom=0;
  57. int nSegLen=nArrowHei;
  58. nBottom+=nSegLen;
  59. UINT uHit=SB_LINEUP;
  60. if(nTestPos<nBottom) goto end;
  61. if(si.nTrackPos==-1) si.nTrackPos=si.nPos;
  62. uHit=SB_PAGEUP;
  63. if((si.nMax-si.nMin-si.nPage+1)==0)
  64. nSegLen=nEmptyHei/2;
  65. else
  66. nSegLen=nEmptyHei*si.nTrackPos/(si.nMax-si.nMin-si.nPage+1);
  67. nBottom+=nSegLen;
  68. if(nTestPos<nBottom) goto end;
  69. nSegLen=nSlideHei;
  70. nBottom+=nSegLen;
  71. uHit=SB_THUMBTRACK;
  72. if(nTestPos<nBottom) goto end;
  73. nBottom=m_nHei-nArrowHei;
  74. uHit=SB_PAGEDOWN;
  75. if(nTestPos<nBottom) goto end;
  76. uHit=SB_LINEDOWN;
  77. end:
  78. return uHit;
  79. }
  80. void CSkinScrollBar::SetBitmap(HBITMAP hBmp)
  81. {
  82. ASSERT(m_hWnd);
  83. m_hBmp=hBmp;
  84. BITMAP bm;
  85. GetObject(hBmp,sizeof(bm),&bm);
  86. m_nWid=bm.bmWidth/9;
  87. m_nFrmHei=bm.bmHeight/3;
  88. CRect rc;
  89. GetWindowRect(&rc);
  90. GetParent()->ScreenToClient(&rc);
  91. if(IsVertical())
  92. {
  93. rc.right=rc.left+m_nWid;
  94. }else
  95. {
  96. rc.bottom=rc.top+m_nWid;
  97. }
  98. MoveWindow(&rc);
  99. }
  100. void CSkinScrollBar::OnSize(UINT nType, int cx, int cy)
  101. {
  102. CScrollBar::OnSize(nType, cx, cy);
  103. m_nHei=IsVertical()?cy:cx;
  104. }
  105. void CSkinScrollBar::OnPaint()
  106. {
  107. CPaintDC dc(this);
  108. if(!m_hBmp) return;
  109. CDC memdc;
  110. memdc.CreateCompatibleDC(&dc);
  111. HGDIOBJ hOldBmp=::SelectObject(memdc,m_hBmp);
  112. RECT rcSour={0,0,m_nWid,m_nWid};
  113. if(!IsVertical()) OffsetRect(&rcSour,m_nWid*4,0);
  114. RECT rcDest;
  115. rcDest=GetRect(SB_LINEUP);
  116. if((rcDest.right-rcDest.left != rcSour.right-rcSour.left)
  117. ||(rcDest.bottom-rcDest.top != rcSour.bottom-rcSour.top))
  118. dc.StretchBlt(rcDest.left,rcDest.top,rcDest.right-rcDest.left,rcDest.bottom-rcDest.top,
  119. &memdc,
  120. rcSour.left,rcSour.top,rcSour.right-rcSour.left,rcSour.bottom-rcSour.top,
  121. SRCCOPY);
  122. else
  123. dc.BitBlt(rcDest.left,rcDest.top,m_nWid,m_nWid,&memdc,rcSour.left,rcSour.top,SRCCOPY);
  124. rcDest=GetRect(SB_LINEDOWN);
  125. OffsetRect(&rcSour,m_nWid,0);
  126. if((rcDest.right-rcDest.left != rcSour.right-rcSour.left)
  127. ||(rcDest.bottom-rcDest.top != rcSour.bottom-rcSour.top))
  128. dc.StretchBlt(rcDest.left,rcDest.top,rcDest.right-rcDest.left,rcDest.bottom-rcDest.top,
  129. &memdc,
  130. rcSour.left,rcSour.top,rcSour.right-rcSour.left,rcSour.bottom-rcSour.top,
  131. SRCCOPY);
  132. else
  133. dc.BitBlt(rcDest.left,rcDest.top,m_nWid,m_nWid,&memdc,rcSour.left,rcSour.top,SRCCOPY);
  134. rcDest=GetRect(SB_THUMBTRACK);
  135. OffsetRect(&rcSour,m_nWid,0);
  136. DrawThumb(&dc,&rcDest,&memdc,&rcSour);
  137. OffsetRect(&rcSour,m_nWid,0);
  138. rcDest=GetRect(SB_PAGEUP);
  139. TileBlt(&dc,&rcDest,&memdc,&rcSour);
  140. rcDest=GetRect(SB_PAGEDOWN);
  141. TileBlt(&dc,&rcDest,&memdc,&rcSour);
  142. ::SelectObject(memdc,hOldBmp);
  143. }
  144. RECT CSkinScrollBar::GetImageRect(UINT uSBCode,int nState)
  145. {
  146. int nIndex=0;
  147. switch(uSBCode)
  148. {
  149. case SB_LINEUP:nIndex=0;break;
  150. case SB_PAGEUP:nIndex=3;break;
  151. case SB_THUMBTRACK:nIndex=2;break;
  152. case SB_PAGEDOWN:nIndex=3;break;
  153. case SB_LINEDOWN:nIndex=1;break;
  154. }
  155. if(!IsVertical())nIndex+=4;
  156. RECT rcRet={m_nWid*nIndex,m_nWid*nState,m_nWid*(nIndex+1),m_nWid*(nState+1)};
  157. return rcRet;
  158. }
  159. RECT CSkinScrollBar::GetRect(UINT uSBCode)
  160. {
  161. SCROLLINFO si=m_si;
  162. if(si.nTrackPos==-1) si.nTrackPos=si.nPos;
  163. int nInterHei=m_nHei-2*m_nWid;
  164. if(nInterHei<0) nInterHei=0;
  165. int nSlideHei=si.nPage*nInterHei/(si.nMax-si.nMin+1);
  166. if(nSlideHei<THUMB_MINSIZE) nSlideHei=THUMB_MINSIZE;
  167. if(nInterHei<THUMB_MINSIZE) nSlideHei=0;
  168. if((si.nMax-si.nMin-si.nPage+1)==0) nSlideHei=0;
  169. int nEmptyHei=nInterHei-nSlideHei;
  170. int nArrowHei=m_nWid;
  171. if(nInterHei==0) nArrowHei=m_nHei/2;
  172. RECT rcRet={0,0,m_nWid,nArrowHei};
  173. if(uSBCode==SB_LINEUP) goto end;
  174. rcRet.top=rcRet.bottom;
  175. if((si.nMax-si.nMin-si.nPage+1)==0)
  176. rcRet.bottom+=nEmptyHei/2;
  177. else
  178. rcRet.bottom+=nEmptyHei*si.nTrackPos/(si.nMax-si.nMin-si.nPage+1);
  179. if(uSBCode==SB_PAGEUP) goto end;
  180. rcRet.top=rcRet.bottom;
  181. rcRet.bottom+=nSlideHei;
  182. if(uSBCode==SB_THUMBTRACK) goto end;
  183. rcRet.top=rcRet.bottom;
  184. rcRet.bottom=m_nHei-nArrowHei;
  185. if(uSBCode==SB_PAGEDOWN) goto end;
  186. rcRet.top=rcRet.bottom;
  187. rcRet.bottom=m_nHei;
  188. if(uSBCode==SB_LINEDOWN) goto end;
  189. end:
  190. if(!IsVertical())
  191. {
  192. int t=rcRet.left;
  193. rcRet.left=rcRet.top;
  194. rcRet.top=t;
  195. t=rcRet.right;
  196. rcRet.right=rcRet.bottom;
  197. rcRet.bottom=t;
  198. }
  199. return rcRet;
  200. }
  201. void CSkinScrollBar::TileBlt(CDC *pDestDC, RECT *pDestRect, CDC *pSourDC, RECT *pSourRect)
  202. {
  203. int nSourHei=pSourRect->bottom-pSourRect->top;
  204. int nSourWid=pSourRect->right-pSourRect->left;
  205. int y=pDestRect->top;
  206. while(y<pDestRect->bottom)
  207. {
  208. int nHei=nSourHei;
  209. if(y+nHei>pDestRect->bottom) nHei=pDestRect->bottom-y;
  210. int x=pDestRect->left;
  211. while(x<pDestRect->right)
  212. {
  213. int nWid=nSourWid;
  214. if(x+nWid>pDestRect->right) nWid=pDestRect->right-x;
  215. pDestDC->BitBlt(x,y,nWid,nHei,pSourDC,pSourRect->left,pSourRect->top,SRCCOPY);
  216. x+=nWid;
  217. }
  218. y+=nHei;
  219. }
  220. }
  221. void CSkinScrollBar::DrawThumb(CDC *pDestDC, RECT *pDestRect, CDC *pSourDC, RECT *pSourRect)
  222. {
  223. if(IsRectEmpty(pDestRect)) return;
  224. RECT rcDest=*pDestRect,rcSour=*pSourRect;
  225. if(IsVertical())
  226. {
  227. ASSERT(pDestRect->bottom-pDestRect->top>=THUMB_MINSIZE);
  228. pDestDC->BitBlt(pDestRect->left,pDestRect->top,m_nWid,THUMB_BORDER,pSourDC,pSourRect->left,pSourRect->top,SRCCOPY);
  229. pDestDC->BitBlt(pDestRect->left,pDestRect->bottom-THUMB_BORDER,m_nWid,THUMB_BORDER,pSourDC,pSourRect->left,pSourRect->bottom-THUMB_BORDER,SRCCOPY);
  230. rcDest.top+=THUMB_BORDER,rcDest.bottom-=THUMB_BORDER;
  231. rcSour.top+=THUMB_BORDER,rcSour.bottom-=THUMB_BORDER;
  232. TileBlt(pDestDC,&rcDest,pSourDC,&rcSour);
  233. }else
  234. {
  235. ASSERT(pDestRect->right-pDestRect->left>=THUMB_MINSIZE);
  236. pDestDC->BitBlt(pDestRect->left,pDestRect->top,THUMB_BORDER,m_nWid,pSourDC,pSourRect->left,pSourRect->top,SRCCOPY);
  237. pDestDC->BitBlt(pDestRect->right-THUMB_BORDER,pDestRect->top,THUMB_BORDER,m_nWid,pSourDC,pSourRect->right-THUMB_BORDER,pSourRect->top,SRCCOPY);
  238. rcDest.left+=THUMB_BORDER,rcDest.right-=THUMB_BORDER;
  239. rcSour.left+=THUMB_BORDER,rcSour.right-=THUMB_BORDER;
  240. TileBlt(pDestDC,&rcDest,pSourDC,&rcSour);
  241. }
  242. }
  243. void CSkinScrollBar::OnLButtonDown(UINT nFlags, CPoint point)
  244. {
  245. SetCapture();
  246. UINT uHit=HitTest(point);
  247. if(uHit==SB_THUMBTRACK)
  248. {
  249. m_bDrag=TRUE;
  250. m_ptDrag=point;
  251. m_si.nTrackPos=m_si.nPos;
  252. m_nDragPos=m_si.nPos;
  253. }else
  254. {
  255. m_uClicked=uHit;
  256. GetParent()->SendMessage(IsVertical()?WM_VSCROLL:WM_HSCROLL,MAKELONG(m_uClicked,0),(LPARAM)m_hWnd);
  257. SetTimer(TIMERID_DELAY,TIME_DELAY,NULL);
  258. m_bPause=FALSE;
  259. if(uHit==SB_LINEUP||uHit==SB_LINEDOWN) DrawArrow(uHit,2);
  260. }
  261. }
  262. void CSkinScrollBar::OnMouseMove(UINT nFlags, CPoint point)
  263. {
  264. if(!m_bTrace && nFlags!=-1)
  265. {
  266. m_bTrace=TRUE;
  267. TRACKMOUSEEVENT tme;
  268. tme.cbSize = sizeof(tme);
  269. tme.hwndTrack = m_hWnd;
  270. tme.dwFlags = TME_LEAVE;
  271. tme.dwHoverTime = 1;
  272. m_bTrace = _TrackMouseEvent(&tme);
  273. }
  274. if(m_bDrag)
  275. {
  276. int nInterHei=m_nHei-2*m_nWid;
  277. int nSlideHei=m_si.nPage*nInterHei/(m_si.nMax-m_si.nMin+1);
  278. if(nSlideHei<THUMB_MINSIZE) nSlideHei=THUMB_MINSIZE;
  279. if(nInterHei<THUMB_MINSIZE) nSlideHei=0;
  280. int nEmptyHei=nInterHei-nSlideHei;
  281. int nDragLen=IsVertical()?point.y-m_ptDrag.y:point.x-m_ptDrag.x;
  282. int nSlide=(nEmptyHei==0)?0:(nDragLen*(int)(m_si.nMax-m_si.nMin-m_si.nPage+1)/nEmptyHei);
  283. int nNewTrackPos=m_nDragPos+nSlide;
  284. if(nNewTrackPos<m_si.nMin)
  285. {
  286. nNewTrackPos=m_si.nMin;
  287. }else if(nNewTrackPos>(int)(m_si.nMax-m_si.nMin-m_si.nPage+1))
  288. {
  289. nNewTrackPos=m_si.nMax-m_si.nMin-m_si.nPage+1;
  290. }
  291. if(nNewTrackPos!=m_si.nTrackPos)
  292. {
  293. CDC *pDC=GetDC();
  294. CDC memdc;
  295. memdc.CreateCompatibleDC(pDC);
  296. HGDIOBJ hOldBmp=SelectObject(memdc,m_hBmp);
  297. RECT rcThumb1=GetRect(SB_THUMBTRACK);
  298. m_si.nTrackPos=nNewTrackPos;
  299. RECT rcThumb2=GetRect(SB_THUMBTRACK);
  300. RECT rcSourSlide=GetImageRect(SB_PAGEUP,0);
  301. RECT rcSourThumb=GetImageRect(SB_THUMBTRACK,2);
  302. RECT rcOld;
  303. if(IsVertical())
  304. {
  305. rcOld.left=0,rcOld.right=m_nWid;
  306. if(rcThumb2.bottom>rcThumb1.bottom)
  307. {
  308. rcOld.top=rcThumb1.top;
  309. rcOld.bottom=rcThumb2.top;
  310. }else
  311. {
  312. rcOld.top=rcThumb2.bottom;
  313. rcOld.bottom=rcThumb1.bottom;
  314. }
  315. }else
  316. {
  317. rcOld.top=0,rcOld.bottom=m_nWid;
  318. if(rcThumb2.right>rcThumb1.right)
  319. {
  320. rcOld.left=rcThumb1.left;
  321. rcOld.right=rcThumb2.left;
  322. }else
  323. {
  324. rcOld.left=rcThumb2.right;
  325. rcOld.right=rcThumb1.right;
  326. }
  327. }
  328. TileBlt(pDC,&rcOld,&memdc,&rcSourSlide);
  329. DrawThumb(pDC,&rcThumb2,&memdc,&rcSourThumb);
  330. SelectObject(memdc,hOldBmp);
  331. ReleaseDC(pDC);
  332. GetParent()->SendMessage(IsVertical()?WM_VSCROLL:WM_HSCROLL,MAKELONG(SB_THUMBTRACK,m_si.nTrackPos),(LPARAM)m_hWnd);
  333. }
  334. }else if(m_uClicked!=-1)
  335. {
  336. CRect rc=GetRect(m_uClicked);
  337. m_bPause=!rc.PtInRect(point);
  338. if(m_uClicked==SB_LINEUP||m_uClicked==SB_LINEDOWN)
  339. {
  340. DrawArrow(m_uClicked,m_bPause?0:2);
  341. }
  342. }else
  343. {
  344. UINT uHit=HitTest(point);
  345. if(uHit!=m_uHtPrev)
  346. {
  347. if(m_uHtPrev!=-1)
  348. {
  349. if(m_uHtPrev==SB_THUMBTRACK)
  350. {
  351. CDC *pDC=GetDC();
  352. CDC memdc;
  353. memdc.CreateCompatibleDC(pDC);
  354. HGDIOBJ hOldBmp=SelectObject(memdc,m_hBmp);
  355. RECT rcDest=GetRect(SB_THUMBTRACK);
  356. RECT rcSour=GetImageRect(SB_THUMBTRACK,0);
  357. DrawThumb(pDC,&rcDest,&memdc,&rcSour);
  358. ReleaseDC(pDC);
  359. SelectObject(memdc,hOldBmp);
  360. }else if(m_uHtPrev==SB_LINEUP||m_uHtPrev==SB_LINEDOWN)
  361. {
  362. DrawArrow(m_uHtPrev,0);
  363. }
  364. }
  365. if(uHit!=-1)
  366. {
  367. if(uHit==SB_THUMBTRACK)
  368. {
  369. CDC *pDC=GetDC();
  370. CDC memdc;
  371. memdc.CreateCompatibleDC(pDC);
  372. HGDIOBJ hOldBmp=SelectObject(memdc,m_hBmp);
  373. RECT rcDest=GetRect(SB_THUMBTRACK);
  374. RECT rcSour=GetImageRect(SB_THUMBTRACK,1);
  375. DrawThumb(pDC,&rcDest,&memdc,&rcSour);
  376. ReleaseDC(pDC);
  377. SelectObject(memdc,hOldBmp);
  378. }else if(uHit==SB_LINEUP||uHit==SB_LINEDOWN)
  379. {
  380. DrawArrow(uHit,1);
  381. }
  382. }
  383. m_uHtPrev=uHit;
  384. }
  385. }
  386. }
  387. void CSkinScrollBar::OnLButtonUp(UINT nFlags, CPoint point)
  388. {
  389. ReleaseCapture();
  390. if(m_bDrag)
  391. {
  392. m_bDrag=FALSE;
  393. GetParent()->SendMessage(IsVertical()?WM_VSCROLL:WM_HSCROLL,MAKELONG(SB_THUMBPOSITION,m_si.nTrackPos),(LPARAM)m_hWnd);
  394. CDC *pDC=GetDC();
  395. CDC memdc;
  396. memdc.CreateCompatibleDC(pDC);
  397. HGDIOBJ hOldBmp=SelectObject(memdc,m_hBmp);
  398. if(m_si.nTrackPos != m_si.nPos)
  399. {
  400. RECT rcThumb=GetRect(SB_THUMBTRACK);
  401. RECT rcSour={m_nWid*3,0,m_nWid*4,m_nWid};
  402. if(!IsVertical()) OffsetRect(&rcSour,m_nWid*4,0);
  403. TileBlt(pDC,&rcThumb,&memdc,&rcSour);
  404. }
  405. m_si.nTrackPos=-1;
  406. RECT rcThumb=GetRect(SB_THUMBTRACK);
  407. RECT rcSour={m_nWid*2,0,m_nWid*3,m_nWid};
  408. if(PtInRect(&rcThumb,point)) OffsetRect(&rcSour,0,m_nWid);
  409. if(!IsVertical()) OffsetRect(&rcSour,m_nWid*4,0);
  410. DrawThumb(pDC,&rcThumb,&memdc,&rcSour);
  411. SelectObject(memdc,hOldBmp);
  412. ReleaseDC(pDC);
  413. }else if(m_uClicked!=-1)
  414. {
  415. if(m_bNotify)
  416. {
  417. KillTimer(TIMERID_NOTIFY);
  418. m_bNotify=FALSE;
  419. }else
  420. {
  421. KillTimer(TIMERID_DELAY);
  422. }
  423. if(m_uClicked==SB_LINEUP||m_uClicked==SB_LINEDOWN) DrawArrow(m_uClicked,0);
  424. m_uClicked=-1;
  425. }
  426. }
  427. void CSkinScrollBar::OnTimer(UINT nIDEvent)
  428. {
  429. if(nIDEvent==TIMERID_DELAY)
  430. {
  431. m_bNotify=TRUE;
  432. nIDEvent=TIMERID_NOTIFY;
  433. KillTimer(TIMERID_DELAY);
  434. SetTimer(TIMERID_NOTIFY,TIME_INTER,NULL);
  435. }
  436. if(nIDEvent==TIMERID_NOTIFY && !m_bPause)
  437. {
  438. ASSERT(m_uClicked!=-1 && m_uClicked!=SB_THUMBTRACK);
  439. switch(m_uClicked)
  440. {
  441. case SB_LINEUP:
  442. if(m_si.nPos==m_si.nMin)
  443. {
  444. KillTimer(TIMERID_NOTIFY);
  445. break;
  446. }
  447. GetParent()->SendMessage(IsVertical()?WM_VSCROLL:WM_HSCROLL,MAKELONG(SB_LINEUP,0),(LPARAM)m_hWnd);
  448. break;
  449. case SB_LINEDOWN:
  450. if(m_si.nPos==m_si.nMax)
  451. {
  452. KillTimer(TIMERID_NOTIFY);
  453. break;
  454. }
  455. GetParent()->SendMessage(IsVertical()?WM_VSCROLL:WM_HSCROLL,MAKELONG(SB_LINEDOWN,0),(LPARAM)m_hWnd);
  456. break;
  457. case SB_PAGEUP:
  458. case SB_PAGEDOWN:
  459. {
  460. CPoint pt;
  461. GetCursorPos(&pt);
  462. ScreenToClient(&pt);
  463. CRect rc=GetRect(SB_THUMBTRACK);
  464. if(rc.PtInRect(pt))
  465. {
  466. KillTimer(TIMERID_NOTIFY);
  467. break;
  468. }
  469. GetParent()->SendMessage(IsVertical()?WM_VSCROLL:WM_HSCROLL,MAKELONG(m_uClicked,0),(LPARAM)m_hWnd);
  470. }
  471. break;
  472. default:
  473. ASSERT(FALSE);
  474. break;
  475. }
  476. }
  477. }
  478. void CSkinScrollBar::DrawArrow(UINT uArrow, int nState)
  479. {
  480. ASSERT(uArrow==SB_LINEUP||uArrow==SB_LINEDOWN);
  481. CDC *pDC=GetDC();
  482. CDC memdc ;
  483. memdc.CreateCompatibleDC(pDC);
  484. HGDIOBJ hOldBmp=::SelectObject(memdc,m_hBmp);
  485. RECT rcDest=GetRect(uArrow);
  486. RECT rcSour=GetImageRect(uArrow,nState);
  487. if((rcDest.right-rcDest.left != rcSour.right-rcSour.left)
  488. ||(rcDest.bottom-rcDest.top != rcSour.bottom-rcSour.top))
  489. pDC->StretchBlt(rcDest.left,rcDest.top,rcDest.right-rcDest.left,rcDest.bottom-rcDest.top,
  490. &memdc,
  491. rcSour.left,rcSour.top,rcSour.right-rcSour.left,rcSour.bottom-rcSour.top,
  492. SRCCOPY);
  493. else
  494. pDC->BitBlt(rcDest.left,rcDest.top,m_nWid,m_nWid,&memdc,rcSour.left,rcSour.top,SRCCOPY);
  495. ReleaseDC(pDC);
  496. ::SelectObject(memdc,hOldBmp);
  497. }
  498. LRESULT CSkinScrollBar::OnMouseLeave(WPARAM wparam, LPARAM lparam)
  499. {
  500. m_bTrace = FALSE;
  501. OnMouseMove(-1,CPoint(-1,-1));
  502. return 0;
  503. }
  504. LRESULT CSkinScrollBar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  505. {
  506. if(message==WM_LBUTTONDBLCLK) return 1;
  507. if(message==SBM_SETSCROLLINFO)
  508. {
  509. BOOL bRedraw=(BOOL)wParam;
  510. LPSCROLLINFO lpScrollInfo=(LPSCROLLINFO)lParam;
  511. if(lpScrollInfo->fMask&SIF_PAGE) m_si.nPage=lpScrollInfo->nPage;
  512. if(lpScrollInfo->fMask&SIF_POS) m_si.nPos=lpScrollInfo->nPos;
  513. if(lpScrollInfo->fMask&SIF_RANGE)
  514. {
  515. m_si.nMin=lpScrollInfo->nMin;
  516. m_si.nMax=lpScrollInfo->nMax;
  517. }
  518. if(bRedraw)
  519. {
  520. CDC *pDC=GetDC();
  521. CDC memdc;
  522. memdc.CreateCompatibleDC(pDC);
  523. HGDIOBJ hOldBmp=::SelectObject(memdc,m_hBmp);
  524. RECT rcSour=GetImageRect(SB_PAGEUP);
  525. RECT rcDest=GetRect(SB_PAGEUP);
  526. TileBlt(pDC,&rcDest,&memdc,&rcSour);
  527. rcDest=GetRect(SB_THUMBTRACK);
  528. rcSour=GetImageRect(SB_THUMBTRACK);
  529. DrawThumb(pDC,&rcDest,&memdc,&rcSour);
  530. rcDest=GetRect(SB_PAGEDOWN);
  531. rcSour=GetImageRect(SB_PAGEDOWN);
  532. TileBlt(pDC,&rcDest,&memdc,&rcSour);
  533. ::SelectObject(memdc,hOldBmp);
  534. ReleaseDC(pDC);
  535. }
  536. return TRUE;
  537. }
  538. if(message==SBM_GETSCROLLINFO)
  539. {
  540. LPSCROLLINFO lpScrollInfo=(LPSCROLLINFO)lParam;
  541. int nMask=lpScrollInfo->fMask;
  542. if(nMask&SIF_PAGE) lpScrollInfo->nPage=m_si.nPage;
  543. if(nMask&SIF_POS) lpScrollInfo->nPos=m_si.nPos;
  544. if(nMask&SIF_TRACKPOS) lpScrollInfo->nTrackPos=m_si.nTrackPos;
  545. if(nMask&SIF_RANGE)
  546. {
  547. lpScrollInfo->nMin=m_si.nMin;
  548. lpScrollInfo->nMax=m_si.nMax;
  549. }
  550. return TRUE;
  551. }
  552. return CScrollBar::WindowProc(message, wParam, lParam);
  553. }
  554. void CSkinScrollBar::OnDestroy()
  555. {
  556. CScrollBar::OnDestroy();
  557. RenderEngine->RemoveImage(m_pBackImg);
  558. }
  559. BOOL CSkinScrollBar::SetBackImage( LPCTSTR lpszFileName )
  560. {
  561. RenderEngine->RemoveImage(m_pBackImg);
  562. m_pBackImg = RenderEngine->GetImage(lpszFileName);
  563. if (NULL == m_pBackImg)
  564. return FALSE;
  565. else
  566. {
  567. SetBitmap(m_pBackImg->ImageToBitmap());
  568. return TRUE;
  569. }
  570. }