- Visual C++源码
- Visual Basic源码
- C++ Builder源码
- Java源码
- Delphi源码
- C/C++源码
- PHP源码
- Perl源码
- Python源码
- Asm源码
- Pascal源码
- Borland C++源码
- Others源码
- SQL源码
- VBScript源码
- JavaScript源码
- ASP/ASPX源码
- C#源码
- Flash/ActionScript源码
- matlab源码
- PowerBuilder源码
- LabView源码
- Flex源码
- MathCAD源码
- VBA源码
- IDL源码
- Lisp/Scheme源码
- VHDL源码
- Objective-C源码
- Fortran源码
- tcl/tk源码
- QT源码
QBufferDC.cpp
资源名称:qzoomview.zip [点击查看]
上传用户:xp9161
上传日期:2009-12-21
资源大小:70k
文件大小:6k
源码类别:
Windows编程
开发平台:
Visual C++
- #include "StdAfx.h"
- #include "QBufferDC.h"
- #ifdef _DEBUG
- // #define DEBUG_QBUFFERDC // Uncomment this if you want to see debugging info.
- #endif
- QBufferDC::QBufferDC(CDC * pDC, DWORD dwRopCode /* = SRCCOPY */)
- : m_pDC(pDC)
- , m_pOldBitmap(NULL)
- , m_RopCode(dwRopCode)
- {
- if (! pDC) return;
- ASSERT_VALID(pDC);
- if (pDC->IsPrinting())
- {
- // Do not use a bitmap when printing. There is nothing to gain.
- if (pDC->m_hDC != pDC->m_hAttribDC) // Print Preview
- {
- // This is a hack. In debug mode, Print Preview yields an assert,
- // stating: "Cannot Release Output hDC on Attached CDC."
- // Although I have not found any nasty consequences, up till now,
- // simply setting the handles in stead of attaching seems to work.
- m_hDC = pDC->m_hDC;
- m_hAttribDC = pDC->m_hAttribDC;
- }
- else VERIFY(Attach(pDC->Detach())); // Attach this to the mother DC's handle,
- // so this in effect becomes a 'normal' DC.
- return;
- }
- // Get the clipping boundary of the mother DC, in logical coordinates
- CRect rcClip;
- VERIFY(pDC->GetClipBox(rcClip) != ERROR);
- // Transform to device coordinates (pixels), and normalize
- pDC->LPtoDP(rcClip);
- rcClip.NormalizeRect();
- if (m_BufferBitmap.ReserveBitmap(pDC, rcClip.Size()))
- {
- // Create a compatible DC
- VERIFY(CreateCompatibleDC(pDC));
- // Select the bitmap in it
- ASSERT(m_pOldBitmap == 0);
- m_pOldBitmap = (CBitmap *) SelectObject(& m_BufferBitmap.m_Bitmap);
- // Copy the mapping settings
- int mapmode = pDC->GetMapMode();
- SetMapMode(mapmode);
- SetWindowOrg(pDC->GetWindowOrg());
- SetViewportOrg(pDC->GetViewportOrg());
- if (mapmode > MM_MAX_FIXEDSCALE)
- {
- // These are only relevant to MM_ISOTROPIC and MM_ANISOTROPIC
- SetWindowExt(pDC->GetWindowExt());
- SetViewportExt(pDC->GetViewportExt());
- }
- // Fill the clipping boundary with pDC's background color
- COLORREF col = pDC->GetBkColor();
- #ifdef QBUFFER_DEMO
- // In demo mode, change the color slightly so we can see which parts are updated
- if (m_bDemoMode) col ^= RGB(rand() % 32, rand() % 32, rand() % 32);
- #endif
- // Get the mother DC's clipping boundary in logical coordinates
- // and fill it.
- VERIFY(pDC->GetClipBox(rcClip) != ERROR);
- rcClip.NormalizeRect();
- if (mapmode != MM_TEXT)
- {
- // Other mapping modes may lead to roundof errors, causing artefacts
- // on the screen. To compensate, we inflate the bounding rectangle
- // with two pixels.
- CSize szPixels(2, 2);
- DPtoLP(& szPixels);
- rcClip.InflateRect(szPixels.cx, szPixels.cy);
- }
- FillSolidRect(rcClip, col);
- // Initialize accumulation of boundary information
- SetBoundsRect(NULL, DCB_ENABLE | DCB_ACCUMULATE | DCB_RESET);
- }
- else // We don't have a bitmap
- {
- #ifdef DEBUG_QBUFFERDC
- afxDump << _T("We can't make a bitmapn");
- #endif
- // Attach this to the mother DC's handle, so this in effect becomes a 'normal' DC.
- VERIFY(Attach(pDC->Detach()));
- }
- }
- QBufferDC::~QBufferDC(void)
- {
- if (!m_pDC) return;
- if (m_pDC->IsPrinting() && m_pDC->m_hDC != m_pDC->m_hAttribDC) return;
- // Nothing to do if Print Previewing. See remarks in constructor code.
- if (m_BufferBitmap.IsValid() && !m_pDC->IsPrinting())
- // We have a bitmap, and we are not printing.
- {
- // We only have to bitblt what is inside the accumulated bounding rectangle.
- CRect rcBounds;
- GetBoundsRect(rcBounds, DCB_RESET);
- rcBounds.NormalizeRect();
- #ifdef DEBUG_QBUFFERDC
- afxDump << _T("Bounding rectangle: ") << rcBounds << _T("n");
- #endif
- // No point in bitblt'ing anything outside the clipping box
- CRect rcClip;
- m_pDC->GetClipBox(rcClip);
- rcClip.NormalizeRect();
- // So intersect it with the bounding rectangle.
- rcBounds &= rcClip;
- #ifdef DEBUG_QBUFFERDC
- afxDump << _T(" after clipping: ") << rcBounds
- << _T("n clipping rectangle: ") << rcClip << _T("n");
- #endif
- if (! rcBounds.IsRectEmpty())
- {
- if (GetMapMode() != MM_TEXT)
- {
- // Other mapping modes may lead to roundof errors, causing artefacts
- // on the screen. To compensate, we inflate the bounding rectangle
- // with two pixels.
- CSize szPixels(2, 2);
- DPtoLP(& szPixels);
- rcBounds.InflateRect(szPixels.cx, szPixels.cy);
- }
- // BitBlt the important part of the bitmap to the screen
- VERIFY(m_pDC->BitBlt(
- rcBounds.left, rcBounds.top,
- rcBounds.Width(), rcBounds.Height(),
- this,
- rcBounds.left, rcBounds.top,
- m_RopCode));
- }
- // Clean up, deselect the bitmap.
- if (m_pOldBitmap) SelectObject(m_pOldBitmap);
- }
- else // We don't have a bitmap, or we are printing.
- {
- // Detach from the mother's DC handle, and reattach to the mother
- VERIFY(m_pDC->Attach(Detach()));
- }
- }
- BOOL QBufferDC::BufferBitmap::ReserveBitmap(CDC * pDC, CSize sz)
- {
- if (IsValid()) // We have a bitmap
- {
- BITMAP bm;
- m_Bitmap.GetBitmap(& bm);
- #ifdef DEBUG_QBUFFERDC
- afxDump << _T("We already have a bitmap, size: ") << CSize(bm.bmWidth, bm.bmHeight) << _T("n");
- #endif
- // Compare the bitmap size (in pixels) with the requested size (also in pixels)
- if (sz.cx > bm.bmWidth || sz.cy > bm.bmHeight)
- {
- // If the bitmap is too small, delete it; handle will be set to zero
- m_Bitmap.DeleteObject();
- #ifdef DEBUG_QBUFFERDC
- afxDump << _T("Too small, deletedn");
- #endif
- }
- else return TRUE; // Bitmap is big enough
- }
- // Try to create a bitmap of sufficient size
- BOOL r = m_Bitmap.CreateCompatibleBitmap(pDC, sz.cx, sz.cy);
- #ifdef DEBUG_QBUFFERDC
- afxDump << _T("Tried to create a bitmap, size: ") << sz
- << (r ? _T(" - succeededn") : _T(" - failedn"));
- #endif
- return r;
- }
- QBufferDC::BufferBitmap QBufferDC::m_BufferBitmap;
- #ifdef QBUFFER_DEMO
- BOOL QBufferDC::m_bDemoMode = TRUE;
- #endif