Merge branch 'custom-msw-class'
Allow using custom Windows class names for our windows and use this to give a unique class name allowing to identify it in the screen readers to wxDataViewCtrl. Closes https://github.com/wxWidgets/wxWidgets/pull/373
This commit is contained in:
commit
7cddac83a9
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 <commctrl.h> "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;
|
||||
|
@ -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()) )
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user