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