X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d6f0a4b367c6d68d9fea84817f5a982163665f37..0d1903dbda864780eec30efdc4e91776bdbfd21b:/src/msw/dcmemory.cpp diff --git a/src/msw/dcmemory.cpp b/src/msw/dcmemory.cpp index 64ff3c778f..018c5fa8c5 100644 --- a/src/msw/dcmemory.cpp +++ b/src/msw/dcmemory.cpp @@ -1,11 +1,10 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: dcmemory.cpp +// Name: src/msw/dcmemory.cpp // Purpose: wxMemoryDC class // Author: Julian Smart // Modified by: // Created: 01/02/97 -// RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem +// Copyright: (c) Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -17,10 +16,6 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "dcmemory.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -28,6 +23,9 @@ #pragma hdrstop #endif +#include "wx/dcmemory.h" +#include "wx/msw/dcmemory.h" + #ifndef WX_PRECOMP #include "wx/utils.h" #include "wx/log.h" @@ -35,64 +33,77 @@ #include "wx/msw/private.h" -#include "wx/dcmemory.h" - // ---------------------------------------------------------------------------- -// wxWin macros +// wxMemoryDCImpl // ---------------------------------------------------------------------------- - IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC) +IMPLEMENT_ABSTRACT_CLASS(wxMemoryDCImpl, wxMSWDCImpl) -// ============================================================================ -// implementation -// ============================================================================ +wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner ) + : wxMSWDCImpl( owner ) +{ + CreateCompatible(NULL); + Init(); +} -// ---------------------------------------------------------------------------- -// wxMemoryDC -// ---------------------------------------------------------------------------- +wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner, wxBitmap& bitmap ) + : wxMSWDCImpl( owner ) +{ + CreateCompatible(NULL); + Init(); + DoSelect(bitmap); +} -wxMemoryDC::wxMemoryDC() +wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner, wxDC *dc ) + : wxMSWDCImpl( owner ) { - m_hDC = (WXHDC) ::CreateCompatibleDC((HDC) NULL); - m_ok = (m_hDC != 0); - m_bOwnsDC = TRUE; + wxCHECK_RET( dc, wxT("NULL dc in wxMemoryDC ctor") ); - SetBrush(*wxWHITE_BRUSH); - SetPen(*wxBLACK_PEN); + CreateCompatible(dc); - // the background mode is only used for text background and is set in - // DrawText() to OPAQUE as required, otherwise always TRANSPARENT - ::SetBkMode( GetHdc(), TRANSPARENT ); + Init(); } -wxMemoryDC::wxMemoryDC(wxDC *old_dc) +void wxMemoryDCImpl::Init() { - old_dc->BeginDrawing(); + if ( m_ok ) + { + SetBrush(*wxWHITE_BRUSH); + SetPen(*wxBLACK_PEN); - m_hDC = (WXHDC) ::CreateCompatibleDC(GetHdcOf(*old_dc)); - m_ok = (m_hDC != 0); + // the background mode is only used for text background and is set in + // DrawText() to OPAQUE as required, otherwise always TRANSPARENT + ::SetBkMode( GetHdc(), TRANSPARENT ); + } +} - old_dc->EndDrawing(); +bool wxMemoryDCImpl::CreateCompatible(wxDC *dc) +{ + wxDCImpl *impl = dc ? dc->GetImpl() : NULL ; + wxMSWDCImpl *msw_impl = wxDynamicCast( impl, wxMSWDCImpl ); + if ( dc && !msw_impl) + { + m_ok = false; + return false; + } - SetBrush(*wxWHITE_BRUSH); - SetPen(*wxBLACK_PEN); + m_hDC = (WXHDC)::CreateCompatibleDC(dc ? GetHdcOf(*msw_impl) : NULL); - // the background mode is only used for text background and is set in - // DrawText() to OPAQUE as required, otherwise always TRANSPARENT - ::SetBkMode( GetHdc(), TRANSPARENT ); -} + // as we created the DC, we must delete it in the dtor + m_bOwnsDC = true; -wxMemoryDC::~wxMemoryDC() -{ + m_ok = m_hDC != 0; + + return m_ok; } -void wxMemoryDC::SelectObject(const wxBitmap& bitmap) +void wxMemoryDCImpl::DoSelect( const wxBitmap& bitmap ) { // select old bitmap out of the device context if ( m_oldBitmap ) { ::SelectObject(GetHdc(), (HBITMAP) m_oldBitmap); - if ( m_selectedBitmap.Ok() ) + if ( m_selectedBitmap.IsOk() ) { m_selectedBitmap.SetSelectedInto(NULL); m_selectedBitmap = wxNullBitmap; @@ -100,22 +111,21 @@ void wxMemoryDC::SelectObject(const wxBitmap& bitmap) } // check for whether the bitmap is already selected into a device context - wxCHECK_RET( !bitmap.GetSelectedInto() || - (bitmap.GetSelectedInto() == this), - wxT("Bitmap is selected in another wxMemoryDC, delete the " - "first wxMemoryDC or use SelectObject(NULL)") ); + wxASSERT_MSG( !bitmap.GetSelectedInto() || + (bitmap.GetSelectedInto() == GetOwner()), + wxT("Bitmap is selected in another wxMemoryDC, delete the first wxMemoryDC or use SelectObject(NULL)") ); m_selectedBitmap = bitmap; WXHBITMAP hBmp = m_selectedBitmap.GetHBITMAP(); if ( !hBmp ) return; - m_selectedBitmap.SetSelectedInto(this); + m_selectedBitmap.SetSelectedInto(GetOwner()); hBmp = (WXHBITMAP)::SelectObject(GetHdc(), (HBITMAP)hBmp); if ( !hBmp ) { - wxLogLastError("SelectObject(memDC, bitmap)"); + wxLogLastError(wxT("SelectObject(memDC, bitmap)")); wxFAIL_MSG(wxT("Couldn't select a bitmap into wxMemoryDC")); } @@ -125,9 +135,9 @@ void wxMemoryDC::SelectObject(const wxBitmap& bitmap) } } -void wxMemoryDC::DoGetSize(int *width, int *height) const +void wxMemoryDCImpl::DoGetSize(int *width, int *height) const { - if ( m_selectedBitmap.Ok() ) + if ( m_selectedBitmap.IsOk() ) { *width = m_selectedBitmap.GetWidth(); *height = m_selectedBitmap.GetHeight(); @@ -139,13 +149,20 @@ void wxMemoryDC::DoGetSize(int *width, int *height) const } } +// the rest of this file deals with drawing rectangles workaround, disabled by +// default + +#define wxUSE_MEMORY_DC_DRAW_RECTANGLE 0 + +#if wxUSE_MEMORY_DC_DRAW_RECTANGLE + // For some reason, drawing a rectangle on a memory DC has problems. // Use this substitute if we can. static void wxDrawRectangle(wxDC& dc, wxCoord x, wxCoord y, wxCoord width, wxCoord height) { wxBrush brush(dc.GetBrush()); wxPen pen(dc.GetPen()); - if (brush.Ok() && brush.GetStyle() != wxTRANSPARENT) + if (brush.IsOk() && brush.GetStyle() != wxTRANSPARENT) { HBRUSH hBrush = (HBRUSH) brush.GetResourceHandle() ; if (hBrush) @@ -158,7 +175,7 @@ static void wxDrawRectangle(wxDC& dc, wxCoord x, wxCoord y, wxCoord width, wxCoo } } width --; height --; - if (pen.Ok() && pen.GetStyle() != wxTRANSPARENT) + if (pen.IsOk() && pen.GetStyle() != wxTRANSPARENT) { dc.DrawLine(x, y, x + width, y); dc.DrawLine(x, y, x, y + height); @@ -167,22 +184,23 @@ static void wxDrawRectangle(wxDC& dc, wxCoord x, wxCoord y, wxCoord width, wxCoo } } -void wxMemoryDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) +#endif // wxUSE_MEMORY_DC_DRAW_RECTANGLE + +void wxMemoryDCImpl::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { -// Set this to 0 to demonstrate strange rectangle behaviour in the Drawing sample. -#if 0 - if (m_brush.Ok() && m_pen.Ok() && + // Set this to 1 to work around an apparent video driver bug + // (visible with e.g. 70x70 rectangle on a memory DC; see Drawing sample) +#if wxUSE_MEMORY_DC_DRAW_RECTANGLE + if (m_brush.IsOk() && m_pen.IsOk() && (m_brush.GetStyle() == wxSOLID || m_brush.GetStyle() == wxTRANSPARENT) && - (m_pen.GetStyle() == wxSOLID || m_pen.GetStyle() == wxTRANSPARENT)) + (m_pen.GetStyle() == wxSOLID || m_pen.GetStyle() == wxTRANSPARENT) && + (GetLogicalFunction() == wxCOPY)) { wxDrawRectangle(* this, x, y, width, height); } else +#endif // wxUSE_MEMORY_DC_DRAW_RECTANGLE { - wxDC::DoDrawRectangle(x, y, width, height); + wxMSWDCImpl::DoDrawRectangle(x, y, width, height); } -#else - wxDC::DoDrawRectangle(x, y, width, height); -#endif } -