/* * $Header: /home/dscott/nasty/memory/autogdi.cpp,v 1.1 2001/11/06 21:48:50 dscott Exp $ * $NoKeywords: $ */ #include <Platform.h> #include <win32/autogdi.h> DeviceContext::DeviceContext() : type_(memory) , hWnd_(0) , hDC_(::CreateCompatibleDC(0)) , pPaint_(0) { } /** * Ctor, takes a window context * Intended usage: * DeviceContext dc(hWnd, ::GetDC(hWnd)); * DeviceContext dc(hWnd, ::GetWindowDC(hWnd)); * hWnd can be null when retrieving the DC of the screen. */ DeviceContext::DeviceContext(HWND hWnd, HDC hDC) : type_(window), hWnd_(hWnd), hDC_(hDC), pPaint_(0) { ASSERT(::IsWindow(hWnd)); } DeviceContext::DeviceContext(HWND hWnd /*, HRGN hRgn, DWORD flags */) : type_(window) , hWnd_(hWnd) // , hDC_(::GetDCEx(hWnd, hRgn, flags)) , hDC_(::GetDC(hWnd)) , pPaint_(0) { ASSERT(::IsWindow(hWnd)); } /** * Ctor, to be used instead of ::BeginPaint() */ DeviceContext::DeviceContext(HWND hWnd, PAINTSTRUCT& ps) : type_(paint), hWnd_(hWnd), hDC_(0), pPaint_(&ps) { ASSERT(::IsWindow(hWnd_)); hDC_ = ::BeginPaint(hWnd, pPaint_); } /** * Ctor, creates a memory devices context compatible with that.hDC_ */ DeviceContext::DeviceContext(const DeviceContext& that) : type_(memory) , hDC_(::CreateCompatibleDC(that.hDC_)) , hWnd_(0) , pPaint_(0) { } /** * Dtor, unselects and destroys all objects currently selected * into the context, then releases the context depending on how * it was created */ DeviceContext::~DeviceContext() { if (!IsValid()) { return; } // restore originals std::map<DWORD, HGDIOBJ>::const_iterator i(orgSelected_.begin()); for (; i != orgSelected_.end(); ++i) { ASSERT(i->second); ::SelectObject(hDC_, i->second); } switch (type_) { case memory: ::DeleteDC(hDC_); break; case window: ::ReleaseDC(hWnd_, hDC_); break; case paint: ASSERT(pPaint_); ASSERT(::IsWindow(hWnd_)); ::EndPaint(hWnd_, pPaint_); break; default: ASSERT(false); } } /** * Selects an object into the device context. Returns false if * it fails, clients may call GetLastError() to get the error code */ HGDIOBJ DeviceContext::SelectObject(gdi_handle& h) { ASSERT(IsValid()); // clients must check for a valid DeviceContext ASSERT(h.get()); DWORD objType(::GetObjectType(h.get())); // ASSERT(objType <= maxObjType); HGDIOBJ hOld(::SelectObject(hDC_, h.get())); // MSDN: "If an error occurs and the selected object is not a // region, the return value is NULL. Otherwise, it is GDI_ERROR." if (!hOld || (objType == OBJ_REGION && hOld == HGDI_ERROR)) { return 0; } ASSERT(objType == ::GetObjectType(hOld)); ASSERT(objType > 0); --objType; // base to zero if (orgSelected_[objType] == 0) { orgSelected_[objType] = hOld; } ResetPtr(curSelected_[objType], new gdi_handle(h)); return hOld; } /** * */ bool DeviceContext::CreateCompatibleBitmap(const DeviceContext& src, int width, int height) { ASSERT(IsValid()); ASSERT(src.IsValid()); HBITMAP hBmp(::CreateCompatibleBitmap(src.hDC_, width, height)); if (!hBmp) { return false; } gdi_handle bmp(hBmp); SelectObject(bmp); return true; } /** * */ bool DeviceContext::CopyBitmapFrom( const DeviceContext& src, const RECT& rcSrc, const RECT& rcDest, DWORD rop) { ASSERT(IsValid()); ASSERT(src.IsValid()); ASSERT(&src != this); ASSERT(rcDest.left >= 0); ASSERT(rcDest.top >= 0); ASSERT(rcDest.right >= 0); ASSERT(rcDest.bottom >= 0); int width(rcDest.right - rcDest.left); int height(rcDest.bottom - rcDest.top); return ::BitBlt(hDC_, rcDest.left, rcDest.top, width, height, src.hDC_, rcSrc.left, rcSrc.top, rop) != 0; } /** * */ void DeviceContext::CreateDIBSection( const BITMAPINFO* pbi, UINT usage, void** ppvBits, HANDLE hSection, DWORD offset, gdi_handle& bmp) const { ASSERT(pbi); ASSERT(ppvBits); ASSERT(IsValid()); bmp.reset(::CreateDIBSection(hDC_, pbi, usage, ppvBits, hSection, offset)); } /** * */ int DeviceContext::SetDIBits(const gdi_handle& bmp, UINT uStartScan, // starting scan line UINT cScanLines, // number of scan lines const void* lpvBits, // array of bitmap bits const BITMAPINFO *lpbmi, // address of struct with // bitmap data UINT fuColorUse) { ASSERT(bmp.get()); ASSERT(lpvBits); ASSERT(lpbmi); ASSERT(IsValid()); return ::SetDIBits(hDC_, static_cast<HBITMAP>(bmp.get()), uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse); } /** * */ int DeviceContext::FillRect(const RECT& rc, HBRUSH hBrush) { ASSERT(IsValid()); return ::FillRect(hDC_, &rc, hBrush); } /** * */ bool DeviceContext::PatBlt( int nXLeft, // x-coord. of upper-left corner of rect. to be filled int nYLeft, // y-coord. of upper-left corner of rect. to be filled int nWidth, // width of rectangle to be filled int nHeight, // height of rectangle to be filled DWORD dwRop) // raster operation code { ASSERT(IsValid()); return ::PatBlt(hDC_, nXLeft, nYLeft, nWidth, nHeight, dwRop) != 0; } 1