]> git.saurik.com Git - wxWidgets.git/blame - src/msw/dialog.cpp
wxGetOsVersion() compilation andl inking fixes for wxMac
[wxWidgets.git] / src / msw / dialog.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
b6c588e1 2// Name: src/msw/dialog.cpp
2bda0e17
KB
3// Purpose: wxDialog class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
6c9a19aa 8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
b6c588e1
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
2bda0e17
KB
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
b6c588e1 24 #pragma hdrstop
2bda0e17
KB
25#endif
26
fdf565fe
WS
27#include "wx/dialog.h"
28
2bda0e17 29#ifndef WX_PRECOMP
b6c588e1
VZ
30 #include "wx/utils.h"
31 #include "wx/frame.h"
32 #include "wx/app.h"
95e92d90 33 #include "wx/button.h"
b6c588e1
VZ
34 #include "wx/settings.h"
35 #include "wx/intl.h"
36 #include "wx/log.h"
4e3e485b 37 #include "wx/toolbar.h"
2bda0e17
KB
38#endif
39
40#include "wx/msw/private.h"
ac8d0c11 41#include "wx/evtloop.h"
8c7f5f03 42#include "wx/ptr_scpd.h"
2bda0e17 43
660296aa 44#include "wx/msw/wrapcdlg.h"
2bda0e17 45
3180bc0e 46#if defined(__SMARTPHONE__) && defined(__WXWINCE__)
ef6d716b 47 #include "wx/msw/wince/resources.h"
3180bc0e 48#endif // __SMARTPHONE__ && __WXWINCE__
ef6d716b 49
b6c588e1
VZ
50// ----------------------------------------------------------------------------
51// wxWin macros
52// ----------------------------------------------------------------------------
53
ffca575c
SC
54#if wxUSE_EXTENDED_RTTI
55WX_DEFINE_FLAGS( wxDialogStyle )
56
3ff066a4 57wxBEGIN_FLAGS( wxDialogStyle )
ffca575c
SC
58 // new style border flags, we put them first to
59 // use them for streaming out
3ff066a4
SC
60 wxFLAGS_MEMBER(wxBORDER_SIMPLE)
61 wxFLAGS_MEMBER(wxBORDER_SUNKEN)
62 wxFLAGS_MEMBER(wxBORDER_DOUBLE)
63 wxFLAGS_MEMBER(wxBORDER_RAISED)
64 wxFLAGS_MEMBER(wxBORDER_STATIC)
65 wxFLAGS_MEMBER(wxBORDER_NONE)
044fe836 66
ffca575c 67 // old style border flags
3ff066a4
SC
68 wxFLAGS_MEMBER(wxSIMPLE_BORDER)
69 wxFLAGS_MEMBER(wxSUNKEN_BORDER)
70 wxFLAGS_MEMBER(wxDOUBLE_BORDER)
71 wxFLAGS_MEMBER(wxRAISED_BORDER)
72 wxFLAGS_MEMBER(wxSTATIC_BORDER)
73 wxFLAGS_MEMBER(wxNO_BORDER)
ffca575c
SC
74
75 // standard window styles
3ff066a4
SC
76 wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
77 wxFLAGS_MEMBER(wxCLIP_CHILDREN)
ffca575c
SC
78
79 // dialog styles
3ff066a4
SC
80 wxFLAGS_MEMBER(wxWS_EX_VALIDATE_RECURSIVELY)
81 wxFLAGS_MEMBER(wxSTAY_ON_TOP)
82 wxFLAGS_MEMBER(wxCAPTION)
1c067fe3 83#if WXWIN_COMPATIBILITY_2_6
3ff066a4 84 wxFLAGS_MEMBER(wxTHICK_FRAME)
1c067fe3 85#endif // WXWIN_COMPATIBILITY_2_6
3ff066a4
SC
86 wxFLAGS_MEMBER(wxSYSTEM_MENU)
87 wxFLAGS_MEMBER(wxRESIZE_BORDER)
1c067fe3 88#if WXWIN_COMPATIBILITY_2_6
3ff066a4 89 wxFLAGS_MEMBER(wxRESIZE_BOX)
1c067fe3 90#endif // WXWIN_COMPATIBILITY_2_6
3ff066a4
SC
91 wxFLAGS_MEMBER(wxCLOSE_BOX)
92 wxFLAGS_MEMBER(wxMAXIMIZE_BOX)
93 wxFLAGS_MEMBER(wxMINIMIZE_BOX)
94wxEND_FLAGS( wxDialogStyle )
ffca575c
SC
95
96IMPLEMENT_DYNAMIC_CLASS_XTI(wxDialog, wxTopLevelWindow,"wx/dialog.h")
97
3ff066a4 98wxBEGIN_PROPERTIES_TABLE(wxDialog)
af498247
VZ
99 wxPROPERTY( Title, wxString, SetTitle, GetTitle, wxString() , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
100 wxPROPERTY_FLAGS( WindowStyle , wxDialogStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
3ff066a4 101wxEND_PROPERTIES_TABLE()
ffca575c 102
3ff066a4
SC
103wxBEGIN_HANDLERS_TABLE(wxDialog)
104wxEND_HANDLERS_TABLE()
ffca575c 105
044fe836 106wxCONSTRUCTOR_6( wxDialog , wxWindow* , Parent , wxWindowID , Id , wxString , Title , wxPoint , Position , wxSize , Size , long , WindowStyle)
ffca575c
SC
107
108#else
82c9f85c 109IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxTopLevelWindow)
ffca575c 110#endif
066f1b7a 111
138e1502 112BEGIN_EVENT_TABLE(wxDialog, wxDialogBase)
1b6452df
VZ
113 EVT_BUTTON(wxID_OK, wxDialog::OnOK)
114 EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
115 EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
b6c588e1 116
1b6452df 117 EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
b6c588e1 118
1b6452df
VZ
119 EVT_CLOSE(wxDialog::OnCloseWindow)
120END_EVENT_TABLE()
2bda0e17 121
6757b5e3
VZ
122// ----------------------------------------------------------------------------
123// wxDialogModalData
124// ----------------------------------------------------------------------------
125
8c7f5f03
VZ
126// this is simply a container for any data we need to implement modality which
127// allows us to avoid changing wxDialog each time the implementation changes
6757b5e3
VZ
128class wxDialogModalData
129{
130public:
8c7f5f03 131 wxDialogModalData(wxDialog *dialog) : m_evtLoop(dialog) { }
6757b5e3 132
8c7f5f03 133 void RunLoop()
6757b5e3 134 {
6757b5e3
VZ
135 m_evtLoop.Run();
136 }
137
138 void ExitLoop()
139 {
6757b5e3
VZ
140 m_evtLoop.Exit();
141 }
142
6757b5e3 143private:
8c7f5f03 144 wxModalEventLoop m_evtLoop;
6757b5e3
VZ
145};
146
259c43f6 147wxDEFINE_TIED_SCOPED_PTR_TYPE(wxDialogModalData)
8c7f5f03 148
b6c588e1
VZ
149// ============================================================================
150// implementation
151// ============================================================================
152
153// ----------------------------------------------------------------------------
154// wxDialog construction
155// ----------------------------------------------------------------------------
156
b0a6bb75 157void wxDialog::Init()
2bda0e17 158{
52a07708 159 m_oldFocus = (wxWindow *)NULL;
044fe836 160 m_isShown = false;
6757b5e3 161 m_modalData = NULL;
044fe836 162 m_endModalCalled = false;
ec5f0c24
JS
163#if wxUSE_TOOLBAR && defined(__POCKETPC__)
164 m_dialogToolBar = NULL;
165#endif
2bda0e17
KB
166}
167
b3daa5a3
VZ
168bool wxDialog::Create(wxWindow *parent,
169 wxWindowID id,
462e2437
VZ
170 const wxString& title,
171 const wxPoint& pos,
172 const wxSize& size,
173 long style,
174 const wxString& name)
2bda0e17 175{
82c9f85c 176 SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG);
bd9d76cb 177
b225f659 178 // save focus before doing anything which can potentially change it
82c9f85c 179 m_oldFocus = FindFocus();
462e2437 180
706bb5f9 181 // All dialogs should really have this style
b225f659 182 style |= wxTAB_TRAVERSAL;
2bda0e17 183
b225f659 184 if ( !wxTopLevelWindow::Create(parent, id, title, pos, size, style, name) )
044fe836 185 return false;
00233716
VZ
186
187 if ( !m_hasFont )
6f951810 188 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
e1bdd507 189
3180bc0e 190#if defined(__SMARTPHONE__) && defined(__WXWINCE__)
ef6d716b
WS
191 SetLeftMenu(wxID_OK, _("OK"));
192#endif
ec5f0c24
JS
193#if wxUSE_TOOLBAR && defined(__POCKETPC__)
194 CreateToolBar();
195#endif
ef6d716b 196
044fe836 197 return true;
2bda0e17
KB
198}
199
40ff126a
WS
200#if WXWIN_COMPATIBILITY_2_6
201
f46f4c86
VZ
202// deprecated ctor
203wxDialog::wxDialog(wxWindow *parent,
204 const wxString& title,
205 bool WXUNUSED(modal),
206 int x,
207 int y,
208 int w,
209 int h,
210 long style,
211 const wxString& name)
2bda0e17 212{
f46f4c86
VZ
213 Init();
214
d71cc120 215 Create(parent, wxID_ANY, title, wxPoint(x, y), wxSize(w, h), style, name);
f46f4c86
VZ
216}
217
218void wxDialog::SetModal(bool WXUNUSED(flag))
219{
220 // nothing to do, obsolete method
2bda0e17
KB
221}
222
40ff126a
WS
223#endif // WXWIN_COMPATIBILITY_2_6
224
2bda0e17
KB
225wxDialog::~wxDialog()
226{
044fe836 227 m_isBeingDeleted = true;
2bda0e17 228
b0a6bb75 229 // this will also reenable all the other windows for a modal dialog
044fe836 230 Show(false);
2bda0e17
KB
231}
232
b6c588e1
VZ
233// ----------------------------------------------------------------------------
234// showing the dialogs
235// ----------------------------------------------------------------------------
22cf5fec 236
40ff126a
WS
237#if WXWIN_COMPATIBILITY_2_6
238
b6c588e1 239bool wxDialog::IsModalShowing() const
2bda0e17 240{
f46f4c86 241 return IsModal();
2bda0e17
KB
242}
243
40ff126a
WS
244#endif // WXWIN_COMPATIBILITY_2_6
245
a543e3ce
VZ
246wxWindow *wxDialog::FindSuitableParent() const
247{
248 // first try to use the currently active window
249 HWND hwndFg = ::GetForegroundWindow();
250 wxWindow *parent = hwndFg ? wxFindWinFromHandle((WXHWND)hwndFg)
251 : NULL;
252 if ( !parent )
253 {
254 // next try the main app window
255 parent = wxTheApp->GetTopWindow();
256 }
257
258 // finally, check if the parent we found is really suitable
259 if ( !parent || parent == (wxWindow *)this || !parent->IsShown() )
260 {
261 // don't use this one
262 parent = NULL;
263 }
264
265 return parent;
266}
267
b6c588e1 268bool wxDialog::Show(bool show)
2bda0e17 269{
044fe836
VZ
270 if ( show == IsShown() )
271 return false;
272
6757b5e3 273 if ( !show && m_modalData )
86ad564e 274 {
6757b5e3
VZ
275 // we need to do this before calling wxDialogBase version because if we
276 // had disabled other app windows, they must be reenabled right now as
b0a6bb75 277 // if they stay disabled Windows will activate another window (one
6757b5e3
VZ
278 // which is enabled, anyhow) when we're hidden in the base class Show()
279 // and we will lose activation
280 m_modalData->ExitLoop();
86ad564e
JS
281 }
282
044fe836 283 if ( show )
b6c588e1 284 {
044fe836
VZ
285 // this usually will result in TransferDataToWindow() being called
286 // which will change the controls values so do it before showing as
287 // otherwise we could have some flicker
288 InitDialog();
b6c588e1 289 }
2bda0e17 290
044fe836
VZ
291 wxDialogBase::Show(show);
292
b6c588e1
VZ
293 if ( show )
294 {
2b5f62a0
VZ
295 // dialogs don't get WM_SIZE message after creation unlike most (all?)
296 // other windows and so could start their life non laid out correctly
297 // if we didn't call Layout() from here
298 //
299 // NB: normally we should call it just the first time but doing it
300 // every time is simpler than keeping a flag
301 Layout();
b6c588e1 302 }
2bda0e17 303
044fe836 304 return true;
2bda0e17
KB
305}
306
313901f3
JS
307void wxDialog::Raise()
308{
309 ::SetForegroundWindow(GetHwnd());
310}
311
f46f4c86 312// show dialog modally
a23fd0e1 313int wxDialog::ShowModal()
2bda0e17 314{
f46f4c86
VZ
315 wxASSERT_MSG( !IsModal(), _T("wxDialog::ShowModal() reentered?") );
316
044fe836 317 m_endModalCalled = false;
f46f4c86
VZ
318
319 Show();
320
321 // EndModal may have been called from InitDialog handler (called from
322 // inside Show()), which would cause an infinite loop if we didn't take it
323 // into account
324 if ( !m_endModalCalled )
5e1febfa 325 {
f46f4c86
VZ
326 // modal dialog needs a parent window, so try to find one
327 wxWindow *parent = GetParent();
328 if ( !parent )
329 {
330 parent = FindSuitableParent();
331 }
5e1febfa 332
f46f4c86
VZ
333 // remember where the focus was
334 wxWindow *oldFocus = m_oldFocus;
335 if ( !oldFocus )
336 {
337 // VZ: do we really want to do this?
338 oldFocus = parent;
339 }
340
341 // We have to remember the HWND because we need to check
342 // the HWND still exists (oldFocus can be garbage when the dialog
343 // exits, if it has been destroyed)
344 HWND hwndOldFocus = oldFocus ? GetHwndOf(oldFocus) : NULL;
345
346
347 // enter and run the modal loop
348 {
349 wxDialogModalDataTiedPtr modalData(&m_modalData,
350 new wxDialogModalData(this));
351 modalData->RunLoop();
352 }
353
354
355 // and restore focus
356 // Note that this code MUST NOT access the dialog object's data
357 // in case the object has been deleted (which will be the case
358 // for a modal dialog that has been destroyed before calling EndModal).
359 if ( oldFocus && (oldFocus != this) && ::IsWindow(hwndOldFocus))
360 {
361 // This is likely to prove that the object still exists
362 if (wxFindWinFromHandle((WXHWND) hwndOldFocus) == oldFocus)
363 oldFocus->SetFocus();
364 }
365 }
5e1febfa 366
b6c588e1 367 return GetReturnCode();
2bda0e17
KB
368}
369
370void wxDialog::EndModal(int retCode)
371{
f46f4c86
VZ
372 wxASSERT_MSG( IsModal(), _T("EndModal() called for non modal dialog") );
373
044fe836 374 m_endModalCalled = true;
b6c588e1 375 SetReturnCode(retCode);
6a088435 376
12b58624
VZ
377 Hide();
378}
379
380void wxDialog::EndDialog(int rc)
381{
382 if ( IsModal() )
383 EndModal(rc);
384 else
385 Hide();
2bda0e17
KB
386}
387
b6c588e1
VZ
388// ----------------------------------------------------------------------------
389// wxWin event handlers
390// ----------------------------------------------------------------------------
2bda0e17 391
f55fee08
VZ
392bool wxDialog::EmulateButtonClickIfPresent(int id)
393{
394 wxButton *btn = wxDynamicCast(FindWindow(id), wxButton);
395
08f80371 396 if ( !btn || !btn->IsEnabled() || !btn->IsShown() )
f55fee08
VZ
397 return false;
398
399 btn->MSWCommand(BN_CLICKED, 0 /* unused */);
400 return true;
401}
402
2bda0e17 403// Standard buttons
33ac7e6f 404void wxDialog::OnOK(wxCommandEvent& WXUNUSED(event))
2bda0e17 405{
dc1c4b62
VZ
406 if ( Validate() && TransferDataFromWindow() )
407 {
12b58624 408 EndDialog(wxID_OK);
dc1c4b62 409 }
2bda0e17
KB
410}
411
33ac7e6f 412void wxDialog::OnApply(wxCommandEvent& WXUNUSED(event))
2bda0e17 413{
b6c588e1
VZ
414 if ( Validate() )
415 TransferDataFromWindow();
416
417 // TODO probably need to disable the Apply button until things change again
2bda0e17
KB
418}
419
33ac7e6f 420void wxDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
2bda0e17 421{
12b58624 422 EndDialog(wxID_CANCEL);
2bda0e17
KB
423}
424
33ac7e6f 425void wxDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
2bda0e17 426{
b6c588e1 427 // We'll send a Cancel message by default, which may close the dialog.
e3065973
JS
428 // Check for looping if the Cancel event handler calls Close().
429
430 // Note that if a cancel button and handler aren't present in the dialog,
431 // nothing will happen when you close the dialog via the window manager, or
b6c588e1
VZ
432 // via Close(). We wouldn't want to destroy the dialog by default, since
433 // the dialog may have been created on the stack. However, this does mean
434 // that calling dialog->Close() won't delete the dialog unless the handler
435 // for wxID_CANCEL does so. So use Destroy() if you want to be sure to
436 // destroy the dialog. The default OnCancel (above) simply ends a modal
437 // dialog, and hides a modeless dialog.
438
439 // VZ: this is horrible and MT-unsafe. Can't we reuse some of these global
440 // lists here? don't dare to change it now, but should be done later!
2bda0e17 441 static wxList closing;
bd9d76cb 442
2bda0e17 443 if ( closing.Member(this) )
e3065973 444 return;
bd9d76cb 445
2bda0e17 446 closing.Append(this);
bd9d76cb 447
387a3b02
JS
448 wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
449 cancelEvent.SetEventObject( this );
e3065973 450 GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
2bda0e17
KB
451
452 closing.DeleteObject(this);
e3065973 453}
2bda0e17 454
33ac7e6f 455void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event))
2bda0e17 456{
a756f210 457 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
b6c588e1 458 Refresh();
68ad65f8 459}
42e69d6b 460
9ceeecb9
JS
461#ifdef __POCKETPC__
462// Responds to the OK button in a PocketPC titlebar. This
463// can be overridden, or you can change the id used for
464// sending the event, by calling SetAffirmativeId.
465bool wxDialog::DoOK()
466{
f55fee08
VZ
467 const int idOk = GetAffirmativeId();
468 if ( EmulateButtonClickIfPresent(idOk) )
9ceeecb9 469 return true;
9ceeecb9 470
f55fee08
VZ
471 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetAffirmativeId());
472 event.SetEventObject(this);
473
474 return GetEventHandler()->ProcessEvent(event);
9ceeecb9 475}
f55fee08 476#endif // __POCKETPC__
9ceeecb9 477
ec5f0c24
JS
478#if wxUSE_TOOLBAR && defined(__POCKETPC__)
479// create main toolbar by calling OnCreateToolBar()
480wxToolBar* wxDialog::CreateToolBar(long style, wxWindowID winid, const wxString& name)
481{
482 m_dialogToolBar = OnCreateToolBar(style, winid, name);
483
484 return m_dialogToolBar;
485}
486
487// return a new toolbar
488wxToolBar *wxDialog::OnCreateToolBar(long style,
489 wxWindowID winid,
490 const wxString& name)
491{
492 return new wxToolMenuBar(this, winid,
493 wxDefaultPosition, wxDefaultSize,
494 style, name);
660296aa 495}
ec5f0c24 496#endif
9ceeecb9 497
42e69d6b 498// ---------------------------------------------------------------------------
f55fee08 499// dialog Windows messages processing
42e69d6b
VZ
500// ---------------------------------------------------------------------------
501
f55fee08
VZ
502bool wxDialog::MSWProcessMessage(WXMSG* pMsg)
503{
504 const MSG * const msg = wx_reinterpret_cast(MSG *, pMsg);
505 if ( msg->message == WM_KEYDOWN && msg->wParam == VK_ESCAPE )
506 {
507 int idCancel = GetEscapeId();
508 switch ( idCancel )
509 {
510 case wxID_NONE:
511 // don't handle Esc specially at all
512 break;
513
514 case wxID_ANY:
515 // this value is special: it means translate Esc to wxID_CANCEL
516 // but if there is no such button, then fall back to wxID_OK
517 if ( EmulateButtonClickIfPresent(wxID_CANCEL) )
518 return true;
519 idCancel = wxID_OK;
520 // fall through
521
522 default:
523 // translate Esc to button press for the button with given id
524 if ( EmulateButtonClickIfPresent(idCancel) )
525 return true;
526 }
527 }
528
529 return wxDialogBase::MSWProcessMessage(pMsg);
530}
531
c140b7e7 532WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
42e69d6b 533{
c140b7e7 534 WXLRESULT rc = 0;
044fe836 535 bool processed = false;
42e69d6b
VZ
536
537 switch ( message )
538 {
0fc58b86
RR
539#ifdef __WXWINCE__
540 // react to pressing the OK button in the title
541 case WM_COMMAND:
ef6d716b
WS
542 {
543 switch ( LOWORD(wParam) )
0fc58b86 544 {
9ceeecb9 545#ifdef __POCKETPC__
ef6d716b 546 case IDOK:
9ceeecb9
JS
547 processed = DoOK();
548 if (!processed)
b554cf63 549 processed = !Close();
9ceeecb9
JS
550#endif
551#ifdef __SMARTPHONE__
ef6d716b
WS
552 case IDM_LEFT:
553 case IDM_RIGHT:
554 processed = HandleCommand( LOWORD(wParam) , 0 , NULL );
0fc58b86 555 break;
ef6d716b 556#endif // __SMARTPHONE__
0fc58b86
RR
557 }
558 break;
ef6d716b 559 }
044fe836 560#endif
42e69d6b
VZ
561 case WM_CLOSE:
562 // if we can't close, tell the system that we processed the
563 // message - otherwise it would close us
564 processed = !Close();
565 break;
abceee76 566
f73f67be
VZ
567 case WM_SIZE:
568 // the Windows dialogs unfortunately are not meant to be resizeable
569 // at all and their standard class doesn't include CS_[VH]REDRAW
570 // styles which means that the window is not refreshed properly
571 // after the resize and no amount of WS_CLIPCHILDREN/SIBLINGS can
572 // help with it - so we have to refresh it manually which certainly
573 // creates flicker but at least doesn't show garbage on the screen
574 rc = wxWindow::MSWWindowProc(message, wParam, lParam);
044fe836 575 processed = true;
e441e1f4 576 if ( HasFlag(wxFULL_REPAINT_ON_RESIZE) )
f73f67be 577 {
044fe836 578 ::InvalidateRect(GetHwnd(), NULL, false /* erase bg */);
f73f67be
VZ
579 }
580 break;
581
04ef50df 582#ifndef __WXMICROWIN__
abceee76
VZ
583 case WM_SETCURSOR:
584 // we want to override the busy cursor for modal dialogs:
585 // typically, wxBeginBusyCursor() is called and then a modal dialog
bfbd6dc1 586 // is shown, but the modal dialog shouldn't have hourglass cursor
f46f4c86 587 if ( IsModal() && wxIsBusy() )
abceee76 588 {
bfbd6dc1
VZ
589 // set our cursor for all windows (but see below)
590 wxCursor cursor = m_cursor;
591 if ( !cursor.Ok() )
592 cursor = wxCURSOR_ARROW;
abceee76 593
bfbd6dc1
VZ
594 ::SetCursor(GetHcursorOf(cursor));
595
596 // in any case, stop here and don't let wxWindow process this
597 // message (it would set the busy cursor)
044fe836 598 processed = true;
bfbd6dc1 599
044fe836 600 // but return false to tell the child window (if the event
bfbd6dc1
VZ
601 // comes from one of them and not from ourselves) that it can
602 // set its own cursor if it has one: thus, standard controls
603 // (e.g. text ctrl) still have correct cursors in a dialog
604 // invoked while wxIsBusy()
044fe836 605 rc = false;
abceee76 606 }
bfbd6dc1 607 break;
82c9f85c 608#endif // __WXMICROWIN__
42e69d6b
VZ
609 }
610
611 if ( !processed )
612 rc = wxWindow::MSWWindowProc(message, wParam, lParam);
613
614 return rc;
615}