home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / os2 / dialog.cpp < prev    next >
C/C++ Source or Header  |  2002-01-21  |  12KB  |  441 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        dialog.cpp
  3. // Purpose:     wxDialog class
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/14/99
  7. // RCS-ID:      $Id: DIALOG.CPP,v 1.15 2002/01/21 18:45:09 DW Exp $
  8. // Copyright:   (c) David Webster
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // For compilers that support precompilation, includes "wx.h".
  13. #include "wx/wxprec.h"
  14.  
  15. #ifndef WX_PRECOMP
  16. #include "wx/dialog.h"
  17. #include "wx/utils.h"
  18. #include "wx/frame.h"
  19. #include "wx/app.h"
  20. #include "wx/settings.h"
  21. #include "wx/intl.h"
  22. #include "wx/log.h"
  23. #endif
  24.  
  25. #include "wx/os2/private.h"
  26. #include "wx/log.h"
  27.  
  28. #define wxDIALOG_DEFAULT_X 300
  29. #define wxDIALOG_DEFAULT_Y 300
  30.  
  31. #define wxDIALOG_DEFAULT_WIDTH 500
  32. #define wxDIALOG_DEFAULT_HEIGHT 500
  33.  
  34. wxWindowList wxModalDialogs;
  35.  
  36. IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxTopLevelWindow)
  37.  
  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)
  45. END_EVENT_TABLE()
  46.  
  47. void wxDialog::Init()
  48. {
  49.     m_pOldFocus = (wxWindow *)NULL;
  50.     m_isShown = FALSE;
  51.     m_pWindowDisabler = (wxWindowDisabler *)NULL;
  52.     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
  53. } // end of wxDialog::Init
  54.  
  55. bool wxDialog::Create(
  56.   wxWindow*                         pParent
  57. , wxWindowID                        vId
  58. , const wxString&                   rsTitle
  59. , const wxPoint&                    rPos
  60. , const wxSize&                     rSize
  61. , long                              lStyle
  62. , const wxString&                   rsName
  63. )
  64. {
  65.     long                            lX = rPos.x;
  66.     long                            lY = rPos.y;
  67.     long                            lWidth = rSize.x;
  68.     long                            lHeight = rSize.y;
  69.     const char*                     zDlg;
  70.     WXDWORD                         dwExtendedStyle = 0L;
  71.     HWND                            hWnd;
  72.  
  73.     Init();
  74.     SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG);
  75.  
  76.     //
  77.     // Save focus before doing anything which can potentially change it
  78.     //
  79.     m_pOldFocus = FindFocus();
  80.  
  81.     //
  82.     // All dialogs should really have this style
  83.     //
  84.     lStyle |= wxTAB_TRAVERSAL;
  85.  
  86.     if (!wxTopLevelWindow::Create( pParent
  87.                                   ,vId
  88.                                   ,rsTitle
  89.                                   ,rPos
  90.                                   ,rSize
  91.                                   ,lStyle
  92.                                   ,rsName
  93.                                  ))
  94.         return FALSE;
  95.     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
  96.  
  97.     //
  98.     // Must defer setting the title until after dialog is created and sized
  99.     //
  100.     if (!rsTitle.IsNull())
  101.         SetTitle(rsTitle);
  102.     return TRUE;
  103. } // end of wxDialog::Create
  104.  
  105. void wxDialog::SetModal(
  106.   bool                              bFlag
  107. )
  108. {
  109.     if (bFlag)
  110.     {
  111.         m_windowStyle |= wxDIALOG_MODAL ;
  112.         wxModelessWindows.DeleteObject(this);
  113.     }
  114.     else
  115.     {
  116.         m_windowStyle &= ~wxDIALOG_MODAL ;
  117.         wxModelessWindows.Append(this);
  118.     }
  119. } // end of wxDialog::SetModal
  120.  
  121. wxDialog::~wxDialog()
  122. {
  123.     m_isBeingDeleted = TRUE;
  124.     Show(FALSE);
  125. } // end of wxDialog::~wxDialog
  126.  
  127. //
  128. // By default, pressing escape cancels the dialog
  129. //
  130. void wxDialog::OnCharHook(
  131.   wxKeyEvent&                       rEvent
  132. )
  133. {
  134.     if (GetHWND())
  135.     {
  136.         if (rEvent.m_keyCode == WXK_ESCAPE)
  137.         {
  138.             //
  139.             // Behaviour changed in 2.0: we'll send a Cancel message
  140.             // to the dialog instead of Close.
  141.             //
  142.             wxCommandEvent          vCancelEvent( wxEVT_COMMAND_BUTTON_CLICKED
  143.                                                  ,wxID_CANCEL
  144.                                                 );
  145.  
  146.             vCancelEvent.SetEventObject( this );
  147.             GetEventHandler()->ProcessEvent(vCancelEvent);
  148.  
  149.             //
  150.             // Ensure that there is another message for this window so the
  151.             // ShowModal loop will exit and won't get stuck in GetMessage().
  152.             //
  153.             ::WinPostMsg(GetHwnd(), WM_NULL, 0, 0);
  154.             return;
  155.         }
  156.     }
  157.     // We didn't process this event.
  158.     rEvent.Skip();
  159. }
  160.  
  161. // ----------------------------------------------------------------------------
  162. // showing the dialogs
  163. // ----------------------------------------------------------------------------
  164.  
  165. bool wxDialog::IsModal() const
  166. {
  167.     return (GetWindowStyleFlag() & wxDIALOG_MODAL) != 0;
  168. } // end of wxDialog::IsModal
  169.  
  170. bool wxDialog::IsModalShowing() const
  171. {
  172.     return wxModalDialogs.Find((wxDialog *)this) != NULL; // const_cast
  173. } // end of wxDialog::IsModalShowing
  174.  
  175. void wxDialog::DoShowModal()
  176. {
  177.     wxWindow*                       pParent = GetParent();
  178.     wxWindow*                       pOldFocus = m_pOldFocus;
  179.     HWND                            hWndOldFocus = 0;
  180.  
  181.     wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") );
  182.     wxCHECK_RET( IsModal(), _T("can't DoShowModal() modeless dialog") );
  183.  
  184.     wxModalDialogs.Append(this);
  185.     if (pOldFocus)
  186.         hWndOldFocus = (HWND)pOldFocus->GetHWND();
  187.  
  188.     //
  189.     // Remember where the focus was
  190.     //
  191.     if (!pOldFocus)
  192.     {
  193.         pOldFocus = pParent;
  194.         if (pParent)
  195.             hWndOldFocus = GetHwndOf(pParent);
  196.     }
  197.  
  198.     //
  199.     // Disable all other app windows
  200.     //
  201.     wxASSERT_MSG(!m_pWindowDisabler, _T("disabling windows twice?"));
  202.  
  203.     //
  204.     // Disables other app windows and window proc message processing
  205.     // until WinDismissDlg called
  206.     //
  207.     ::WinProcessDlg((HWND)GetHwnd());
  208.  
  209.     //
  210.     // Enter the modal loop
  211.     //
  212.     while ( IsModalShowing() )
  213.     {
  214. #if wxUSE_THREADS
  215.         wxMutexGuiLeaveOrEnter();
  216. #endif // wxUSE_THREADS
  217.  
  218.         while ( !wxTheApp->Pending() && wxTheApp->ProcessIdle() )
  219.             ;
  220.  
  221.         // a message came or no more idle processing to do
  222.         wxTheApp->DoMessage();
  223.     }
  224.  
  225.     //
  226.     // Snd restore focus
  227.     // Note that this code MUST NOT access the dialog object's data
  228.     // in case the object has been deleted (which will be the case
  229.     // for a modal dialog that has been destroyed before calling EndModal).
  230.     //
  231.     if (pOldFocus && (pOldFocus != this) && ::WinIsWindow(vHabmain, hWndOldFocus))
  232.     {
  233.         //
  234.         // This is likely to prove that the object still exists
  235.         //
  236.         if (wxFindWinFromHandle((WXHWND) hWndOldFocus) == pOldFocus)
  237.             pOldFocus->SetFocus();
  238.     }
  239. } // end of wxDialog::DoShowModal
  240.  
  241. bool wxDialog::Show(
  242.   bool                              bShow
  243. )
  244. {
  245.     if (!bShow)
  246.     {
  247.         //
  248.         // If we had disabled other app windows, reenable them back now because
  249.         // if they stay disabled Windows will activate another window (one
  250.         // which is enabled, anyhow) and we will lose activation.  We really don't
  251.         // do this in OS/2 since PM does this for us.
  252.         //
  253.         if (m_pWindowDisabler)
  254.         {
  255.             delete m_pWindowDisabler;
  256.             m_pWindowDisabler = NULL;
  257.         }
  258.     }
  259.  
  260.     //
  261.     // ShowModal() may be called for already shown dialog
  262.     //
  263.     if (!wxDialogBase::Show(bShow) && !(bShow && IsModal()))
  264.     {
  265.         //
  266.         // Nothing to do
  267.         //
  268.         return FALSE;
  269.     }
  270.  
  271.     if (bShow)
  272.     {
  273.         //
  274.         // Usually will result in TransferDataToWindow() being called
  275.         //
  276.         InitDialog();
  277.     }
  278.  
  279.     if (GetTitle().c_str())
  280.         ::WinSetWindowText((HWND)GetHwnd(), GetTitle().c_str());
  281.     if (IsModal())
  282.     {
  283.         if (bShow)
  284.         {
  285.             //
  286.             // Modal dialog needs a parent window, so try to find one
  287.             //
  288.             if (!GetParent())
  289.             {
  290.                 wxWindow*           pParent = wxTheApp->GetTopWindow();
  291.  
  292.                 if ( pParent && pParent != this && pParent->IsShown() )
  293.                 {
  294.                     //
  295.                     // Use it
  296.                     //
  297.                     m_parent = pParent;
  298.  
  299.                 }
  300.             }
  301.             DoShowModal();
  302.         }
  303.         else // end of modal dialog
  304.         {
  305.             //
  306.             // This will cause IsModalShowing() return FALSE and our local
  307.             // message loop will terminate
  308.             //
  309.             wxModalDialogs.DeleteObject(this);
  310.         }
  311.     }
  312.     return TRUE;
  313. } // end of wxDialog::Show
  314.  
  315. //
  316. // Replacement for Show(TRUE) for modal dialogs - returns return code
  317. //
  318. int wxDialog::ShowModal()
  319. {
  320.     if (!IsModal())
  321.     {
  322.         SetModal(TRUE);
  323.     }
  324.     Show(TRUE);
  325.     return GetReturnCode();
  326. } // end of wxDialog::ShowModal
  327.  
  328. void wxDialog::EndModal(
  329.   int                               nRetCode
  330. )
  331. {
  332.     SetReturnCode(nRetCode);
  333.     Show(FALSE);
  334.     ::WinDismissDlg((HWND)GetHwnd(), nRetCode);
  335. } // end of wxDialog::EndModal
  336.  
  337. // ----------------------------------------------------------------------------
  338. // wxWin event handlers
  339. // ----------------------------------------------------------------------------
  340.  
  341. void wxDialog::OnApply(
  342.   wxCommandEvent&                   rEvent
  343. )
  344. {
  345.     if (Validate())
  346.         TransferDataFromWindow();
  347. } // end of wxDialog::OnApply
  348.  
  349. // Standard buttons
  350. void wxDialog::OnOK(
  351.   wxCommandEvent&                   rEvent
  352. )
  353. {
  354.     if ( Validate() && TransferDataFromWindow() )
  355.     {
  356.         EndModal(wxID_OK);
  357.     }
  358. } // end of wxDialog::OnOK
  359.  
  360. void wxDialog::OnCancel(
  361.   wxCommandEvent&                   rEvent
  362. )
  363. {
  364.     EndModal(wxID_CANCEL);
  365. } // end of wxDialog::OnCancel
  366.  
  367. void wxDialog::OnCloseWindow(
  368.   wxCloseEvent&                     rEvent
  369. )
  370. {
  371.     //
  372.     // We'll send a Cancel message by default,
  373.     // which may close the dialog.
  374.     // Check for looping if the Cancel event handler calls Close().
  375.     //
  376.     // Note that if a cancel button and handler aren't present in the dialog,
  377.     // nothing will happen when you close the dialog via the window manager, or
  378.     // via Close().
  379.     // We wouldn't want to destroy the dialog by default, since the dialog may have been
  380.     // created on the stack.
  381.     // However, this does mean that calling dialog->Close() won't delete the dialog
  382.     // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
  383.     // sure to destroy the dialog.
  384.     // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
  385.     //
  386.  
  387.     //
  388.     // Ugh???  This is not good but until I figure out a global list it'll have to do
  389.     //
  390.     static wxList closing;
  391.  
  392.     if ( closing.Member(this) )
  393.         return;
  394.  
  395.     closing.Append(this);
  396.  
  397.     wxCommandEvent                  vCancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
  398.  
  399.     vCancelEvent.SetEventObject( this );
  400.     GetEventHandler()->ProcessEvent(vCancelEvent); // This may close the dialog
  401.  
  402.     closing.DeleteObject(this);
  403. } // end of wxDialog::OnCloseWindow
  404.  
  405. void wxDialog::OnSysColourChanged(
  406.   wxSysColourChangedEvent&          rEvent
  407. )
  408. {
  409.     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
  410.     Refresh();
  411. } // end of wxDialog::OnSysColourChanged
  412.  
  413. MRESULT wxDialog::OS2WindowProc(
  414.   WXUINT                            uMessage
  415. , WXWPARAM                          wParam
  416. , WXLPARAM                          lParam
  417. )
  418. {
  419.     MRESULT                         rc = 0;
  420.     bool                            bProcessed = FALSE;
  421.  
  422.     switch (uMessage)
  423.     {
  424.         case WM_CLOSE:
  425.             //
  426.             // If we can't close, tell the system that we processed the
  427.             // message - otherwise it would close us
  428.             //
  429.             bProcessed = !Close();
  430.             break;
  431.     }
  432.  
  433.     if (!bProcessed)
  434.         rc = wxWindow::OS2WindowProc( uMessage
  435.                                      ,wParam
  436.                                      ,lParam
  437.                                     );
  438.     return rc;
  439. } // end of wxDialog::OS2WindowProc
  440.  
  441.