BitmapSlider.cpp
上传用户:dengkfang
上传日期:2008-12-30
资源大小:5233k
文件大小:22k
源码类别:

CA认证

开发平台:

Visual C++

  1. // BitmapSlider.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "BitmapSlider.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. /////////////////////////////////////////////////////////////////////////////
  11. //
  12. // CBitmapSlider v1.5
  13. //
  14. // It's free for everywhere - 16/September/2003 - Joon-ho Ryu
  15. //
  16. /////////////////////////////////////////////////////////////////////////////
  17. CBitmapSlider::CBitmapSlider()
  18. {
  19. m_nPos = m_nMin = 0;
  20. m_nMax = 100;
  21. m_nPage = 20;
  22. m_nMarginLeft = m_nMarginRight = m_nMarginTop = m_nMarginBottom = 0;
  23. m_nThumbWidth = m_nThumbHeight = 0;
  24. m_bChannel = m_bVertical = m_bThumb = m_bLButtonDown = FALSE;
  25. m_bFocusRect = m_bFocus = FALSE;
  26. m_bDrawFocusRect = TRUE;
  27. m_bEnable = TRUE;
  28. m_nThumbBgX = m_nThumbBgY = -1;
  29. }
  30. CBitmapSlider::~CBitmapSlider()
  31. {
  32. }
  33. BEGIN_MESSAGE_MAP(CBitmapSlider, CStatic)
  34. //{{AFX_MSG_MAP(CBitmapSlider)
  35. ON_WM_ERASEBKGND()
  36. ON_WM_PAINT()
  37. ON_WM_LBUTTONDOWN()
  38. ON_WM_MOUSEMOVE()
  39. ON_WM_LBUTTONUP()
  40. ON_WM_GETDLGCODE()
  41. ON_WM_KEYDOWN()
  42. ON_WM_KILLFOCUS()
  43. ON_WM_SETFOCUS()
  44. ON_WM_CREATE()
  45. ON_WM_DESTROY()
  46. //}}AFX_MSG_MAP
  47. END_MESSAGE_MAP()
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CBitmapSlider message handlers
  50. BOOL CBitmapSlider::OnEraseBkgnd(CDC* pDC) 
  51. {
  52. // Do not erase background for the transparency effect
  53. return TRUE;
  54. }
  55. // Draw channel and thumb
  56. //
  57. void CBitmapSlider::OnPaint() 
  58. {
  59. CPaintDC dcOrigin(this);
  60. // "Flicker Free Drawing In MFC" by Keith Rule
  61. CMemDC dc( &dcOrigin, &m_rect, m_bTransparentChannel );
  62. CDC dcMem;
  63. dcMem.CreateCompatibleDC( &dc );
  64. CBitmap *pbmTmp;
  65. // Delete focus rectangle for transparent channel
  66. if( m_bFocusRect && ( m_bTransparentChannel || !m_bChannel ) ) {
  67. dc.DrawFocusRect( m_rect );
  68. m_bFocusRect = FALSE;
  69. }
  70. // Draw channel
  71. if( m_bChannel ) {
  72. pbmTmp = dcMem.SelectObject( &m_bmChannel );
  73. // There is a bitmap for active channel
  74. if( m_bChannelActive && m_bEnable ) {
  75. // Vertical slider
  76. if( m_bVertical ) {
  77. // Lower part
  78. DrawBitmap( &dc, 0, Pos2Pixel(m_nPos),
  79. m_nWidth, m_nHeight - Pos2Pixel(m_nPos),
  80. &dcMem, 0, Pos2Pixel(m_nPos),
  81. &m_bmChannelActiveMask, m_bTransparentChannel );
  82. dcMem.SelectObject( &m_bmChannelActive );
  83. // Upper part
  84. DrawBitmap( &dc, 0, 0, m_nWidth, Pos2Pixel(m_nPos),
  85. &dcMem, 0, 0, &m_bmChannelMask, m_bTransparentChannel );
  86. // Horizontal slider
  87. } else {
  88. // Right side
  89. DrawBitmap( &dc, Pos2Pixel(m_nPos), 0,
  90. m_nWidth - Pos2Pixel(m_nPos), m_nHeight,
  91. &dcMem, Pos2Pixel(m_nPos), 0, 
  92. &m_bmChannelActiveMask, m_bTransparentChannel );
  93. dcMem.SelectObject( &m_bmChannelActive );
  94. // Left side
  95. DrawBitmap( &dc, 0, 0, Pos2Pixel(m_nPos), m_nHeight,
  96. &dcMem, 0, 0, &m_bmChannelMask, m_bTransparentChannel );
  97. }
  98. // Only one bitmap for channel
  99. } else {
  100. DrawBitmap( &dc, 0, 0, m_nWidth, m_nHeight,
  101. &dcMem, 0, 0, &m_bmChannelMask, m_bTransparentChannel );
  102. }
  103. dcMem.SelectObject( pbmTmp );
  104. }
  105. // If there is a bitmap to restore background image of a thumb
  106. if( m_nThumbBgX != -1 ) {
  107. RestoreBackground(
  108. &dc, m_nThumbBgX, m_nThumbBgY,
  109. m_nThumbWidth, m_nThumbHeight, &m_bmThumbBg );
  110. m_nThumbBgX = -1;
  111. }
  112. // Draw thumb
  113. if( m_bThumb && m_bEnable ) {
  114. if( m_bThumbActive && m_bLButtonDown )
  115. pbmTmp = dcMem.SelectObject( &m_bmThumbActive ); // Active thumb
  116. else
  117. pbmTmp = dcMem.SelectObject( &m_bmThumb ); // Normal thumb
  118. // Vertical slider
  119. if( m_bVertical ) {
  120. // Background image is need to be restored
  121. if( m_bTransparentChannel || !m_bChannel ) {
  122. m_nThumbBgX = m_nMarginLeft;
  123. m_nThumbBgY = Pos2Pixel(m_nPos) - m_nThumbHeight/2;
  124. CopyBackground(
  125. &dc, m_nThumbBgX, m_nThumbBgY,
  126. m_nThumbWidth, m_nThumbHeight, &m_bmThumbBg );
  127. }
  128. DrawBitmap(
  129. &dc, m_nMarginLeft, Pos2Pixel(m_nPos) - m_nThumbHeight/2,
  130. m_nThumbWidth, m_nThumbHeight,
  131. &dcMem, 0, 0, &m_bmThumbMask, m_bTransparentThumb );
  132. // Horizontal slider
  133. } else {
  134. // Background image is need to be restored
  135. if( m_bTransparentChannel || !m_bChannel ) {
  136. m_nThumbBgX = Pos2Pixel(m_nPos) - m_nThumbWidth/2;
  137. m_nThumbBgY = m_nMarginTop;
  138. CopyBackground(
  139. &dc, m_nThumbBgX, m_nThumbBgY,
  140. m_nThumbWidth, m_nThumbHeight, &m_bmThumbBg );
  141. }
  142. DrawBitmap(
  143. &dc, Pos2Pixel(m_nPos) - m_nThumbWidth/2, m_nMarginTop,
  144. m_nThumbWidth, m_nThumbHeight,
  145. &dcMem, 0, 0, &m_bmThumbMask, m_bTransparentThumb );
  146. } // if horizontal
  147. dcMem.SelectObject( pbmTmp );
  148. } // if draw thumb
  149. // Draw focus rectangle
  150. if( m_bDrawFocusRect && m_bFocus && m_bEnable ) {
  151. dc.DrawFocusRect( m_rect );
  152. m_bFocusRect = TRUE;
  153. }
  154. dcMem.DeleteDC();
  155. }
  156. // Sets the maximum range for the slider.
  157. //
  158. // Parameters:
  159. // [IN] nMax
  160. // Maximum position for the slider.
  161. // [IN] bRedraw
  162. // TRUE to redraw after the range is set.
  163. // FALSE to only change maximum position.
  164. //
  165. void CBitmapSlider::SetRangeMax(int nMax, BOOL bRedraw)
  166. {
  167. m_nMax = nMax;
  168. if( bRedraw )
  169. Invalidate();
  170. }
  171. // Sets the minimum range for the slider.
  172. //
  173. // Parameters:
  174. // [IN] nMin
  175. // Minimum position for the slider.
  176. // [IN] bRedraw
  177. // TRUE to redraw after the range is set.
  178. // FALSE to only change minimum position.
  179. //
  180. void CBitmapSlider::SetRangeMin(int nMin, BOOL bRedraw)
  181. {
  182. m_nMin = nMin;
  183. if( bRedraw )
  184. Invalidate();
  185. }
  186. // Sets the range (minimum and maximum positions) for the slider.
  187. //
  188. // Parameters:
  189. // [IN] nMin
  190. // Minimum position for the slider.
  191. // [IN] nMax
  192. // Maximum position for the slider.
  193. // [IN] bRedraw
  194. // TRUE to redraw after the range is set.
  195. // FALSE to only change the range.
  196. //
  197. void CBitmapSlider::SetRange(int nMin, int nMax, BOOL bRedraw)
  198. {
  199. SetRangeMin( nMin, FALSE );
  200. SetRangeMax( nMax, bRedraw );
  201. }
  202. // Sets the current position of the slider.
  203. //
  204. // Parameters:
  205. // [IN] nPos
  206. // Specifies the new slider position.
  207. //
  208. void CBitmapSlider::SetPos(int nPos)
  209. {
  210. m_nPos = nPos;
  211. // Boundary check
  212. if( m_nPos > m_nMax )
  213. m_nPos = m_nMax;
  214. if( m_nPos < m_nMin )
  215. m_nPos = m_nMin;
  216. Invalidate();
  217. }
  218. // Sets the size of the page for a control.
  219. //
  220. // Parameters:
  221. // [IN] nSize
  222. // The new page size of the control.
  223. //
  224. // Return value:
  225. // The previous page size.
  226. //
  227. int CBitmapSlider::SetPageSize(int nSize)
  228. {
  229. int nRet = m_nPage;
  230. m_nPage = nSize;
  231. return nRet;
  232. }
  233. // Sets the left, top, right, and bottom margins for a control
  234. //
  235. void CBitmapSlider::SetMargin(int nLeft, int nTop, int nRight, int nBottom )
  236. {
  237. SetMarginLeft( nLeft );
  238. SetMarginTop( nTop );
  239. SetMarginRight( nRight );
  240. SetMarginBottom( nBottom );
  241. }
  242. // Enables or disables control.
  243. //
  244. // [IN] bEnable
  245. // TRUE to enable control.
  246. // FALSE to disable control.
  247. //
  248. void CBitmapSlider::Enable(BOOL bEnable)
  249. {
  250. m_bEnable = bEnable;
  251. // If control is disabled during dragging
  252. if( !m_bEnable && m_bLButtonDown ) {
  253. m_bLButtonDown = FALSE;
  254. ReleaseCapture();
  255. }
  256. Invalidate();
  257. }
  258. // Specify whether draw focus rectangle or not.
  259. //
  260. // [IN] bDraw
  261. // TRUE to draw focus rectangle.
  262. // FALSE to hide focus rectangle.
  263. //
  264. // [IN] bRedraw
  265. // TRUE to redraw status is changed.
  266. // FALSE to only change the status.
  267. //
  268. void CBitmapSlider::DrawFocusRect(BOOL bDraw, BOOL bRedraw)
  269. {
  270. m_bDrawFocusRect = bDraw;
  271. if( bRedraw )
  272. Invalidate();
  273. }
  274. // Load bitmaps for a channel
  275. //
  276. // Parameters:
  277. // [IN] nChannelID
  278. // ID number of the bitmap resource of the channel.
  279. // [IN] nActiveID
  280. // ID number of the bitmap resource of the active channel.
  281. // [IN] bTransparent
  282. // TRUE to apply transparency effect.
  283. // FALSE to display normal bitmap.
  284. // [IN] clrpTransColor
  285. // RGB color to treat as transparent.
  286. // [IN] iTransPixelX
  287. // Logical x-coordinate of a point.
  288. // It's color will be treated as transparent.
  289. // [IN] iTransPixelY
  290. // Logical y-coordinate of a point.
  291. // It's color will be treated as transparent.
  292. //
  293. // Return value:
  294. // TRUE
  295. // Function succeedes.
  296. // FALSE
  297. // Function failes to load bitmaps.
  298. //
  299. BOOL CBitmapSlider::SetBitmapChannel(
  300. UINT nChannelID, UINT nActiveID , BOOL bTransparent,
  301. COLORREF clrpTransColor, int iTransPixelX, int iTransPixelY )
  302. {
  303. // This control will not have any bitmap for channel
  304. if( !nChannelID ) {
  305. m_bChannel = FALSE;
  306. m_bmChannel.DeleteObject();
  307. m_bmChannelMask.DeleteObject();
  308. m_bmChannelActive.DeleteObject();
  309. m_bmChannelActiveMask.DeleteObject();
  310. return TRUE;
  311. }
  312. // load a bitmap
  313. m_bmChannel.DeleteObject();
  314. if( !m_bmChannel.LoadBitmap( nChannelID ) )
  315. return FALSE;
  316. // Prepare mask for transparency effect.
  317. if( bTransparent ) {
  318. PrepareMask( &m_bmChannel, &m_bmChannelMask,
  319. clrpTransColor, iTransPixelX, iTransPixelY );
  320. }
  321. // Load a bitmap for active state.
  322. if( nActiveID ) {
  323. m_bmChannelActive.DeleteObject();
  324. if( !m_bmChannelActive.LoadBitmap( nActiveID ) ) {
  325. m_bmChannel.DeleteObject();
  326. if( bTransparent )
  327. m_bmChannelMask.DeleteObject();
  328. return FALSE;
  329. }
  330. if( bTransparent ) {
  331. PrepareMask( &m_bmChannelActive, &m_bmChannelActiveMask,
  332. clrpTransColor, iTransPixelX, iTransPixelY );
  333. }
  334. m_bChannelActive = TRUE;
  335. // There is no bitmap for active state.
  336. } else
  337. m_bChannelActive = FALSE;
  338. // Get size of bitmap.
  339. BITMAP bitmap;
  340. m_bmChannel.GetBitmap( &bitmap );
  341. m_nWidth = bitmap.bmWidth;
  342. m_nHeight = bitmap.bmHeight;
  343. // Compare size
  344. if( m_bChannelActive ) {
  345. BITMAP bitmap;
  346. m_bmChannelActive.GetBitmap( &bitmap );
  347. ASSERT( m_nWidth == bitmap.bmWidth && m_nHeight == bitmap.bmHeight );
  348. }
  349. // Change size of control as same as the bitmap.
  350. SetWindowPos(NULL, 0, 0, m_nWidth, m_nHeight, SWP_NOZORDER | SWP_NOMOVE);
  351. GetClientRect( &m_rect );
  352. m_bTransparentChannel = bTransparent;
  353. m_bChannel = TRUE;
  354. return TRUE;
  355. }
  356. // Load bitmaps for a thumb
  357. //
  358. // Parameters:
  359. // [IN] nThumbID
  360. // ID number of the bitmap resource of the thumb
  361. // [IN] nActiveID
  362. // ID number of the bitmap resource of the active thumb
  363. // [IN] bTransparent
  364. // TRUE to apply transparency effect
  365. // FALSE to display normal bitmap
  366. // [IN] clrpTransColor
  367. // RGB color to treat as transparent
  368. // [IN] iTransPixelX
  369. // Logical x-coordinate of a point.
  370. // It's color will be treated as transparent
  371. // [IN] iTransPixelY
  372. // Logical y-coordinate of a point.
  373. // It's color will be treated as transparent
  374. //
  375. // Return value:
  376. // TRUE
  377. // Function succeedes.
  378. // FALSE
  379. // Function failes to load bitmaps.
  380. //
  381. BOOL CBitmapSlider::SetBitmapThumb(
  382. UINT nThumbID, UINT nActiveID, BOOL bTransparent,
  383. COLORREF clrpTransColor, int iTransPixelX, int iTransPixelY )
  384. {
  385. // This control will not have bitmap
  386. if( !nThumbID ) {
  387. m_bThumb = FALSE;
  388. m_bmThumb.DeleteObject();
  389. m_bmThumbMask.DeleteObject();
  390. m_bmThumbActive.DeleteObject();
  391. m_bmThumbActiveMask.DeleteObject();
  392. m_bmThumbBg.DeleteObject();
  393. return TRUE;
  394. }
  395. // load a bitmap
  396. m_bmThumb.DeleteObject();
  397. if( !m_bmThumb.LoadBitmap( nThumbID ) )
  398. return FALSE;
  399. // Prepare mask for transparency effect.
  400. if( bTransparent ) {
  401. PrepareMask( &m_bmThumb, &m_bmThumbMask,
  402. clrpTransColor, iTransPixelX, iTransPixelY );
  403. }
  404. // Load a bitmap for active state.
  405. if( nActiveID ) {
  406. m_bmThumbActive.DeleteObject();
  407. if( !m_bmThumbActive.LoadBitmap( nActiveID ) ) {
  408. m_bmThumb.DeleteObject();
  409. if( bTransparent )
  410. m_bmThumbMask.DeleteObject();
  411. return FALSE;
  412. }
  413. if( bTransparent ) {
  414. PrepareMask( &m_bmThumbActive, &m_bmThumbActiveMask,
  415. clrpTransColor, iTransPixelX, iTransPixelY );
  416. }
  417. m_bThumbActive = TRUE;
  418. // There is no bitmap for active state.
  419. } else
  420. m_bThumbActive = FALSE;
  421. // Get size of the bitmap
  422. BITMAP bitmap;
  423. m_bmThumb.GetBitmap( &bitmap );
  424. m_nThumbWidth = bitmap.bmWidth;
  425. m_nThumbHeight = bitmap.bmHeight;
  426. // Get size of the control if there was no bitmap for channel.
  427. if( !m_bChannel ) {
  428. GetClientRect( &m_rect );
  429. m_nHeight = m_rect.Height();
  430. m_nWidth = m_rect.Width();
  431. }
  432. ASSERT( m_nThumbWidth <= m_nWidth && m_nThumbHeight <= m_nHeight );
  433. // Compare size
  434. if( m_bThumbActive ) {
  435. BITMAP bitmap;
  436. m_bmThumbActive.GetBitmap( &bitmap );
  437. ASSERT(
  438. m_nThumbWidth == bitmap.bmWidth &&
  439. m_nThumbHeight == bitmap.bmHeight );
  440. }
  441. // Set attributes
  442. m_bTransparentThumb = bTransparent;
  443. m_bThumb = TRUE;
  444. return TRUE;
  445. }
  446. // OnLButtonDown
  447. //
  448. // Dragging is started
  449. //
  450. void CBitmapSlider::OnLButtonDown(UINT nFlags, CPoint point) 
  451. {
  452. if( !m_bEnable )
  453. return;
  454. SetCapture();
  455. SetFocus();
  456. m_bLButtonDown = TRUE;
  457. // If mouse button is clicked on the thumb,
  458. // capture the coordinates of mouse pointer and center of thumb
  459. // and calculate distance between them.
  460. if( m_bVertical ) {
  461. if( abs( point.y - Pos2Pixel( m_nPos ) ) <= m_nThumbHeight / 2 )
  462. m_nMouseOffset = point.y - Pos2Pixel( m_nPos );
  463. else
  464. m_nMouseOffset = 0;
  465. } else {
  466. if( abs( point.x - Pos2Pixel( m_nPos ) ) <= m_nThumbWidth / 2 )
  467. m_nMouseOffset = point.x - Pos2Pixel( m_nPos );
  468. else
  469. m_nMouseOffset = 0;
  470. }
  471. OnMouseMove( nFlags, point );
  472. Invalidate();
  473. CStatic::OnLButtonDown(nFlags, point);
  474. }
  475. // OnMouseMove
  476. //
  477. // During dragging
  478. //
  479. void CBitmapSlider::OnMouseMove(UINT nFlags, CPoint point) 
  480. {
  481. if( !m_bLButtonDown || !m_bEnable )
  482. return;
  483. int nPixel;
  484. // Boundary check
  485. if( m_bVertical ) {
  486. nPixel = point.y - m_nMouseOffset;
  487. if( nPixel > m_nHeight - m_nMarginBottom - m_nThumbHeight/2 )
  488. nPixel = m_nHeight - m_nMarginBottom - m_nThumbHeight/2;
  489. if( nPixel < m_nMarginTop + m_nThumbHeight/2 )
  490. nPixel = m_nMarginTop + m_nThumbHeight/2;
  491. } else {
  492. nPixel = point.x - m_nMouseOffset;
  493. if( nPixel < m_nMarginLeft + m_nThumbWidth/2 )
  494. nPixel = m_nMarginLeft + m_nThumbWidth/2;
  495. if( nPixel > m_nWidth - m_nMarginRight - m_nThumbWidth/2 )
  496. nPixel = m_nWidth - m_nMarginRight - m_nThumbWidth/2;
  497. }
  498. // Apply change
  499. if( Pos2Pixel(m_nPos) != nPixel ) {
  500. SetPos( Pixel2Pos( nPixel ) );
  501. ::PostMessage(
  502. GetParent()->GetSafeHwnd(), WM_BITMAPSLIDER_MOVING,
  503. GetDlgCtrlID(), m_nPos );
  504. }
  505. CStatic::OnMouseMove(nFlags, point);
  506. }
  507. // OnLButtonUp
  508. //
  509. // Dragging is finished
  510. //
  511. void CBitmapSlider::OnLButtonUp(UINT nFlags, CPoint point) 
  512. {
  513. if( !m_bEnable )
  514. return;
  515. ReleaseCapture();
  516. m_bLButtonDown = FALSE;
  517. Invalidate();
  518. ::PostMessage(
  519. GetParent()->GetSafeHwnd(), WM_BITMAPSLIDER_MOVED,
  520. GetDlgCtrlID(), m_nPos );
  521. CStatic::OnLButtonUp(nFlags, point);
  522. }
  523. // Calculate point of thumb from position value
  524. //
  525. int CBitmapSlider::Pos2Pixel(int nPos)
  526. {
  527. if( m_bVertical ) {
  528. return
  529. m_nMarginTop + m_nThumbHeight/2 +
  530. (int)(
  531. ( m_nHeight - m_nMarginTop - m_nMarginBottom - m_nThumbHeight ) *
  532. ((double) ( nPos - m_nMin ) / ( m_nMax - m_nMin ) )
  533. );
  534. } else {
  535. return (int)(
  536. ( m_nWidth - m_nMarginLeft - m_nMarginRight - m_nThumbWidth ) *
  537. ((double) ( nPos - m_nMin ) / ( m_nMax - m_nMin ) )
  538. ) + m_nMarginLeft + m_nThumbWidth/2;
  539. }
  540. }
  541. // Calculate position value from point of mouse
  542. //
  543. int CBitmapSlider::Pixel2Pos(int nPixel)
  544. {
  545. if( m_bVertical ) {
  546. return (int)(
  547. m_nMin +
  548. (double)( nPixel - m_nMarginTop - m_nThumbHeight/2) /
  549. ( m_nHeight - m_nMarginBottom - m_nMarginTop - m_nThumbHeight ) *
  550. ( m_nMax - m_nMin )
  551. );
  552. } else {
  553. return (int)(
  554. m_nMin +
  555. (double)( nPixel - m_nMarginLeft - m_nThumbWidth/2 ) /
  556. ( m_nWidth - m_nMarginLeft - m_nMarginRight - m_nThumbWidth ) *
  557. ( m_nMax - m_nMin )
  558. );
  559. }
  560. }
  561. // Copy background image to bitmap
  562. //
  563. void CBitmapSlider::CopyBackground(
  564. CDC *pDC, int nXSrc, int nYSrc, int nWidth, int nHeight, CBitmap *pBmDst)
  565. {
  566. pBmDst->DeleteObject();
  567. pBmDst->CreateCompatibleBitmap( pDC, nWidth, nHeight );
  568. CDC memDC;
  569. memDC.CreateCompatibleDC( pDC );
  570. CBitmap *pBmTmp = memDC.SelectObject( pBmDst );
  571. memDC.BitBlt( 0, 0, nWidth, nHeight, pDC, nXSrc, nYSrc, SRCCOPY );
  572. memDC.SelectObject( pBmTmp );
  573. memDC.DeleteDC();
  574. }
  575. // Restore background image from bitmap
  576. //
  577. void CBitmapSlider::RestoreBackground(
  578. CDC *pDC, int nXDst, int nYDst, int nWidth, int nHeight, CBitmap *pBmSrc)
  579. {
  580. CDC memDC;
  581. memDC.CreateCompatibleDC( pDC );
  582. CBitmap *pBmTmp = memDC.SelectObject( pBmSrc );
  583. pDC->BitBlt( nXDst, nYDst, nWidth, nHeight, &memDC, 0, 0, SRCCOPY );
  584. memDC.SelectObject( pBmTmp );
  585. memDC.DeleteDC();
  586. }
  587. // DrawBitmap
  588. //
  589. // It's for code readability
  590. //
  591. void CBitmapSlider::DrawBitmap(
  592. CDC *pDC, int xStart, int yStart, int wWidth, int wHeight,
  593. CDC *pTmpDC, int xSource, int ySource, CBitmap *bmMask, BOOL bTransparent )
  594. {
  595. if( bTransparent ) {
  596. DrawTransparentBitmap(
  597. pDC, xStart, yStart,
  598. wWidth, wHeight,
  599. pTmpDC, xSource, ySource, bmMask );
  600. } else {
  601. pDC->BitBlt( xStart, yStart,
  602. wWidth, wHeight,
  603. pTmpDC, xSource, ySource, SRCCOPY );
  604. }
  605. }
  606. // PrepareMask
  607. //
  608. // "Drawing Transparent Bitmap with ease with on the fly masks in MFC"
  609. // By Raja Segar
  610. //
  611. // I changed default clrpTransColor value from NULL(black) to 0xFF000000(not RGB color)
  612. //
  613. void CBitmapSlider::PrepareMask(
  614. CBitmap *pBmpSource, CBitmap *pBmpMask,
  615. COLORREF clrpTransColor, int iTransPixelX, int iTransPixelY)
  616. {
  617. BITMAP bm;
  618. // Get the dimensions of the source bitmap
  619. pBmpSource->GetObject(sizeof(BITMAP), &bm);
  620. // Create the mask bitmap
  621. pBmpMask->DeleteObject();
  622. pBmpMask->CreateBitmap( bm.bmWidth, bm.bmHeight, 1, 1, NULL);
  623. // We will need two DCs to work with. One to hold the Image
  624. // (the source), and one to hold the mask (destination).
  625. // When blitting onto a monochrome bitmap from a color, pixels
  626. // in the source color bitmap that are equal to the background
  627. // color are blitted as white. All the remaining pixels are
  628. // blitted as black.
  629. CDC hdcSrc, hdcDst;
  630. hdcSrc.CreateCompatibleDC(NULL);
  631. hdcDst.CreateCompatibleDC(NULL);
  632. // Load the bitmaps into memory DC
  633. CBitmap* hbmSrcT = (CBitmap*) hdcSrc.SelectObject(pBmpSource);
  634. CBitmap* hbmDstT = (CBitmap*) hdcDst.SelectObject(pBmpMask);
  635. // Dynamically get the transparent color
  636. COLORREF clrTrans;
  637. if (clrpTransColor == 0xFF000000)
  638. {
  639. // User did not specify trans color so get it from bmp
  640. clrTrans = hdcSrc.GetPixel(iTransPixelX, iTransPixelY);
  641. }
  642. else
  643. {
  644. clrTrans = clrpTransColor;
  645. }
  646. // Change the background to trans color
  647. COLORREF clrSaveBk  = hdcSrc.SetBkColor(clrTrans);
  648. // This call sets up the mask bitmap.
  649. hdcDst.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &hdcSrc,0,0,SRCCOPY);
  650. // Now, we need to paint onto the original image, making
  651. // sure that the "transparent" area is set to black. What
  652. // we do is AND the monochrome image onto the color Image
  653. // first. When blitting from mono to color, the monochrome
  654. // pixel is first transformed as follows:
  655. // if  1 (black) it is mapped to the color set by SetTextColor().
  656. // if  0 (white) is is mapped to the color set by SetBkColor().
  657. // Only then is the raster operation performed.
  658. COLORREF clrSaveDstText = hdcSrc.SetTextColor(RGB(255,255,255));
  659. hdcSrc.SetBkColor(RGB(0,0,0));
  660. hdcSrc.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &hdcDst,0,0,SRCAND);
  661. // Clean up by deselecting any objects, and delete the
  662. // DC's.
  663. hdcDst.SetTextColor(clrSaveDstText);
  664. hdcSrc.SetBkColor(clrSaveBk);
  665. hdcSrc.SelectObject(hbmSrcT);
  666. hdcDst.SelectObject(hbmDstT);
  667. hdcSrc.DeleteDC();
  668. hdcDst.DeleteDC();
  669. }
  670. // DrawTransparentBitmap
  671. //
  672. // "Drawing Transparent Bitmap with ease with on the fly masks in MFC"
  673. // By Raja Segar
  674. //
  675. void CBitmapSlider::DrawTransparentBitmap(
  676. CDC *pDC, int xStart, int yStart, int wWidth, int wHeight,
  677. CDC *pTmpDC, int xSource, int ySource, CBitmap *bmMask )
  678. {
  679. // We are going to paint the two DDB's in sequence to the destination.
  680. // 1st the monochrome bitmap will be blitted using an AND operation to
  681. // cut a hole in the destination. The color image will then be ORed
  682. // with the destination, filling it into the hole, but leaving the
  683. // surrounding area untouched.
  684. CDC hdcMem;
  685. hdcMem.CreateCompatibleDC(NULL);
  686. CBitmap* hbmT = hdcMem.SelectObject(bmMask);
  687. pDC->BitBlt( xStart, yStart, wWidth, wHeight, &hdcMem,
  688. xSource, ySource, SRCAND);
  689. // Also note the use of SRCPAINT rather than SRCCOPY.
  690. pDC->BitBlt(xStart, yStart, wWidth, wHeight, pTmpDC,
  691. xSource, ySource,SRCPAINT);
  692. // Now, clean up.
  693. hdcMem.SelectObject(hbmT);
  694. hdcMem.DeleteDC();
  695. }
  696. // To get keyboard input
  697. //
  698. UINT CBitmapSlider::OnGetDlgCode() 
  699. {
  700. if( GetKeyState(VK_TAB) >= 0 ) {
  701. return  DLGC_WANTALLKEYS;
  702. }
  703. return CStatic::OnGetDlgCode();
  704. }
  705. // Handling keyboard input
  706. //
  707. void CBitmapSlider::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  708. {
  709. if( !m_bEnable )
  710. return;
  711. switch( nChar ) {
  712. // Left & up
  713. case VK_LEFT :
  714. case VK_UP :
  715. SetPos( m_nPos-1 );
  716. break;
  717. // Right & down
  718. case VK_RIGHT :
  719. case VK_DOWN :
  720. SetPos( m_nPos+1 );
  721. break;
  722. // Home
  723. case VK_HOME :
  724. SetPos( m_nMin );
  725. break;
  726. // End
  727. case VK_END :
  728. SetPos( m_nMax );
  729. break;
  730. // Page up
  731. case VK_PRIOR :
  732. SetPos( m_nPos - m_nPage );
  733. break;
  734. // Page down
  735. case VK_NEXT :
  736. SetPos( m_nPos + m_nPage );
  737. break;
  738. default :
  739. CStatic::OnKeyDown(nChar, nRepCnt, nFlags);
  740. return;
  741. }
  742. ::PostMessage(
  743. GetParent()->GetSafeHwnd(), WM_BITMAPSLIDER_MOVED,
  744. GetDlgCtrlID(), m_nPos );
  745. CStatic::OnKeyDown(nChar, nRepCnt, nFlags);
  746. }
  747. // Control looses its focus
  748. //
  749. void CBitmapSlider::OnKillFocus(CWnd* pNewWnd) 
  750. {
  751. CStatic::OnKillFocus(pNewWnd);
  752. m_bFocus = FALSE;
  753. Invalidate();
  754. }
  755. // This control gains its focus
  756. //
  757. void CBitmapSlider::OnSetFocus(CWnd* pOldWnd) 
  758. {
  759. CStatic::OnSetFocus(pOldWnd);
  760. m_bFocus = TRUE;
  761. Invalidate();
  762. }
  763. // Release resources
  764. //
  765. void CBitmapSlider::OnDestroy() 
  766. {
  767. CStatic::OnDestroy();
  768. m_bmThumb.DeleteObject();
  769. m_bmThumbMask.DeleteObject();
  770. m_bmThumbActive.DeleteObject();
  771. m_bmThumbActiveMask.DeleteObject();
  772. m_bmThumbBg.DeleteObject();
  773. m_bmChannel.DeleteObject();
  774. m_bmChannelMask.DeleteObject();
  775. m_bmChannelActive.DeleteObject();
  776. m_bmChannelActiveMask.DeleteObject();
  777. }