mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-10-06 07:00:16 +08:00
Fix using wxComboCtrl popup inside AUI floating panes
Handle correctly the strange case of the popup window being destroyed
by Windows itself, which happened when the AUI floating frame, which was
used as the parent of the popup when it was created for a wxComboCtrl
inside an AUI pane, was itself destroyed. This resulted in problems
because we kept using popup window even though its HWND wasn't valid any
longer.
Detect when this happens and destroy the popup window too, to force
recreating it when/if it's needed again in the future.
This also requires keeping wxOwnerDrawnComboBox::m_initChs even after
using them, as they will be needed again if we need to recreate the
popup.
See #23399.
(cherry picked from commit ac21107b95)
This commit is contained in:
@@ -380,6 +380,7 @@ wxMSW:
|
||||
- Fix drawing owner-drawn menu items with bitmaps (Jacob Gillespie, #23230).
|
||||
- Improve ScrollTo() with wxDV_VARIABLE_LINE_HEIGHT (Jens Göpfert, #23102).
|
||||
- Fix libraries names in Arch64 CMake build (Tobias Taschner, #23347).
|
||||
- Fix using wxComboCtrl with AUI floating pane as parent (#23399).
|
||||
|
||||
wxOSX:
|
||||
|
||||
|
||||
@@ -455,6 +455,9 @@ public:
|
||||
// common code to be called on popup hide/dismiss
|
||||
void OnPopupDismiss(bool generateEvent);
|
||||
|
||||
// called if popup is destroyed not by wxComboCtrl itself
|
||||
void OnPopupDestroy();
|
||||
|
||||
// PopupShown states
|
||||
enum
|
||||
{
|
||||
|
||||
@@ -351,6 +351,46 @@ protected:
|
||||
virtual void OnDismiss() wxOVERRIDE;
|
||||
#endif
|
||||
|
||||
#ifdef __WXMSW__
|
||||
virtual bool MSWHandleMessage(WXLRESULT *result,
|
||||
WXUINT message,
|
||||
WXWPARAM wParam,
|
||||
WXLPARAM lParam) wxOVERRIDE
|
||||
{
|
||||
// This is a workaround for a MSW-specific problem: popup windows are
|
||||
// created with the TLW and not the combobox itself as their parent and
|
||||
// so if the TLW gets destroyed, they're destroyed together with it,
|
||||
// but the associated wxComboCtrl may survive if it gets reparented to
|
||||
// something else, which is exactly what happens when it's used inside
|
||||
// a wxAUI pane. And if this wxComboCtrl is opened again later, it
|
||||
// tries to use the existing popup whose HWND had been destroyed, which
|
||||
// doesn't work at all.
|
||||
//
|
||||
// To prevent this from happening, we delete the popup if this happens
|
||||
// to force recreating it later.
|
||||
if ( message == WM_DESTROY && !m_isBeingDeleted )
|
||||
{
|
||||
m_combo->OnPopupDestroy();
|
||||
|
||||
// We can't delete it immediately because this object is used after
|
||||
// this function returns, so do it slightly later.
|
||||
wxWindow* const self = this;
|
||||
m_combo->CallAfter([self]()
|
||||
{
|
||||
// Before really deleting it, reset the HWND which had been
|
||||
// already destroyed, to prevent us from trying to destroy it
|
||||
// again (which would just fail with an error).
|
||||
self->DissociateHandle();
|
||||
|
||||
delete self;
|
||||
});
|
||||
}
|
||||
|
||||
return wxComboPopupWindowBase::MSWHandleMessage(result, message,
|
||||
wParam, lParam);
|
||||
}
|
||||
#endif // __WXMSW__
|
||||
|
||||
private:
|
||||
// This is the same as our parent, but has the right type, so that we can
|
||||
// avoid using casts later.
|
||||
@@ -2367,6 +2407,14 @@ void wxComboCtrlBase::HidePopup(bool generateEvent)
|
||||
OnPopupDismiss(generateEvent);
|
||||
}
|
||||
|
||||
void wxComboCtrlBase::OnPopupDestroy()
|
||||
{
|
||||
m_winPopup = NULL;
|
||||
|
||||
delete m_popupInterface;
|
||||
m_popupInterface = NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// customization methods
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -990,7 +990,6 @@ void wxOwnerDrawnComboBox::DoSetPopupControl(wxComboPopup* popup)
|
||||
if ( !GetVListBoxComboPopup()->GetCount() )
|
||||
{
|
||||
GetVListBoxComboPopup()->Populate(m_initChs);
|
||||
m_initChs.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user