]> git.saurik.com Git - wxWidgets.git/commitdiff
fixed bugs with moving/centering the file dialog (replaces patch 1825170)
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 9 Nov 2007 20:02:47 +0000 (20:02 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 9 Nov 2007 20:02:47 +0000 (20:02 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49771 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/msw/filedlg.h
src/msw/filedlg.cpp

index 0235372502793a91bc93f295c06138378aeba61e..5650f0df43b59924995d88353acc80185146a551 100644 (file)
@@ -258,6 +258,7 @@ wxMSW:
 - Return the restored window size from GetSize() when window is minimized.
 - wxCheckListBox now looks more native, especially under XP (Marcin Malich).
 - Allow tooltips longer than 64 (up to 128) characters in wxTaskBarIcon
+- Fix centering wxFileDialog
 
 wxX11:
 
index 169cfb12a53a5edf9a80c5f9808bc36ff0eda350..482200ad1ab90466d724c60d48d1b58034b0b6b3 100644 (file)
@@ -35,17 +35,28 @@ public:
 
     virtual int ShowModal();
 
+    // wxMSW-specific implementation from now on
+    // -----------------------------------------
+
+    // called from the hook procedure on CDN_INITDONE reception
+    virtual void MSWOnInitDone(WXHWND hDlg);
+
 protected:
 
 #if !(defined(__SMARTPHONE__) && defined(__WXWINCE__))
     virtual void DoMoveWindow(int x, int y, int width, int height);
+    virtual void DoCentre(int dir);
     virtual void DoGetSize( int *width, int *height ) const;
     virtual void DoGetPosition( int *x, int *y ) const;
 #endif // !(__SMARTPHONE__ && __WXWINCE__)
 
 private:
     wxArrayString m_fileNames;
+
+    // remember if our SetPosition() or Centre() (which requires special
+    // treatment) was called
     bool m_bMovedWindow;
+    int m_centreDir;        // nothing to do if 0
 
     DECLARE_DYNAMIC_CLASS(wxFileDialog)
     DECLARE_NO_COPY_CLASS(wxFileDialog)
index 175b241358a330f141e98f63b6229ecdeb1b8763..7aea0ff0069caf0e332d1029425e23a48bac412c 100644 (file)
 // globals
 // ----------------------------------------------------------------------------
 
-// standard dialog size
+// standard dialog size for the old Windows systems where the dialog wasn't
+// resizeable
 static wxRect gs_rectDialog(0, 0, 428, 266);
 
+// we have no way to retrieve the dialog size before it is shown so calling
+// Centre() before ShowModal() doesn't work correctly (and we can't do it
+// after), hence we set a special flag and recenter the dialog when it's about
+// to be shown
+static bool gs_centerDialog = false;
+
 // ============================================================================
 // implementation
 // ============================================================================
@@ -90,16 +97,9 @@ wxFileDialogHookFunction(HWND      hDlg,
                 OFNOTIFY *pNotifyCode = wx_reinterpret_cast(OFNOTIFY *, lParam);
                 if ( pNotifyCode->hdr.code == CDN_INITDONE )
                 {
-                    // note that we need to move the parent window: hDlg is a
-                    // child of it when OFN_EXPLORER is used
-                    ::SetWindowPos
-                      (
-                        ::GetParent(hDlg),
-                        HWND_TOP,
-                        gs_rectDialog.x, gs_rectDialog.y,
-                        0, 0,
-                        SWP_NOZORDER | SWP_NOSIZE
-                      );
+                    wx_reinterpret_cast(wxFileDialog *,
+                                        pNotifyCode->lpOFN->lCustData)
+                        ->MSWOnInitDone((WXHWND)hDlg);
                  }
             }
             break;
@@ -138,14 +138,15 @@ wxFileDialog::wxFileDialog(wxWindow *parent,
     // NB: all style checks are done by wxFileDialogBase::Create
 
     m_bMovedWindow = false;
+    m_centreDir = 0;
 
     // Must set to zero, otherwise the wx routines won't size the window
     // the second time you call the file dialog, because it thinks it is
     // already at the requested size.. (when centering)
     gs_rectDialog.x =
     gs_rectDialog.y = 0;
-
 }
+
 void wxFileDialog::GetPaths(wxArrayString& paths) const
 {
     paths.Empty();
@@ -185,7 +186,6 @@ void wxFileDialog::DoGetPosition(int *x, int *y) const
         *y = gs_rectDialog.y;
 }
 
-
 void wxFileDialog::DoGetSize(int *width, int *height) const
 {
     if ( width )
@@ -196,13 +196,64 @@ void wxFileDialog::DoGetSize(int *width, int *height) const
 
 void wxFileDialog::DoMoveWindow(int x, int y, int WXUNUSED(w), int WXUNUSED(h))
 {
-    m_bMovedWindow = true;
-
     gs_rectDialog.x = x;
     gs_rectDialog.y = y;
 
-    // size of the dialog can't be changed because the controls are not laid
-    // out correctly then
+    // our HWND is only set when we're called from MSWOnInitDone(), test if
+    // this is the case
+    HWND hwnd = GetHwnd();
+    if ( hwnd )
+    {
+        // size of the dialog can't be changed because the controls are not
+        // laid out correctly then
+       ::SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+    }
+    else // just remember that we were requested to move the window
+    {
+        m_bMovedWindow = true;
+
+        // if Centre() had been called before, it shouldn't be taken into
+        // account now
+        m_centreDir = 0;
+    }
+}
+
+void wxFileDialog::DoCentre(int dir)
+{
+    m_centreDir = dir;
+    m_bMovedWindow = true;
+
+    // it's unnecessary to do anything else at this stage as we'll redo it in
+    // MSWOnInitDone() anyhow
+}
+
+void wxFileDialog::MSWOnInitDone(WXHWND hDlg)
+{
+    // note the the dialog is the parent window: hDlg is a child of it when
+    // OFN_EXPLORER is used
+    HWND hFileDlg = ::GetParent((HWND)hDlg);
+
+    // set HWND so that our DoMoveWindow() works correctly
+    SetHWND((WXHWND)hFileDlg);
+
+    if ( m_centreDir )
+    {
+        // now we have the real dialog size, remember it
+        RECT rect;
+        GetWindowRect(hFileDlg, &rect);
+        gs_rectDialog = wxRectFromRECT(rect);
+
+        // and position the window correctly: notice that we must use the base
+        // class version as our own doesn't do anything except setting flags
+        wxFileDialogBase::DoCentre(m_centreDir);
+    }
+    else // need to just move it to the correct place
+    {
+        SetPosition(gs_rectDialog.GetPosition());
+    }
+
+    // we shouldn't destroy this HWND
+    SetHWND(NULL);
 }
 
 // helper used below in ShowModal(): style is used to determine whether to show
@@ -367,6 +418,7 @@ int wxFileDialog::ShowModal()
 
     of.Flags             = msw_flags;
     of.lpfnHook          = wxFileDialogHookFunction;
+    of.lCustData         = (LPARAM)this;
 
     wxArrayString wildDescriptions, wildFilters;