From c6eba8f8b204b0d722db0007e3e0d5e2d2d20085 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin <vadim@wxwidgets.org> Date: Thu, 3 Jun 1999 23:17:01 +0000 Subject: [PATCH] 1. more (minor) wxCaret bug fixes 2. try to enforce wxPaintDC usage only inside EVT_PAINT handler (only in debug mode) 3. warnings removed from pnghand.cpp and dibuitls.cpp git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2664 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/caret.cpp | 9 ++-- src/msw/dcclient.cpp | 121 +++++++++++++++++++++++++++---------------- src/msw/dibutils.cpp | 1 - src/msw/pnghand.cpp | 7 +-- src/msw/window.cpp | 17 +++++- 5 files changed, 99 insertions(+), 56 deletions(-) diff --git a/src/msw/caret.cpp b/src/msw/caret.cpp index a6fbf35525..9d72d6bae0 100644 --- a/src/msw/caret.cpp +++ b/src/msw/caret.cpp @@ -140,11 +140,12 @@ void wxCaret::DoShow() void wxCaret::DoHide() { - wxASSERT_MSG( m_hasCaret, "cannot hide non existent caret" ); - - if ( !::HideCaret(GetWinHwnd(GetWindow())) ) + if ( m_hasCaret ) { - wxLogLastError("HideCaret"); + if ( !::HideCaret(GetWinHwnd(GetWindow())) ) + { + wxLogLastError("HideCaret"); + } } } diff --git a/src/msw/dcclient.cpp b/src/msw/dcclient.cpp index 50fd1ad86e..81dac38ce8 100644 --- a/src/msw/dcclient.cpp +++ b/src/msw/dcclient.cpp @@ -6,39 +6,66 @@ // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// =========================================================================== +// declarations +// =========================================================================== + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "dcclient.h" + #pragma implementation "dcclient.h" #endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#ifndef WX_PRECOMP + #pragma hdrstop #endif #include "wx/dcclient.h" #include "wx/log.h" -#include <windows.h> +#include "wx/msw/private.h" + +// ---------------------------------------------------------------------------- +// macros +// ---------------------------------------------------------------------------- #if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) -IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) -IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC) + IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) + IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) + IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC) #endif -/* - * wxWindowDC - */ +// ---------------------------------------------------------------------------- +// global variables +// ---------------------------------------------------------------------------- + +static PAINTSTRUCT g_paintStruct; + +#ifdef __WXDEBUG__ + // a global variable which we check to verify that wxPaintDC are only + // created in resopnse to WM_PAINT message - doing this from elsewhere is a + // common programming error among wxWindows programmers and might lead to + // very subtle and difficult to debug refresh/repaint bugs. + extern bool g_isPainting = FALSE; +#endif // __WXDEBUG__ + +// =========================================================================== +// implementation +// =========================================================================== -wxWindowDC::wxWindowDC(void) +// ---------------------------------------------------------------------------- +// wxWindowDC +// ---------------------------------------------------------------------------- + +wxWindowDC::wxWindowDC() { m_canvas = NULL; } @@ -46,30 +73,30 @@ wxWindowDC::wxWindowDC(void) wxWindowDC::wxWindowDC(wxWindow *the_canvas) { m_canvas = the_canvas; -// m_hDC = (WXHDC) ::GetDCEx((HWND) the_canvas->GetHWND(), NULL, DCX_WINDOW); - m_hDC = (WXHDC) ::GetWindowDC((HWND) the_canvas->GetHWND() ); - m_hDCCount ++; + m_hDC = (WXHDC) ::GetWindowDC(GetWinHwnd(the_canvas) ); + m_hDCCount++; SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID)); } -wxWindowDC::~wxWindowDC(void) +wxWindowDC::~wxWindowDC() { if (m_canvas && m_hDC) { SelectOldObjects(m_hDC); - ::ReleaseDC((HWND) m_canvas->GetHWND(), (HDC) m_hDC); - m_hDC = 0; + ::ReleaseDC(GetWinHwnd(m_canvas), GetHdc()); + m_hDC = 0; } - m_hDCCount --; + + m_hDCCount--; } -/* - * wxClientDC - */ +// ---------------------------------------------------------------------------- +// wxClientDC +// ---------------------------------------------------------------------------- -wxClientDC::wxClientDC(void) +wxClientDC::wxClientDC() { m_canvas = NULL; } @@ -77,47 +104,49 @@ wxClientDC::wxClientDC(void) wxClientDC::wxClientDC(wxWindow *the_canvas) { m_canvas = the_canvas; -// BeginDrawing(); - m_hDC = (WXHDC) ::GetDC((HWND) the_canvas->GetHWND()); + m_hDC = (WXHDC) ::GetDC(GetWinHwnd(the_canvas)); SetBackground(wxBrush(m_canvas->GetBackgroundColour(), wxSOLID)); } -wxClientDC::~wxClientDC(void) +wxClientDC::~wxClientDC() { -// EndDrawing(); - - if (m_canvas && (HDC) m_hDC) + if ( m_canvas && GetHdc() ) { SelectOldObjects(m_hDC); - ::ReleaseDC((HWND) m_canvas->GetHWND(), (HDC) m_hDC); - m_hDC = 0; + ::ReleaseDC(GetWinHwnd(m_canvas), GetHdc()); + m_hDC = 0; } } -/* - * wxPaintDC - */ +// ---------------------------------------------------------------------------- +// wxPaintDC +// ---------------------------------------------------------------------------- -wxPaintDC::wxPaintDC(void) -{ - m_canvas = NULL; -} - -static PAINTSTRUCT g_paintStruct; - -// Don't call Begin/EndPaint if it's already been called: -// for example, if calling a base class OnPaint. +// TODO (VZ) I have still some doubts about this hack and I still think that we +// should store pairs of (hwnd, hdc) and not just the DC - what if +// BeginPaint() was called on other window? It seems to work like +// this, but to be sure about it we'd need to store hwnd too... WXHDC wxPaintDC::ms_PaintHDC = 0; size_t wxPaintDC::ms_PaintCount = 0; // count of ms_PaintHDC usage +wxPaintDC::wxPaintDC() +{ + m_canvas = NULL; +} + wxPaintDC::wxPaintDC(wxWindow *canvas) { wxCHECK_RET( canvas, "NULL canvas in wxPaintDC ctor" ); + wxCHECK_RET( g_isPainting, + _T("wxPaintDC may be created only in EVT_PAINT handler!") ); m_canvas = canvas; + + // Don't call Begin/EndPaint if it's already been called: for example, if + // calling a base class OnPaint. if ( ms_PaintCount > 0 ) { // it means that we've already called BeginPaint and so we must just // reuse the same HDC (BeginPaint shouldn't be called more than once) @@ -145,7 +174,7 @@ wxPaintDC::~wxPaintDC() m_hDC = (WXHDC) NULL; ms_PaintHDC = (WXHDC) NULL; } - else { }//: ms_PaintHDC still in use + //else: ms_PaintHDC still in use } } diff --git a/src/msw/dibutils.cpp b/src/msw/dibutils.cpp index d1f3e95c77..10a61b9249 100644 --- a/src/msw/dibutils.cpp +++ b/src/msw/dibutils.cpp @@ -243,7 +243,6 @@ PDIB DibOpenFile(LPSTR szFile) PDIB DibReadBitmapInfo(HFILE fh) { DWORD off; - HANDLE hbi = NULL; int size; int i; int nNumColors; diff --git a/src/msw/pnghand.cpp b/src/msw/pnghand.cpp index 01309d2b84..ec8bbd781d 100644 --- a/src/msw/pnghand.cpp +++ b/src/msw/pnghand.cpp @@ -38,7 +38,7 @@ #include <wx/msw/dibutils.h> extern "C" { -#include "png.h" +#include "../png/png.h" } extern "C" void png_read_init PNGARG((png_structp png_ptr)); @@ -130,7 +130,8 @@ wxPNGReader::Create(int width, int height, int depth, int colortype) } RawImage = 0; Palette = 0; - if (lpbi = DibCreate(Depth, Width, Height)) { + lpbi = DibCreate(Depth, Width, Height); + if (lpbi) { RawImage = (ImagePointerType)DibPtr(lpbi); EfeWidth = (long)(((long)Width*Depth + 31) / 32) * 4; imageOK = TRUE; @@ -291,7 +292,7 @@ bool wxPNGReader::InstantiateBitmap(wxBitmap *bitmap) if ( Palette ) { - HPALETTE oldPal = ::SelectPalette(dc, (HPALETTE) Palette->GetHPALETTE(), FALSE); + ::SelectPalette(dc, (HPALETTE) Palette->GetHPALETTE(), FALSE); ::RealizePalette(dc); } diff --git a/src/msw/window.cpp b/src/msw/window.cpp index a1423f78e7..78b7232946 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -102,8 +102,8 @@ // standard macros missing from some compilers headers #ifndef GET_X_LPARAM - #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) - #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) + #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) + #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) #endif // GET_X_LPARAM // --------------------------------------------------------------------------- @@ -117,6 +117,17 @@ wxMenu *wxCurrentPopupMenu = NULL; extern wxList WXDLLEXPORT wxPendingDelete; extern char wxCanvasClassName[]; +#ifdef __WXDEBUG__ + // see comments in dcclient.cpp where g_isPainting is defined + extern bool g_isPainting; + + inline static void wxStartPainting() { g_isPainting = TRUE; } + inline static void wxEndPainting() { g_isPainting = FALSE; } +#else // !debug + inline static void wxStartPainting() { } + inline static void wxEndPainting() { } +#endif // debug/!debug + // --------------------------------------------------------------------------- // private functions // --------------------------------------------------------------------------- @@ -1674,7 +1685,9 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) break; case WM_PAINT: + wxStartPainting(); processed = HandlePaint(); + wxEndPainting(); break; case WM_CLOSE: -- 2.47.2