1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/fdrepdlg.cpp
3 // Purpose: wxFindReplaceDialog class
4 // Author: Markus Greither
5 // Modified by: 31.07.01: VZ: integrated into wxWindows
8 // Copyright: (c) Markus Greither
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "fdrepdlg.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
38 #include "wx/msw/private.h"
40 #if !defined(__WIN32__) || defined(__SALFORDC__) || defined(__WXWINE__)
44 #include "wx/fdrepdlg.h"
46 // ----------------------------------------------------------------------------
47 // functions prototypes
48 // ----------------------------------------------------------------------------
50 LRESULT APIENTRY
FindReplaceWindowProc(HWND hwnd
, WXUINT nMsg
,
51 WPARAM wParam
, LPARAM lParam
);
53 UINT CALLBACK
wxFindReplaceDialogHookProc(HWND hwnd
,
58 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
62 IMPLEMENT_DYNAMIC_CLASS(wxFindReplaceDialog
, wxDialog
)
64 IMPLEMENT_DYNAMIC_CLASS(wxFindDialogEvent
, wxCommandEvent
)
66 // ----------------------------------------------------------------------------
67 // wxFindReplaceDialogImpl: the internals of wxFindReplaceDialog
68 // ----------------------------------------------------------------------------
70 class WXDLLEXPORT wxFindReplaceDialogImpl
73 wxFindReplaceDialogImpl(wxFindReplaceDialog
*dialog
, int flagsWX
);
74 ~wxFindReplaceDialogImpl();
76 void InitFindWhat(const wxString
& str
);
77 void InitReplaceWith(const wxString
& str
);
79 void SubclassDialog(HWND hwnd
);
81 static UINT
GetFindDialogMessage() { return ms_msgFindDialog
; }
83 // only for passing to ::FindText or ::ReplaceText
84 FINDREPLACE
*GetPtrFindReplace() { return &m_findReplace
; }
87 void InitString(const wxString
& str
, LPTSTR
*ppStr
, WORD
*pLen
);
89 // the owner of the dialog
92 // the previous window proc of our owner
93 WNDPROC m_oldParentWndProc
;
95 // the find replace data used by the dialog
96 FINDREPLACE m_findReplace
;
98 // registered Message for Dialog
99 static UINT ms_msgFindDialog
;
102 UINT
wxFindReplaceDialogImpl::ms_msgFindDialog
= 0;
104 // ============================================================================
106 // ============================================================================
108 // ----------------------------------------------------------------------------
109 // wxFindReplaceDialogImpl
110 // ----------------------------------------------------------------------------
112 wxFindReplaceDialogImpl::wxFindReplaceDialogImpl(wxFindReplaceDialog
*dialog
,
115 // get the identifier for the find dialog message if we don't have it yet
116 if ( !ms_msgFindDialog
)
118 ms_msgFindDialog
= ::RegisterWindowMessage(FINDMSGSTRING
);
120 if ( !ms_msgFindDialog
)
122 wxLogLastError(_T("RegisterWindowMessage(FINDMSGSTRING)"));
127 m_oldParentWndProc
= NULL
;
129 wxZeroMemory(m_findReplace
);
131 // translate the flags
133 // always set this to be able to set the title
134 int flags
= FR_ENABLEHOOK
;
136 if ( flagsWX
& wxFR_NOMATCHCASE
)
137 flags
|= FR_NOMATCHCASE
;
138 if ( flagsWX
& wxFR_NOWHOLEWORD
)
139 flags
|= FR_NOWHOLEWORD
;
140 if ( flagsWX
& wxFR_NOUPDOWN
)
141 flags
|= FR_NOUPDOWN
;
142 if ( flagsWX
& wxFR_DOWN
)
145 m_findReplace
.lStructSize
= sizeof(FINDREPLACE
);
146 m_findReplace
.hwndOwner
= GetHwndOf(dialog
->GetParent());
147 m_findReplace
.Flags
= flags
;
149 m_findReplace
.lCustData
= (LPARAM
)dialog
;
150 m_findReplace
.lpfnHook
= wxFindReplaceDialogHookProc
;
153 void wxFindReplaceDialogImpl::InitString(const wxString
& str
,
154 LPTSTR
*ppStr
, WORD
*pLen
)
156 size_t len
= str
.length() + 1;
159 // MSDN docs say that the buffer must be at least 80 chars
163 *ppStr
= new wxChar
[len
];
164 wxStrcpy(*ppStr
, str
);
168 void wxFindReplaceDialogImpl::InitFindWhat(const wxString
& str
)
170 InitString(str
, &m_findReplace
.lpstrFindWhat
, &m_findReplace
.wFindWhatLen
);
173 void wxFindReplaceDialogImpl::InitReplaceWith(const wxString
& str
)
176 &m_findReplace
.lpstrReplaceWith
,
177 &m_findReplace
.wReplaceWithLen
);
180 void wxFindReplaceDialogImpl::SubclassDialog(HWND hwnd
)
183 m_oldParentWndProc
= (WNDPROC
)::SetWindowLong
187 (LONG
)FindReplaceWindowProc
190 // save it elsewhere to access it from FindReplaceWindowProc()
191 (void)::SetWindowLong(hwnd
, GWL_USERDATA
, (LONG
)m_oldParentWndProc
);
194 wxFindReplaceDialogImpl::~wxFindReplaceDialogImpl()
196 delete [] m_findReplace
.lpstrFindWhat
;
197 delete [] m_findReplace
.lpstrReplaceWith
;
201 ::SetWindowLong(m_hwndOwner
, GWL_WNDPROC
, (LONG
)m_oldParentWndProc
);
205 // ----------------------------------------------------------------------------
206 // Window Proc for handling RegisterWindowMessage(FINDMSGSTRING)
207 // ----------------------------------------------------------------------------
209 LRESULT APIENTRY
FindReplaceWindowProc(HWND hwnd
, WXUINT nMsg
,
210 WPARAM wParam
, LPARAM lParam
)
212 if ( nMsg
== wxFindReplaceDialogImpl::GetFindDialogMessage() )
214 FINDREPLACE
*pFR
= (FINDREPLACE
*)lParam
;
215 wxFindReplaceDialog
*dialog
= (wxFindReplaceDialog
*)pFR
->lCustData
;
217 // map flags from Windows
220 bool replace
= FALSE
;
221 if ( pFR
->Flags
& FR_DIALOGTERM
)
223 evtType
= wxEVT_COMMAND_FIND_CLOSE
;
225 else if ( pFR
->Flags
& FR_FINDNEXT
)
227 evtType
= wxEVT_COMMAND_FIND_NEXT
;
229 else if ( pFR
->Flags
& FR_REPLACE
)
231 evtType
= wxEVT_COMMAND_REPLACE
;
235 else if ( pFR
->Flags
& FR_REPLACEALL
)
237 evtType
= wxEVT_COMMAND_REPLACE_ALL
;
243 wxFAIL_MSG( _T("unknown find dialog event") );
249 if ( pFR
->Flags
& FR_DOWN
)
251 if ( pFR
->Flags
& FR_WHOLEWORD
)
252 flags
|= wxFR_WHOLEWORD
;
253 if ( pFR
->Flags
& FR_MATCHCASE
)
254 flags
|= wxFR_MATCHCASE
;
256 wxFindDialogEvent
event(evtType
, dialog
->GetId());
257 event
.SetFlags(flags
);
258 event
.SetFindString(pFR
->lpstrFindWhat
);
261 event
.SetReplaceString(pFR
->lpstrReplaceWith
);
264 (void)dialog
->GetEventHandler()->ProcessEvent(event
);
267 WNDPROC wndProc
= (WNDPROC
)::GetWindowLong(hwnd
, GWL_USERDATA
);
269 return ::CallWindowProc(wndProc
, hwnd
, nMsg
, wParam
, lParam
);
272 // ----------------------------------------------------------------------------
273 // Find/replace dialog hook proc
274 // ----------------------------------------------------------------------------
276 UINT CALLBACK
wxFindReplaceDialogHookProc(HWND hwnd
,
278 WPARAM
WXUNUSED(wParam
),
281 if ( uiMsg
== WM_INITDIALOG
)
283 FINDREPLACE
*pFR
= (FINDREPLACE
*)lParam
;
284 wxFindReplaceDialog
*dialog
= (wxFindReplaceDialog
*)pFR
->lCustData
;
286 ::SetWindowText(hwnd
, dialog
->GetTitle());
288 // don't return FALSE from here or the dialog won't be shown
295 // ============================================================================
296 // wxFindReplaceDialog implementation
297 // ============================================================================
299 // ----------------------------------------------------------------------------
300 // wxFindReplaceDialog ctors/dtor
301 // ----------------------------------------------------------------------------
303 void wxFindReplaceDialog::Init()
306 m_FindReplaceData
= NULL
;
308 // as we're created in the hidden state, bring the internal flag in sync
312 wxFindReplaceDialog::wxFindReplaceDialog(wxWindow
*parent
,
313 wxFindReplaceData
*data
,
314 const wxString
&title
)
315 : m_FindReplaceData(data
)
319 (void)Create(parent
, data
, title
);
322 wxFindReplaceDialog::~wxFindReplaceDialog()
327 bool wxFindReplaceDialog::Create(wxWindow
*parent
,
328 wxFindReplaceData
*data
,
329 const wxString
&title
)
331 m_FindReplaceData
= data
;
336 // we must have a parent as it will get the messages from us
337 return parent
!= NULL
;
340 // ----------------------------------------------------------------------------
341 // wxFindReplaceDialog data access
342 // ----------------------------------------------------------------------------
344 void wxFindReplaceDialog::SetData(wxFindReplaceData
*data
)
346 delete m_FindReplaceData
;
347 m_FindReplaceData
= data
;
350 // ----------------------------------------------------------------------------
351 // wxFindReplaceData show/hide
352 // ----------------------------------------------------------------------------
354 bool wxFindReplaceDialog::Show(bool show
)
356 if ( !wxWindowBase::Show(show
) )
358 // visibility status didn't change
362 // do we already have the dialog window?
366 return ::ShowWindow(GetHwnd(), show
? SW_SHOW
: SW_HIDE
);
371 // well, it doesn't exist which is as good as being hidden
375 wxCHECK_MSG( m_FindReplaceData
, FALSE
, _T("call Create() first!") );
377 wxASSERT_MSG( !m_impl
, _T("why don't we have the window then?") );
379 int flagsWX
= m_FindReplaceData
->GetFlags();
381 m_impl
= new wxFindReplaceDialogImpl(this, flagsWX
);
383 m_impl
->InitFindWhat(m_FindReplaceData
->GetFindString());
385 if ( flagsWX
& wxFR_REPLACEDIALOG
)
387 m_impl
->InitFindWhat(m_FindReplaceData
->GetReplaceString());
390 // call the right function to show the dialog which does what we want
391 HWND (*pfn
)(FINDREPLACE
*) = flagsWX
& wxFR_REPLACEDIALOG
? ::ReplaceText
393 m_hWnd
= (WXHWND
)(*pfn
)(m_impl
->GetPtrFindReplace());
396 wxLogError(_("Failed to create the standard find/replace dialog (error code %d)"),
397 ::CommDlgExtendedError());
405 // subclass parent window in order to get FINDMSGSTRING message
406 m_impl
->SubclassDialog(GetHwndOf(m_parent
));
408 if ( !::ShowWindow((HWND
)m_hWnd
, SW_SHOW
) )
410 wxLogLastError(_T("ShowWindow(find dialog)"));
416 // ----------------------------------------------------------------------------
417 // wxFindReplaceDialog title handling
418 // ----------------------------------------------------------------------------
420 // we set the title of this dialog in our jook proc but for now don't crash in
421 // the base class version because of m_hWnd == 0
423 void wxFindReplaceDialog::SetTitle( const wxString
& title
)
428 wxString
wxFindReplaceDialog::GetTitle() const
433 // ----------------------------------------------------------------------------
434 // wxFindReplaceDialog position/size
435 // ----------------------------------------------------------------------------
437 void wxFindReplaceDialog::DoSetSize(int WXUNUSED(x
), int WXUNUSED(y
),
438 int WXUNUSED(width
), int WXUNUSED(height
),
439 int WXUNUSED(sizeFlags
))
441 // ignore - we can't change the size of this standard dialog
445 // NB: of course, both of these functions are completely bogus, but it's better
447 void wxFindReplaceDialog::DoGetSize(int *width
, int *height
) const
449 // the standard dialog size
456 void wxFindReplaceDialog::DoGetClientSize(int *width
, int *height
) const
458 // the standard dialog size
465 #endif // wxUSE_FINDREPLDLG