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
This commit is contained in:
Vadim Zeitlin 2009-01-21 15:32:02 +00:00
parent 14fd5e968b
commit 6fa6d65956
5 changed files with 82 additions and 4 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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) )

View File

@ -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
//----------------------------------------------------------------------------

View File

@ -86,6 +86,14 @@ wxFileDialogHookFunction(HWND hDlg,
{
switch ( iMsg )
{
case WM_INITDIALOG:
{
OPENFILENAME* ofn = reinterpret_cast<OPENFILENAME *>(lParam);
reinterpret_cast<wxFileDialog *>(ofn->lCustData)
->MSWOnInitDialogHook((WXHWND)hDlg);
}
break;
case WM_NOTIFY:
{
OFNOTIFY *pNotifyCode = reinterpret_cast<OFNOTIFY *>(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<LPDLGTEMPLATE>(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