// 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));
// 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;
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();
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) )
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
//----------------------------------------------------------------------------
{
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);
return true;
}
+void wxFileDialog::MSWOnInitDialogHook(WXHWND hwnd)
+{
+ SetHWND(hwnd);
+
+ CreateExtraControl();
+
+ SetHWND(NULL);
+}
+
int wxFileDialog::ShowModal()
{
HWND hWnd = 0;
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__
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