Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

transparent_painter.cpp

00001 // transparent_painter.cpp
00002 
00003 // Copyright (C) 2004 Steven Weiß (steven11@gmx.de)
00004 //
00005 // Permission to copy, use, sell and distribute this software is granted
00006 // provided this copyright notice appears in all copies.
00007 // Permission to modify the code and to distribute modified code is granted
00008 // provided this copyright notice appears in all copies, and a notice
00009 // that the code was modified is included with the copyright notice.
00010 //
00011 // This software is provided "as is" without express or implied warranty,
00012 // and with no claim as to its suitability for any purpose.
00013 
00014 
00015 #include <background_wnd/painters/transparent_painter.hpp>
00016 
00017 
00018 namespace win32 { namespace gui {
00019 
00026 transparent_painter::transparent_painter(param0 crTransparent) : crTransparent_(crTransparent)
00027 {}
00028 
00029 transparent_painter* transparent_painter::clone() const
00030 {
00031      return new transparent_painter(*this);
00032 }
00033 
00034 void transparent_painter::draw(HDC hDC, int cx, int cy)
00035 {    
00036      if (cx <= 0 || cy <= 0)
00037           return;
00038 
00039      if (painter_available()) {
00040           // prepare mem dc
00041           painter_base& painter = get_painter();                                
00042           HDC hPainterDC = CreateCompatibleDC(hDC);         
00043           HBITMAP hBmp   = CreateCompatibleBitmap(hDC, cx, cy);
00044           HBITMAP hOldBmp = (HBITMAP) SelectObject(hPainterDC, hBmp);      
00045           
00046           // FIXED:
00047           // first fill with transparent color
00048           RECT rc = { 0, 0, cx, cy };
00049           HBRUSH hbr = CreateSolidBrush(crTransparent_);         
00050           FillRect(hPainterDC, &rc, hbr);
00051           DeleteObject(hbr);
00052         
00053           // draw the painter
00054           painter.draw(hPainterDC, cx, cy);       
00055 
00056           #if (!defined WINVER || WINVER < 0x0500)
00057                SelectObject(hPainterDC, hOldBmp);
00058                DeleteDC(hPainterDC);
00059                          
00060                // create the mask
00061                HBITMAP hMaskBmp = prepare_mask(hBmp, cx, cy);
00062 
00063                // draw transparently
00064                HDC hTemp = CreateCompatibleDC(NULL);
00065                hOldBmp = (HBITMAP) SelectObject(hTemp, hBmp);
00066                draw_transparent_bitmap(hDC, hTemp, hMaskBmp, cx, cy);
00067 
00068                // clean up              
00069                SelectObject(hTemp, hOldBmp);
00070                DeleteObject(hBmp);
00071                DeleteObject(hMaskBmp);
00072                DeleteDC(hTemp);
00073           #else
00074                TransparentBlt(hDC, 0, 0, cx, cy, hPainterDC, 0, 0, cx, cy, crTransparent_);
00075                               
00076                // clean up
00077                SelectObject(hPainterDC, hOldBmp);
00078                DeleteObject(hBmp);
00079                DeleteDC(hPainterDC);
00080           #endif
00081      }
00082 }
00083 
00084 // only use our implementation on Win98 or below (TransparentBlt() has a resource leak on those OSes)
00085 #if (!defined WINVER || WINVER < 0x0500)
00086      // This code is based on the Raja Segar's article at codeproject.com. Thx!
00087      HBITMAP transparent_painter::prepare_mask(HBITMAP hSourceBmp, int cx, int cy)                         
00088      {   
00089           // create the mask bitmap   
00090           HBITMAP hMaskBmp = CreateBitmap(cx, cy, 1, 1, NULL);
00091              
00092           // load the bitmaps into the DCs
00093           HDC hSourceDC = CreateCompatibleDC(NULL);
00094           HDC hMaskDC = CreateCompatibleDC(NULL);   
00095           HBITMAP hOldSourceBmp = (HBITMAP) SelectObject(hSourceDC, hSourceBmp);
00096           HBITMAP hOldMaskBmp   = (HBITMAP) SelectObject(hMaskDC, hMaskBmp);
00097                 
00098           // create the mask
00099           COLORREF clrSaveBk  = SetBkColor(hSourceDC, crTransparent_);
00100           BitBlt(hMaskDC, 0, 0, cx, cy, hSourceDC, 0, 0, SRCCOPY);
00101              
00102           // transparent color -> black
00103           COLORREF crOldText = SetTextColor(hSourceDC, RGB(255, 255, 255));
00104           SetBkColor(hSourceDC, RGB(0, 0, 0));
00105           BitBlt(hSourceDC, 0, 0, cx, cy, hMaskDC, 0, 0, SRCAND);
00106 
00107           // clean up
00108           SetTextColor(hSourceDC, crOldText);
00109           SetBkColor(hSourceDC,   clrSaveBk);
00110           SelectObject(hSourceDC, hOldSourceBmp);
00111           SelectObject(hMaskDC,   hOldMaskBmp);
00112           DeleteDC(hSourceDC);
00113           DeleteDC(hMaskDC);
00114 
00115           return hMaskBmp;
00116      }
00117 
00118      void transparent_painter::draw_transparent_bitmap(HDC hDC, HDC hSourceDC, HBITMAP hMaskBmp, int cx, int cy)
00119      {    
00120           HDC hMaskDC = CreateCompatibleDC(NULL);
00121           HBITMAP hOldMaskBmp = (HBITMAP) SelectObject(hMaskDC, hMaskBmp);
00122 
00123           // blit
00124           BitBlt(hDC, 0, 0, cx, cy, hMaskDC, 0, 0, SRCAND);   
00125           BitBlt(hDC, 0, 0, cx, cy, hSourceDC, 0, 0, SRCPAINT);
00126 
00127           // clean up
00128           SelectObject(hMaskDC, hOldMaskBmp);
00129           DeleteDC(hMaskDC);
00130      }
00131 #endif    // #ifndef WINVER || WINVER < 0x0500
00132 
00133 
00135 void transparent_painter::transparent_color(COLORREF crTransparent)
00136 {
00137      crTransparent_ = crTransparent;
00138 }
00139 
00141 COLORREF transparent_painter::transparent_color() const
00142 {
00143      return crTransparent_;
00144 }
00145 
00146 } }  // namespace win32::gui

Generated on Mon Dec 27 15:30:12 2004 for background_wnd by  doxygen 1.3.9.1