]> git.saurik.com Git - wxWidgets.git/blame - src/msw/fdrepdlg.cpp
Handle WebKitWebView create-web-view.
[wxWidgets.git] / src / msw / fdrepdlg.cpp
CommitLineData
c41b00c9
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/msw/fdrepdlg.cpp
3// Purpose: wxFindReplaceDialog class
8db37e06
VZ
4// Author: Markus Greither and Vadim Zeitlin
5// Modified by:
c41b00c9 6// Created: 23/03/2001
c41b00c9 7// Copyright: (c) Markus Greither
65571936 8// Licence: wxWindows licence
c41b00c9
VZ
9/////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
c41b00c9
VZ
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#if wxUSE_FINDREPLDLG
27
28#ifndef WX_PRECOMP
57bd4c60 29 #include "wx/msw/wrapcdlg.h"
c41b00c9
VZ
30 #include "wx/intl.h"
31 #include "wx/log.h"
32#endif
33
c41b00c9
VZ
34#include "wx/fdrepdlg.h"
35
ccddcbac
RD
36#include "wx/msw/mslu.h"
37
c41b00c9
VZ
38// ----------------------------------------------------------------------------
39// functions prototypes
40// ----------------------------------------------------------------------------
41
975b6bcf
VZ
42UINT_PTR CALLBACK wxFindReplaceDialogHookProc(HWND hwnd,
43 UINT uiMsg,
44 WPARAM wParam,
45 LPARAM lParam);
c41b00c9
VZ
46
47// ----------------------------------------------------------------------------
48// wxWin macros
49// ----------------------------------------------------------------------------
50
51IMPLEMENT_DYNAMIC_CLASS(wxFindReplaceDialog, wxDialog)
52
c41b00c9
VZ
53// ----------------------------------------------------------------------------
54// wxFindReplaceDialogImpl: the internals of wxFindReplaceDialog
55// ----------------------------------------------------------------------------
56
57class WXDLLEXPORT wxFindReplaceDialogImpl
58{
59public:
60 wxFindReplaceDialogImpl(wxFindReplaceDialog *dialog, int flagsWX);
61 ~wxFindReplaceDialogImpl();
62
63 void InitFindWhat(const wxString& str);
64 void InitReplaceWith(const wxString& str);
65
c41b00c9
VZ
66 // only for passing to ::FindText or ::ReplaceText
67 FINDREPLACE *GetPtrFindReplace() { return &m_findReplace; }
68
14fca738 69 // set/query the "closed by user" flag
cbe874bd 70 void SetClosedByUser() { m_wasClosedByUser = true; }
14fca738
VZ
71 bool WasClosedByUser() const { return m_wasClosedByUser; }
72
c41b00c9 73private:
5acec112
VZ
74 // called from window procedure for ms_msgFindDialog
75 static bool FindMessageHandler(wxWindow *win,
76 WXUINT nMsg,
77 WPARAM wParam,
78 LPARAM lParam);
c41b00c9 79
5acec112
VZ
80 // copy string str contents to ppStr and fill pLen with its length
81 void InitString(const wxString& str, LPTSTR *ppStr, WORD *pLen);
c41b00c9 82
c41b00c9
VZ
83
84 // the find replace data used by the dialog
85 FINDREPLACE m_findReplace;
86
cbe874bd 87 // true if the user closed us, false otherwise
14fca738
VZ
88 bool m_wasClosedByUser;
89
c41b00c9
VZ
90 // registered Message for Dialog
91 static UINT ms_msgFindDialog;
22f3361e 92
c0c133e1 93 wxDECLARE_NO_COPY_CLASS(wxFindReplaceDialogImpl);
c41b00c9
VZ
94};
95
96UINT wxFindReplaceDialogImpl::ms_msgFindDialog = 0;
97
98// ============================================================================
99// implementation
100// ============================================================================
101
102// ----------------------------------------------------------------------------
103// wxFindReplaceDialogImpl
104// ----------------------------------------------------------------------------
105
106wxFindReplaceDialogImpl::wxFindReplaceDialogImpl(wxFindReplaceDialog *dialog,
107 int flagsWX)
108{
109 // get the identifier for the find dialog message if we don't have it yet
110 if ( !ms_msgFindDialog )
111 {
112 ms_msgFindDialog = ::RegisterWindowMessage(FINDMSGSTRING);
113
114 if ( !ms_msgFindDialog )
115 {
9a83f860 116 wxLogLastError(wxT("RegisterWindowMessage(FINDMSGSTRING)"));
c41b00c9 117 }
c41b00c9 118
5acec112
VZ
119 wxWindow::MSWRegisterMessageHandler
120 (
121 ms_msgFindDialog,
122 &wxFindReplaceDialogImpl::FindMessageHandler
123 );
124 }
c41b00c9 125
cbe874bd 126 m_wasClosedByUser = false;
14fca738 127
c41b00c9
VZ
128 wxZeroMemory(m_findReplace);
129
761989ff 130 // translate the flags: first the dialog creation flags
c41b00c9
VZ
131
132 // always set this to be able to set the title
133 int flags = FR_ENABLEHOOK;
134
761989ff
VZ
135 int flagsDialog = dialog->GetWindowStyle();
136 if ( flagsDialog & wxFR_NOMATCHCASE)
c41b00c9 137 flags |= FR_NOMATCHCASE;
761989ff 138 if ( flagsDialog & wxFR_NOWHOLEWORD)
c41b00c9 139 flags |= FR_NOWHOLEWORD;
761989ff 140 if ( flagsDialog & wxFR_NOUPDOWN)
c41b00c9 141 flags |= FR_NOUPDOWN;
761989ff
VZ
142
143 // and now the flags governing the initial values of the dialogs controls
c41b00c9
VZ
144 if ( flagsWX & wxFR_DOWN)
145 flags |= FR_DOWN;
761989ff
VZ
146 if ( flagsWX & wxFR_MATCHCASE)
147 flags |= FR_MATCHCASE;
148 if ( flagsWX & wxFR_WHOLEWORD )
149 flags |= FR_WHOLEWORD;
c41b00c9
VZ
150
151 m_findReplace.lStructSize = sizeof(FINDREPLACE);
152 m_findReplace.hwndOwner = GetHwndOf(dialog->GetParent());
153 m_findReplace.Flags = flags;
154
155 m_findReplace.lCustData = (LPARAM)dialog;
156 m_findReplace.lpfnHook = wxFindReplaceDialogHookProc;
157}
158
159void wxFindReplaceDialogImpl::InitString(const wxString& str,
160 LPTSTR *ppStr, WORD *pLen)
161{
162 size_t len = str.length() + 1;
163 if ( len < 80 )
164 {
165 // MSDN docs say that the buffer must be at least 80 chars
166 len = 80;
167 }
168
169 *ppStr = new wxChar[len];
170 wxStrcpy(*ppStr, str);
5c519b6c 171 *pLen = (WORD)len;
c41b00c9
VZ
172}
173
174void wxFindReplaceDialogImpl::InitFindWhat(const wxString& str)
175{
176 InitString(str, &m_findReplace.lpstrFindWhat, &m_findReplace.wFindWhatLen);
177}
178
179void wxFindReplaceDialogImpl::InitReplaceWith(const wxString& str)
180{
181 InitString(str,
182 &m_findReplace.lpstrReplaceWith,
183 &m_findReplace.wReplaceWithLen);
184}
185
c41b00c9
VZ
186wxFindReplaceDialogImpl::~wxFindReplaceDialogImpl()
187{
188 delete [] m_findReplace.lpstrFindWhat;
189 delete [] m_findReplace.lpstrReplaceWith;
c41b00c9
VZ
190}
191
192// ----------------------------------------------------------------------------
5acec112 193// handler for FINDMSGSTRING message
c41b00c9
VZ
194// ----------------------------------------------------------------------------
195
5acec112
VZ
196bool
197wxFindReplaceDialogImpl::FindMessageHandler(wxWindow * WXUNUSED(win),
198 WXUINT WXUNUSED_UNLESS_DEBUG(nMsg),
199 WPARAM WXUNUSED(wParam),
200 LPARAM lParam)
c41b00c9 201{
ea392212
VZ
202#if wxUSE_UNICODE_MSLU
203 static unsigned long s_lastMsgFlags = 0;
204
205 // This flag helps us to identify the bogus ANSI message
206 // sent by UNICOWS.DLL (see below)
207 // while we're sending our message to the dialog
208 // we ignore possible messages sent in between
209 static bool s_blockMsg = false;
210#endif // wxUSE_UNICODE_MSLU
211
9a83f860 212 wxASSERT_MSG( nMsg == ms_msgFindDialog, wxT("unexpected message received") );
5acec112
VZ
213
214 FINDREPLACE *pFR = (FINDREPLACE *)lParam;
ea392212
VZ
215
216#if wxUSE_UNICODE_MSLU
5acec112
VZ
217 // This is a hack for a MSLU problem: Versions up to 1.0.4011
218 // of UNICOWS.DLL send the correct UNICODE item after button press
4c51a665 219 // and a bogus ANSI mode item right after this, so let's ignore
5acec112
VZ
220 // the second bogus message
221 if ( wxUsingUnicowsDll() && s_lastMsgFlags == pFR->Flags )
222 {
223 s_lastMsgFlags = 0;
224 return 0;
225 }
226 s_lastMsgFlags = pFR->Flags;
ea392212
VZ
227#endif // wxUSE_UNICODE_MSLU
228
5acec112 229 wxFindReplaceDialog *dialog = (wxFindReplaceDialog *)pFR->lCustData;
c41b00c9 230
5acec112
VZ
231 // map flags from Windows
232 wxEventType evtType;
c41b00c9 233
5acec112
VZ
234 bool replace = false;
235 if ( pFR->Flags & FR_DIALOGTERM )
236 {
237 // we have to notify the dialog that it's being closed by user and
238 // not deleted programmatically as it behaves differently in these
239 // 2 cases
240 dialog->GetImpl()->SetClosedByUser();
14fca738 241
ce7fe42e 242 evtType = wxEVT_FIND_CLOSE;
5acec112
VZ
243 }
244 else if ( pFR->Flags & FR_FINDNEXT )
245 {
ce7fe42e 246 evtType = wxEVT_FIND_NEXT;
5acec112
VZ
247 }
248 else if ( pFR->Flags & FR_REPLACE )
249 {
ce7fe42e 250 evtType = wxEVT_FIND_REPLACE;
c41b00c9 251
5acec112
VZ
252 replace = true;
253 }
254 else if ( pFR->Flags & FR_REPLACEALL )
255 {
ce7fe42e 256 evtType = wxEVT_FIND_REPLACE_ALL;
c41b00c9 257
5acec112
VZ
258 replace = true;
259 }
260 else
261 {
9a83f860 262 wxFAIL_MSG( wxT("unknown find dialog event") );
c41b00c9 263
5acec112
VZ
264 return 0;
265 }
c41b00c9 266
5acec112
VZ
267 wxUint32 flags = 0;
268 if ( pFR->Flags & FR_DOWN )
269 flags |= wxFR_DOWN;
270 if ( pFR->Flags & FR_WHOLEWORD )
271 flags |= wxFR_WHOLEWORD;
272 if ( pFR->Flags & FR_MATCHCASE )
273 flags |= wxFR_MATCHCASE;
274
275 wxFindDialogEvent event(evtType, dialog->GetId());
276 event.SetEventObject(dialog);
277 event.SetFlags(flags);
278 event.SetFindString(pFR->lpstrFindWhat);
279 if ( replace )
280 {
281 event.SetReplaceString(pFR->lpstrReplaceWith);
282 }
c41b00c9 283
ea392212 284#if wxUSE_UNICODE_MSLU
5acec112 285 s_blockMsg = true;
ea392212
VZ
286#endif // wxUSE_UNICODE_MSLU
287
5acec112 288 dialog->Send(event);
ea392212
VZ
289
290#if wxUSE_UNICODE_MSLU
5acec112 291 s_blockMsg = false;
ea392212 292#endif // wxUSE_UNICODE_MSLU
c41b00c9 293
5acec112 294 return true;
761989ff 295}
c41b00c9
VZ
296
297// ----------------------------------------------------------------------------
298// Find/replace dialog hook proc
299// ----------------------------------------------------------------------------
300
975b6bcf
VZ
301UINT_PTR CALLBACK
302wxFindReplaceDialogHookProc(HWND hwnd,
303 UINT uiMsg,
304 WPARAM WXUNUSED(wParam),
305 LPARAM lParam)
c41b00c9
VZ
306{
307 if ( uiMsg == WM_INITDIALOG )
308 {
309 FINDREPLACE *pFR = (FINDREPLACE *)lParam;
310 wxFindReplaceDialog *dialog = (wxFindReplaceDialog *)pFR->lCustData;
311
017dc06b 312 ::SetWindowText(hwnd, dialog->GetTitle().t_str());
c41b00c9
VZ
313
314 // don't return FALSE from here or the dialog won't be shown
315 return TRUE;
316 }
317
318 return 0;
319}
320
321// ============================================================================
322// wxFindReplaceDialog implementation
323// ============================================================================
324
325// ----------------------------------------------------------------------------
326// wxFindReplaceDialog ctors/dtor
327// ----------------------------------------------------------------------------
328
329void wxFindReplaceDialog::Init()
330{
331 m_impl = NULL;
332 m_FindReplaceData = NULL;
333
334 // as we're created in the hidden state, bring the internal flag in sync
cbe874bd 335 m_isShown = false;
c41b00c9
VZ
336}
337
338wxFindReplaceDialog::wxFindReplaceDialog(wxWindow *parent,
339 wxFindReplaceData *data,
761989ff
VZ
340 const wxString &title,
341 int flags)
208c5141 342 : wxFindReplaceDialogBase(parent, data, title, flags)
c41b00c9
VZ
343{
344 Init();
345
761989ff 346 (void)Create(parent, data, title, flags);
c41b00c9
VZ
347}
348
349wxFindReplaceDialog::~wxFindReplaceDialog()
350{
86d87075 351 if ( m_impl )
14fca738 352 {
86d87075
VZ
353 // the dialog might have been already deleted if the user closed it
354 // manually but in this case we should have got a notification about it
355 // and the flag must have been set
356 if ( !m_impl->WasClosedByUser() )
14fca738 357 {
86d87075
VZ
358 // if it wasn't, delete the dialog ourselves
359 if ( !::DestroyWindow(GetHwnd()) )
360 {
9a83f860 361 wxLogLastError(wxT("DestroyWindow(find dialog)"));
86d87075 362 }
14fca738 363 }
14fca738 364
86d87075
VZ
365 // unsubclass the parent
366 delete m_impl;
367 }
761989ff
VZ
368
369 // prevent the base class dtor from trying to hide us!
cbe874bd 370 m_isShown = false;
761989ff 371
14fca738 372 // and from destroying our window [again]
44d5b352 373 m_hWnd = (WXHWND)NULL;
c41b00c9
VZ
374}
375
376bool wxFindReplaceDialog::Create(wxWindow *parent,
377 wxFindReplaceData *data,
761989ff
VZ
378 const wxString &title,
379 int flags)
c41b00c9 380{
761989ff 381 m_windowStyle = flags;
c41b00c9
VZ
382 m_FindReplaceData = data;
383 m_parent = parent;
384
385 SetTitle(title);
386
387 // we must have a parent as it will get the messages from us
388 return parent != NULL;
389}
390
c41b00c9
VZ
391// ----------------------------------------------------------------------------
392// wxFindReplaceData show/hide
393// ----------------------------------------------------------------------------
394
395bool wxFindReplaceDialog::Show(bool show)
396{
397 if ( !wxWindowBase::Show(show) )
398 {
399 // visibility status didn't change
cbe874bd 400 return false;
c41b00c9
VZ
401 }
402
403 // do we already have the dialog window?
404 if ( m_hWnd )
405 {
406 // yes, just use it
761989ff
VZ
407 (void)::ShowWindow(GetHwnd(), show ? SW_SHOW : SW_HIDE);
408
cbe874bd 409 return true;
c41b00c9
VZ
410 }
411
412 if ( !show )
413 {
414 // well, it doesn't exist which is as good as being hidden
cbe874bd 415 return true;
c41b00c9
VZ
416 }
417
9a83f860 418 wxCHECK_MSG( m_FindReplaceData, false, wxT("call Create() first!") );
c41b00c9 419
9a83f860 420 wxASSERT_MSG( !m_impl, wxT("why don't we have the window then?") );
c41b00c9 421
761989ff 422 m_impl = new wxFindReplaceDialogImpl(this, m_FindReplaceData->GetFlags());
c41b00c9
VZ
423
424 m_impl->InitFindWhat(m_FindReplaceData->GetFindString());
425
761989ff
VZ
426 bool replace = HasFlag(wxFR_REPLACEDIALOG);
427 if ( replace )
c41b00c9 428 {
761989ff 429 m_impl->InitReplaceWith(m_FindReplaceData->GetReplaceString());
c41b00c9
VZ
430 }
431
432 // call the right function to show the dialog which does what we want
761989ff
VZ
433 FINDREPLACE *pFR = m_impl->GetPtrFindReplace();
434 HWND hwnd;
435 if ( replace )
436 hwnd = ::ReplaceText(pFR);
437 else
438 hwnd = ::FindText(pFR);
439
440 if ( !hwnd )
c41b00c9
VZ
441 {
442 wxLogError(_("Failed to create the standard find/replace dialog (error code %d)"),
443 ::CommDlgExtendedError());
444
5276b0a5 445 wxDELETE(m_impl);
c41b00c9 446
cbe874bd 447 return false;
c41b00c9
VZ
448 }
449
761989ff 450 if ( !::ShowWindow(hwnd, SW_SHOW) )
c41b00c9 451 {
9a83f860 452 wxLogLastError(wxT("ShowWindow(find dialog)"));
c41b00c9
VZ
453 }
454
761989ff
VZ
455 m_hWnd = (WXHWND)hwnd;
456
cbe874bd 457 return true;
c41b00c9
VZ
458}
459
460// ----------------------------------------------------------------------------
461// wxFindReplaceDialog title handling
462// ----------------------------------------------------------------------------
463
464// we set the title of this dialog in our jook proc but for now don't crash in
465// the base class version because of m_hWnd == 0
466
467void wxFindReplaceDialog::SetTitle( const wxString& title)
468{
469 m_title = title;
470}
471
472wxString wxFindReplaceDialog::GetTitle() const
473{
474 return m_title;
475}
476
477// ----------------------------------------------------------------------------
478// wxFindReplaceDialog position/size
479// ----------------------------------------------------------------------------
480
481void wxFindReplaceDialog::DoSetSize(int WXUNUSED(x), int WXUNUSED(y),
482 int WXUNUSED(width), int WXUNUSED(height),
483 int WXUNUSED(sizeFlags))
484{
485 // ignore - we can't change the size of this standard dialog
486 return;
487}
488
489// NB: of course, both of these functions are completely bogus, but it's better
490// than nothing
491void wxFindReplaceDialog::DoGetSize(int *width, int *height) const
492{
493 // the standard dialog size
494 if ( width )
495 *width = 225;
496 if ( height )
497 *height = 324;
498}
499
500void wxFindReplaceDialog::DoGetClientSize(int *width, int *height) const
501{
502 // the standard dialog size
503 if ( width )
504 *width = 219;
505 if ( height )
506 *height = 299;
507}
508
509#endif // wxUSE_FINDREPLDLG