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.

175 lines
4.4 KiB

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