Fix IsEnabled() return value for wxMSW TLWs with native dialogs
IsEnabled() wrongly returned true even when the TLW was actually disabled due to a native modal dialog using it as owner being currently shown. Fix this by trusting the actual HWND state, rather than our internal m_isEnabled, except before the window is created. Do it for TLWs only even if, in principle, we could check for WS_DISABLED for the other windows too. However this would make IsThisEnabled() inconsistent with the other platforms, where it returns true when the window parent is disabled, but the window itself isn't, which is currently also emulated by wxMSW, but wouldn't be the case if we trusted WS_DISABLED presence. And while there might be other problems due to lying about the actual window state in this function, it doesn't seem to create any problems in practice, so for now leave the old logic in place. As a side effect, this makes wxWindowDisabler work correctly when a message box is shown by another window when it's created, as it will now correctly avoid re-enabling the message box parent in its dtor. Closes https://github.com/wxWidgets/wxWidgets/pull/2117 See #11887.
This commit is contained in:
@@ -24,6 +24,7 @@ public:
|
|||||||
|
|
||||||
virtual bool Reparent(wxWindowBase* newParent) wxOVERRIDE;
|
virtual bool Reparent(wxWindowBase* newParent) wxOVERRIDE;
|
||||||
virtual void InheritAttributes() wxOVERRIDE;
|
virtual void InheritAttributes() wxOVERRIDE;
|
||||||
|
virtual bool IsThisEnabled() const wxOVERRIDE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool DoClearShape() wxOVERRIDE;
|
virtual bool DoClearShape() wxOVERRIDE;
|
||||||
|
@@ -655,7 +655,7 @@ public:
|
|||||||
// state, i.e. the state in which the window would be if all its
|
// state, i.e. the state in which the window would be if all its
|
||||||
// parents were enabled (use IsEnabled() above to get the effective
|
// parents were enabled (use IsEnabled() above to get the effective
|
||||||
// window state)
|
// window state)
|
||||||
bool IsThisEnabled() const { return m_isEnabled; }
|
virtual bool IsThisEnabled() const { return m_isEnabled; }
|
||||||
|
|
||||||
// returns true if the window is visible, i.e. IsShown() returns true
|
// returns true if the window is visible, i.e. IsShown() returns true
|
||||||
// if called on it and all its parents up to the first TLW
|
// if called on it and all its parents up to the first TLW
|
||||||
|
@@ -221,6 +221,21 @@ void wxNonOwnedWindow::InheritAttributes()
|
|||||||
wxNonOwnedWindowBase::InheritAttributes();
|
wxNonOwnedWindowBase::InheritAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxNonOwnedWindow::IsThisEnabled() const
|
||||||
|
{
|
||||||
|
// Under MSW we use the actual window state rather than the value of
|
||||||
|
// m_isEnabled because the latter might be out of sync for TLWs disabled
|
||||||
|
// by a native modal dialog being shown, as native functions such as
|
||||||
|
// ::MessageBox() etc just call ::EnableWindow() on them without updating
|
||||||
|
// m_isEnabled and we have no way to be notified about this.
|
||||||
|
//
|
||||||
|
// But we can only do this if the window had been already created, so test
|
||||||
|
// for this in order to return correct result if it was disabled after
|
||||||
|
// using default ctor but before calling Create().
|
||||||
|
return m_hWnd ? !(::GetWindowLong(GetHwnd(), GWL_STYLE) & WS_DISABLED)
|
||||||
|
: m_isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
WXLRESULT wxNonOwnedWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
|
WXLRESULT wxNonOwnedWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
|
||||||
{
|
{
|
||||||
WXLRESULT rc = 0;
|
WXLRESULT rc = 0;
|
||||||
|
Reference in New Issue
Block a user