diff --git a/include/wx/msw/app.h b/include/wx/msw/app.h index 5d55406004..8ac49eb5fa 100644 --- a/include/wx/msw/app.h +++ b/include/wx/msw/app.h @@ -53,6 +53,23 @@ public: // variant registered without CS_[HV]REDRAW styles static const wxChar *GetNoRedrawClassSuffix() { return wxT("NR"); } + // Flags for GetRegisteredClassName() + enum + { + // Just a symbolic name indicating absence of any special flags. + RegClass_Default = 0, + + // Return the name with the GetNoRedrawClassSuffix() appended to it. + RegClass_ReturnNR = 1, + + // Don't register the class with CS_[HV]REDRAW styles. This is useful + // for internal windows for which we can guarantee that they will be + // never created with wxFULL_REPAINT_ON_RESIZE flag. + // + // Notice that this implies RegClass_ReturnNR. + RegClass_OnlyNR = 3 + }; + // 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 @@ -68,7 +85,8 @@ public: // or (default) -1 meaning that the class paints its background itself static const wxChar *GetRegisteredClassName(const wxChar *name, int bgBrushCol = -1, - int extraStyles = 0); + int extraStyles = 0, + int flags = RegClass_Default); // return true if this name corresponds to one of the classes we registered // in the previous GetRegisteredClassName() calls diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 54d937b38b..c3c1fe7c7e 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -52,7 +52,23 @@ public: const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, - const wxString& name = wxPanelNameStr); + const wxString& name = wxPanelNameStr) + { + return CreateUsingMSWClass(GetMSWClassName(), + parent, id, pos, size, style, name); + } + + // Non-portable, MSW-specific Create() variant allowing to create the + // window with a custom Windows class name. This can be useful to assign a + // custom Windows class, that can be recognized from the outside of the + // application, for windows of specific type. + bool CreateUsingMSWClass(const wxChar* classname, + wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxPanelNameStr); // implement base class pure virtuals virtual void SetLabel(const wxString& label) wxOVERRIDE; @@ -230,8 +246,11 @@ public: // get the HWND to be used as parent of this window with CreateWindow() virtual WXHWND MSWGetParent() const; - // get the Win32 window class name used by all wxWindow objects by default - static const wxChar *MSWGetRegisteredClassName(); + // Return the name of the Win32 class that should be used by this wxWindow + // object, taking into account wxFULL_REPAINT_ON_RESIZE style (if it's not + // specified, the wxApp::GetNoRedrawClassSuffix()-suffixed version of the + // class is used). + const wxChar *GetMSWClassName() const; // creates the window of specified Windows class with given style, extended // style, title and geometry (default values diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index b7d807f08e..e173613674 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -22,6 +22,7 @@ #ifndef WX_PRECOMP #ifdef __WXMSW__ + #include "wx/app.h" // GetRegisteredClassName() #include "wx/msw/private.h" #include "wx/msw/wrapwin.h" #include "wx/msw/wrapcctl.h" // include "properly" @@ -1689,9 +1690,26 @@ wxBEGIN_EVENT_TABLE(wxDataViewMainWindow,wxWindow) wxEND_EVENT_TABLE() wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID id, - const wxPoint &pos, const wxSize &size, const wxString &name ) : - wxWindow( parent, id, pos, size, wxWANTS_CHARS|wxBORDER_NONE, name ) + const wxPoint &pos, const wxSize &size, const wxString &name ) { + // We want to use a specific class name for this window in wxMSW to make it + // possible to configure screen readers to handle it specifically. +#ifdef __WXMSW__ + CreateUsingMSWClass + ( + wxApp::GetRegisteredClassName + ( + wxT("wxDataView"), + -1, // no specific background brush + 0, // no special styles neither + wxApp::RegClass_OnlyNR + ), + parent, id, pos, size, wxWANTS_CHARS|wxBORDER_NONE, name + ); +#else + Create( parent, id, pos, size, wxWANTS_CHARS|wxBORDER_NONE, name ) +#endif + SetOwner( parent ); m_editorRenderer = NULL; diff --git a/src/msw/app.cpp b/src/msw/app.cpp index c8f49b8306..910a96979e 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -106,10 +106,29 @@ extern void wxSetKeyboardHook(bool doIt); // see http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/110282 struct ClassRegInfo { - ClassRegInfo(const wxChar *name) - : regname(name), - regnameNR(regname + wxApp::GetNoRedrawClassSuffix()) + ClassRegInfo(const wxChar *name, int flags) { + if ( (flags & wxApp::RegClass_OnlyNR) == wxApp::RegClass_OnlyNR ) + { + // We don't register the "normal" variant, so leave its name empty + // to indicate that it's not used and use the given name for the + // class that we do register: we don't need the "NR" suffix to + // distinguish it in this case as there is only a single variant. + regnameNR = name; + } + else // Register both normal and NR variants. + { + // Here we use a special suffix to make the class names unique. + regname = name; + regnameNR = regname + wxApp::GetNoRedrawClassSuffix(); + } + } + + // Return the appropriate string depending on the presence of + // RegClass_ReturnNR bit in the flags. + const wxChar* GetRequestedName(int flags) const + { + return (flags & wxApp::RegClass_ReturnNR ? regnameNR : regname).t_str(); } // the name of the registered class with and without CS_[HV]REDRAW styles @@ -630,13 +649,15 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_) /* static */ const wxChar *wxApp::GetRegisteredClassName(const wxChar *name, int bgBrushCol, - int extraStyles) + int extraStyles, + int flags) { const size_t count = gs_regClassesInfo.size(); for ( size_t n = 0; n < count; n++ ) { - if ( gs_regClassesInfo[n].regname == name ) - return gs_regClassesInfo[n].regname.c_str(); + if ( gs_regClassesInfo[n].regname == name || + gs_regClassesInfo[n].regnameNR == name ) + return gs_regClassesInfo[n].GetRequestedName(flags); } // we need to register this class @@ -650,13 +671,16 @@ const wxChar *wxApp::GetRegisteredClassName(const wxChar *name, wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | extraStyles; - ClassRegInfo regClass(name); - wndclass.lpszClassName = regClass.regname.t_str(); - if ( !::RegisterClass(&wndclass) ) + ClassRegInfo regClass(name, flags); + if ( !regClass.regname.empty() ) { - wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"), - regClass.regname)); - return NULL; + wndclass.lpszClassName = regClass.regname.t_str(); + if ( !::RegisterClass(&wndclass) ) + { + wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"), + regClass.regname)); + return NULL; + } } wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW); @@ -675,7 +699,7 @@ const wxChar *wxApp::GetRegisteredClassName(const wxChar *name, // 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.t_str(); + return gs_regClassesInfo.back().GetRequestedName(flags); } bool wxApp::IsRegisteredClassName(const wxString& name) @@ -697,10 +721,13 @@ void wxApp::UnregisterWindowClasses() for ( size_t n = 0; n < count; n++ ) { const ClassRegInfo& regClass = gs_regClassesInfo[n]; - if ( !::UnregisterClass(regClass.regname.c_str(), wxGetInstance()) ) + if ( !regClass.regname.empty() ) { - wxLogLastError(wxString::Format(wxT("UnregisterClass(%s)"), - regClass.regname)); + if ( !::UnregisterClass(regClass.regname.c_str(), wxGetInstance()) ) + { + wxLogLastError(wxString::Format(wxT("UnregisterClass(%s)"), + regClass.regname)); + } } if ( !::UnregisterClass(regClass.regnameNR.c_str(), wxGetInstance()) ) diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index c9576fb9f1..a9a331a184 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -407,8 +407,7 @@ bool wxTopLevelWindowMSW::CreateFrame(const wxString& title, if ( wxApp::MSWGetDefaultLayout(m_parent) == wxLayout_RightToLeft ) exflags |= WS_EX_LAYOUTRTL; - return MSWCreate(MSWGetRegisteredClassName(), - title.t_str(), pos, sz, flags, exflags); + return MSWCreate(GetMSWClassName(), title.t_str(), pos, sz, flags, exflags); } bool wxTopLevelWindowMSW::Create(wxWindow *parent, diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 17085898c4..458f24083a 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -468,19 +468,26 @@ wxWindowMSW::~wxWindowMSW() } -/* static */ -const wxChar *wxWindowMSW::MSWGetRegisteredClassName() +const wxChar *wxWindowMSW::GetMSWClassName() const { - return wxApp::GetRegisteredClassName(wxT("wxWindow"), COLOR_BTNFACE); + return wxApp::GetRegisteredClassName + ( + wxT("wxWindow"), + COLOR_BTNFACE, + 0, // no special extra style + HasFlag(wxFULL_REPAINT_ON_RESIZE) ? wxApp::RegClass_Default + : wxApp::RegClass_ReturnNR + ); } // real construction (Init() must have been called before!) -bool wxWindowMSW::Create(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) +bool wxWindowMSW::CreateUsingMSWClass(const wxChar* classname, + wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") ); @@ -506,8 +513,7 @@ bool wxWindowMSW::Create(wxWindow *parent, msflags |= WS_VISIBLE; } - if ( !MSWCreate(MSWGetRegisteredClassName(), - NULL, pos, size, msflags, exstyle) ) + if ( !MSWCreate(classname, NULL, pos, size, msflags, exstyle) ) return false; InheritAttributes(); @@ -3695,22 +3701,13 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, // unless we're creating a child window int controlId = style & WS_CHILD ? GetId() : 0; - // for each class "Foo" we have we also have "FooNR" ("no repaint") class - // which is the same but without CS_[HV]REDRAW class styles so using it - // ensures that the window is not fully repainted on each resize - wxString className(wclass); - if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) ) - { - className += wxApp::GetNoRedrawClassSuffix(); - } - // do create the window wxWindowCreationHook hook(this); m_hWnd = (WXHWND)::CreateWindowEx ( extendedStyle, - className.t_str(), + wclass, title ? title : m_windowName.t_str(), style, x, y, w, h, @@ -3722,7 +3719,7 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, if ( !m_hWnd ) { - wxLogSysError(_("Can't create window of class %s"), className.c_str()); + wxLogSysError(_("Can't create window of class %s"), wclass); return false; }