1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxDialog class 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  16 #include "wx/dialog.h" 
  20 #include "wx/settings.h" 
  25 #include "wx/os2/private.h" 
  28 #define wxDIALOG_DEFAULT_X 300 
  29 #define wxDIALOG_DEFAULT_Y 300 
  31 #define wxDIALOG_DEFAULT_WIDTH 500 
  32 #define wxDIALOG_DEFAULT_HEIGHT 500 
  34 wxWindowList wxModalDialogs
; 
  36 IMPLEMENT_DYNAMIC_CLASS(wxDialog
, wxTopLevelWindow
) 
  38 BEGIN_EVENT_TABLE(wxDialog
, wxDialogBase
) 
  39     EVT_BUTTON(wxID_OK
, wxDialog::OnOK
) 
  40     EVT_BUTTON(wxID_APPLY
, wxDialog::OnApply
) 
  41     EVT_BUTTON(wxID_CANCEL
, wxDialog::OnCancel
) 
  42     EVT_CHAR_HOOK(wxDialog::OnCharHook
) 
  43     EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged
) 
  44     EVT_CLOSE(wxDialog::OnCloseWindow
) 
  49     m_pOldFocus 
= (wxWindow 
*)NULL
; 
  51     m_pWindowDisabler 
= (wxWindowDisabler 
*)NULL
; 
  52     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)); 
  53 } // end of wxDialog::Init 
  55 bool wxDialog::Create( 
  58 , const wxString
&                   rsTitle
 
  62 , const wxString
&                   rsName
 
  67     long                            lWidth 
= rSize
.x
; 
  68     long                            lHeight 
= rSize
.y
; 
  70     WXDWORD                         dwExtendedStyle 
= 0L; 
  74     SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG
); 
  77     // Save focus before doing anything which can potentially change it 
  79     m_pOldFocus 
= FindFocus(); 
  82     // All dialogs should really have this style 
  84     lStyle 
|= wxTAB_TRAVERSAL
; 
  86     if (!wxTopLevelWindow::Create( pParent
 
  95     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
  98     // Must defer setting the title until after dialog is created and sized 
 100     if (!rsTitle
.IsNull()) 
 103 } // end of wxDialog::Create 
 105 void wxDialog::SetModal( 
 111         m_windowStyle 
|= wxDIALOG_MODAL 
; 
 112         wxModelessWindows
.DeleteObject(this); 
 116         m_windowStyle 
&= ~wxDIALOG_MODAL 
; 
 117         wxModelessWindows
.Append(this); 
 119 } // end of wxDialog::SetModal 
 121 wxDialog::~wxDialog() 
 123     m_isBeingDeleted 
= TRUE
; 
 125 } // end of wxDialog::~wxDialog 
 128 // By default, pressing escape cancels the dialog 
 130 void wxDialog::OnCharHook( 
 136         if (rEvent
.m_keyCode 
== WXK_ESCAPE
) 
 139             // Behaviour changed in 2.0: we'll send a Cancel message 
 140             // to the dialog instead of Close. 
 142             wxCommandEvent          
vCancelEvent( wxEVT_COMMAND_BUTTON_CLICKED
 
 146             vCancelEvent
.SetEventObject( this ); 
 147             GetEventHandler()->ProcessEvent(vCancelEvent
); 
 150             // Ensure that there is another message for this window so the 
 151             // ShowModal loop will exit and won't get stuck in GetMessage(). 
 153             ::WinPostMsg(GetHwnd(), WM_NULL
, 0, 0); 
 157     // We didn't process this event. 
 161 // ---------------------------------------------------------------------------- 
 162 // showing the dialogs 
 163 // ---------------------------------------------------------------------------- 
 165 bool wxDialog::IsModal() const 
 167     return (GetWindowStyleFlag() & wxDIALOG_MODAL
) != 0; 
 168 } // end of wxDialog::IsModal 
 170 bool wxDialog::IsModalShowing() const 
 172     return wxModalDialogs
.Find((wxDialog 
*)this) != NULL
; // const_cast 
 173 } // end of wxDialog::IsModalShowing 
 175 void wxDialog::DoShowModal() 
 177     wxWindow
*                       pParent 
= GetParent(); 
 178     wxWindow
*                       pOldFocus 
= m_pOldFocus
; 
 179     HWND                            hWndOldFocus 
= 0; 
 181     wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") ); 
 182     wxCHECK_RET( IsModal(), _T("can't DoShowModal() modeless dialog") ); 
 184     wxModalDialogs
.Append(this); 
 186         hWndOldFocus 
= (HWND
)pOldFocus
->GetHWND(); 
 189     // Remember where the focus was 
 195             hWndOldFocus 
= GetHwndOf(pParent
); 
 199     // Disable all other app windows 
 201     wxASSERT_MSG(!m_pWindowDisabler
, _T("disabling windows twice?")); 
 203     m_pWindowDisabler 
= new wxWindowDisabler(this); 
 206     // Enter the modal loop 
 208     while ( IsModalShowing() ) 
 211         wxMutexGuiLeaveOrEnter(); 
 212 #endif // wxUSE_THREADS 
 214         while ( !wxTheApp
->Pending() && wxTheApp
->ProcessIdle() ) 
 217         // a message came or no more idle processing to do 
 218         wxTheApp
->DoMessage(); 
 223     // Note that this code MUST NOT access the dialog object's data 
 224     // in case the object has been deleted (which will be the case 
 225     // for a modal dialog that has been destroyed before calling EndModal). 
 227     if (pOldFocus 
&& (pOldFocus 
!= this) && ::WinIsWindow(vHabmain
, hWndOldFocus
)) 
 230         // This is likely to prove that the object still exists 
 232         if (wxFindWinFromHandle((WXHWND
) hWndOldFocus
) == pOldFocus
) 
 233             pOldFocus
->SetFocus(); 
 235 } // end of wxDialog::DoShowModal 
 244         // If we had disabled other app windows, reenable them back now because 
 245         // if they stay disabled Windows will activate another window (one 
 246         // which is enabled, anyhow) and we will lose activation 
 248         if (m_pWindowDisabler
) 
 250             delete m_pWindowDisabler
; 
 251             m_pWindowDisabler 
= NULL
; 
 256     // ShowModal() may be called for already shown dialog 
 258     if (!wxDialogBase::Show(bShow
) && !(bShow 
&& IsModal())) 
 269         // Usually will result in TransferDataToWindow() being called 
 274     if (GetTitle().c_str()) 
 275         ::WinSetWindowText((HWND
)GetHwnd(), GetTitle().c_str()); 
 281             // Modal dialog needs a parent window, so try to find one 
 285                 wxWindow
*           pParent 
= wxTheApp
->GetTopWindow(); 
 287                 if ( pParent 
&& pParent 
!= this && pParent
->IsShown() ) 
 298         else // end of modal dialog 
 301             // This will cause IsModalShowing() return FALSE and our local 
 302             // message loop will terminate 
 304             wxModalDialogs
.DeleteObject(this); 
 308 } // end of wxDialog::Show 
 311 // Replacement for Show(TRUE) for modal dialogs - returns return code 
 313 int wxDialog::ShowModal() 
 320     return GetReturnCode(); 
 321 } // end of wxDialog::ShowModal 
 323 void wxDialog::EndModal( 
 327     SetReturnCode(nRetCode
); 
 329 } // end of wxDialog::EndModal 
 331 // ---------------------------------------------------------------------------- 
 332 // wxWin event handlers 
 333 // ---------------------------------------------------------------------------- 
 335 void wxDialog::OnApply( 
 336   wxCommandEvent
&                   rEvent
 
 340         TransferDataFromWindow(); 
 341 } // end of wxDialog::OnApply 
 345   wxCommandEvent
&                   rEvent
 
 348     if ( Validate() && TransferDataFromWindow() ) 
 352 } // end of wxDialog::OnOK 
 354 void wxDialog::OnCancel( 
 355   wxCommandEvent
&                   rEvent
 
 358     EndModal(wxID_CANCEL
); 
 359 } // end of wxDialog::OnCancel 
 361 void wxDialog::OnCloseWindow( 
 366     // We'll send a Cancel message by default, 
 367     // which may close the dialog. 
 368     // Check for looping if the Cancel event handler calls Close(). 
 370     // Note that if a cancel button and handler aren't present in the dialog, 
 371     // nothing will happen when you close the dialog via the window manager, or 
 373     // We wouldn't want to destroy the dialog by default, since the dialog may have been 
 374     // created on the stack. 
 375     // However, this does mean that calling dialog->Close() won't delete the dialog 
 376     // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be 
 377     // sure to destroy the dialog. 
 378     // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog. 
 382     // Ugh???  This is not good but until I figure out a global list it'll have to do 
 384     static wxList closing
; 
 386     if ( closing
.Member(this) ) 
 389     closing
.Append(this); 
 391     wxCommandEvent                  
vCancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
); 
 393     vCancelEvent
.SetEventObject( this ); 
 394     GetEventHandler()->ProcessEvent(vCancelEvent
); // This may close the dialog 
 396     closing
.DeleteObject(this); 
 397 } // end of wxDialog::OnCloseWindow 
 399 void wxDialog::OnSysColourChanged( 
 400   wxSysColourChangedEvent
&          rEvent
 
 403     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)); 
 405 } // end of wxDialog::OnSysColourChanged 
 407 MRESULT 
wxDialog::OS2WindowProc( 
 414     bool                            bProcessed 
= FALSE
; 
 420             // If we can't close, tell the system that we processed the 
 421             // message - otherwise it would close us 
 423             bProcessed 
= !Close(); 
 428         rc 
= wxWindow::OS2WindowProc( uMessage
 
 433 } // end of wxDialog::OS2WindowProc