sprint 1-alpha
|
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