From 761989ffb536ab51e977142aa018064ef32b539b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 1 Aug 2001 02:29:35 +0000 Subject: [PATCH] Vain attempts to make kbd navigation work inside find/replace dialog - it still doesn't. But at least the dialog itself does work now. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11228 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/fdrepdlg.h | 43 ++++++++---- samples/dialogs/dialogs.cpp | 91 +++++++++++++++++++++++++- samples/dialogs/dialogs.h | 16 ++++- src/msw/app.cpp | 10 ++- src/msw/fdrepdlg.cpp | 127 ++++++++++++++++++++++++++---------- src/msw/frame.cpp | 1 - src/msw/window.cpp | 23 ++++--- 7 files changed, 251 insertions(+), 60 deletions(-) diff --git a/include/wx/fdrepdlg.h b/include/wx/fdrepdlg.h index 0d2da818e6..f290451a47 100644 --- a/include/wx/fdrepdlg.h +++ b/include/wx/fdrepdlg.h @@ -66,8 +66,8 @@ enum wxFindReplaceDialogStyles class WXDLLEXPORT wxFindReplaceData : public wxObject { public: - wxFindReplaceData() { } - wxFindReplaceData(wxUint32 flags) { SetFlags(flags); } + wxFindReplaceData() { Init(); } + wxFindReplaceData(wxUint32 flags) { Init(); SetFlags(flags); } // accessors const wxString& GetFindString() { return m_FindWhat; } @@ -81,6 +81,9 @@ public: void SetFindString(const wxString& str) { m_FindWhat = str; } void SetReplaceString(const wxString& str) { m_ReplaceWith = str; } +protected: + void Init(); + private: wxUint32 m_Flags; wxString m_FindWhat, @@ -100,11 +103,13 @@ public: wxFindReplaceDialog() { Init(); } wxFindReplaceDialog(wxWindow *parent, wxFindReplaceData *data, - const wxString &title); + const wxString &title, + int style = 0); bool Create(wxWindow *parent, wxFindReplaceData *data, - const wxString &title); + const wxString &title, + int style = 0); virtual ~wxFindReplaceDialog(); @@ -117,7 +122,7 @@ public: wxFindReplaceDialogImpl *GetImpl() const { return m_impl; } // override some base class virtuals - virtual bool Show(bool show); + virtual bool Show(bool show = TRUE); virtual void SetTitle( const wxString& title); virtual wxString GetTitle() const; @@ -152,6 +157,9 @@ public: wxString GetFindString() const { return GetString(); } const wxString& GetReplaceString() const { return m_strReplace; } + wxFindReplaceDialog *GetDialog() const + { return wxStaticCast(GetEventObject(), wxFindReplaceDialog); } + // implementation only void SetFlags(int flags) { SetInt(flags); } void SetFindString(const wxString& str) { SetString(str); } @@ -164,14 +172,23 @@ private: }; BEGIN_DECLARE_EVENT_TYPES() - DECLARE_EVENT_TYPE(wxEVT_COMMAND_FIND_NEXT, 510) - DECLARE_EVENT_TYPE(wxEVT_COMMAND_REPLACE, 511) - DECLARE_EVENT_TYPE(wxEVT_COMMAND_REPLACE_ALL, 512) - DECLARE_EVENT_TYPE(wxEVT_COMMAND_FIND_CLOSE, 513) + DECLARE_EVENT_TYPE(wxEVT_COMMAND_FIND, 510) + DECLARE_EVENT_TYPE(wxEVT_COMMAND_FIND_NEXT, 511) + DECLARE_EVENT_TYPE(wxEVT_COMMAND_FIND_REPLACE, 512) + DECLARE_EVENT_TYPE(wxEVT_COMMAND_FIND_REPLACE_ALL, 513) + DECLARE_EVENT_TYPE(wxEVT_COMMAND_FIND_CLOSE, 514) END_DECLARE_EVENT_TYPES() typedef void (wxEvtHandler::*wxFindDialogEventFunction)(wxFindDialogEvent&); +#define EVT_FIND(id, fn) \ + DECLARE_EVENT_TABLE_ENTRY( \ + wxEVT_COMMAND_FIND, id, -1, \ + (wxObjectEventFunction)(wxEventFunction)(wxFindDialogEventFunction) \ + & fn, \ + (wxObject *) NULL \ + ), + #define EVT_FIND_NEXT(id, fn) \ DECLARE_EVENT_TABLE_ENTRY( \ wxEVT_COMMAND_FIND_NEXT, id, -1, \ @@ -180,9 +197,9 @@ typedef void (wxEvtHandler::*wxFindDialogEventFunction)(wxFindDialogEvent&); (wxObject *) NULL \ ), -#define EVT_REPLACE(id, fn) \ +#define EVT_FIND_REPLACE(id, fn) \ DECLARE_EVENT_TABLE_ENTRY( \ - wxEVT_COMMAND_REPLACE, id, -1, \ + wxEVT_COMMAND_FIND_REPLACE, id, -1, \ (wxObjectEventFunction)(wxEventFunction)(wxFindDialogEventFunction) \ & fn, \ (wxObject *) NULL \ @@ -190,13 +207,13 @@ typedef void (wxEvtHandler::*wxFindDialogEventFunction)(wxFindDialogEvent&); #define EVT_FIND_REPLACE_ALL(id, fn) \ DECLARE_EVENT_TABLE_ENTRY( \ - wxEVT_COMMAND_REPLACE_ALL, id, -1, \ + wxEVT_COMMAND_FIND_REPLACE_ALL, id, -1, \ (wxObjectEventFunction)(wxEventFunction)(wxFindDialogEventFunction) \ & fn, \ (wxObject *) NULL \ ), -#define EVT_FIND_FIND_CLOSE(id, fn) \ +#define EVT_FIND_CLOSE(id, fn) \ DECLARE_EVENT_TABLE_ENTRY( \ wxEVT_COMMAND_FIND_CLOSE, id, -1, \ (wxObjectEventFunction)(wxEventFunction)(wxFindDialogEventFunction) \ diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index af929a2dd4..08d8abd3c7 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -32,6 +32,7 @@ #include "wx/choicdlg.h" #include "wx/tipdlg.h" #include "wx/progdlg.h" +#include "wx/fdrepdlg.h" #define wxTEST_GENERIC_DIALOGS_IN_MSW 0 @@ -78,7 +79,17 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) #endif #if wxUSE_PROGRESSDLG EVT_MENU(DIALOGS_PROGRESS, MyFrame::ShowProgress) -#endif +#endif // wxUSE_PROGRESSDLG +#if wxUSE_FINDREPLDLG + EVT_MENU(DIALOGS_FIND, MyFrame::ShowFindDialog) + EVT_MENU(DIALOGS_REPLACE, MyFrame::ShowReplaceDialog) + + EVT_FIND(-1, MyFrame::OnFindDialog) + EVT_FIND_NEXT(-1, MyFrame::OnFindDialog) + EVT_FIND_REPLACE(-1, MyFrame::OnFindDialog) + EVT_FIND_REPLACE_ALL(-1, MyFrame::OnFindDialog) + EVT_FIND_CLOSE(-1, MyFrame::OnFindDialog) +#endif // wxUSE_FINDREPLDLG EVT_MENU(wxID_EXIT, MyFrame::OnExit) EVT_BUTTON(DIALOGS_MODELESS_BTN, MyFrame::OnButton) @@ -143,8 +154,12 @@ bool MyApp::OnInit() #if wxUSE_PROGRESSDLG file_menu->Append(DIALOGS_PROGRESS, "Pro&gress dialog\tCtrl-G"); #endif // wxUSE_PROGRESSDLG +#if wxUSE_FINDREPLDLG + file_menu->Append(DIALOGS_FIND, "&Find dialog\tCtrl-F"); + file_menu->Append(DIALOGS_REPLACE, "Find and &replace dialog\tShift-Ctrl-F"); +#endif // wxUSE_FINDREPLDLG file_menu->AppendSeparator(); - file_menu->Append(DIALOGS_MODAL, "Mo&dal dialog\tCtrl-F"); + file_menu->Append(DIALOGS_MODAL, "Mo&dal dialog\tCtrl-D"); file_menu->Append(DIALOGS_MODELESS, "Modeless &dialog\tCtrl-Z", "", TRUE); file_menu->AppendSeparator(); file_menu->Append(wxID_EXIT, "E&xit\tAlt-X"); @@ -614,6 +629,78 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) ) #endif // wxUSE_PROGRESSDLG +#if wxUSE_FINDREPLDLG + +void MyFrame::ShowReplaceDialog( wxCommandEvent& WXUNUSED(event) ) +{ + wxFindReplaceDialog *dialog = new wxFindReplaceDialog + ( + this, + &m_findData, + "Find and replace dialog", + wxFR_REPLACEDIALOG + ); + dialog->Show(); +} + +void MyFrame::ShowFindDialog( wxCommandEvent& WXUNUSED(event) ) +{ + wxFindReplaceDialog *dialog = new wxFindReplaceDialog + ( + this, + &m_findData, + "Find dialog", + // just for testing + wxFR_NOWHOLEWORD + ); + dialog->Show(); +} + +static wxString DecodeFindDialogEventFlags(int flags) +{ + wxString str; + str << (flags & wxFR_DOWN ? "down" : "up") << ", " + << (flags & wxFR_WHOLEWORD ? "whole words only, " : "") + << (flags & wxFR_MATCHCASE ? "" : "not ") + << "case sensitive"; + + return str; +} + +void MyFrame::OnFindDialog(wxFindDialogEvent& event) +{ + wxEventType type = event.GetEventType(); + + if ( type == wxEVT_COMMAND_FIND || type == wxEVT_COMMAND_FIND_NEXT ) + { + wxLogMessage("Find %s'%s' (flags: %s)", + type == wxEVT_COMMAND_FIND_NEXT ? "next " : "", + event.GetFindString().c_str(), + DecodeFindDialogEventFlags(event.GetFlags()).c_str()); + } + else if ( type == wxEVT_COMMAND_FIND_REPLACE || + type == wxEVT_COMMAND_FIND_REPLACE_ALL ) + { + wxLogMessage("Replace %s'%s' with '%s' (flags: %s)", + type == wxEVT_COMMAND_FIND_REPLACE_ALL ? "all " : "", + event.GetFindString().c_str(), + event.GetReplaceString().c_str(), + DecodeFindDialogEventFlags(event.GetFlags()).c_str()); + } + else if ( type == wxEVT_COMMAND_FIND_CLOSE ) + { + wxLogMessage("Find dialog is being closed."); + + event.GetDialog()->Destroy(); + } + else + { + wxLogError("Unknown find dialog event!"); + } +} + +#endif // wxUSE_FINDREPLDLG + // ---------------------------------------------------------------------------- // MyCanvas // ---------------------------------------------------------------------------- diff --git a/samples/dialogs/dialogs.h b/samples/dialogs/dialogs.h index bcf6e2a083..ccf3da8b7d 100644 --- a/samples/dialogs/dialogs.h +++ b/samples/dialogs/dialogs.h @@ -74,7 +74,15 @@ public: void ShowTip(wxCommandEvent& event); void ModalDlg(wxCommandEvent& event); void ModelessDlg(wxCommandEvent& event); +#if wxUSE_PROGRESSDLG void ShowProgress(wxCommandEvent& event); +#endif // wxUSE_PROGRESSDLG +#if wxUSE_FINDREPLDLG + void ShowFindDialog(wxCommandEvent& event); + void ShowReplaceDialog(wxCommandEvent& event); + + void OnFindDialog(wxFindDialogEvent& event); +#endif // wxUSE_FINDREPLDLG #if !defined(__WXMSW__) || wxTEST_GENERIC_DIALOGS_IN_MSW void ChooseColourGeneric(wxCommandEvent& event); @@ -88,6 +96,10 @@ public: private: MyModelessDialog *m_dialog; +#if wxUSE_FINDREPLDLG + wxFindReplaceData m_findData; +#endif // wxUSE_FINDREPLDLG + DECLARE_EVENT_TABLE() }; @@ -126,7 +138,9 @@ enum DIALOGS_MODAL, DIALOGS_MODELESS, DIALOGS_MODELESS_BTN, - DIALOGS_PROGRESS + DIALOGS_PROGRESS, + DIALOGS_FIND, + DIALOGS_REPLACE }; #endif diff --git a/src/msw/app.cpp b/src/msw/app.cpp index f542a094a8..165ef715c0 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -1050,10 +1050,18 @@ bool wxApp::ProcessMessage(WXMSG *wxmsg) HWND hWnd = msg->hwnd; wxWindow *wndThis = wxGetWindowFromHWND((WXHWND)hWnd); + // this may happen if the event occured in a standard modeless dialog (the + // only example of which I know of is the find/replace dialog) - then call + // IsDialogMessage() to make TAB navigation in it work + if ( !wndThis ) + { + return ::IsDialogMessage(hWnd, msg) != 0; + } + #if wxUSE_TOOLTIPS // we must relay WM_MOUSEMOVE events to the tooltip ctrl if we want it to // popup the tooltip bubbles - if ( wndThis && (msg->message == WM_MOUSEMOVE) ) + if ( (msg->message == WM_MOUSEMOVE) ) { wxToolTip *tt = wndThis->GetToolTip(); if ( tt ) diff --git a/src/msw/fdrepdlg.cpp b/src/msw/fdrepdlg.cpp index cb74cb9596..ca6e4e533f 100644 --- a/src/msw/fdrepdlg.cpp +++ b/src/msw/fdrepdlg.cpp @@ -47,7 +47,7 @@ // functions prototypes // ---------------------------------------------------------------------------- -LRESULT APIENTRY FindReplaceWindowProc(HWND hwnd, WXUINT nMsg, +LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg, WPARAM wParam, LPARAM lParam); UINT CALLBACK wxFindReplaceDialogHookProc(HWND hwnd, @@ -63,6 +63,12 @@ IMPLEMENT_DYNAMIC_CLASS(wxFindReplaceDialog, wxDialog) IMPLEMENT_DYNAMIC_CLASS(wxFindDialogEvent, wxCommandEvent) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_FIND) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_FIND_NEXT) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_FIND_REPLACE) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_FIND_REPLACE_ALL) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_FIND_CLOSE) + // ---------------------------------------------------------------------------- // wxFindReplaceDialogImpl: the internals of wxFindReplaceDialog // ---------------------------------------------------------------------------- @@ -128,19 +134,26 @@ wxFindReplaceDialogImpl::wxFindReplaceDialogImpl(wxFindReplaceDialog *dialog, wxZeroMemory(m_findReplace); - // translate the flags + // translate the flags: first the dialog creation flags // always set this to be able to set the title int flags = FR_ENABLEHOOK; - if ( flagsWX & wxFR_NOMATCHCASE) + int flagsDialog = dialog->GetWindowStyle(); + if ( flagsDialog & wxFR_NOMATCHCASE) flags |= FR_NOMATCHCASE; - if ( flagsWX & wxFR_NOWHOLEWORD) + if ( flagsDialog & wxFR_NOWHOLEWORD) flags |= FR_NOWHOLEWORD; - if ( flagsWX & wxFR_NOUPDOWN) + if ( flagsDialog & wxFR_NOUPDOWN) flags |= FR_NOUPDOWN; + + // and now the flags governing the initial values of the dialogs controls if ( flagsWX & wxFR_DOWN) flags |= FR_DOWN; + if ( flagsWX & wxFR_MATCHCASE) + flags |= FR_MATCHCASE; + if ( flagsWX & wxFR_WHOLEWORD ) + flags |= FR_WHOLEWORD; m_findReplace.lStructSize = sizeof(FINDREPLACE); m_findReplace.hwndOwner = GetHwndOf(dialog->GetParent()); @@ -180,15 +193,21 @@ void wxFindReplaceDialogImpl::InitReplaceWith(const wxString& str) void wxFindReplaceDialogImpl::SubclassDialog(HWND hwnd) { m_hwndOwner = hwnd; - m_oldParentWndProc = (WNDPROC)::SetWindowLong - ( - hwnd, - GWL_WNDPROC, - (LONG)FindReplaceWindowProc - ); - - // save it elsewhere to access it from FindReplaceWindowProc() - (void)::SetWindowLong(hwnd, GWL_USERDATA, (LONG)m_oldParentWndProc); + + // check that we don't subclass the parent twice: this would be a bad idea + // as then we'd have infinite recursion in wxFindReplaceWindowProc + WNDPROC oldParentWndProc = (WNDPROC)::GetWindowLong(hwnd, GWL_WNDPROC); + + if ( oldParentWndProc != wxFindReplaceWindowProc ) + { + // save old wnd proc elsewhere to access it from + // wxFindReplaceWindowProc + m_oldParentWndProc = oldParentWndProc; + (void)::SetWindowLong(hwnd, GWL_USERDATA, (LONG)oldParentWndProc); + + // and set the new one + (void)::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)wxFindReplaceWindowProc); + } } wxFindReplaceDialogImpl::~wxFindReplaceDialogImpl() @@ -206,8 +225,8 @@ wxFindReplaceDialogImpl::~wxFindReplaceDialogImpl() // Window Proc for handling RegisterWindowMessage(FINDMSGSTRING) // ---------------------------------------------------------------------------- -LRESULT APIENTRY FindReplaceWindowProc(HWND hwnd, WXUINT nMsg, - WPARAM wParam, LPARAM lParam) +LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg, + WPARAM wParam, LPARAM lParam) { if ( nMsg == wxFindReplaceDialogImpl::GetFindDialogMessage() ) { @@ -228,13 +247,13 @@ LRESULT APIENTRY FindReplaceWindowProc(HWND hwnd, WXUINT nMsg, } else if ( pFR->Flags & FR_REPLACE ) { - evtType = wxEVT_COMMAND_REPLACE; + evtType = wxEVT_COMMAND_FIND_REPLACE; replace = TRUE; } else if ( pFR->Flags & FR_REPLACEALL ) { - evtType = wxEVT_COMMAND_REPLACE_ALL; + evtType = wxEVT_COMMAND_FIND_REPLACE_ALL; replace = TRUE; } @@ -254,6 +273,7 @@ LRESULT APIENTRY FindReplaceWindowProc(HWND hwnd, WXUINT nMsg, flags |= wxFR_MATCHCASE; wxFindDialogEvent event(evtType, dialog->GetId()); + event.SetEventObject(dialog); event.SetFlags(flags); event.SetFindString(pFR->lpstrFindWhat); if ( replace ) @@ -261,13 +281,26 @@ LRESULT APIENTRY FindReplaceWindowProc(HWND hwnd, WXUINT nMsg, event.SetReplaceString(pFR->lpstrReplaceWith); } - (void)dialog->GetEventHandler()->ProcessEvent(event); + // TODO: should we copy the strings to dialog->GetData() as well? + + if ( !dialog->GetEventHandler()->ProcessEvent(event) ) + { + // the event is not propagated upwards to the parent automatically + // because the dialog is a top level window, so do it manually as + // in 9 cases of 10 the message must be processed by the dialog + // owner and not the dialog itself + (void)dialog->GetParent()->GetEventHandler()->ProcessEvent(event); + } } WNDPROC wndProc = (WNDPROC)::GetWindowLong(hwnd, GWL_USERDATA); + // sanity check + wxASSERT_MSG( wndProc != wxFindReplaceWindowProc, + _T("infinite recursion detected") ); + return ::CallWindowProc(wndProc, hwnd, nMsg, wParam, lParam); -}; +} // ---------------------------------------------------------------------------- // Find/replace dialog hook proc @@ -292,6 +325,15 @@ UINT CALLBACK wxFindReplaceDialogHookProc(HWND hwnd, return 0; } +// ---------------------------------------------------------------------------- +// wxFindReplaceData +// ---------------------------------------------------------------------------- + +void wxFindReplaceData::Init() +{ + m_Flags = 0; +} + // ============================================================================ // wxFindReplaceDialog implementation // ============================================================================ @@ -311,23 +353,33 @@ void wxFindReplaceDialog::Init() wxFindReplaceDialog::wxFindReplaceDialog(wxWindow *parent, wxFindReplaceData *data, - const wxString &title) + const wxString &title, + int flags) : m_FindReplaceData(data) { Init(); - (void)Create(parent, data, title); + (void)Create(parent, data, title, flags); } wxFindReplaceDialog::~wxFindReplaceDialog() { + // unsubclass the parent delete m_impl; + + // prevent the base class dtor from trying to hide us! + m_isShown = FALSE; + + // and from destroying our window + m_hWnd = NULL; } bool wxFindReplaceDialog::Create(wxWindow *parent, wxFindReplaceData *data, - const wxString &title) + const wxString &title, + int flags) { + m_windowStyle = flags; m_FindReplaceData = data; m_parent = parent; @@ -363,7 +415,9 @@ bool wxFindReplaceDialog::Show(bool show) if ( m_hWnd ) { // yes, just use it - return ::ShowWindow(GetHwnd(), show ? SW_SHOW : SW_HIDE); + (void)::ShowWindow(GetHwnd(), show ? SW_SHOW : SW_HIDE); + + return TRUE; } if ( !show ) @@ -376,22 +430,25 @@ bool wxFindReplaceDialog::Show(bool show) wxASSERT_MSG( !m_impl, _T("why don't we have the window then?") ); - int flagsWX = m_FindReplaceData->GetFlags(); - - m_impl = new wxFindReplaceDialogImpl(this, flagsWX); + m_impl = new wxFindReplaceDialogImpl(this, m_FindReplaceData->GetFlags()); m_impl->InitFindWhat(m_FindReplaceData->GetFindString()); - if ( flagsWX & wxFR_REPLACEDIALOG) + bool replace = HasFlag(wxFR_REPLACEDIALOG); + if ( replace ) { - m_impl->InitFindWhat(m_FindReplaceData->GetReplaceString()); + m_impl->InitReplaceWith(m_FindReplaceData->GetReplaceString()); } // call the right function to show the dialog which does what we want - HWND (*pfn)(FINDREPLACE *) = flagsWX & wxFR_REPLACEDIALOG ? ::ReplaceText - : ::FindText; - m_hWnd = (WXHWND)(*pfn)(m_impl->GetPtrFindReplace()); - if ( !m_hWnd ) + FINDREPLACE *pFR = m_impl->GetPtrFindReplace(); + HWND hwnd; + if ( replace ) + hwnd = ::ReplaceText(pFR); + else + hwnd = ::FindText(pFR); + + if ( !hwnd ) { wxLogError(_("Failed to create the standard find/replace dialog (error code %d)"), ::CommDlgExtendedError()); @@ -405,11 +462,13 @@ bool wxFindReplaceDialog::Show(bool show) // subclass parent window in order to get FINDMSGSTRING message m_impl->SubclassDialog(GetHwndOf(m_parent)); - if ( !::ShowWindow((HWND)m_hWnd, SW_SHOW) ) + if ( !::ShowWindow(hwnd, SW_SHOW) ) { wxLogLastError(_T("ShowWindow(find dialog)")); } + m_hWnd = (WXHWND)hwnd; + return TRUE; } diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index c67dd43753..b1b4e12a8f 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -64,7 +64,6 @@ // ---------------------------------------------------------------------------- extern wxWindowList wxModelessWindows; -extern wxList WXDLLEXPORT wxPendingDelete; extern const wxChar *wxFrameClassName; #if wxUSE_MENUS_NATIVE diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 989cf2021b..26eabca0eb 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -131,7 +131,6 @@ extern MSG s_currentMsg; wxMenu *wxCurrentPopupMenu = NULL; #endif // wxUSE_MENUS_NATIVE -extern wxList WXDLLEXPORT wxPendingDelete; extern const wxChar *wxCanvasClassName; // --------------------------------------------------------------------------- @@ -4394,19 +4393,27 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd) #endif // wxUSE_SPINCTRL #endif // Win32 - - if ( !win ) - { - // hwnd is not a wxWindow, try its parent next below - hwnd = ::GetParent(hwnd); - } } } while ( hwnd && !win ) { - win = wxFindWinFromHandle((WXHWND)hwnd); + // this is a really ugly hack needed to avoid mistakenly returning the + // parent frame wxWindow for the find/replace modeless dialog HWND - + // this, in turn, is needed to call IsDialogMessage() from + // wxApp::ProcessMessage() as for this we must return NULL from here + // + // FIXME: this is clearly not the best way to do it but I think we'll + // need to change HWND <-> wxWindow code more heavily than I can + // do it now to fix it + if ( ::GetWindow(hwnd, GW_OWNER) ) + { + // it's a dialog box, don't go upwards + break; + } + hwnd = ::GetParent(hwnd); + win = wxFindWinFromHandle((WXHWND)hwnd); } return win; -- 2.45.2