moved OnActivate() logic from wxFrame to wxDialog -- this fixes infinite loop when handling WM_ACTIVATE in DefDlgProc in some crazy situations
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15816 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -52,7 +52,6 @@ public:
|
|||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
|
||||||
// event handlers
|
// event handlers
|
||||||
void OnActivate(wxActivateEvent& event);
|
|
||||||
void OnSysColourChanged(wxSysColourChangedEvent& event);
|
void OnSysColourChanged(wxSysColourChangedEvent& event);
|
||||||
|
|
||||||
// Toolbar
|
// Toolbar
|
||||||
@@ -103,10 +102,6 @@ public:
|
|||||||
// current size - this has an effect of refreshing the window layout
|
// current size - this has an effect of refreshing the window layout
|
||||||
void SendSizeEvent();
|
void SendSizeEvent();
|
||||||
|
|
||||||
// called by wxWindow whenever it gets focus
|
|
||||||
void SetLastFocus(wxWindow *win) { m_winLastFocused = win; }
|
|
||||||
wxWindow *GetLastFocus() const { return m_winLastFocused; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
void Init();
|
void Init();
|
||||||
@@ -142,14 +137,10 @@ protected:
|
|||||||
static bool m_useNativeStatusBar;
|
static bool m_useNativeStatusBar;
|
||||||
#endif // wxUSE_STATUSBAR
|
#endif // wxUSE_STATUSBAR
|
||||||
|
|
||||||
// the last focused child: we restore focus to it on activation
|
|
||||||
wxWindow *m_winLastFocused;
|
|
||||||
|
|
||||||
// Data to save/restore when calling ShowFullScreen
|
// Data to save/restore when calling ShowFullScreen
|
||||||
int m_fsStatusBarFields; // 0 for no status bar
|
int m_fsStatusBarFields; // 0 for no status bar
|
||||||
int m_fsStatusBarHeight;
|
int m_fsStatusBarHeight;
|
||||||
int m_fsToolBarHeight;
|
int m_fsToolBarHeight;
|
||||||
// WXHMENU m_fsMenu;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if wxUSE_TOOLTIPS
|
#if wxUSE_TOOLTIPS
|
||||||
|
@@ -70,6 +70,13 @@ public:
|
|||||||
// implementation from now on
|
// implementation from now on
|
||||||
// --------------------------
|
// --------------------------
|
||||||
|
|
||||||
|
// event handlers
|
||||||
|
void OnActivate(wxActivateEvent& event);
|
||||||
|
|
||||||
|
// called by wxWindow whenever it gets focus
|
||||||
|
void SetLastFocus(wxWindow *win) { m_winLastFocused = win; }
|
||||||
|
wxWindow *GetLastFocus() const { return m_winLastFocused; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
void Init();
|
void Init();
|
||||||
@@ -89,10 +96,6 @@ protected:
|
|||||||
// common part of Iconize(), Maximize() and Restore()
|
// common part of Iconize(), Maximize() and Restore()
|
||||||
void DoShowWindow(int nShowCmd);
|
void DoShowWindow(int nShowCmd);
|
||||||
|
|
||||||
// prevent the window from being deactivated sometimes (see comments in the
|
|
||||||
// code)
|
|
||||||
long HandleNcActivate(bool activate);
|
|
||||||
|
|
||||||
// translate wxWindows flags to Windows ones
|
// translate wxWindows flags to Windows ones
|
||||||
virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle) const;
|
virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle) const;
|
||||||
|
|
||||||
@@ -113,9 +116,14 @@ protected:
|
|||||||
bool m_fsIsMaximized;
|
bool m_fsIsMaximized;
|
||||||
bool m_fsIsShowing;
|
bool m_fsIsShowing;
|
||||||
|
|
||||||
|
// the last focused child: we restore focus to it on activation
|
||||||
|
wxWindow *m_winLastFocused;
|
||||||
|
|
||||||
// the hidden parent window for the frames which shouldn't appear in the
|
// the hidden parent window for the frames which shouldn't appear in the
|
||||||
// taskbar
|
// taskbar
|
||||||
static wxWindow *ms_hiddenParent;
|
static wxWindow *ms_hiddenParent;
|
||||||
|
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
// list of all frames and modeless dialogs
|
// list of all frames and modeless dialogs
|
||||||
|
@@ -364,6 +364,17 @@ void wxWindowBase::Centre(int direction)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we shouldn't center the dialog on the iconized window: under
|
||||||
|
// Windows, for example, this places it completely off the screen
|
||||||
|
if ( parent )
|
||||||
|
{
|
||||||
|
wxTopLevelWindow *winTop = wxDynamicCast(parent, wxTopLevelWindow);
|
||||||
|
if ( winTop && winTop->IsIconized() )
|
||||||
|
{
|
||||||
|
parent = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// did we find the parent?
|
// did we find the parent?
|
||||||
if ( !parent )
|
if ( !parent )
|
||||||
{
|
{
|
||||||
|
@@ -72,7 +72,6 @@
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
|
BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
|
||||||
EVT_ACTIVATE(wxFrame::OnActivate)
|
|
||||||
EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
|
EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
@@ -108,11 +107,8 @@ void wxFrame::Init()
|
|||||||
m_fsStatusBarFields = 0;
|
m_fsStatusBarFields = 0;
|
||||||
m_fsStatusBarHeight = 0;
|
m_fsStatusBarHeight = 0;
|
||||||
m_fsToolBarHeight = 0;
|
m_fsToolBarHeight = 0;
|
||||||
// m_fsMenu = 0;
|
|
||||||
|
|
||||||
m_wasMinimized = FALSE;
|
m_wasMinimized = FALSE;
|
||||||
|
|
||||||
m_winLastFocused = (wxWindow *)NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxFrame::Create(wxWindow *parent,
|
bool wxFrame::Create(wxWindow *parent,
|
||||||
@@ -324,7 +320,7 @@ void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
|
|||||||
// Pass TRUE to show full screen, FALSE to restore.
|
// Pass TRUE to show full screen, FALSE to restore.
|
||||||
bool wxFrame::ShowFullScreen(bool show, long style)
|
bool wxFrame::ShowFullScreen(bool show, long style)
|
||||||
{
|
{
|
||||||
if ( IsFullScreen() == show )
|
if ( IsFullScreen() == show )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (show)
|
if (show)
|
||||||
@@ -395,60 +391,10 @@ bool wxFrame::ShowFullScreen(bool show, long style)
|
|||||||
SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
|
SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxFrameBase::ShowFullScreen(show, style);
|
return wxFrameBase::ShowFullScreen(show, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default activation behaviour - set the focus for the first child
|
|
||||||
// subwindow found.
|
|
||||||
void wxFrame::OnActivate(wxActivateEvent& event)
|
|
||||||
{
|
|
||||||
if ( event.GetActive() )
|
|
||||||
{
|
|
||||||
// restore focus to the child which was last focused
|
|
||||||
wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd);
|
|
||||||
|
|
||||||
wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
|
|
||||||
: NULL;
|
|
||||||
if ( !parent )
|
|
||||||
{
|
|
||||||
parent = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxSetFocusToChild(parent, &m_winLastFocused);
|
|
||||||
}
|
|
||||||
else // deactivating
|
|
||||||
{
|
|
||||||
// remember the last focused child if it is our child
|
|
||||||
m_winLastFocused = FindFocus();
|
|
||||||
|
|
||||||
// so we NULL it out if it's a child from some other frame
|
|
||||||
wxWindow *win = m_winLastFocused;
|
|
||||||
while ( win )
|
|
||||||
{
|
|
||||||
if ( win->IsTopLevel() )
|
|
||||||
{
|
|
||||||
if ( win != this )
|
|
||||||
{
|
|
||||||
m_winLastFocused = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
win = win->GetParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxLogTrace(_T("focus"),
|
|
||||||
_T("wxFrame %08x deactivated, last focused: %08x."),
|
|
||||||
m_hWnd,
|
|
||||||
m_winLastFocused ? GetHwndOf(m_winLastFocused)
|
|
||||||
: NULL);
|
|
||||||
|
|
||||||
event.Skip();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// tool/status bar stuff
|
// tool/status bar stuff
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -77,6 +77,10 @@ wxWindow *wxTopLevelWindowMSW::ms_hiddenParent = NULL;
|
|||||||
// wxTopLevelWindowMSW implementation
|
// wxTopLevelWindowMSW implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(wxTopLevelWindowMSW, wxTopLevelWindowBase)
|
||||||
|
EVT_ACTIVATE(wxTopLevelWindowMSW::OnActivate)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxDialog helpers
|
// wxDialog helpers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -116,6 +120,8 @@ void wxTopLevelWindowMSW::Init()
|
|||||||
m_fsOldWindowStyle = 0;
|
m_fsOldWindowStyle = 0;
|
||||||
m_fsIsMaximized = FALSE;
|
m_fsIsMaximized = FALSE;
|
||||||
m_fsIsShowing = FALSE;
|
m_fsIsShowing = FALSE;
|
||||||
|
|
||||||
|
m_winLastFocused = (wxWindow *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
|
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
|
||||||
@@ -740,3 +746,57 @@ bool wxTopLevelWindowMSW::EnableCloseButton(bool enable)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxTopLevelWindow event handling
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Default activation behaviour - set the focus for the first child
|
||||||
|
// subwindow found.
|
||||||
|
void wxTopLevelWindowMSW::OnActivate(wxActivateEvent& event)
|
||||||
|
{
|
||||||
|
if ( event.GetActive() )
|
||||||
|
{
|
||||||
|
// restore focus to the child which was last focused
|
||||||
|
wxLogTrace(_T("focus"), _T("wxTLW %08x activated."), m_hWnd);
|
||||||
|
|
||||||
|
wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
|
||||||
|
: NULL;
|
||||||
|
if ( !parent )
|
||||||
|
{
|
||||||
|
parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxSetFocusToChild(parent, &m_winLastFocused);
|
||||||
|
}
|
||||||
|
else // deactivating
|
||||||
|
{
|
||||||
|
// remember the last focused child if it is our child
|
||||||
|
m_winLastFocused = FindFocus();
|
||||||
|
|
||||||
|
// so we NULL it out if it's a child from some other frame
|
||||||
|
wxWindow *win = m_winLastFocused;
|
||||||
|
while ( win )
|
||||||
|
{
|
||||||
|
if ( win->IsTopLevel() )
|
||||||
|
{
|
||||||
|
if ( win != this )
|
||||||
|
{
|
||||||
|
m_winLastFocused = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
win = win->GetParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxLogTrace(_T("focus"),
|
||||||
|
_T("wxTLW %08x deactivated, last focused: %08x."),
|
||||||
|
m_hWnd,
|
||||||
|
m_winLastFocused ? GetHwndOf(m_winLastFocused)
|
||||||
|
: NULL);
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -348,12 +348,12 @@ wxWindowMSW::~wxWindowMSW()
|
|||||||
// VS: make sure there's no wxFrame with last focus set to us:
|
// VS: make sure there's no wxFrame with last focus set to us:
|
||||||
for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
|
for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
|
||||||
{
|
{
|
||||||
wxFrame *frame = wxDynamicCast(win, wxFrame);
|
wxTopLevelWindow *frame = wxDynamicCast(win, wxTopLevelWindow);
|
||||||
if ( frame )
|
if ( frame )
|
||||||
{
|
{
|
||||||
if ( frame->GetLastFocus() == this )
|
if ( frame->GetLastFocus() == this )
|
||||||
{
|
{
|
||||||
frame->SetLastFocus((wxWindow*)NULL);
|
frame->SetLastFocus(NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2083,15 +2083,27 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
|
|||||||
// ::IsDialogMessage() can enter in an infinite loop when
|
// ::IsDialogMessage() can enter in an infinite loop when
|
||||||
// WS_EX_CONTROLPARENT is specified and the currently focused
|
// WS_EX_CONTROLPARENT is specified and the currently focused
|
||||||
// window is disabled or hidden, so don't call it in this case
|
// window is disabled or hidden, so don't call it in this case
|
||||||
|
bool canSafelyCallIsDlgMsg = TRUE;
|
||||||
|
|
||||||
HWND hwndFocus = ::GetFocus();
|
HWND hwndFocus = ::GetFocus();
|
||||||
if ( !hwndFocus ||
|
while ( hwndFocus )
|
||||||
::IsWindowEnabled(hwndFocus) && ::IsWindowVisible(hwndFocus) )
|
|
||||||
{
|
{
|
||||||
if ( ::IsDialogMessage(GetHwnd(), msg) )
|
if ( !::IsWindowEnabled(hwndFocus) ||
|
||||||
|
!::IsWindowVisible(hwndFocus) )
|
||||||
{
|
{
|
||||||
// IsDialogMessage() did something...
|
// it would enter an infinite loop if we do this!
|
||||||
return TRUE;
|
canSafelyCallIsDlgMsg = FALSE;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hwndFocus = ::GetParent(hwndFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( canSafelyCallIsDlgMsg && ::IsDialogMessage(GetHwnd(), msg) )
|
||||||
|
{
|
||||||
|
// IsDialogMessage() did something...
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user