/////////////////////////////////////////////////////////////////////////////
// Name: src/msw/fdrepdlg.cpp
// Purpose: wxFindReplaceDialog class
-// Author: Markus Greither
-// Modified by: 31.07.01: VZ: integrated into wxWindows
+// Author: Markus Greither and Vadim Zeitlin
+// Modified by:
// Created: 23/03/2001
// RCS-ID:
// Copyright: (c) Markus Greither
// headers
// ----------------------------------------------------------------------------
-#ifdef __GNUG__
- #pragma implementation "fdrepdlg.h"
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+ #pragma implementation "mswfdrepdlg.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/msw/private.h"
-#if !defined(__WIN32__) || defined(__SALFORDC__) || defined(__WXWINE__)
+#if !defined(__WIN32__) || defined(__WXWINCE__)
#include <commdlg.h>
#endif
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
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
// ----------------------------------------------------------------------------
// 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);
// 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;
m_hwndOwner = NULL;
m_oldParentWndProc = NULL;
+ m_wasClosedByUser = FALSE;
+
wxZeroMemory(m_findReplace);
// translate the flags: first the dialog creation flags
// 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);
}
}
if ( m_hwndOwner )
{
- ::SetWindowLong(m_hwndOwner, GWL_WNDPROC, (LONG)m_oldParentWndProc);
+ // undo subclassing
+ wxSetWindowProc(m_hwndOwner, m_oldParentWndProc);
}
}
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
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 )
event.SetReplaceString(pFR->lpstrReplaceWith);
}
- // TODO: should we copy the strings to dialog->GetData() as well?
+#if wxUSE_UNICODE_MSLU
+ s_blockMsg = true;
+#endif // wxUSE_UNICODE_MSLU
- 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);
- }
+ 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,
// 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 )
{
return 0;
}
-// ----------------------------------------------------------------------------
-// wxFindReplaceData
-// ----------------------------------------------------------------------------
-
-void wxFindReplaceData::Init()
-{
- m_Flags = 0;
-}
-
// ============================================================================
// wxFindReplaceDialog implementation
// ============================================================================
wxFindReplaceData *data,
const wxString &title,
int flags)
- : m_FindReplaceData(data)
+ : wxFindReplaceDialogBase(parent, data, title, flags)
{
Init();
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,
return parent != NULL;
}
-// ----------------------------------------------------------------------------
-// wxFindReplaceDialog data access
-// ----------------------------------------------------------------------------
-
-void wxFindReplaceDialog::SetData(wxFindReplaceData *data)
-{
- delete m_FindReplaceData;
- m_FindReplaceData = data;
-}
-
// ----------------------------------------------------------------------------
// wxFindReplaceData show/hide
// ----------------------------------------------------------------------------