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:
@@ -53,6 +53,23 @@ public:
|
|||||||
// variant registered without CS_[HV]REDRAW styles
|
// variant registered without CS_[HV]REDRAW styles
|
||||||
static const wxChar *GetNoRedrawClassSuffix() { return wxT("NR"); }
|
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
|
// 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
|
// 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
|
// 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
|
// or (default) -1 meaning that the class paints its background itself
|
||||||
static const wxChar *GetRegisteredClassName(const wxChar *name,
|
static const wxChar *GetRegisteredClassName(const wxChar *name,
|
||||||
int bgBrushCol = -1,
|
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
|
// return true if this name corresponds to one of the classes we registered
|
||||||
// in the previous GetRegisteredClassName() calls
|
// in the previous GetRegisteredClassName() calls
|
||||||
|
@@ -52,7 +52,23 @@ public:
|
|||||||
const wxPoint& pos = wxDefaultPosition,
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
const wxSize& size = wxDefaultSize,
|
const wxSize& size = wxDefaultSize,
|
||||||
long style = 0,
|
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
|
// implement base class pure virtuals
|
||||||
virtual void SetLabel(const wxString& label) wxOVERRIDE;
|
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()
|
// 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
|
// Return the name of the Win32 class that should be used by this wxWindow
|
||||||
static const wxChar *MSWGetRegisteredClassName();
|
// 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
|
// creates the window of specified Windows class with given style, extended
|
||||||
// style, title and geometry (default values
|
// style, title and geometry (default values
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
|
#include "wx/app.h" // GetRegisteredClassName()
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
#include "wx/msw/wrapwin.h"
|
#include "wx/msw/wrapwin.h"
|
||||||
#include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly"
|
#include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly"
|
||||||
@@ -1689,9 +1690,26 @@ wxBEGIN_EVENT_TABLE(wxDataViewMainWindow,wxWindow)
|
|||||||
wxEND_EVENT_TABLE()
|
wxEND_EVENT_TABLE()
|
||||||
|
|
||||||
wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID id,
|
wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID id,
|
||||||
const wxPoint &pos, const wxSize &size, const wxString &name ) :
|
const wxPoint &pos, const wxSize &size, const wxString &name )
|
||||||
wxWindow( parent, id, pos, size, wxWANTS_CHARS|wxBORDER_NONE, 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 );
|
SetOwner( parent );
|
||||||
|
|
||||||
m_editorRenderer = NULL;
|
m_editorRenderer = NULL;
|
||||||
|
@@ -106,10 +106,29 @@ extern void wxSetKeyboardHook(bool doIt);
|
|||||||
// see http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/110282
|
// see http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/110282
|
||||||
struct ClassRegInfo
|
struct ClassRegInfo
|
||||||
{
|
{
|
||||||
ClassRegInfo(const wxChar *name)
|
ClassRegInfo(const wxChar *name, int flags)
|
||||||
: regname(name),
|
|
||||||
regnameNR(regname + wxApp::GetNoRedrawClassSuffix())
|
|
||||||
{
|
{
|
||||||
|
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
|
// 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 */
|
/* static */
|
||||||
const wxChar *wxApp::GetRegisteredClassName(const wxChar *name,
|
const wxChar *wxApp::GetRegisteredClassName(const wxChar *name,
|
||||||
int bgBrushCol,
|
int bgBrushCol,
|
||||||
int extraStyles)
|
int extraStyles,
|
||||||
|
int flags)
|
||||||
{
|
{
|
||||||
const size_t count = gs_regClassesInfo.size();
|
const size_t count = gs_regClassesInfo.size();
|
||||||
for ( size_t n = 0; n < count; n++ )
|
for ( size_t n = 0; n < count; n++ )
|
||||||
{
|
{
|
||||||
if ( gs_regClassesInfo[n].regname == name )
|
if ( gs_regClassesInfo[n].regname == name ||
|
||||||
return gs_regClassesInfo[n].regname.c_str();
|
gs_regClassesInfo[n].regnameNR == name )
|
||||||
|
return gs_regClassesInfo[n].GetRequestedName(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to register this class
|
// 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;
|
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | extraStyles;
|
||||||
|
|
||||||
|
|
||||||
ClassRegInfo regClass(name);
|
ClassRegInfo regClass(name, flags);
|
||||||
wndclass.lpszClassName = regClass.regname.t_str();
|
if ( !regClass.regname.empty() )
|
||||||
if ( !::RegisterClass(&wndclass) )
|
|
||||||
{
|
{
|
||||||
wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"),
|
wndclass.lpszClassName = regClass.regname.t_str();
|
||||||
regClass.regname));
|
if ( !::RegisterClass(&wndclass) )
|
||||||
return NULL;
|
{
|
||||||
|
wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"),
|
||||||
|
regClass.regname));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW);
|
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
|
// 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
|
// added to the vector and it's reallocated but this shouldn't matter as
|
||||||
// this pointer should be used right now, not stored)
|
// 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)
|
bool wxApp::IsRegisteredClassName(const wxString& name)
|
||||||
@@ -697,10 +721,13 @@ void wxApp::UnregisterWindowClasses()
|
|||||||
for ( size_t n = 0; n < count; n++ )
|
for ( size_t n = 0; n < count; n++ )
|
||||||
{
|
{
|
||||||
const ClassRegInfo& regClass = gs_regClassesInfo[n];
|
const ClassRegInfo& regClass = gs_regClassesInfo[n];
|
||||||
if ( !::UnregisterClass(regClass.regname.c_str(), wxGetInstance()) )
|
if ( !regClass.regname.empty() )
|
||||||
{
|
{
|
||||||
wxLogLastError(wxString::Format(wxT("UnregisterClass(%s)"),
|
if ( !::UnregisterClass(regClass.regname.c_str(), wxGetInstance()) )
|
||||||
regClass.regname));
|
{
|
||||||
|
wxLogLastError(wxString::Format(wxT("UnregisterClass(%s)"),
|
||||||
|
regClass.regname));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !::UnregisterClass(regClass.regnameNR.c_str(), wxGetInstance()) )
|
if ( !::UnregisterClass(regClass.regnameNR.c_str(), wxGetInstance()) )
|
||||||
|
@@ -407,8 +407,7 @@ bool wxTopLevelWindowMSW::CreateFrame(const wxString& title,
|
|||||||
if ( wxApp::MSWGetDefaultLayout(m_parent) == wxLayout_RightToLeft )
|
if ( wxApp::MSWGetDefaultLayout(m_parent) == wxLayout_RightToLeft )
|
||||||
exflags |= WS_EX_LAYOUTRTL;
|
exflags |= WS_EX_LAYOUTRTL;
|
||||||
|
|
||||||
return MSWCreate(MSWGetRegisteredClassName(),
|
return MSWCreate(GetMSWClassName(), title.t_str(), pos, sz, flags, exflags);
|
||||||
title.t_str(), pos, sz, flags, exflags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTopLevelWindowMSW::Create(wxWindow *parent,
|
bool wxTopLevelWindowMSW::Create(wxWindow *parent,
|
||||||
|
@@ -468,19 +468,26 @@ wxWindowMSW::~wxWindowMSW()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
const wxChar *wxWindowMSW::GetMSWClassName() const
|
||||||
const wxChar *wxWindowMSW::MSWGetRegisteredClassName()
|
|
||||||
{
|
{
|
||||||
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!)
|
// real construction (Init() must have been called before!)
|
||||||
bool wxWindowMSW::Create(wxWindow *parent,
|
bool wxWindowMSW::CreateUsingMSWClass(const wxChar* classname,
|
||||||
wxWindowID id,
|
wxWindow *parent,
|
||||||
const wxPoint& pos,
|
wxWindowID id,
|
||||||
const wxSize& size,
|
const wxPoint& pos,
|
||||||
long style,
|
const wxSize& size,
|
||||||
const wxString& name)
|
long style,
|
||||||
|
const wxString& name)
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") );
|
wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") );
|
||||||
|
|
||||||
@@ -506,8 +513,7 @@ bool wxWindowMSW::Create(wxWindow *parent,
|
|||||||
msflags |= WS_VISIBLE;
|
msflags |= WS_VISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !MSWCreate(MSWGetRegisteredClassName(),
|
if ( !MSWCreate(classname, NULL, pos, size, msflags, exstyle) )
|
||||||
NULL, pos, size, msflags, exstyle) )
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
InheritAttributes();
|
InheritAttributes();
|
||||||
@@ -3695,22 +3701,13 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
|
|||||||
// unless we're creating a child window
|
// unless we're creating a child window
|
||||||
int controlId = style & WS_CHILD ? GetId() : 0;
|
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
|
// do create the window
|
||||||
wxWindowCreationHook hook(this);
|
wxWindowCreationHook hook(this);
|
||||||
|
|
||||||
m_hWnd = (WXHWND)::CreateWindowEx
|
m_hWnd = (WXHWND)::CreateWindowEx
|
||||||
(
|
(
|
||||||
extendedStyle,
|
extendedStyle,
|
||||||
className.t_str(),
|
wclass,
|
||||||
title ? title : m_windowName.t_str(),
|
title ? title : m_windowName.t_str(),
|
||||||
style,
|
style,
|
||||||
x, y, w, h,
|
x, y, w, h,
|
||||||
@@ -3722,7 +3719,7 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
|
|||||||
|
|
||||||
if ( !m_hWnd )
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user