]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/dialog.cpp
Initial revision
[wxWidgets.git] / src / msw / dialog.cpp
index e68427dbd2b0bd497b3d469e565514281ad0c5d0..2820cfaa33130eba61f7024af4c166fe46c7229a 100644 (file)
@@ -26,6 +26,8 @@
 #include "wx/frame.h"
 #include "wx/app.h"
 #include "wx/settings.h"
 #include "wx/frame.h"
 #include "wx/app.h"
 #include "wx/settings.h"
+#include "wx/intl.h"
+#include "wx/log.h"
 #endif
 
 #include "wx/msw/private.h"
 #endif
 
 #include "wx/msw/private.h"
 
 // Lists to keep track of windows, so we can disable/enable them
 // for modal dialogs
 
 // Lists to keep track of windows, so we can disable/enable them
 // for modal dialogs
-wxList wxModalDialogs;
-wxList wxModelessWindows;  // Frames and modeless dialogs
+wxWindowList wxModalDialogs;
+wxWindowList wxModelessWindows;  // Frames and modeless dialogs
 extern wxList WXDLLEXPORT wxPendingDelete;
 
 extern wxList WXDLLEXPORT wxPendingDelete;
 
-#if !USE_SHARED_LIBRARY
     IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxPanel)
 
     BEGIN_EVENT_TABLE(wxDialog, wxPanel)
     IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxPanel)
 
     BEGIN_EVENT_TABLE(wxDialog, wxPanel)
@@ -56,19 +57,8 @@ extern wxList WXDLLEXPORT wxPendingDelete;
         EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
         EVT_CLOSE(wxDialog::OnCloseWindow)
     END_EVENT_TABLE()
         EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
         EVT_CLOSE(wxDialog::OnCloseWindow)
     END_EVENT_TABLE()
-#endif
-
-bool wxDialog::MSWProcessMessage(WXMSG* pMsg)
-{
-  return (::IsDialogMessage((HWND) GetHWND(), (MSG*)pMsg) != 0);
-}
 
 
-bool wxDialog::MSWOnClose(void)
-{
-    return Close();
-}
-
-wxDialog::wxDialog(void)
+wxDialog::wxDialog()
 {
   m_isShown = FALSE;
   m_modalShowing = FALSE;
 {
   m_isShown = FALSE;
   m_modalShowing = FALSE;
@@ -83,9 +73,13 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id,
                       long style,
                       const wxString& name)
 {
                       long style,
                       const wxString& name)
 {
+#if wxUSE_TOOLTIPS
+    m_hwndToolTip = 0;
+#endif
+
     SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
     SetName(name);
     SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
     SetName(name);
-    
+
     if (!parent)
         wxTopLevelWindows.Append(this);
 
     if (!parent)
         wxTopLevelWindows.Append(this);
 
@@ -116,6 +110,9 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id,
     if (height < 0)
         height = 500;
 
     if (height < 0)
         height = 500;
 
+    // All dialogs should really have this style
+    m_windowStyle |= wxTAB_TRAVERSAL;
+
     WXDWORD extendedStyle = MakeExtendedStyle(m_windowStyle);
     if (m_windowStyle & wxSTAY_ON_TOP)
         extendedStyle |= WS_EX_TOPMOST;
     WXDWORD extendedStyle = MakeExtendedStyle(m_windowStyle);
     if (m_windowStyle & wxSTAY_ON_TOP)
         extendedStyle |= WS_EX_TOPMOST;
@@ -123,13 +120,13 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id,
     // Allows creation of dialogs with & without captions under MSWindows,
     // resizeable or not (but a resizeable dialog always has caption -
     // otherwise it would look too strange)
     // Allows creation of dialogs with & without captions under MSWindows,
     // resizeable or not (but a resizeable dialog always has caption -
     // otherwise it would look too strange)
-    const char *dlg;
-    if ( style & wxTHICK_FRAME )
-        dlg = "wxResizeableDialog";
+    const wxChar *dlg;
+    if ( style & wxRESIZE_BORDER )
+        dlg = wxT("wxResizeableDialog");
     else if ( style & wxCAPTION )
     else if ( style & wxCAPTION )
-        dlg = "wxCaptionDialog";
+        dlg = wxT("wxCaptionDialog");
     else
     else
-        dlg = "wxNoCaptionDialog";
+        dlg = wxT("wxNoCaptionDialog");
     MSWCreate(m_windowId, parent, NULL, this, NULL,
               x, y, width, height,
               0, // style is not used if we have dlg template
     MSWCreate(m_windowId, parent, NULL, this, NULL,
               x, y, width, height,
               0, // style is not used if we have dlg template
@@ -140,13 +137,13 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id,
 
     if ( !hwnd )
     {
 
     if ( !hwnd )
     {
-        wxLogError(_("Failed to created dialog."));
+        wxLogError(_("Failed to create dialog."));
 
         return FALSE;
     }
 
     SubclassWin(GetHWND());
 
         return FALSE;
     }
 
     SubclassWin(GetHWND());
-    
+
     SetWindowText(hwnd, title);
     SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
 
     SetWindowText(hwnd, title);
     SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
 
@@ -160,7 +157,7 @@ void wxDialog::SetModal(bool flag)
   else
     if ( m_windowStyle & wxDIALOG_MODAL )
         m_windowStyle -= wxDIALOG_MODAL ;
   else
     if ( m_windowStyle & wxDIALOG_MODAL )
         m_windowStyle -= wxDIALOG_MODAL ;
-  
+
   wxModelessWindows.DeleteObject(this);
   if (!flag)
     wxModelessWindows.Append(this);
   wxModelessWindows.DeleteObject(this);
   if (!flag)
     wxModelessWindows.Append(this);
@@ -172,9 +169,10 @@ wxDialog::~wxDialog()
 
   wxTopLevelWindows.DeleteObject(this);
 
 
   wxTopLevelWindows.DeleteObject(this);
 
+  Show(FALSE);
+
   if (m_modalShowing)
   {
   if (m_modalShowing)
   {
-    Show(FALSE);
     // For some reason, wxWindows can activate another task altogether
     // when a frame is destroyed after a modal dialog has been invoked.
     // Try to bring the parent to the top.
     // For some reason, wxWindows can activate another task altogether
     // when a frame is destroyed after a modal dialog has been invoked.
     // Try to bring the parent to the top.
@@ -186,14 +184,10 @@ wxDialog::~wxDialog()
   }
 
   m_modalShowing = FALSE;
   }
 
   m_modalShowing = FALSE;
-  if ( GetHWND() )
-    ShowWindow((HWND) GetHWND(), SW_HIDE);
 
   if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL )
     wxModelessWindows.DeleteObject(this);
 
 
   if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL )
     wxModelessWindows.DeleteObject(this);
 
-  UnsubclassWin();
-
   // If this is the last top-level window, exit.
   if (wxTheApp && (wxTopLevelWindows.Number() == 0))
   {
   // If this is the last top-level window, exit.
   if (wxTheApp && (wxTopLevelWindows.Number() == 0))
   {
@@ -213,13 +207,16 @@ void wxDialog::OnCharHook(wxKeyEvent& event)
   {
     if (event.m_keyCode == WXK_ESCAPE)
     {
   {
     if (event.m_keyCode == WXK_ESCAPE)
     {
-    // Behaviour changed in 2.0: we'll send a Cancel message
-    // to the dialog instead of Close.
-    wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
-    cancelEvent.SetEventObject( this );
-    GetEventHandler()->ProcessEvent(cancelEvent);
-
-    return;
+        // Behaviour changed in 2.0: we'll send a Cancel message
+        // to the dialog instead of Close.
+        wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
+        cancelEvent.SetEventObject( this );
+        GetEventHandler()->ProcessEvent(cancelEvent);
+
+        // ensure that there is another message for this window so the
+        // ShowModal loop will exit and won't get stuck in GetMessage().
+        ::PostMessage(GetHwnd(), WM_NULL, 0, 0);
+        return;
     }
   }
   // We didn't process this event.
     }
   }
   // We didn't process this event.
@@ -233,7 +230,7 @@ void wxDialog::OnPaint(wxPaintEvent& event)
 //  wxWindow::OnPaint(event);
 }
 
 //  wxWindow::OnPaint(event);
 }
 
-void wxDialog::Fit(void)
+void wxDialog::Fit()
 {
   wxWindow::Fit();
 }
 {
   wxWindow::Fit();
 }
@@ -243,12 +240,12 @@ void wxDialog::Iconize(bool WXUNUSED(iconize))
   // Windows dialog boxes can't be iconized
 }
 
   // Windows dialog boxes can't be iconized
 }
 
-bool wxDialog::IsIconized(void) const
+bool wxDialog::IsIconized() const
 {
   return FALSE;
 }
 
 {
   return FALSE;
 }
 
-void wxDialog::SetClientSize(int width, int height)
+void wxDialog::DoSetClientSize(int width, int height)
 {
   HWND hWnd = (HWND) GetHWND();
   RECT rect;
 {
   HWND hWnd = (HWND) GetHWND();
   RECT rect;
@@ -280,11 +277,16 @@ void wxDialog::GetPosition(int *x, int *y) const
   *y = rect.top;
 }
 
   *y = rect.top;
 }
 
-bool wxDialog::IsShown(void) const
+bool wxDialog::IsShown() const
 {
   return m_isShown;
 }
 
 {
   return m_isShown;
 }
 
+bool wxDialog::IsModal() const
+{
+    return wxModalDialogs.Find((wxDialog *)this) != 0; // const_cast
+}
+
 bool wxDialog::Show(bool show)
 {
   m_isShown = show;
 bool wxDialog::Show(bool show)
 {
   m_isShown = show;
@@ -297,13 +299,13 @@ bool wxDialog::Show(bool show)
 #if WXGARBAGE_COLLECTION_ON /* MATTHEW: GC */
   if (!modal) {
     if (show) {
 #if WXGARBAGE_COLLECTION_ON /* MATTHEW: GC */
   if (!modal) {
     if (show) {
-      if (!wxModelessWindows.Member(this))
-  wxModelessWindows.Append(this);
+      if (!wxModelessWindows.Find(this))
+        wxModelessWindows.Append(this);
     } else
       wxModelessWindows.DeleteObject(this);
   }
   if (show) {
     } else
       wxModelessWindows.DeleteObject(this);
   }
   if (show) {
-    if (!wxTopLevelWindows.Member(this))
+    if (!wxTopLevelWindows.Find(this))
       wxTopLevelWindows.Append(this);
   } else
     wxTopLevelWindows.DeleteObject(this);
       wxTopLevelWindows.Append(this);
   } else
     wxTopLevelWindows.DeleteObject(this);
@@ -313,14 +315,20 @@ bool wxDialog::Show(bool show)
   {
     if (show)
     {
   {
     if (show)
     {
-      m_hwndOldFocus = (WXHWND)::GetFocus();
+      // find the top level window which had focus before - we will restore
+      // focus to it later
+      m_hwndOldFocus = 0;
+      for ( HWND hwnd = ::GetFocus(); hwnd; hwnd = ::GetParent(hwnd) )
+      {
+        m_hwndOldFocus = (WXHWND)hwnd;
+      }
 
       if (m_modalShowing)
       {
         BringWindowToTop((HWND) GetHWND());
         return TRUE;
       }
 
       if (m_modalShowing)
       {
         BringWindowToTop((HWND) GetHWND());
         return TRUE;
       }
-      
+
       m_modalShowing = TRUE;
       wxNode *node = wxModalDialogs.First();
       while (node)
       m_modalShowing = TRUE;
       wxNode *node = wxModalDialogs.First();
       while (node)
@@ -353,20 +361,22 @@ bool wxDialog::Show(bool show)
       EnableWindow((HWND) GetHWND(), TRUE);
       BringWindowToTop((HWND) GetHWND());
 
       EnableWindow((HWND) GetHWND(), TRUE);
       BringWindowToTop((HWND) GetHWND());
 
-      if (!wxModalDialogs.Member(this))
+      if ( !wxModalDialogs.Find(this) )
         wxModalDialogs.Append(this);
 
       MSG msg;
       // Must test whether this dialog still exists: we may not process
       // a message before the deletion.
         wxModalDialogs.Append(this);
 
       MSG msg;
       // Must test whether this dialog still exists: we may not process
       // a message before the deletion.
-      while (wxModalDialogs.Member(this) && m_modalShowing && GetMessage(&msg, NULL, 0, 0))
+      while (wxModalDialogs.Find(this) && m_modalShowing && GetMessage(&msg, NULL, 0, 0))
       {
       {
-        if (m_acceleratorTable.Ok() &&
-          ::TranslateAccelerator((HWND) GetHWND(), (HACCEL) m_acceleratorTable.GetHACCEL(), &msg))
+        if ( m_acceleratorTable.Ok() &&
+             ::TranslateAccelerator((HWND)GetHWND(),
+                                     (HACCEL)m_acceleratorTable.GetHACCEL(),
+                                     &msg) )
         {
             // Have processed the message
         }
         {
             // Have processed the message
         }
-        else if (!IsDialogMessage((HWND) GetHWND(), &msg))
+        else if ( !wxTheApp->ProcessMessage((WXMSG *)&msg) )
         {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
         {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
@@ -390,7 +400,7 @@ bool wxDialog::Show(bool show)
       node=disabledWindows.First();
       while(node) {
         wxWindow* win = (wxWindow*) node->Data();
       node=disabledWindows.First();
       while(node) {
         wxWindow* win = (wxWindow*) node->Data();
-        if (wxModalDialogs.Member(win) || wxModelessWindows.Member(win))
+        if (wxModalDialogs.Find(win) || wxModelessWindows.Find(win))
         {
           HWND hWnd = (HWND) win->GetHWND();
           if (::IsWindow(hWnd))
         {
           HWND hWnd = (HWND) win->GetHWND();
           if (::IsWindow(hWnd))
@@ -411,9 +421,13 @@ bool wxDialog::Show(bool show)
       // enable it, else we enable all modeless windows
       if (last)
       {
       // enable it, else we enable all modeless windows
       if (last)
       {
+          // VZ: I don't understand what this is supposed to do, so I'll leave
+          //     it out for now and look for horrible consequences
         wxDialog *box = (wxDialog *)last->Data();
         HWND hwnd = (HWND) box->GetHWND();
         wxDialog *box = (wxDialog *)last->Data();
         HWND hwnd = (HWND) box->GetHWND();
-        if (box->m_winEnabled)
+#if 0
+        if (box->IsUserEnabled())
+#endif // 0
           EnableWindow(hwnd, TRUE);
         BringWindowToTop(hwnd);
       }
           EnableWindow(hwnd, TRUE);
         BringWindowToTop(hwnd);
       }
@@ -425,7 +439,9 @@ bool wxDialog::Show(bool show)
           wxWindow *win = (wxWindow *)node->Data();
           HWND hwnd = (HWND) win->GetHWND();
           // Only enable again if not user-disabled.
           wxWindow *win = (wxWindow *)node->Data();
           HWND hwnd = (HWND) win->GetHWND();
           // Only enable again if not user-disabled.
+#if 0
           if (win->IsUserEnabled())
           if (win->IsUserEnabled())
+#endif // 0
             EnableWindow(hwnd, TRUE);
           node = node->Next();
         }
             EnableWindow(hwnd, TRUE);
           node = node->Next();
         }
@@ -459,7 +475,9 @@ bool wxDialog::Show(bool show)
         if (hWndParent)
           ::BringWindowToTop(hWndParent);
       }
         if (hWndParent)
           ::BringWindowToTop(hWndParent);
       }
-      ShowWindow((HWND) GetHWND(), SW_HIDE);
+
+      if ( m_hWnd )
+        ShowWindow((HWND) GetHWND(), SW_HIDE);
     }
   }
   return TRUE;
     }
   }
   return TRUE;
@@ -467,10 +485,10 @@ bool wxDialog::Show(bool show)
 
 void wxDialog::SetTitle(const wxString& title)
 {
 
 void wxDialog::SetTitle(const wxString& title)
 {
-  SetWindowText((HWND) GetHWND(), (const char *)title);
+  SetWindowText((HWND) GetHWND(), title.c_str());
 }
 
 }
 
-wxString wxDialog::GetTitle(void) const
+wxString wxDialog::GetTitle() const
 {
   GetWindowText((HWND) GetHWND(), wxBuffer, 1000);
   return wxString(wxBuffer);
 {
   GetWindowText((HWND) GetHWND(), wxBuffer, 1000);
   return wxString(wxBuffer);
@@ -506,7 +524,7 @@ void wxDialog::Centre(int direction)
 }
 
 // Replacement for Show(TRUE) for modal dialogs - returns return code
 }
 
 // Replacement for Show(TRUE) for modal dialogs - returns return code
-int wxDialog::ShowModal(void)
+int wxDialog::ShowModal()
 {
   m_windowStyle |= wxDIALOG_MODAL;
   Show(TRUE);
 {
   m_windowStyle |= wxDIALOG_MODAL;
   Show(TRUE);
@@ -560,7 +578,7 @@ void wxDialog::OnCancel(wxCommandEvent& event)
     else
     {
         SetReturnCode(wxID_CANCEL);
     else
     {
         SetReturnCode(wxID_CANCEL);
-    this->Show(FALSE);
+        this->Show(FALSE);
     }
 }
 
     }
 }
 
@@ -581,12 +599,12 @@ void wxDialog::OnCloseWindow(wxCloseEvent& event)
     // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
 
     static wxList closing;
     // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
 
     static wxList closing;
-    
+
     if ( closing.Member(this) )
         return;
     if ( closing.Member(this) )
         return;
-    
+
     closing.Append(this);
     closing.Append(this);
-    
+
     wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
     cancelEvent.SetEventObject( this );
     GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
     wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
     cancelEvent.SetEventObject( this );
     GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
@@ -595,7 +613,7 @@ void wxDialog::OnCloseWindow(wxCloseEvent& event)
 }
 
 // Destroy the window (delayed, if a managed window)
 }
 
 // Destroy the window (delayed, if a managed window)
-bool wxDialog::Destroy(void)
+bool wxDialog::Destroy()
 {
   if (!wxPendingDelete.Member(this))
     wxPendingDelete.Append(this);
 {
   if (!wxPendingDelete.Member(this))
     wxPendingDelete.Append(this);
@@ -606,7 +624,8 @@ void wxDialog::OnSize(wxSizeEvent& WXUNUSED(event))
 {
   // if we're using constraints - do use them
   #if wxUSE_CONSTRAINTS
 {
   // if we're using constraints - do use them
   #if wxUSE_CONSTRAINTS
-    if ( GetAutoLayout() ) {
+    if ( GetAutoLayout() )
+    {
       Layout();
     }
   #endif
       Layout();
     }
   #endif
@@ -620,4 +639,28 @@ void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& event)
   SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
   Refresh();
 #endif
   SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
   Refresh();
 #endif
-}
\ No newline at end of file
+}
+
+// ---------------------------------------------------------------------------
+// dialog window proc
+// ---------------------------------------------------------------------------
+
+long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+{
+    long rc = 0;
+    bool processed = FALSE;
+
+    switch ( message )
+    {
+        case WM_CLOSE:
+            // if we can't close, tell the system that we processed the
+            // message - otherwise it would close us
+            processed = !Close();
+            break;
+    }
+
+    if ( !processed )
+        rc = wxWindow::MSWWindowProc(message, wParam, lParam);
+
+    return rc;
+}