SkinVerticleScrollbar.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. // SkinVerticleScrollbar.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "CP_Main.h"
  5. #include "Misc.h"
  6. #include "SkinVerticleScrollbar.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CSkinVerticleScrollbar
  14. CSkinVerticleScrollbar::CSkinVerticleScrollbar()
  15. {
  16. m_bMouseDown = false;
  17. m_nThumbTop = 36;
  18. m_dbThumbInterval = 0.000000;
  19. m_pList = NULL;
  20. m_cbArrow1.LoadBitmap(IDB_VERTICAL_SCROLLBAR_UPARROW);
  21. m_cbArrow2.LoadBitmap(IDB_VERTICAL_SCROLLBAR_DOWNARROW);
  22. m_cbSpan.LoadBitmap(IDB_VERTICAL_SCROLLBAR_CHANNEL);
  23. m_cbThumb.LoadBitmap(IDB_VERTICAL_SCROLLBAR_THUMB);
  24. m_csArrow1 = CSize(GetCBitmapWidth(m_cbArrow1), GetCBitmapHeight(m_cbArrow1));
  25. m_csArrow2 = CSize(GetCBitmapWidth(m_cbArrow2), GetCBitmapHeight(m_cbArrow2));
  26. m_csSpan = CSize(GetCBitmapWidth(m_cbSpan), GetCBitmapHeight(m_cbSpan));
  27. m_csThumb = CSize(GetCBitmapWidth(m_cbThumb), GetCBitmapHeight(m_cbThumb));
  28. }
  29. CSkinVerticleScrollbar::~CSkinVerticleScrollbar()
  30. {
  31. m_cbArrow1.DeleteObject();
  32. m_cbArrow2.DeleteObject();
  33. m_cbSpan.DeleteObject();
  34. m_cbThumb.DeleteObject();
  35. }
  36. BEGIN_MESSAGE_MAP(CSkinVerticleScrollbar, CStatic)
  37. //{{AFX_MSG_MAP(CSkinVerticleScrollbar)
  38. ON_WM_ERASEBKGND()
  39. ON_WM_LBUTTONDOWN()
  40. ON_WM_LBUTTONUP()
  41. ON_WM_MOUSEMOVE()
  42. ON_WM_PAINT()
  43. ON_WM_TIMER()
  44. //}}AFX_MSG_MAP
  45. END_MESSAGE_MAP()
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CSkinVerticleScrollbar message handlers
  48. BOOL CSkinVerticleScrollbar::OnEraseBkgnd(CDC* pDC)
  49. {
  50. return CStatic::OnEraseBkgnd(pDC);
  51. }
  52. void CSkinVerticleScrollbar::OnLButtonDown(UINT nFlags, CPoint point)
  53. {
  54. SetCapture();
  55. CRect clientRect;
  56. GetClientRect(&clientRect);
  57. CRect rectThumb(0, m_nThumbTop, m_csThumb.cx, m_nThumbTop + m_csThumb.cy);
  58. if(rectThumb.PtInRect(point))
  59. {
  60. m_bMouseDown = true;
  61. }
  62. else
  63. {
  64. Scroll();
  65. }
  66. SetTimer(2, 250, NULL);
  67. CStatic::OnLButtonDown(nFlags, point);
  68. }
  69. void CSkinVerticleScrollbar::OnLButtonUp(UINT nFlags, CPoint point)
  70. {
  71. ReleaseCapture();
  72. KillTimer(2);
  73. KillTimer(1);
  74. m_bMouseDown = false;
  75. CStatic::OnLButtonUp(nFlags, point);
  76. }
  77. void CSkinVerticleScrollbar::Scroll()
  78. {
  79. bool bInChannel = true;
  80. CRect clientRect;
  81. GetClientRect(&clientRect);
  82. CRect rectUpArrow(0, 0, m_csArrow1.cx, m_csArrow1.cy);
  83. CRect rectDownArrow(0, clientRect.bottom - m_csArrow2.cy,
  84. m_csArrow2.cx,
  85. clientRect.bottom);
  86. CRect rectThumb(0, m_nThumbTop, m_csThumb.cx, m_nThumbTop + m_csThumb.cy);
  87. CPoint point;
  88. GetCursorPos(&point);
  89. ScreenToClient(&point);
  90. if(rectUpArrow.PtInRect(point))
  91. {
  92. ScrollUp();
  93. }
  94. else if(rectDownArrow.PtInRect(point))
  95. {
  96. ScrollDown();
  97. }
  98. else if(rectThumb.PtInRect(point))
  99. {
  100. }
  101. else if(clientRect.PtInRect(point))
  102. {
  103. if(!m_bMouseDown)
  104. {
  105. if(point.y > m_nThumbTop)
  106. {
  107. PageDown();
  108. }
  109. else
  110. {
  111. PageUp();
  112. }
  113. }
  114. }
  115. }
  116. void CSkinVerticleScrollbar::OnMouseMove(UINT nFlags, CPoint point)
  117. {
  118. if(m_bMouseDown)
  119. {
  120. CRect clientRect;
  121. GetClientRect(&clientRect);
  122. m_nThumbTop = point.y - m_csThumb.cy / 2; //so mouse is in middle of thumb
  123. int nMax = m_pList->GetScrollLimit(SB_VERT);
  124. int nPos = m_pList->GetScrollPos(SB_VERT);
  125. int nHeight = clientRect.Height() - m_csArrow1.cy - m_csArrow2.cy - m_csThumb.cy;
  126. m_dbThumbInterval = nHeight/(double)nMax;
  127. double dScrollTimes = ((m_nThumbTop-m_csArrow1.cy) / m_dbThumbInterval)-nPos;
  128. //grab the row height dynamically
  129. //so if the font size or type changes
  130. //our scroll will still work properly
  131. CRect itemrect;
  132. m_pList->GetItemRect(0,&itemrect, LVIR_BOUNDS);
  133. CSize size;
  134. size.cx = 0;
  135. size.cy = dScrollTimes * itemrect.Height();
  136. m_pList->Scroll(size);
  137. LimitThumbPosition();
  138. Draw();
  139. }
  140. CStatic::OnMouseMove(nFlags, point);
  141. }
  142. void CSkinVerticleScrollbar::OnPaint()
  143. {
  144. CPaintDC dc(this);
  145. Draw();
  146. }
  147. void CSkinVerticleScrollbar::OnTimer(UINT nIDEvent)
  148. {
  149. if(nIDEvent == 1)
  150. {
  151. Scroll();
  152. }
  153. else if(nIDEvent == 2)
  154. {
  155. KillTimer(2);
  156. SetTimer(1, 50, NULL);
  157. }
  158. CStatic::OnTimer(nIDEvent);
  159. }
  160. void CSkinVerticleScrollbar::PageDown()
  161. {
  162. m_pList->SendMessage(WM_VSCROLL, MAKELONG(SB_PAGEDOWN,0),NULL);
  163. UpdateThumbPosition();
  164. }
  165. void CSkinVerticleScrollbar::PageUp()
  166. {
  167. m_pList->SendMessage(WM_VSCROLL, MAKELONG(SB_PAGEUP,0),NULL);
  168. UpdateThumbPosition();
  169. }
  170. void CSkinVerticleScrollbar::ScrollUp()
  171. {
  172. m_pList->SendMessage(WM_VSCROLL, MAKELONG(SB_LINEUP,0),NULL);
  173. UpdateThumbPosition();
  174. }
  175. void CSkinVerticleScrollbar::ScrollDown()
  176. {
  177. m_pList->SendMessage(WM_VSCROLL, MAKELONG(SB_LINEDOWN,0),NULL);
  178. UpdateThumbPosition();
  179. }
  180. void CSkinVerticleScrollbar::UpdateThumbPosition()
  181. {
  182. CRect clientRect;
  183. GetClientRect(&clientRect);
  184. double nPos = m_pList->GetScrollPos(SB_VERT);
  185. double nMax = m_pList->GetScrollLimit(SB_VERT);
  186. double nHeight = clientRect.Height() - (m_csArrow2.cy + m_csArrow1.cy + m_csThumb.cy);
  187. m_dbThumbInterval = nHeight/nMax;
  188. m_nThumbTop = m_dbThumbInterval * nPos;
  189. m_nThumbTop += m_csArrow1.cy;
  190. LimitThumbPosition();
  191. Draw();
  192. }
  193. void CSkinVerticleScrollbar::Draw()
  194. {
  195. CClientDC dc(this);
  196. CRect clientRect;
  197. GetClientRect(&clientRect);
  198. CMemDC memDC(&dc, &clientRect);
  199. memDC.FillSolidRect(&clientRect, RGB(255, 255, 255));
  200. CDC bitmapDC;
  201. bitmapDC.CreateCompatibleDC(&dc);
  202. //Top arrow
  203. CBitmap * pOldBitmap = bitmapDC.SelectObject(&m_cbArrow1);
  204. memDC.BitBlt(clientRect.left, clientRect.top, m_csArrow1.cx, m_csArrow1.cy, &bitmapDC, 0, 0, SRCCOPY);
  205. //draw the background (span)
  206. bitmapDC.SelectObject(&m_cbSpan);
  207. memDC.StretchBlt(clientRect.left,
  208. m_csArrow1.cy,
  209. m_csSpan.cx,
  210. m_nThumbTop,
  211. &bitmapDC, 0,0, 12, 1, SRCCOPY);
  212. //draw the down arrow of the scrollbar
  213. bitmapDC.SelectObject(&m_cbArrow2);
  214. memDC.BitBlt(clientRect.left,
  215. clientRect.bottom - m_csArrow2.cy,
  216. m_csArrow2.cx, m_csArrow2.cy,
  217. &bitmapDC, 0, 0, SRCCOPY);
  218. //draw the thumb control
  219. pOldBitmap = bitmapDC.SelectObject(&m_cbThumb);
  220. memDC.BitBlt(0, m_nThumbTop, m_csThumb.cx, m_csThumb.cy, &bitmapDC, 0, 0, SRCCOPY);
  221. bitmapDC.SelectObject(pOldBitmap);
  222. pOldBitmap = NULL;
  223. }
  224. void CSkinVerticleScrollbar::LimitThumbPosition()
  225. {
  226. CRect clientRect;
  227. GetClientRect(&clientRect);
  228. if(m_nThumbTop + m_csThumb.cy > (clientRect.Height() - m_csArrow2.cy))
  229. {
  230. m_nThumbTop = clientRect.Height() - m_csArrow2.cy - m_csThumb.cy;
  231. }
  232. if(m_nThumbTop < (clientRect.top + m_csArrow1.cy))
  233. {
  234. m_nThumbTop = clientRect.top + m_csArrow1.cy;
  235. }
  236. }