cleanup the Win32 window classes registration code: remove global variables and register the window classes we use on demand to avoid registering MDI or GL classes unnecessarily

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57030 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-11-29 22:19:55 +00:00
parent 12b661cd1e
commit d9698bd4ac
7 changed files with 157 additions and 281 deletions

View File

@@ -25,8 +25,6 @@ class WXDLLIMPEXP_FWD_BASE wxLog;
// a new App object to start application // a new App object to start application
class WXDLLIMPEXP_CORE wxApp : public wxAppBase class WXDLLIMPEXP_CORE wxApp : public wxAppBase
{ {
DECLARE_DYNAMIC_CLASS(wxApp)
public: public:
wxApp(); wxApp();
virtual ~wxApp(); virtual ~wxApp();
@@ -50,13 +48,40 @@ public:
virtual bool OnExceptionInMainLoop(); virtual bool OnExceptionInMainLoop();
#endif // wxUSE_EXCEPTIONS #endif // wxUSE_EXCEPTIONS
// MSW-specific from now on
// ------------------------
// this suffix should be appended to all our Win32 class names to obtain a
// variant registered without CS_[HV]REDRAW styles
static const wxChar *GetNoRedrawClassSuffix() { return _T("NR"); }
// get the name of the registered Win32 class with the given (unique) base
// name: this function constructs the unique class name using this name as
// prefix, checks if the class is already registered and registers it if it
// isn't and returns the name it was registered under (or NULL if it failed)
//
// the registered class will always have CS_[HV]REDRAW and CS_DBLCLKS
// styles as well as any additional styles specified as arguments here; and
// there will be also a companion registered class identical to this one
// but without CS_[HV]REDRAW whose name will be the same one but with
// GetNoRedrawClassSuffix()
//
// the background brush argument must be either a COLOR_XXX standard value
// or (default) -1 meaning that the class paints its background itself
static const wxChar *GetRegisteredClassName(const wxChar *name,
int bgBrushCol = -1,
int extraStyles = 0);
// return true if this name corresponds to one of the classes we registered
// in the previous GetRegisteredClassName() calls
static bool IsRegisteredClassName(const wxString& name);
protected: protected:
int m_printMode; // wxPRINT_WINDOWS, wxPRINT_POSTSCRIPT int m_printMode; // wxPRINT_WINDOWS, wxPRINT_POSTSCRIPT
public: public:
// Implementation // unregister any window classes registered by GetRegisteredClassName()
static bool RegisterWindowClasses(); static void UnregisterWindowClasses();
static bool UnregisterWindowClasses();
#if wxUSE_RICHEDIT #if wxUSE_RICHEDIT
// initialize the richedit DLL of (at least) given version, return true if // initialize the richedit DLL of (at least) given version, return true if
@@ -79,6 +104,7 @@ public:
protected: protected:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxApp) DECLARE_NO_COPY_CLASS(wxApp)
DECLARE_DYNAMIC_CLASS(wxApp)
}; };
#ifdef __WXWINCE__ #ifdef __WXWINCE__

View File

@@ -245,6 +245,9 @@ public:
// get the HWND to be used as parent of this window with CreateWindow() // get the HWND to be used as parent of this window with CreateWindow()
virtual WXHWND MSWGetParent() const; virtual WXHWND MSWGetParent() const;
// get the Win32 window class name used by all wxWindow objects by default
static const wxChar *MSWGetRegisteredClassName();
// creates the window of specified Windows class with given style, extended // creates the window of specified Windows class with given style, extended
// style, title and geometry (default values // style, title and geometry (default values
// //

View File

@@ -51,6 +51,7 @@
#include "wx/evtloop.h" #include "wx/evtloop.h"
#include "wx/thread.h" #include "wx/thread.h"
#include "wx/scopeguard.h" #include "wx/scopeguard.h"
#include "wx/vector.h"
#include "wx/msw/private.h" #include "wx/msw/private.h"
#include "wx/msw/dc.h" #include "wx/msw/dc.h"
@@ -116,12 +117,23 @@
extern void wxSetKeyboardHook(bool doIt); extern void wxSetKeyboardHook(bool doIt);
#endif #endif
WXDLLIMPEXP_CORE const wxChar *wxCanvasClassName = NULL; namespace
WXDLLIMPEXP_CORE const wxChar *wxCanvasClassNameNR = NULL; {
WXDLLIMPEXP_CORE const wxChar *wxMDIFrameClassName = NULL;
WXDLLIMPEXP_CORE const wxChar *wxMDIFrameClassNameNoRedraw = NULL; struct ClassRegInfo
WXDLLIMPEXP_CORE const wxChar *wxMDIChildFrameClassName = NULL; {
WXDLLIMPEXP_CORE const wxChar *wxMDIChildFrameClassNameNoRedraw = NULL; // the base name of the class: this is used to construct the unique name in
// RegisterClassWithUniqueNames()
wxString basename;
// the name of the registered class with and without CS_[HV]REDRAW styles
wxString regname,
regnameNR;
};
wxVector<ClassRegInfo> gs_regClassesInfo;
} // anonymous namespace
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// private functions // private functions
@@ -620,8 +632,6 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
wxOleInitialize(); wxOleInitialize();
RegisterWindowClasses();
#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
wxSetKeyboardHook(true); wxSetKeyboardHook(true);
#endif #endif
@@ -632,143 +642,106 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// RegisterWindowClasses // Win32 window class registration
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// This function registers the given class name and stores a pointer to a /* static */
// heap-allocated copy of it at the specified location, it must be deleted const wxChar *wxApp::GetRegisteredClassName(const wxChar *name,
// later. int bgBrushCol,
static void RegisterAndStoreClassName(const wxString& uniqueClassName, int extraStyles)
const wxChar **className,
WNDCLASS *lpWndClass)
{ {
const size_t length = uniqueClassName.length() + 1; // for trailing NUL const size_t count = gs_regClassesInfo.size();
wxChar * const newChars = new wxChar[length]; for ( size_t n = 0; n < count; n++ )
wxStrlcpy(newChars, uniqueClassName, length);
*className = newChars;
lpWndClass->lpszClassName = *className;
if ( !::RegisterClass(lpWndClass) )
{ {
wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"), newChars)); if ( gs_regClassesInfo[n].basename == name )
return gs_regClassesInfo[n].regname;
} }
}
// This function registers the class defined by the provided WNDCLASS struct // we need to register this class
// contents using a unique name constructed from the specified base name and
// and a suffix unique to this library instance. It also stores the generated
// unique names for normal and "no redraw" versions of the class in the
// provided variables, caller must delete their contents later.
static void RegisterClassWithUniqueNames(const wxString& baseName,
const wxChar **className,
const wxChar **classNameNR,
WNDCLASS *lpWndClass)
{
// for each class we register one with CS_(V|H)REDRAW style and one
// without for windows created with wxNO_FULL_REDRAW_ON_REPAINT flag
static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
static const long styleNoRedraw = CS_DBLCLKS;
const wxString uniqueSuffix(wxString::Format(wxT("@%p"), className));
wxString uniqueClassName(baseName + uniqueSuffix);
lpWndClass->style = styleNormal;
RegisterAndStoreClassName(uniqueClassName, className, lpWndClass);
// NB: remember that code elsewhere supposes that no redraw class names
// use the same names as normal classes with "NR" suffix so we must put
// "NR" at the end instead of using more natural baseName+"NR"+suffix
wxString uniqueClassNameNR(uniqueClassName + wxT("NR"));
lpWndClass->style = styleNoRedraw;
RegisterAndStoreClassName(uniqueClassNameNR, classNameNR, lpWndClass);
}
// TODO we should only register classes really used by the app. For this it
// would be enough to just delay the class registration until an attempt
// to create a window of this class is made.
bool wxApp::RegisterWindowClasses()
{
WNDCLASS wndclass; WNDCLASS wndclass;
wxZeroMemory(wndclass); wxZeroMemory(wndclass);
// the fields which are common to all classes
wndclass.lpfnWndProc = (WNDPROC)wxWndProc; wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
wndclass.hInstance = wxhInstance; wndclass.hInstance = wxhInstance;
wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW); wndclass.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)wxUIntToPtr(bgBrushCol + 1);
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | extraStyles;
// register the class for all normal windows and "no redraw" frames
wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
RegisterClassWithUniqueNames(wxT("wxWindowClass"),
&wxCanvasClassName,
&wxCanvasClassNameNR,
&wndclass);
// Register the MDI frame window class and "no redraw" MDI frame ClassRegInfo regClass;
wndclass.hbrBackground = (HBRUSH)NULL; // paint MDI frame ourselves regClass.basename = name;
RegisterClassWithUniqueNames(wxT("wxMDIFrameClass"),
&wxMDIFrameClassName,
&wxMDIFrameClassNameNoRedraw,
&wndclass);
// Register the MDI child frame window class and "no redraw" MDI child frame // constuct a unique suffix to allow registering the class with the same
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // base name in a main application using wxWidgets and a DLL using
RegisterClassWithUniqueNames(wxT("wxMDIChildFrameClass"), // wxWidgets loaded into its address space: as gs_regClassesInfo variable
&wxMDIChildFrameClassName, // is different in them, we're going to obtain a unique prefix by using its
&wxMDIChildFrameClassNameNoRedraw, // address here
&wndclass); regClass.regname = regClass.basename +
wxString::Format(wxT("@%p"), &gs_regClassesInfo);
return true; wndclass.lpszClassName = regClass.regname.wx_str();
} if ( !::RegisterClass(&wndclass) )
// ---------------------------------------------------------------------------
// UnregisterWindowClasses
// ---------------------------------------------------------------------------
// This function unregisters the class with the given name and frees memory
// allocated for it by RegisterAndStoreClassName().
static bool UnregisterAndFreeClassName(const wxChar **ppClassName)
{
bool retval = true;
if ( !::UnregisterClass(*ppClassName, wxhInstance) )
{ {
wxLogLastError( wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"),
wxString::Format(wxT("UnregisterClass(%s)"), *ppClassName)); regClass.regname));
return NULL;
retval = false;
} }
delete [] (wxChar*) *ppClassName; // NB: remember that code elsewhere supposes that no redraw class names
*ppClassName = NULL; // use the same names as normal classes with "NR" suffix so we must put
// "NR" at the end instead of using more natural basename+"NR"+suffix
regClass.regnameNR = regClass.regname + GetNoRedrawClassSuffix();
wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW);
wndclass.lpszClassName = regClass.regnameNR.wx_str();
if ( !::RegisterClass(&wndclass) )
{
wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"),
regClass.regname));
::UnregisterClass(regClass.regname, wxhInstance);
return NULL;
}
return retval; gs_regClassesInfo.push_back(regClass);
// take care to return the pointer which will remain valid after the
// function returns (it could be invalidated later if new elements are
// added to the vector and it's reallocated but this shouldn't matter as
// this pointer should be used right now, not stored)
return gs_regClassesInfo.back().regname.wx_str();
} }
bool wxApp::UnregisterWindowClasses() bool wxApp::IsRegisteredClassName(const wxString& name)
{ {
bool retval = true; const size_t count = gs_regClassesInfo.size();
for ( size_t n = 0; n < count; n++ )
{
if ( gs_regClassesInfo[n].regname == name ||
gs_regClassesInfo[n].regnameNR == name )
return true;
}
#ifndef __WXMICROWIN__ return false;
if ( !UnregisterAndFreeClassName(&wxMDIFrameClassName) ) }
retval = false;
if ( !UnregisterAndFreeClassName(&wxMDIFrameClassNameNoRedraw) ) void wxApp::UnregisterWindowClasses()
retval = false; {
const size_t count = gs_regClassesInfo.size();
for ( size_t n = 0; n < count; n++ )
{
const ClassRegInfo& regClass = gs_regClassesInfo[n];
if ( !::UnregisterClass(regClass.regname, wxhInstance) )
{
wxLogLastError(wxString::Format(wxT("UnregisterClass(%s)"),
regClass.regname));
}
if ( !UnregisterAndFreeClassName(&wxMDIChildFrameClassName) ) if ( !::UnregisterClass(regClass.regnameNR, wxhInstance) )
retval = false; {
wxLogLastError(wxString::Format(wxT("UnregisterClass(%s)"),
regClass.regnameNR));
}
}
if ( !UnregisterAndFreeClassName(&wxMDIChildFrameClassNameNoRedraw) ) gs_regClassesInfo.clear();
retval = false;
if ( !UnregisterAndFreeClassName(&wxCanvasClassName) )
retval = false;
if ( !UnregisterAndFreeClassName(&wxCanvasClassNameNR) )
retval = false;
#endif // __WXMICROWIN__
return retval;
} }
void wxApp::CleanUp() void wxApp::CleanUp()

View File

@@ -29,7 +29,6 @@
#include "wx/intl.h" #include "wx/intl.h"
#include "wx/log.h" #include "wx/log.h"
#include "wx/app.h" #include "wx/app.h"
#include "wx/module.h"
#endif #endif
#include "wx/msw/private.h" #include "wx/msw/private.h"
@@ -104,110 +103,6 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
# pragma comment( lib, "glu32" ) # pragma comment( lib, "glu32" )
#endif #endif
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
static const wxChar *wxGLCanvasClassName = wxT("wxGLCanvasClass");
static const wxChar *wxGLCanvasClassNameNoRedraw = wxT("wxGLCanvasClassNR");
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxGLModule is responsible for unregistering wxGLCanvasClass Windows class
// ----------------------------------------------------------------------------
class wxGLModule : public wxModule
{
public:
bool OnInit() { return true; }
void OnExit() { UnregisterClasses(); }
// register the GL classes if not done yet, return true if ok, false if
// registration failed
static bool RegisterClasses();
// unregister the classes, done automatically on program termination
static void UnregisterClasses();
private:
// wxGLCanvas is only used from the main thread so this is MT-ok
static bool ms_registeredGLClasses;
DECLARE_DYNAMIC_CLASS(wxGLModule)
};
IMPLEMENT_DYNAMIC_CLASS(wxGLModule, wxModule)
bool wxGLModule::ms_registeredGLClasses = false;
/* static */
bool wxGLModule::RegisterClasses()
{
if ( ms_registeredGLClasses )
return true;
// We have to register a special window class because we need the CS_OWNDC
// style for GLCanvas: some OpenGL drivers are buggy and don't work with
// windows without this style
WNDCLASS wndclass;
// the fields which are common to all classes
wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for?
wndclass.hInstance = wxhInstance;
wndclass.hIcon = (HICON) NULL;
wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
wndclass.lpszMenuName = NULL;
// Register the GLCanvas class name
wndclass.hbrBackground = (HBRUSH)NULL;
wndclass.lpszClassName = wxGLCanvasClassName;
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
if ( !::RegisterClass(&wndclass) )
{
wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)"));
return false;
}
// Register the GLCanvas class name for windows which don't do full repaint
// on resize
wndclass.lpszClassName = wxGLCanvasClassNameNoRedraw;
wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW);
if ( !::RegisterClass(&wndclass) )
{
wxLogLastError(wxT("RegisterClass(wxGLCanvasClassNameNoRedraw)"));
::UnregisterClass(wxGLCanvasClassName, wxhInstance);
return false;
}
ms_registeredGLClasses = true;
return true;
}
/* static */
void wxGLModule::UnregisterClasses()
{
// we need to unregister the classes in case we're in a DLL which is
// unloaded and then loaded again because if we don't, the registration is
// going to fail in wxGLCanvas::Create() the next time we're loaded
if ( ms_registeredGLClasses )
{
::UnregisterClass(wxGLCanvasClassName, wxhInstance);
::UnregisterClass(wxGLCanvasClassNameNoRedraw, wxhInstance);
ms_registeredGLClasses = false;
}
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGLContext // wxGLContext
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -297,13 +192,6 @@ bool wxGLCanvas::CreateWindow(wxWindow *parent,
{ {
wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") ); wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") );
if ( !wxGLModule::RegisterClasses() )
{
wxLogError(_("Failed to register OpenGL window class."));
return false;
}
if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
return false; return false;
@@ -319,7 +207,8 @@ bool wxGLCanvas::CreateWindow(wxWindow *parent,
DWORD msflags = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; DWORD msflags = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
msflags |= MSWGetStyle(style, &exStyle); msflags |= MSWGetStyle(style, &exStyle);
if ( !MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle) ) if ( !MSWCreate(wxApp::GetRegisteredClassName(_T("wxGLCanvas"), -1, CS_OWNDC),
NULL, pos, size, msflags, exStyle) )
return false; return false;
m_hDC = ::GetDC(GetHwnd()); m_hDC = ::GetDC(GetHwnd());

View File

@@ -52,9 +52,6 @@
extern wxMenu *wxCurrentPopupMenu; extern wxMenu *wxCurrentPopupMenu;
extern const wxChar *wxMDIFrameClassName; // from app.cpp
extern const wxChar *wxMDIChildFrameClassName;
extern const wxChar *wxMDIChildFrameClassNameNoRedraw;
extern void wxRemoveHandleAssociation(wxWindow *win); extern void wxRemoveHandleAssociation(wxWindow *win);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -188,7 +185,7 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
msflags &= ~WS_VSCROLL; msflags &= ~WS_VSCROLL;
msflags &= ~WS_HSCROLL; msflags &= ~WS_HSCROLL;
if ( !wxWindow::MSWCreate(wxMDIFrameClassName, if ( !wxWindow::MSWCreate(wxApp::GetRegisteredClassName(_T("wxMDIFrame")),
title.wx_str(), title.wx_str(),
pos, size, pos, size,
msflags, msflags,
@@ -736,9 +733,12 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
MDICREATESTRUCT mcs; MDICREATESTRUCT mcs;
mcs.szClass = style & wxFULL_REPAINT_ON_RESIZE wxString className =
? wxMDIChildFrameClassName wxApp::GetRegisteredClassName(_T("wxMDIChildFrame"), COLOR_WINDOW);
: wxMDIChildFrameClassNameNoRedraw; if ( !(style & wxFULL_REPAINT_ON_RESIZE) )
className += wxApp::GetNoRedrawClassSuffix();
mcs.szClass = className.wx_str();
mcs.szTitle = title.wx_str(); mcs.szTitle = title.wx_str();
mcs.hOwner = wxGetInstance(); mcs.hOwner = wxGetInstance();
if (x != wxDefaultCoord) if (x != wxDefaultCoord)

View File

@@ -78,13 +78,6 @@ static inline bool IsZoomed(HWND WXUNUSED(hwnd)) { return false; }
LONG APIENTRY _EXPORT LONG APIENTRY _EXPORT
wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
// ----------------------------------------------------------------------------
// globals
// ----------------------------------------------------------------------------
// the name of the default wxWidgets class
extern const wxChar *wxCanvasClassName;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxTLWHiddenParentModule: used to manage the hidden parent window (we need a // wxTLWHiddenParentModule: used to manage the hidden parent window (we need a
// module to ensure that the window is always deleted) // module to ensure that the window is always deleted)
@@ -490,7 +483,8 @@ bool wxTopLevelWindowMSW::CreateFrame(const wxString& title,
exflags |= WS_EX_LAYOUTRTL; exflags |= WS_EX_LAYOUTRTL;
#endif #endif
return MSWCreate(wxCanvasClassName, title.wx_str(), pos, sz, flags, exflags); return MSWCreate(MSWGetRegisteredClassName(),
title.wx_str(), pos, sz, flags, exflags);
} }
bool wxTopLevelWindowMSW::Create(wxWindow *parent, bool wxTopLevelWindowMSW::Create(wxWindow *parent,

View File

@@ -183,8 +183,6 @@
extern wxMenu *wxCurrentPopupMenu; extern wxMenu *wxCurrentPopupMenu;
#endif #endif
extern const wxChar *wxCanvasClassName;
// true if we had already created the std colour map, used by // true if we had already created the std colour map, used by
// wxGetStdColourMap() and wxWindow::OnSysColourChanged() (FIXME-MT) // wxGetStdColourMap() and wxWindow::OnSysColourChanged() (FIXME-MT)
static bool gs_hasStdCmap = false; static bool gs_hasStdCmap = false;
@@ -585,6 +583,12 @@ wxWindowMSW::~wxWindowMSW()
} }
/* static */
const wxChar *wxWindowMSW::MSWGetRegisteredClassName()
{
return wxApp::GetRegisteredClassName(_T("wxWindow"), COLOR_BTNFACE);
}
// real construction (Init() must have been called before!) // real construction (Init() must have been called before!)
bool wxWindowMSW::Create(wxWindow *parent, bool wxWindowMSW::Create(wxWindow *parent,
wxWindowID id, wxWindowID id,
@@ -617,7 +621,8 @@ bool wxWindowMSW::Create(wxWindow *parent,
msflags |= WS_VISIBLE; msflags |= WS_VISIBLE;
} }
if ( !MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle) ) if ( !MSWCreate(MSWGetRegisteredClassName(),
NULL, pos, size, msflags, exstyle) )
return false; return false;
InheritAttributes(); InheritAttributes();
@@ -1272,31 +1277,12 @@ void wxWindowMSW::DissociateHandle()
bool wxCheckWindowWndProc(WXHWND hWnd, bool wxCheckWindowWndProc(WXHWND hWnd,
WXFARPROC WXUNUSED(wndProc)) WXFARPROC WXUNUSED(wndProc))
{ {
// TODO: This list of window class names should be factored out so they can be const wxString str(wxGetWindowClass(hWnd));
// managed in one place and then accessed from here and other places, such as
// wxApp::RegisterWindowClasses() and wxApp::UnregisterWindowClasses()
extern const wxChar *wxCanvasClassName; // TODO: get rid of wxTLWHiddenParent special case (currently it's not
extern const wxChar *wxCanvasClassNameNR; // registered by wxApp but using ad hoc code in msw/toplevel.cpp);
extern const wxChar *wxMDIFrameClassName; // there is also a hidden window class used by sockets &c
extern const wxChar *wxMDIFrameClassNameNoRedraw; return wxApp::IsRegisteredClassName(str) || str == _T("wxTLWHiddenParent");
extern const wxChar *wxMDIChildFrameClassName;
extern const wxChar *wxMDIChildFrameClassNameNoRedraw;
wxString str(wxGetWindowClass(hWnd));
if (str == wxCanvasClassName ||
str == wxCanvasClassNameNR ||
#if wxUSE_GLCANVAS
str == _T("wxGLCanvasClass") ||
str == _T("wxGLCanvasClassNR") ||
#endif // wxUSE_GLCANVAS
str == wxMDIFrameClassName ||
str == wxMDIFrameClassNameNoRedraw ||
str == wxMDIChildFrameClassName ||
str == wxMDIChildFrameClassNameNoRedraw ||
str == _T("wxTLWHiddenParent"))
return true; // Effectively means don't subclass
else
return false;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -3676,6 +3662,11 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
// especially for wxTLWs // especially for wxTLWs
wxCHECK_MSG( !m_hWnd, true, "window can't be recreated" ); wxCHECK_MSG( !m_hWnd, true, "window can't be recreated" );
// this can happen if this function is called using the return value of
// wxApp::GetRegisteredClassName() which failed
wxCHECK_MSG( wclass, false, "failed to register window class?" );
// choose the position/size for the new window // choose the position/size for the new window
int x, y, w, h; int x, y, w, h;
(void)MSWGetCreateWindowCoords(pos, size, x, y, w, h); (void)MSWGetCreateWindowCoords(pos, size, x, y, w, h);
@@ -3690,7 +3681,7 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
wxString className(wclass); wxString className(wclass);
if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) ) if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) )
{ {
className += wxT("NR"); className += wxApp::GetNoRedrawClassSuffix();
} }
// do create the window // do create the window