From 6fa6d65956285379aa1d99b76d92db76aaecf11e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 21 Jan 2009 15:32:02 +0000 Subject: [PATCH] allocate size for the extra controls in the file dialog (#9679) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58270 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/filedlg.h | 7 ++++-- include/wx/msw/filedlg.h | 4 ++++ include/wx/msw/private.h | 13 ++++++++++- src/common/fldlgcmn.cpp | 12 ++++++++++ src/msw/filedlg.cpp | 50 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 82 insertions(+), 4 deletions(-) diff --git a/include/wx/filedlg.h b/include/wx/filedlg.h index 1f9b24715a..0ebe1f6a71 100644 --- a/include/wx/filedlg.h +++ b/include/wx/filedlg.h @@ -120,8 +120,6 @@ public: // create the window containing the extra controls we want to show in it typedef wxWindow *(*ExtraControlCreatorFunction)(wxWindow*); - // extra controls are currently supported in GTK and generic versions - // only currently virtual bool SupportsExtraControl() const { return false; } bool SetExtraControlCreator(ExtraControlCreatorFunction WXUNUSED(c)); @@ -155,6 +153,11 @@ protected: // returns true if control is created (if it already exists returns false) bool CreateExtraControl(); + // return true if SetExtraControlCreator() was called + bool HasExtraControlCreator() const + { return m_extraControlCreator != NULL; } + // get the size of the extra control by creating and deleting it + wxSize GetExtraControlSize(); private: ExtraControlCreatorFunction m_extraControlCreator; diff --git a/include/wx/msw/filedlg.h b/include/wx/msw/filedlg.h index 3cc4a52d55..0de223b292 100644 --- a/include/wx/msw/filedlg.h +++ b/include/wx/msw/filedlg.h @@ -32,6 +32,10 @@ public: virtual void SetPath(const wxString& path); virtual void GetPaths(wxArrayString& paths) const; virtual void GetFilenames(wxArrayString& files) const; +#ifndef __WXWINCE__ + virtual bool SupportsExtraControl() const { return true; } +#endif // __WXWINCE__ + void MSWOnInitDialogHook(WXHWND hwnd); virtual int ShowModal(); diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index 146d2d3a37..462bf91ec7 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -605,14 +605,25 @@ private: class GlobalPtr { public: + // default ctor, call Init() later + GlobalPtr() + { + m_hGlobal = NULL; + } + // allocates a block of given size - GlobalPtr(size_t size, unsigned flags = GMEM_MOVEABLE) + void Init(size_t size, unsigned flags = GMEM_MOVEABLE) { m_hGlobal = ::GlobalAlloc(flags, size); if ( !m_hGlobal ) wxLogLastError(_T("GlobalAlloc")); } + GlobalPtr(size_t size, unsigned flags = GMEM_MOVEABLE) + { + Init(size, flags); + } + ~GlobalPtr() { if ( m_hGlobal && ::GlobalFree(m_hGlobal) ) diff --git a/src/common/fldlgcmn.cpp b/src/common/fldlgcmn.cpp index 7c6e7fda2c..ab3908303e 100644 --- a/src/common/fldlgcmn.cpp +++ b/src/common/fldlgcmn.cpp @@ -168,6 +168,18 @@ bool wxFileDialogBase::CreateExtraControl() return true; } +wxSize wxFileDialogBase::GetExtraControlSize() +{ + if ( !m_extraControlCreator ) + return wxDefaultSize; + + // create the extra control in an empty dialog just to find its size: this + // is not terribly efficient but we do need to know the size before + // creating the native dialog and this seems to be the only way + wxDialog dlg(NULL, wxID_ANY, ""); + return (*m_extraControlCreator)(&dlg)->GetSize(); +} + //---------------------------------------------------------------------------- // wxFileDialog convenience functions //---------------------------------------------------------------------------- diff --git a/src/msw/filedlg.cpp b/src/msw/filedlg.cpp index 0cc25b19d6..7b5ac99870 100644 --- a/src/msw/filedlg.cpp +++ b/src/msw/filedlg.cpp @@ -86,6 +86,14 @@ wxFileDialogHookFunction(HWND hDlg, { switch ( iMsg ) { + case WM_INITDIALOG: + { + OPENFILENAME* ofn = reinterpret_cast(lParam); + reinterpret_cast(ofn->lCustData) + ->MSWOnInitDialogHook((WXHWND)hDlg); + } + break; + case WM_NOTIFY: { OFNOTIFY *pNotifyCode = reinterpret_cast(lParam); @@ -360,6 +368,15 @@ static bool ShowCommFileDialog(OPENFILENAME *of, long style) return true; } +void wxFileDialog::MSWOnInitDialogHook(WXHWND hwnd) +{ + SetHWND(hwnd); + + CreateExtraControl(); + + SetHWND(NULL); +} + int wxFileDialog::ShowModal() { HWND hWnd = 0; @@ -385,7 +402,7 @@ int wxFileDialog::ShowModal() in the upper left of the frame, it does not center automatically. */ - if (m_bMovedWindow) // we need these flags. + if (m_bMovedWindow || HasExtraControlCreator()) // we need these flags. { msw_flags |= OFN_EXPLORER|OFN_ENABLEHOOK; #ifndef __WXWINCE__ @@ -421,6 +438,37 @@ int wxFileDialog::ShowModal() of.lpstrFileTitle = titleBuffer; of.nMaxFileTitle = wxMAXFILE + 1 + wxMAXEXT; +#ifndef __WXWINCE__ + GlobalPtr hgbl; + if ( HasExtraControlCreator() ) + { + msw_flags |= OFN_ENABLETEMPLATEHANDLE; + + hgbl.Init(256, GMEM_ZEROINIT); + GlobalPtrLock hgblLock(hgbl); + LPDLGTEMPLATE lpdt = static_cast(hgblLock.Get()); + + // Define a dialog box. + + lpdt->style = DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS; + lpdt->cdit = 0; // Number of controls + lpdt->x = 0; + lpdt->y = 0; + + wxSize extra_size = GetExtraControlSize(); + // setting cx doesn't change the width of the dialog + lpdt->cx = extra_size.GetWidth(); + // Dividing by 2 gives expected height on WinXP and Wine. + // I don't know why (MW). + lpdt->cy = extra_size.GetHeight() / 2; + + // after the DLGTEMPLATE there are 3 additional WORDs for dialog menu, + // class and title, all three set to zeros. + + of.hInstance = (HINSTANCE)lpdt; + } +#endif // __WXWINCE__ + // Convert forward slashes to backslashes (file selector doesn't like // forward slashes) and also squeeze multiple consecutive slashes into one // as it doesn't like two backslashes in a row neither -- 2.45.2