sprint 1-alpha
sprint/gtl/DC.h
Go to the documentation of this file.
00001 /******************************************************************************
00002  *  GTL: GUI Template Library 
00003  *    A Cross Platform C++ Wrapper for Win32 users
00004  *  Copyright (C) 2007-2011 Paolo Medici (www.pmx.it)
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Lesser General Public
00008  *  License as published by the Free Software Foundation; either
00009  *  version 2.1 of the License, or (at your option) any later version.
00010  *
00011  *  This library is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  Lesser General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU Lesser General Public
00017  *  License along with this library; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019  *
00020  *******************************************************************************/
00021 
00022 #ifndef _SPRINT_GTL_DC_H
00023 #define _SPRINT_GTL_DC_H
00024 
00028 #ifdef WIN32
00029 # include <windows.h>
00030 #endif
00031 
00032 #include <string>
00033 #include <sprint/gtl/BaseTypes.h>
00034 #include <sprint/gtl/Brush.h>
00035 #include <sprint/gtl/Font.h>
00036 #include <sprint/gtl/Bitmap.h>
00037 #include <sprint/gtl/Pen.h>
00038 #include <sprint/log.h>
00039 
00040 #undef SelectBitmap
00041 #undef SelectBrush
00042 #undef SelectFont
00043 #undef SelectPen
00044 
00045 namespace sprint {
00046         namespace gtl {
00047 
00049 
00050 // HDC wrapper
00051 // Il Device Context e' il modo per disegnare in una CWindow
00052 template<bool tManagedDC>
00053 class TDC {
00054         typedef TDC<tManagedDC> this_t;
00055         public:
00056         HDC m_hdc;
00057         public:
00058         TDC(HDC hdc = NULL) : m_hdc(hdc) { }
00059   ~TDC() { if(tManagedDC)       DeleteDC(); }
00060 
00061         void Attach(HDC hDC)
00062         {
00063                 if(tManagedDC && m_hdc != NULL && m_hdc != hDC)
00064 			::DeleteDC(m_hdc);
00065                 m_hdc = hDC;
00066         }
00067 
00068         HDC Detach()
00069         {
00070                 HDC hDC = m_hdc;
00071                 m_hdc = NULL;
00072                 return hDC;
00073         }
00074 
00075         operator HDC() const { return m_hdc; }  
00076         
00077         bool IsNull() const { return (m_hdc == NULL); }
00078 
00079         CBrushHandle GetCurrentBrush() const
00080         {
00081                 return CBrushHandle((HBRUSH)::GetCurrentObject(m_hdc, OBJ_BRUSH));
00082         }
00083 
00084         CFontHandle GetCurrentFont() const
00085         {
00086                 return CFontHandle((HFONT)::GetCurrentObject(m_hdc, OBJ_FONT));
00087         }
00088 
00089         CBitmapHandle GetCurrentBitmap() const
00090         {
00091                 return CBitmapHandle((HBITMAP)::GetCurrentObject(m_hdc, OBJ_BITMAP));
00092         }
00093         
00095         void SaveDC() 
00096     { 
00097          ::SaveDC(m_hdc); 
00098     }
00099 
00101         BOOL RestoreDC(int nSavedDC)
00102         {
00103             return ::RestoreDC(m_hdc, nSavedDC);
00104         }
00105         
00111         inline bool FillRect(const RECT &rc, HBRUSH hbr)
00112         {
00113                 return 	::FillRect(m_hdc, &rc, hbr) == TRUE;
00114         }
00115 
00116         inline bool FillRect(int x0, int y0, int x1, int y1, HBRUSH hbr)
00117         {
00118         Rect r(x0,y0,x1,y1);
00119                 return FillRect(r, hbr) == TRUE;
00120         }
00121 
00122         inline bool FrameRect(const RECT &rc, HBRUSH hbr)
00123         {
00124                 return  ::FrameRect(m_hdc, &rc, hbr) == TRUE;
00125         }
00126 
00127         inline bool FrameRect(int x0, int y0, int x1, int y1, HBRUSH hbr)
00128         {
00129                 return  FrameRect(Rect(x0,y0,x1,y1), hbr) == TRUE;
00130         }
00131         
00132         // Rectangle: un rettangolo, che usa la Pen e il Brush correnti
00133         inline bool Rectangle(const RECT &rc)
00134         {
00135                 return ::Rectangle(m_hdc, rc.left, rc.top, rc.right, rc.bottom);
00136         }
00137 
00138         // Rectangle: un rettangolo, che usa la Pen e il Brush correnti
00139         inline bool Rectangle(int x0, int y0, int x1, int y1)
00140         {
00141                 return ::Rectangle(m_hdc, x0, y0, x1, y1);
00142         }
00143         
00144         inline bool Ellipse(int x0, int y0, int x1, int y1)
00145         {
00146                 return ::Ellipse(m_hdc, x0, y0, x1, y1);
00147         }
00148 
00149         inline bool Circle(int x, int y, int r)
00150         {
00151                 return ::Ellipse(m_hdc, x-r, y-r, x+r, y+r);
00152         }
00153         
00154         // Sposta il Cursore di disegno
00155         inline bool MoveTo(int x, int y, LPPOINT lpPoint = NULL)
00156         {
00157                 return ::MoveToEx(m_hdc, x, y, lpPoint);
00158         }
00159 
00160         // Sposta il Cursore di disegno
00161         inline bool MoveTo(POINT point, LPPOINT lpPointRet = NULL)
00162         {
00163                 return MoveTo(point.x, point.y, lpPointRet);
00164         }
00165 
00166         // Disegna una linea dal cursore di disegno a (x,y) e sposta il cursore
00167         inline bool LineTo(int x, int y)
00168         {
00169                 return ::LineTo(m_hdc, x, y);
00170         }
00171 
00172         // Disegna una linea dal cursore di disegno a point e sposta il cursore
00173         inline bool LineTo(POINT point)
00174         {
00175                 return LineTo(point.x, point.y);
00176         }
00177         
00179         
00180         inline bool Line(POINT a, POINT b)
00181         {
00182                 return MoveTo(a) && LineTo(b);
00183         }
00184 
00185         inline bool Line(int x0, int y0, int x1, int y1)
00186         {
00187                 return MoveTo(x0,y0) && LineTo(x1,y1);
00188         }
00189         
00193         inline bool Polygon(LPPOINT lpPoints, int nCount)
00194         {
00195                 return ::Polygon(m_hdc, lpPoints, nCount);
00196         }
00197 
00200         inline bool Polyline(LPPOINT lpPoints, int nCount)
00201         {
00202                 return ::Polyline(m_hdc, lpPoints, nCount);
00203         }
00204         
00205         inline COLORREF SetTextColor(COLORREF rgb)
00206         {
00207                 return ::SetTextColor(m_hdc, rgb);
00208         }
00209         
00210         inline COLORREF SetTextColor(unsigned int r, unsigned int g, unsigned int b)
00211         {
00212                 return ::SetTextColor(m_hdc, RGB(r,g,b) );
00213         }
00214         
00215         COLORREF GetTextColor() const
00216         {
00217                 return ::GetTextColor(m_hdc);
00218         }
00219 
00220         COLORREF SetBkColor(COLORREF crColor)
00221         {
00222                 return ::SetBkColor(m_hdc, crColor);
00223         }
00224 
00225         UINT GetTextAlign() const
00226         {
00227                 return ::GetTextAlign(m_hdc);
00228         }
00229 
00230         UINT SetTextAlign(UINT nFlags)
00231         {
00232                 return ::SetTextAlign(m_hdc, nFlags);
00233         }
00234         
00235         int SetTextJustification(int nBreakExtra, int nBreakCount)
00236         {
00237                 return ::SetTextJustification(m_hdc, nBreakExtra, nBreakCount);
00238         }
00239 
00240         int GetTextCharacterExtra() const
00241         {
00242                 return ::GetTextCharacterExtra(m_hdc);
00243         }
00244 
00245         int SetTextCharacterExtra(int nCharExtra)
00246         {
00247                 return ::SetTextCharacterExtra(m_hdc, nCharExtra);
00248         }
00249 
00250         BOOL DrawEdge(LPRECT lpRect, UINT nEdge, UINT nFlags)
00251         {
00252                 return ::DrawEdge(m_hdc, lpRect, nEdge, nFlags);
00253         }
00254 
00255         BOOL DrawFrameControl(const RECT & lpRect, UINT nType, UINT nState)
00256         {
00257                 return ::DrawFrameControl(m_hdc, & lpRect, nType, nState);
00258         }
00259         
00262         inline bool TextOut(int x,int y, LPCSTR lpString, int nCount = -1)
00263         {
00264         if(nCount == -1)
00265           nCount = strlen(lpString);
00266                 return ::TextOut(m_hdc, x,y,lpString, nCount);
00267         }
00268         
00269         inline bool TextOut(int x,int y, const std::string & lpString)
00270         {
00271                 return ::TextOut(m_hdc, x,y,lpString.data(), lpString.length() );
00272         }
00273         
00274         BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lpRect, LPCTSTR lpszString, UINT nCount = -1, LPINT lpDxWidths = NULL)
00275         {
00276                 if(nCount == -1)
00277                         nCount = lstrlen(lpszString);
00278                 return ::ExtTextOut(m_hdc, x, y, nOptions, lpRect, lpszString, nCount, lpDxWidths);
00279         }
00280         
00281 
00282     inline bool DrawText(LPCSTR lpString, const RECT &rc, UINT uFormat)
00283     {
00284         return ::DrawText(m_hdc, lpString, -1, const_cast<RECT*>(&rc), uFormat);
00285     }
00286 
00287     inline bool DrawText(const std::string & str, const RECT &rc, UINT uFormat)
00288     {
00289         return ::DrawText(m_hdc, str.data(), str.length(), const_cast<RECT*>(&rc), uFormat);
00290     }
00291   
00292     inline bool GetTextExtent(LPCSTR lpString, LPSIZE lpSize) const
00293     {
00294         return ::GetTextExtentPoint32(
00295                     m_hdc,
00296                     lpString,
00297                     strlen(lpString),
00298                     lpSize);
00299     }
00300 
00301     inline bool GetTextExtent(const std::string & str, LPSIZE lpSize) const
00302     {
00303         return ::GetTextExtentPoint32(
00304                     m_hdc,
00305                     str.data(),
00306                     str.length(),
00307                     lpSize);
00308     }
00309     
00310         BOOL GetTextExtent(LPCTSTR lpszString, int nCount, LPSIZE lpSize) const
00311         {
00312                 if(nCount == -1)
00313                         nCount = lstrlen(lpszString);
00314                 return ::GetTextExtentPoint32(m_hdc, lpszString, nCount, lpSize);
00315         }
00316 
00317         SIZE GetTextExtent(LPCTSTR lpszString, int nCount = -1) const
00318         {
00319         SIZE sz;
00320                 if(nCount == -1)
00321                         nCount = strlen(lpszString);
00322                 ::GetTextExtentPoint32(m_hdc, lpszString, nCount, &sz);
00323                 return sz;
00324         }
00325 
00326         SIZE GetTextExtent(const std::string & str) const
00327         {
00328         SIZE sz;
00329                 ::GetTextExtentPoint32(m_hdc, str.data(), str.size(), &sz);
00330                 return sz;
00331         }
00332 
00333         BOOL GetTextExtentExPoint(LPCTSTR lpszString, int cchString, LPSIZE lpSize, int nMaxExtent, LPINT lpnFit = NULL, LPINT alpDx = NULL)
00334         {
00335                 return ::GetTextExtentExPoint(m_hdc, lpszString, cchString, nMaxExtent, lpnFit, alpDx, lpSize);
00336         }
00337     
00340     inline int SetBkMode(int mode) const {
00341         return ::SetBkMode(m_hdc, mode);
00342     }
00343     
00345         inline HBITMAP SelectBitmap(HBITMAP hbmp) const
00346         {
00347                 return reinterpret_cast<HBITMAP>(::SelectObject(m_hdc, hbmp));
00348         }
00349 
00351         inline HBRUSH SelectBrush(HBRUSH hbr) const
00352         {
00353                 return reinterpret_cast<HBRUSH>(::SelectObject(m_hdc, hbr));
00354         }
00355 
00357         inline HFONT SelectFont(HFONT hbr) const
00358         {
00359                 return reinterpret_cast<HFONT>(::SelectObject(m_hdc, hbr));
00360         }
00361 
00363         inline HPEN SelectPen(HPEN hpen) const
00364         {
00365                 return reinterpret_cast<HPEN>(::SelectObject(m_hdc, hpen));
00366         }
00367 
00370         inline TDC<true> CreateCompatibleDC() const
00371         {
00372                 return TDC<true>(::CreateCompatibleDC(m_hdc));
00373   }     
00374   
00376         inline HBITMAP CreateCompatibleBitmap(int nWidth, int nHeight)
00377         {
00378                 return ::CreateCompatibleBitmap(m_hdc, nWidth, nHeight);
00379         }
00380 
00382   inline void DeleteDC() 
00383   {
00384 			::DeleteDC(m_hdc);
00385                         m_hdc = 0;
00386         }
00387 
00389         inline bool BitBlt(int nXDest,  
00390     int nYDest,                                                                         
00391     int nWidth,                                                                         
00392     int nHeight,                                                                        
00393     HDC hdcSrc,                                                                         
00394     int nXSrc = 0,                                                              
00395     int nYSrc = 0,                                                              
00396     DWORD dwRop = SRCCOPY                               
00397     ) const
00398     {
00399     return ::BitBlt(m_hdc, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop) == TRUE;
00400         }
00401 
00403           void BitBlt(int x, int y, HBITMAP hbmp, DWORD dwRop = SRCCOPY) const
00404           {
00405             TDC<true> Mem(CreateCompatibleDC());
00406             HBITMAP hbmOld = Mem.SelectBitmap(hbmp);
00407             BITMAP bm;
00408             ::GetObject(hbmp, sizeof(BITMAP), &bm);
00409             
00410             BitBlt(0, 0, bm.bmWidth, bm.bmHeight, Mem.m_hdc,0,0,dwRop);
00411             Mem.SelectBitmap(hbmOld);
00412                 }
00413 
00414         
00415 };
00416 
00418 typedef TDC<false> CDCHandle;
00420 typedef TDC<true> CDC;
00421 
00424 class CPaintDC: public CDCHandle {
00425         HWND m_hwnd;            
00426         PAINTSTRUCT m_ps;
00427         public:
00434                 CPaintDC(HWND hwnd) : CDCHandle(::BeginPaint(hwnd, &m_ps)) , m_hwnd(hwnd) { }
00435                 ~CPaintDC() { ::EndPaint(m_hwnd, &m_ps); }
00436 };
00437 
00440 class CWindowDC : public CDCHandle
00441 {
00442 public:
00443 // Data members
00444         HWND m_hWnd;
00445 
00446 // Constructor/destructor
00447         CWindowDC(HWND hWnd) : CDCHandle(::GetWindowDC(hWnd))
00448         {
00449                 m_hWnd = hWnd;
00450         }
00451 
00452         ~CWindowDC()
00453         {
00454                 ::ReleaseDC(m_hWnd, m_hdc);
00455         }
00456 };
00457 
00460 class CClientDC : public CDCHandle
00461 {
00462 public:
00463 // Data members
00464         HWND m_hWnd;
00465 
00466 // Constructor/destructor
00467         CClientDC(HWND hWnd) : CDCHandle(::GetDC(hWnd))
00468         {
00469                 m_hWnd = hWnd;
00470         }
00471 
00472         ~CClientDC()
00473         {
00474                 ::ReleaseDC(m_hWnd, m_hdc);
00475         }
00476 };
00477 
00479 
00483 class CObjectContext {
00484         HDC m_hdc;
00485         HGDIOBJ m_hold;
00486         public:
00488                 CObjectContext(HDC hdc, HGDIOBJ hnew) : m_hdc(hdc)
00489                         {
00490                                 m_hold = ::SelectObject(hdc, hnew);
00491                         }
00492 
00494                 ~CObjectContext()
00495                         {
00496                                 ::SelectObject(m_hdc, m_hold);
00497                         }
00498 };
00499 
00500 
00502 
00504 class DoubleBufferDC : public CDCHandle {
00505       RECT rt;                
00506       CDCHandle target_dc;    
00507           HBITMAP bitmap;         
00508           HBITMAP m_hBmpOld;      
00509       public:
00511       DoubleBufferDC(HWND hwnd, HDC hdc) : 
00512                           CDCHandle(::CreateCompatibleDC(hdc)),
00513                           target_dc(hdc)
00514                         {
00515                                 ::GetClientRect(hwnd, &rt);
00516                                 bitmap = ::CreateCompatibleBitmap(hdc, rt.right, rt.bottom);
00517                                 m_hBmpOld = (HBITMAP)::SelectObject(m_hdc, bitmap);
00518                         }
00519                         
00520       DoubleBufferDC(const RECT & r, HDC hdc) :
00521                            CDCHandle(::CreateCompatibleDC(hdc)),
00522                            rt(r),
00523                            target_dc(hdc)
00524                         {
00525                                 bitmap = ::CreateCompatibleBitmap(hdc, rt.right, rt.bottom);
00526                                 m_hBmpOld = (HBITMAP)::SelectObject(m_hdc, bitmap);
00527                         }
00528                         
00529       DoubleBufferDC(unsigned int width, unsigned int height, HDC hdc) :
00530                            CDCHandle(::CreateCompatibleDC(hdc)),
00531                            target_dc(hdc)
00532                         {
00533                                 bitmap = ::CreateCompatibleBitmap(hdc, width, height);
00534                                 rt.left = rt.top = 0;
00535                                 rt.right = width; rt.bottom  = height;
00536                                 m_hBmpOld = (HBITMAP)::SelectObject(m_hdc, bitmap);
00537                         }
00538                                                 
00539       ~DoubleBufferDC()
00540       {
00541         ::SelectObject(m_hdc, m_hBmpOld);
00542         // rilascio il dc
00543 		::DeleteDC(m_hdc);
00544                 // cancello la bitmap
00545                 ::DeleteObject(bitmap);
00546       }
00547       
00549       CBitmapHandle Bitmap() const { return bitmap; }
00550       
00552       void clear(HBRUSH hbr)
00553       {
00554         FillRect(rt, hbr);
00555       }
00556       
00557       inline int width() const { return rt.right; }
00558       inline int height() const { return rt.bottom; }
00559             
00561       bool swap()
00562       {
00563                 // when finished drawing blit the hdcMem to the hdc
00564                 if(::BitBlt(target_dc, 0, 0, rt.right, rt.bottom, m_hdc, 0, 0, SRCCOPY) == 0)
00565                 {
00566                 logPutsf(LOG_LEVEL_ERROR, "BitBlt failed");
00567                 return false;
00568                 }
00569                 else
00570                         return true;
00571       }
00572 };
00573 
00574 }
00575 
00576 }
00577 
00578 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines