X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8db37e069996bf60cbc152eb8d93b199e7c80842..b310cebd711a5a616502012b64cdc37d8f6ab9d8:/src/msw/fdrepdlg.cpp diff --git a/src/msw/fdrepdlg.cpp b/src/msw/fdrepdlg.cpp index aac3a07202..b6acec5dab 100644 --- a/src/msw/fdrepdlg.cpp +++ b/src/msw/fdrepdlg.cpp @@ -17,7 +17,7 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "mswfdrepdlg.h" #endif @@ -37,7 +37,7 @@ #include "wx/msw/private.h" -#if !defined(__WIN32__) || defined(__SALFORDC__) || defined(__WXWINE__) +#if !defined(__WIN32__) || defined(__WXWINCE__) #include #endif @@ -50,10 +50,10 @@ LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg, WPARAM wParam, LPARAM lParam); -UINT CALLBACK wxFindReplaceDialogHookProc(HWND hwnd, - UINT uiMsg, - WPARAM wParam, - LPARAM lParam); +UINT_PTR CALLBACK wxFindReplaceDialogHookProc(HWND hwnd, + UINT uiMsg, + WPARAM wParam, + LPARAM lParam); // ---------------------------------------------------------------------------- // wxWin macros @@ -81,6 +81,10 @@ public: // only for passing to ::FindText or ::ReplaceText FINDREPLACE *GetPtrFindReplace() { return &m_findReplace; } + // set/query the "closed by user" flag + void SetClosedByUser() { m_wasClosedByUser = TRUE; } + bool WasClosedByUser() const { return m_wasClosedByUser; } + private: void InitString(const wxString& str, LPTSTR *ppStr, WORD *pLen); @@ -93,8 +97,13 @@ private: // the find replace data used by the dialog FINDREPLACE m_findReplace; + // TRUE if the user closed us, FALSE otherwise + bool m_wasClosedByUser; + // registered Message for Dialog static UINT ms_msgFindDialog; + + DECLARE_NO_COPY_CLASS(wxFindReplaceDialogImpl) }; UINT wxFindReplaceDialogImpl::ms_msgFindDialog = 0; @@ -124,6 +133,8 @@ wxFindReplaceDialogImpl::wxFindReplaceDialogImpl(wxFindReplaceDialog *dialog, m_hwndOwner = NULL; m_oldParentWndProc = NULL; + m_wasClosedByUser = FALSE; + wxZeroMemory(m_findReplace); // translate the flags: first the dialog creation flags @@ -188,17 +199,13 @@ void wxFindReplaceDialogImpl::SubclassDialog(HWND hwnd) // 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 ) + if ( !wxCheckWindowWndProc((WXHWND)hwnd, (WXFARPROC)wxFindReplaceWindowProc) ) { - // save old wnd proc elsewhere to access it from - // wxFindReplaceWindowProc - m_oldParentWndProc = oldParentWndProc; - (void)::SetWindowLong(hwnd, GWL_USERDATA, (LONG)oldParentWndProc); + // set the new one and save the old as user data to allow access to it + // from wxFindReplaceWindowProc + m_oldParentWndProc = wxSetWindowProc(hwnd, wxFindReplaceWindowProc); - // and set the new one - (void)::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)wxFindReplaceWindowProc); + wxSetWindowUserData(hwnd, (void *)m_oldParentWndProc); } } @@ -209,7 +216,8 @@ wxFindReplaceDialogImpl::~wxFindReplaceDialogImpl() if ( m_hwndOwner ) { - ::SetWindowLong(m_hwndOwner, GWL_WNDPROC, (LONG)m_oldParentWndProc); + // undo subclassing + wxSetWindowProc(m_hwndOwner, m_oldParentWndProc); } } @@ -220,9 +228,33 @@ wxFindReplaceDialogImpl::~wxFindReplaceDialogImpl() LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg, WPARAM wParam, LPARAM lParam) { +#if wxUSE_UNICODE_MSLU + static unsigned long s_lastMsgFlags = 0; + + // This flag helps us to identify the bogus ANSI message + // sent by UNICOWS.DLL (see below) + // while we're sending our message to the dialog + // we ignore possible messages sent in between + static bool s_blockMsg = false; +#endif // wxUSE_UNICODE_MSLU + if ( nMsg == wxFindReplaceDialogImpl::GetFindDialogMessage() ) { FINDREPLACE *pFR = (FINDREPLACE *)lParam; + +#if wxUSE_UNICODE_MSLU + // This is a hack for a MSLU problem: Versions up to 1.0.4011 + // of UNICOWS.DLL send the correct UNICODE item after button press + // and a bogus ANSI mode item right after this, so lets ignore + // the second bogus message + if ( s_lastMsgFlags == pFR->Flags ) + { + s_lastMsgFlags = 0; + return 0; + } + s_lastMsgFlags = pFR->Flags; +#endif // wxUSE_UNICODE_MSLU + wxFindReplaceDialog *dialog = (wxFindReplaceDialog *)pFR->lCustData; // map flags from Windows @@ -231,6 +263,11 @@ LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg, bool replace = FALSE; if ( pFR->Flags & FR_DIALOGTERM ) { + // we have to notify the dialog that it's being closed by user and + // not deleted programmatically as it behaves differently in these + // 2 cases + dialog->GetImpl()->SetClosedByUser(); + evtType = wxEVT_COMMAND_FIND_CLOSE; } else if ( pFR->Flags & FR_FINDNEXT ) @@ -273,10 +310,22 @@ LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg, event.SetReplaceString(pFR->lpstrReplaceWith); } +#if wxUSE_UNICODE_MSLU + s_blockMsg = true; +#endif // wxUSE_UNICODE_MSLU + dialog->Send(event); + +#if wxUSE_UNICODE_MSLU + s_blockMsg = false; +#endif // wxUSE_UNICODE_MSLU } +#if wxUSE_UNICODE_MSLU + else if ( !s_blockMsg ) + s_lastMsgFlags = 0; +#endif // wxUSE_UNICODE_MSLU - WNDPROC wndProc = (WNDPROC)::GetWindowLong(hwnd, GWL_USERDATA); + WNDPROC wndProc = (WNDPROC)wxGetWindowUserData(hwnd); // sanity check wxASSERT_MSG( wndProc != wxFindReplaceWindowProc, @@ -289,10 +338,11 @@ LRESULT APIENTRY wxFindReplaceWindowProc(HWND hwnd, WXUINT nMsg, // Find/replace dialog hook proc // ---------------------------------------------------------------------------- -UINT CALLBACK wxFindReplaceDialogHookProc(HWND hwnd, - UINT uiMsg, - WPARAM WXUNUSED(wParam), - LPARAM lParam) +UINT_PTR CALLBACK +wxFindReplaceDialogHookProc(HWND hwnd, + UINT uiMsg, + WPARAM WXUNUSED(wParam), + LPARAM lParam) { if ( uiMsg == WM_INITDIALOG ) { @@ -329,7 +379,7 @@ wxFindReplaceDialog::wxFindReplaceDialog(wxWindow *parent, wxFindReplaceData *data, const wxString &title, int flags) - : m_FindReplaceData(data) + : wxFindReplaceDialogBase(parent, data, title, flags) { Init(); @@ -338,14 +388,26 @@ wxFindReplaceDialog::wxFindReplaceDialog(wxWindow *parent, wxFindReplaceDialog::~wxFindReplaceDialog() { + // the dialog might have been already deleted if the user closed it + // manually but in this case we should have got a notification about it and + // the flagmust have been set + if ( !m_impl->WasClosedByUser() ) + { + // if it wasn't, delete the dialog ourselves + if ( !::DestroyWindow(GetHwnd()) ) + { + wxLogLastError(_T("DestroyWindow(find dialog)")); + } + } + // 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; + // and from destroying our window [again] + m_hWnd = (WXHWND)NULL; } bool wxFindReplaceDialog::Create(wxWindow *parent, @@ -363,16 +425,6 @@ bool wxFindReplaceDialog::Create(wxWindow *parent, return parent != NULL; } -// ---------------------------------------------------------------------------- -// wxFindReplaceDialog data access -// ---------------------------------------------------------------------------- - -void wxFindReplaceDialog::SetData(wxFindReplaceData *data) -{ - delete m_FindReplaceData; - m_FindReplaceData = data; -} - // ---------------------------------------------------------------------------- // wxFindReplaceData show/hide // ----------------------------------------------------------------------------