Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
4.0 KiB

  1. // transbmp.cpp : implementation of the CTransBmp class
  2. //
  3. // support for transparent CBitmap objects. Used in the CUserList class.
  4. // Based on a class from MSDN 7/95
  5. #include "stdafx.h"
  6. #include "transbmp.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char BASED_CODE THIS_FILE[] = __FILE__;
  10. #endif
  11. // Colors
  12. #define rgbWhite RGB(255,255,255)
  13. // Raster op codes
  14. #define DSa 0x008800C6L
  15. #define DSx 0x00660046L
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CTransBmp construction/destruction
  18. CTransBmp::CTransBmp()
  19. {
  20. m_iWidth = 0;
  21. m_iHeight = 0;
  22. m_hbmMask = NULL;
  23. }
  24. CTransBmp::~CTransBmp()
  25. {
  26. if (m_hbmMask != NULL) delete m_hbmMask;
  27. }
  28. void CTransBmp::GetMetrics()
  29. {
  30. // Get the width and height
  31. BITMAP bm;
  32. GetObject(sizeof(bm), &bm);
  33. m_iWidth = bm.bmWidth;
  34. m_iHeight = bm.bmHeight;
  35. }
  36. int CTransBmp::GetWidth()
  37. {
  38. if ((m_iWidth == 0) || (m_iHeight == 0)){
  39. GetMetrics();
  40. }
  41. return m_iWidth;
  42. }
  43. int CTransBmp::GetHeight()
  44. {
  45. if ((m_iWidth == 0) || (m_iHeight == 0)){
  46. GetMetrics();
  47. }
  48. return m_iHeight;
  49. }
  50. void CTransBmp::CreateMask(CDC* pDC)
  51. {
  52. m_hbmMask = new CBitmap;
  53. // Nuke any existing mask
  54. if (m_hbmMask) m_hbmMask->DeleteObject();
  55. // Create memory DCs to work with
  56. CDC* hdcMask = new CDC;
  57. CDC* hdcImage = new CDC;
  58. hdcMask->CreateCompatibleDC(pDC);
  59. hdcImage->CreateCompatibleDC(pDC);
  60. // Create a monochrome bitmap for the mask
  61. m_hbmMask->CreateBitmap(GetWidth(),
  62. GetHeight(),
  63. 1,
  64. 1,
  65. NULL);
  66. // Select the mono bitmap into its DC
  67. CBitmap* hbmOldMask = hdcMask->SelectObject(m_hbmMask);
  68. // Select the image bitmap into its DC
  69. CBitmap* hbmOldImage = hdcImage->SelectObject(CBitmap::FromHandle((HBITMAP)m_hObject));
  70. // Set the transparency color to be the top-left pixel
  71. hdcImage->SetBkColor(hdcImage->GetPixel(0, 0));
  72. // Make the mask
  73. hdcMask->BitBlt(0, 0,
  74. GetWidth(), GetHeight(),
  75. hdcImage,
  76. 0, 0,
  77. SRCCOPY);
  78. // clean up
  79. hdcMask->SelectObject(hbmOldMask);
  80. hdcImage->SelectObject(hbmOldImage);
  81. delete hdcMask;
  82. delete hdcImage;
  83. }
  84. // draw the transparent bitmap using the created mask
  85. void CTransBmp::DrawTrans(CDC* pDC, int x, int y)
  86. {
  87. if (m_hbmMask == NULL) CreateMask(pDC);
  88. int dx = GetWidth();
  89. int dy = GetHeight();
  90. // Create a memory DC to do the drawing to
  91. CDC* hdcOffScr = new CDC;
  92. hdcOffScr->CreateCompatibleDC(pDC);
  93. // Create a bitmap for the off-screen DC that is really
  94. // color compatible with the destination DC.
  95. CBitmap hbmOffScr;
  96. hbmOffScr.CreateBitmap(dx, dy,
  97. pDC->GetDeviceCaps(PLANES),
  98. pDC->GetDeviceCaps(BITSPIXEL),
  99. NULL);
  100. // Select the buffer bitmap into the off-screen DC
  101. HBITMAP hbmOldOffScr = (HBITMAP)hdcOffScr->SelectObject(hbmOffScr);
  102. // Copy the image of the destination rectangle to the
  103. // off-screen buffer DC so we can play with it
  104. hdcOffScr->BitBlt(0, 0, dx, dy, pDC, x, y, SRCCOPY);
  105. // Create a memory DC for the source image
  106. CDC* hdcImage = new CDC;
  107. hdcImage->CreateCompatibleDC(pDC);
  108. CBitmap* hbmOldImage = hdcImage->SelectObject(CBitmap::FromHandle((HBITMAP)m_hObject));
  109. // Create a memory DC for the mask
  110. CDC* hdcMask = new CDC;
  111. hdcMask->CreateCompatibleDC(pDC);
  112. CBitmap* hbmOldMask = hdcMask->SelectObject(m_hbmMask);
  113. // XOR the image with the destination
  114. hdcOffScr->SetBkColor(rgbWhite);
  115. hdcOffScr->BitBlt(0, 0, dx, dy ,hdcImage, 0, 0, DSx);
  116. // AND the destination with the mask
  117. hdcOffScr->BitBlt(0, 0, dx, dy, hdcMask, 0,0, DSa);
  118. // XOR the destination with the image again
  119. hdcOffScr->BitBlt(0, 0, dx, dy, hdcImage, 0, 0, DSx);
  120. // Copy the resultant image back to the screen DC
  121. pDC->BitBlt(x, y, dx, dy, hdcOffScr, 0, 0, SRCCOPY);
  122. // Tidy up
  123. hdcOffScr->SelectObject(hbmOldOffScr);
  124. hdcImage->SelectObject(hbmOldImage);
  125. hdcMask->SelectObject(hbmOldMask);
  126. delete hdcOffScr;
  127. delete hdcImage;
  128. delete hdcMask;
  129. }