]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/dirdlg.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDirDialog
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "dirdlg.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
33 #if defined(__WIN95__) && !defined(__GNUWIN32_OLD__) && wxUSE_OLE
37 #include "wx/dialog.h"
38 #include "wx/dirdlg.h"
40 #include "wx/app.h" // for GetComCtl32Version()
43 #include "wx/msw/private.h"
45 #include <shlobj.h> // Win95 shell
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
52 #define MAX_PATH 4096 // be generous
55 #ifndef BIF_NEWDIALOGSTYLE
56 #define BIF_NEWDIALOGSTYLE 0x0040
59 #ifndef BIF_NONEWFOLDERBUTTON
60 #define BIF_NONEWFOLDERBUTTON 0x0200
64 #define BIF_EDITBOX 16
67 // ----------------------------------------------------------------------------
69 // ----------------------------------------------------------------------------
71 IMPLEMENT_CLASS(wxDirDialog
, wxDialog
)
73 // ----------------------------------------------------------------------------
74 // private functions prototypes
75 // ----------------------------------------------------------------------------
78 static void ItemListFree(LPITEMIDLIST pidl
);
80 // the callback proc for the dir dlg
81 static int CALLBACK
BrowseCallbackProc(HWND hwnd
, UINT uMsg
, LPARAM lp
,
85 // ============================================================================
87 // ============================================================================
89 // ----------------------------------------------------------------------------
91 // ----------------------------------------------------------------------------
93 wxDirDialog::wxDirDialog(wxWindow
*parent
,
94 const wxString
& message
,
95 const wxString
& defaultPath
,
97 const wxPoint
& WXUNUSED(pos
),
98 const wxSize
& WXUNUSED(size
),
99 const wxString
& WXUNUSED(name
))
105 SetPath(defaultPath
);
108 void wxDirDialog::SetPath(const wxString
& path
)
112 // SHBrowseForFolder doesn't like '/'s nor the trailing backslashes
113 m_path
.Replace(_T("/"), _T("\\"));
114 if ( !m_path
.empty() )
116 while ( *(m_path
.end() - 1) == _T('\\') )
118 m_path
.erase(m_path
.length() - 1);
121 // but the root drive should have a trailing slash (again, this is just
122 // the way the native dialog works)
123 if ( *(m_path
.end() - 1) == _T(':') )
130 int wxDirDialog::ShowModal()
132 wxWindow
*parent
= GetParent();
135 bi
.hwndOwner
= parent
? GetHwndOf(parent
) : NULL
;
137 bi
.pszDisplayName
= NULL
;
138 bi
.lpszTitle
= m_message
.c_str();
139 bi
.ulFlags
= BIF_RETURNONLYFSDIRS
| BIF_STATUSTEXT
;
140 bi
.lpfn
= BrowseCallbackProc
;
141 bi
.lParam
= (LPARAM
)m_path
.c_str(); // param for the callback
143 static const int verComCtl32
= wxApp::GetComCtl32Version();
145 // we always add the edit box (it doesn't hurt anybody, does it?) if it is
146 // supported by the system
147 if ( verComCtl32
>= 471 )
149 bi
.ulFlags
|= BIF_EDITBOX
;
152 // normally the commented out part should work -- but in practice
153 // BIF_NONEWFOLDERBUTTON doesn't have any effect (Win2k, comctl 5.81) so I
154 // have to disable it [for now]
156 // to have the "New Folder" button we must use the "new" dialog style which
157 // is also the only way to have a resizable dialog
159 // "new" style is only available in the version 5.0+ of comctl32.dll
160 const bool needNewDir
= HasFlag(wxDD_NEW_DIR_BUTTON
);
161 if ( (needNewDir
|| HasFlag(wxRESIZE_BORDER
)) && (verComCtl32
>= 500) )
163 bi
.ulFlags
|= BIF_NEWDIALOGSTYLE
;
165 // we'll get the "New Folder" button by default now, don't show it if
168 bi
.ulFlags
|= BIF_NONEWFOLDERBUTTON
;
171 if ( HasFlag(wxDD_NEW_DIR_BUTTON
) && verComCtl32
>= 500 )
173 // use the new style to make the "New Folder" button appear
174 bi
.ulFlags
|= BIF_NEWDIALOGSTYLE
;
178 // do show the dialog
179 LPITEMIDLIST pidl
= SHBrowseForFolder(&bi
);
183 ItemListFree((LPITEMIDLIST
)bi
.pidlRoot
);
188 // Cancel button pressed
192 BOOL ok
= SHGetPathFromIDList(pidl
, wxStringBuffer(m_path
, MAX_PATH
));
198 wxLogLastError(wxT("SHGetPathFromIDList"));
206 // ----------------------------------------------------------------------------
208 // ----------------------------------------------------------------------------
211 BrowseCallbackProc(HWND hwnd
, UINT uMsg
, LPARAM lp
, LPARAM pData
)
215 case BFFM_INITIALIZED
:
216 // sent immediately after initialisation and so we may set the
217 // initial selection here
219 // wParam = TRUE => lParam is a string and not a PIDL
220 SendMessage(hwnd
, BFFM_SETSELECTION
, TRUE
, pData
);
223 case BFFM_SELCHANGED
:
224 // note that this doesn't work with the new style UI (MSDN doesn't
225 // say anything about it, but the comments in shlobj.h do!) but we
226 // still execute this code in case it starts working again with the
227 // "new new UI" (or would it be "NewUIEx" according to tradition?)
229 // Set the status window to the currently selected path.
231 if ( SHGetPathFromIDList((LPITEMIDLIST
)lp
,
232 wxStringBuffer(strDir
, MAX_PATH
)) )
234 // NB: this shouldn't be necessary with the new style box
235 // (which is resizable), but as for now it doesn't work
236 // anyhow (see the comment above) no harm in doing it
238 // need to truncate or it displays incorrectly
239 static const size_t maxChars
= 37;
240 if ( strDir
.length() > maxChars
)
242 strDir
= strDir
.Right(maxChars
);
243 strDir
= wxString(wxT("...")) + strDir
;
246 SendMessage(hwnd
, BFFM_SETSTATUSTEXT
,
247 0, (LPARAM
)strDir
.c_str());
252 //case BFFM_VALIDATEFAILED: -- might be used to provide custom message
253 // if the user types in invalid dir name
260 static void ItemListFree(LPITEMIDLIST pidl
)
265 SHGetMalloc(&pMalloc
);
273 wxLogLastError(wxT("SHGetMalloc"));
279 #include "../generic/dirdlgg.cpp"
280 #endif // compiler/platform on which the code here compiles
282 #endif // wxUSE_DIRDLG