From 0a7b022960a68e1d9cf2561375e8c0376e07e93b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 9 Nov 2007 20:02:47 +0000 Subject: [PATCH] fixed bugs with moving/centering the file dialog (replaces patch 1825170) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49771 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/msw/filedlg.h | 11 +++++ src/msw/filedlg.cpp | 86 ++++++++++++++++++++++++++++++++-------- 3 files changed, 81 insertions(+), 17 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 0235372502..5650f0df43 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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: diff --git a/include/wx/msw/filedlg.h b/include/wx/msw/filedlg.h index 169cfb12a5..482200ad1a 100644 --- a/include/wx/msw/filedlg.h +++ b/include/wx/msw/filedlg.h @@ -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) diff --git a/src/msw/filedlg.cpp b/src/msw/filedlg.cpp index 175b241358..7aea0ff006 100644 --- a/src/msw/filedlg.cpp +++ b/src/msw/filedlg.cpp @@ -64,9 +64,16 @@ // 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; -- 2.45.2