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 // Lists to keep track of windows, so we can disable/enable them 
  36 wxWindowList wxModalDialogs
; 
  37 wxWindowList wxModelessWindows
;  // Frames and modeless dialogs 
  38 extern wxList WXDLLEXPORT wxPendingDelete
; 
  40    IMPLEMENT_DYNAMIC_CLASS(wxDialog
, wxPanel
) 
  42    BEGIN_EVENT_TABLE(wxDialog
, wxPanel
) 
  43       EVT_SIZE(wxDialog::OnSize
) 
  44       EVT_BUTTON(wxID_OK
, wxDialog::OnOK
) 
  45       EVT_BUTTON(wxID_APPLY
, wxDialog::OnApply
) 
  46       EVT_BUTTON(wxID_CANCEL
, wxDialog::OnCancel
) 
  47       EVT_CHAR_HOOK(wxDialog::OnCharHook
) 
  48       EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged
) 
  49       EVT_CLOSE(wxDialog::OnCloseWindow
) 
  54     m_pOldFocus 
= (wxWindow 
*)NULL
; 
  56     m_pWindowDisabler 
= (wxWindowDisabler 
*)NULL
; 
  57     SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
)); 
  58 } // end of wxDialog::Init 
  60 bool wxDialog::Create( 
  63 , const wxString
&                   rsTitle
 
  67 , const wxString
&                   rsName
 
  72     long                            lWidth 
= rSize
.x
; 
  73     long                            lHeight 
= rSize
.y
; 
  75     WXDWORD                         dwExtendedStyle 
= 0L; 
  79     m_pOldFocus 
= (wxWindow
*)FindFocus(); 
  81     wxTopLevelWindows
.Append(this); 
  83         pParent
->AddChild(this); 
  85         m_windowId 
= NewControlId(); 
  89         lX 
= wxDIALOG_DEFAULT_X
; 
  91         lY 
= wxDIALOG_DEFAULT_Y
; 
  92     m_windowStyle 
= lStyle
; 
  94         lWidth 
= wxDIALOG_DEFAULT_WIDTH
; 
  96         lHeight 
= wxDIALOG_DEFAULT_HEIGHT
; 
  99     // All dialogs should really have this style 
 101     m_windowStyle 
|= wxTAB_TRAVERSAL
; 
 104     // Allows creation of dialogs with & without captions under MSWindows, 
 105     // resizeable or not (but a resizeable dialog always has caption - 
 106     // otherwise it would look too strange) 
 108     if (lStyle 
& wxRESIZE_BORDER 
) 
 109         zDlg 
= "wxResizeableDialog"; 
 110     else if (lStyle 
& wxCAPTION 
) 
 111         zDlg 
= "wxCaptionDialog"; 
 113         zDlg 
= "wxNoCaptionDialog"; 
 114     OS2Create( GetWinHwnd(pParent
) 
 128     hWnd 
= (HWND
)GetHWND(); 
 133     SubclassWin(GetHWND()); 
 134     ::WinSetWindowText( hWnd
 
 135                        ,(PSZ
)rsTitle
.c_str() 
 137     SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
)); 
 139 } // end of wxDialog::Create 
 141 void wxDialog::SetModal( 
 146         m_windowStyle 
|= wxDIALOG_MODAL 
; 
 147     else if ( m_windowStyle 
& wxDIALOG_MODAL 
) 
 148         m_windowStyle 
-= wxDIALOG_MODAL 
; 
 150       wxModelessWindows
.DeleteObject(this); 
 152           wxModelessWindows
.Append(this); 
 153 } // end of wxDialog::SetModal 
 155 wxDialog::~wxDialog() 
 157     m_isBeingDeleted 
= TRUE
; 
 158     wxTopLevelWindows
.DeleteObject(this); 
 161         wxModelessWindows
.DeleteObject(this); 
 164     // If this is the last top-level window, exit. 
 166     if (wxTheApp 
&& (wxTopLevelWindows
.Number() == 0)) 
 168         wxTheApp
->SetTopWindow(NULL
); 
 170         if (wxTheApp
->GetExitOnFrameDelete()) 
 172             ::WinPostMsg(GetHwnd(), WM_QUIT
, 0, 0); 
 175 } // end of wxDialog::~wxDialog 
 178 // By default, pressing escape cancels the dialog 
 180 void wxDialog::OnCharHook( 
 186         if (rEvent
.m_keyCode 
== WXK_ESCAPE
) 
 189             // Behaviour changed in 2.0: we'll send a Cancel message 
 190             // to the dialog instead of Close. 
 192             wxCommandEvent          
vCancelEvent( wxEVT_COMMAND_BUTTON_CLICKED
 
 196             vCancelEvent
.SetEventObject( this ); 
 197             GetEventHandler()->ProcessEvent(vCancelEvent
); 
 200             // Ensure that there is another message for this window so the 
 201             // ShowModal loop will exit and won't get stuck in GetMessage(). 
 203             ::WinPostMsg(GetHwnd(), WM_NULL
, 0, 0); 
 207     // We didn't process this event. 
 211 void wxDialog::Iconize( 
 212   bool                              WXUNUSED(bIconize
) 
 215 } // end of wxDialog::Iconize 
 217 bool wxDialog::IsIconized() const 
 220 } // end of wxDialog::IsIconized 
 222 void wxDialog::DoSetClientSize( 
 227     HWND                            hWnd 
= (HWND
) GetHWND(); 
 231     ::WinQueryWindowRect(hWnd
, &vRect
); 
 232     ::WinQueryWindowRect(hWnd
, &vRect2
); 
 234     LONG                            lActualWidth 
= vRect2
.xRight 
- vRect2
.xLeft 
- vRect
.xRight 
+ nWidth
; 
 235     LONG                            lActualHeight 
= vRect2
.yTop 
+ vRect2
.yTop 
- vRect
.yTop 
+ nHeight
; 
 237     ::WinSetWindowPos( GetHwnd() 
 246     wxSizeEvent                     
vEvent( wxSize( lActualWidth
 
 252     vEvent
.SetEventObject( this ); 
 253     GetEventHandler()->ProcessEvent(vEvent
); 
 254 } // end of wxDialog::DoSetClientSize 
 256 void wxDialog::DoGetPosition( 
 263     ::WinQueryWindowRect(GetHwnd(), &vRect
); 
 267         *pnY 
= vRect
.yBottom
; // OS/2's bottom is windows' top??? 
 268 } // end of wxDialog::DoGetPosition 
 270 bool wxDialog::IsModal() const 
 272     return (GetWindowStyleFlag() & wxDIALOG_MODAL
) != 0; 
 273 } // end of wxDialog::IsModal 
 275 bool wxDialog::IsModalShowing() const 
 277     return wxModalDialogs
.Find((wxDialog 
*)this) != NULL
; // const_cast 
 278 } // end of wxDialog::IsModalShowing 
 280 void wxDialog::DoShowModal() 
 282     wxWindow
*                       pParent 
= GetParent(); 
 283     wxWindow
*                       pOldFocus 
= m_pOldFocus
; 
 284     HWND                            hWndOldFocus 
= 0; 
 286     wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") ); 
 287     wxCHECK_RET( IsModal(), _T("can't DoShowModal() modeless dialog") ); 
 289     wxModalDialogs
.Append(this); 
 291         hWndOldFocus 
= (HWND
)pOldFocus
->GetHWND(); 
 294     // Remember where the focus was 
 300             hWndOldFocus 
= GetHwndOf(pParent
); 
 304     // Disable all other app windows 
 306     wxASSERT_MSG(!m_pWindowDisabler
, _T("disabling windows twice?")); 
 308     m_pWindowDisabler 
= new wxWindowDisabler(this); 
 311     // Enter the modal loop 
 313     while ( IsModalShowing() ) 
 316         wxMutexGuiLeaveOrEnter(); 
 317 #endif // wxUSE_THREADS 
 319         while ( !wxTheApp
->Pending() && wxTheApp
->ProcessIdle() ) 
 322         // a message came or no more idle processing to do 
 323         wxTheApp
->DoMessage(); 
 328     // Note that this code MUST NOT access the dialog object's data 
 329     // in case the object has been deleted (which will be the case 
 330     // for a modal dialog that has been destroyed before calling EndModal). 
 332     if (pOldFocus 
&& (pOldFocus 
!= this) && ::WinIsWindow(vHabmain
, hWndOldFocus
)) 
 335         // This is likely to prove that the object still exists 
 337         if (wxFindWinFromHandle((WXHWND
) hWndOldFocus
) == pOldFocus
) 
 338             pOldFocus
->SetFocus(); 
 340 } // end of wxDialog::DoShowModal 
 349         // If we had disabled other app windows, reenable them back now because 
 350         // if they stay disabled Windows will activate another window (one 
 351         // which is enabled, anyhow) and we will lose activation 
 353         if (m_pWindowDisabler
) 
 355             delete m_pWindowDisabler
; 
 356             m_pWindowDisabler 
= NULL
; 
 361     // ShowModal() may be called for already shown dialog 
 363     if (!wxDialogBase::Show(bShow
) && !(bShow 
&& IsModal())) 
 374         // Usually will result in TransferDataToWindow() being called 
 384             // Modal dialog needs a parent window, so try to find one 
 388                 wxWindow
*           pParent 
= wxTheApp
->GetTopWindow(); 
 390                 if ( pParent 
&& pParent 
!= this && pParent
->IsShown() ) 
 401         else // end of modal dialog 
 404             // This will cause IsModalShowing() return FALSE and our local 
 405             // message loop will terminate 
 407             wxModalDialogs
.DeleteObject(this); 
 411 } // end of wxDialog::Show 
 414 // Replacement for Show(TRUE) for modal dialogs - returns return code 
 416 int wxDialog::ShowModal() 
 423     return GetReturnCode(); 
 424 } // end of wxDialog::ShowModal 
 426 void wxDialog::EndModal( 
 430     SetReturnCode(nRetCode
); 
 432 } // end of wxDialog::EndModal 
 434 void wxDialog::OnApply( 
 435   wxCommandEvent
&                   rEvent
 
 439         TransferDataFromWindow(); 
 440 } // end of wxDialog::OnApply 
 444   wxCommandEvent
&                   rEvent
 
 447     if ( Validate() && TransferDataFromWindow() ) 
 451 } // end of wxDialog::OnOK 
 453 void wxDialog::OnCancel( 
 454   wxCommandEvent
&                   rEvent
 
 457     EndModal(wxID_CANCEL
); 
 458 } // end of wxDialog::OnCancel 
 460 void wxDialog::OnCloseWindow( 
 465     // We'll send a Cancel message by default, 
 466     // which may close the dialog. 
 467     // Check for looping if the Cancel event handler calls Close(). 
 469     // Note that if a cancel button and handler aren't present in the dialog, 
 470     // nothing will happen when you close the dialog via the window manager, or 
 472     // We wouldn't want to destroy the dialog by default, since the dialog may have been 
 473     // created on the stack. 
 474     // However, this does mean that calling dialog->Close() won't delete the dialog 
 475     // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be 
 476     // sure to destroy the dialog. 
 477     // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog. 
 481     // Ugh???  This is not good but until I figure out a global list it'll have to do 
 483     static wxList closing
; 
 485     if ( closing
.Member(this) ) 
 488     closing
.Append(this); 
 490     wxCommandEvent                  
vCancelEvent(wxEVT_COMMAND_BUTTON_CLICKED
, wxID_CANCEL
); 
 492     vCancelEvent
.SetEventObject( this ); 
 493     GetEventHandler()->ProcessEvent(vCancelEvent
); // This may close the dialog 
 495     closing
.DeleteObject(this); 
 496 } // end of wxDialog::OnCloseWindow 
 499 // Destroy the window (delayed, if a managed window) 
 501 bool wxDialog::Destroy() 
 503     wxCHECK_MSG( !wxPendingDelete
.Member(this), FALSE
, 
 504                  _T("wxDialog destroyed twice") ); 
 505     wxPendingDelete
.Append(this); 
 507 } // end of wxDialog::Destroy 
 509 void wxDialog::OnSysColourChanged( 
 510   wxSysColourChangedEvent
&          rEvent
 
 513     SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
)); 
 515 } // end of wxDialog::OnSysColourChanged 
 517 MRESULT 
wxDialog::OS2WindowProc( 
 524     bool                            bProcessed 
= FALSE
; 
 530             // If we can't close, tell the system that we processed the 
 531             // message - otherwise it would close us 
 533             bProcessed 
= !Close(); 
 538         rc 
= wxWindow::OS2WindowProc( uMessage
 
 543 } // end of wxDialog::OS2WindowProc