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.2 KiB

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