]>
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 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "dirdlg.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  31 #if wxUSE_DIRDLG && (!defined(__WXWINCE__) || defined(__HANDHELDPC__)) 
  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" 
  44 #include "wx/msw/wrapshl.h" 
  46 // ---------------------------------------------------------------------------- 
  48 // ---------------------------------------------------------------------------- 
  50 #ifndef BIF_NEWDIALOGSTYLE 
  51     #define BIF_NEWDIALOGSTYLE 0x0040 
  54 #ifndef BIF_NONEWFOLDERBUTTON 
  55     #define BIF_NONEWFOLDERBUTTON  0x0200 
  59     #define BIF_EDITBOX 16 
  62 // ---------------------------------------------------------------------------- 
  64 // ---------------------------------------------------------------------------- 
  66 IMPLEMENT_CLASS(wxDirDialog
, wxDialog
) 
  68 // ---------------------------------------------------------------------------- 
  69 // private functions prototypes 
  70 // ---------------------------------------------------------------------------- 
  72 // the callback proc for the dir dlg 
  73 static int CALLBACK 
BrowseCallbackProc(HWND hwnd
, UINT uMsg
, LPARAM lp
, 
  77 // ============================================================================ 
  79 // ============================================================================ 
  81 // ---------------------------------------------------------------------------- 
  83 // ---------------------------------------------------------------------------- 
  85 wxDirDialog::wxDirDialog(wxWindow 
*parent
, 
  86                          const wxString
& message
, 
  87                          const wxString
& defaultPath
, 
  89                          const wxPoint
& WXUNUSED(pos
), 
  90                          const wxSize
& WXUNUSED(size
), 
  91                          const wxString
& WXUNUSED(name
)) 
 100 void wxDirDialog::SetPath(const wxString
& path
) 
 104     // SHBrowseForFolder doesn't like '/'s nor the trailing backslashes 
 105     m_path
.Replace(_T("/"), _T("\\")); 
 106     if ( !m_path
.empty() ) 
 108         while ( *(m_path
.end() - 1) == _T('\\') ) 
 110             m_path
.erase(m_path
.length() - 1); 
 113         // but the root drive should have a trailing slash (again, this is just 
 114         // the way the native dialog works) 
 115         if ( *(m_path
.end() - 1) == _T(':') ) 
 122 int wxDirDialog::ShowModal() 
 124     wxWindow 
*parent 
= GetParent(); 
 127     bi
.hwndOwner      
= parent 
? GetHwndOf(parent
) : NULL
; 
 129     bi
.pszDisplayName 
= NULL
; 
 130     // Please don't change this without checking it compiles 
 132 #if defined(__POCKETPC__) || defined(__SMARTPHONE__) 
 133     bi
.lpszTitle      
= m_message
.mb_str(); 
 135     bi
.lpszTitle      
= m_message
.c_str(); 
 137     bi
.ulFlags        
= BIF_RETURNONLYFSDIRS 
| BIF_STATUSTEXT
; 
 138     bi
.lpfn           
= BrowseCallbackProc
; 
 139     bi
.lParam         
= (LPARAM
)m_path
.c_str();    // param for the callback 
 141     static const int verComCtl32 
= wxApp::GetComCtl32Version(); 
 143     // we always add the edit box (it doesn't hurt anybody, does it?) if it is 
 144     // supported by the system 
 145     if ( verComCtl32 
>= 471 ) 
 147         bi
.ulFlags 
|= BIF_EDITBOX
; 
 150     // to have the "New Folder" button we must use the "new" dialog style which 
 151     // is also the only way to have a resizable dialog 
 153     // "new" style is only available in the version 5.0+ of comctl32.dll 
 154     const bool needNewDir 
= HasFlag(wxDD_NEW_DIR_BUTTON
); 
 155     if ( (needNewDir 
|| HasFlag(wxRESIZE_BORDER
)) && (verComCtl32 
>= 500) ) 
 159             bi
.ulFlags 
|= BIF_NEWDIALOGSTYLE
; 
 163             // Versions < 600 doesn't support BIF_NONEWFOLDERBUTTON 
 164             // The only way to get rid of the Make New Folder button is use 
 165             // the old dialog style which doesn't have the button thus we 
 166             // simply don't set the New Dialog Style for such comctl versions. 
 167             if (verComCtl32 
>= 600) 
 169                 bi
.ulFlags 
|= BIF_NEWDIALOGSTYLE
; 
 170                 bi
.ulFlags 
|= BIF_NONEWFOLDERBUTTON
; 
 175     // do show the dialog 
 176     wxItemIdList 
pidl(SHBrowseForFolder(&bi
)); 
 178     wxItemIdList::Free((LPITEMIDLIST
)bi
.pidlRoot
); 
 182         // Cancel button pressed 
 186     m_path 
= pidl
.GetPath(); 
 188     return m_path
.empty() ? wxID_CANCEL 
: wxID_OK
; 
 191 // ---------------------------------------------------------------------------- 
 193 // ---------------------------------------------------------------------------- 
 196 BrowseCallbackProc(HWND hwnd
, UINT uMsg
, LPARAM lp
, LPARAM pData
) 
 200 #ifdef BFFM_SETSELECTION 
 201         case BFFM_INITIALIZED
: 
 202             // sent immediately after initialisation and so we may set the 
 203             // initial selection here 
 205             // wParam = TRUE => lParam is a string and not a PIDL 
 206             ::SendMessage(hwnd
, BFFM_SETSELECTION
, TRUE
, pData
); 
 208 #endif // BFFM_SETSELECTION 
 211         case BFFM_SELCHANGED
: 
 212             // note that this doesn't work with the new style UI (MSDN doesn't 
 213             // say anything about it, but the comments in shlobj.h do!) but we 
 214             // still execute this code in case it starts working again with the 
 215             // "new new UI" (or would it be "NewUIEx" according to tradition?) 
 217                 // Set the status window to the currently selected path. 
 219                 if ( SHGetPathFromIDList((LPITEMIDLIST
)lp
, 
 220                                          wxStringBuffer(strDir
, MAX_PATH
)) ) 
 222                     // NB: this shouldn't be necessary with the new style box 
 223                     //     (which is resizable), but as for now it doesn't work 
 224                     //     anyhow (see the comment above) no harm in doing it 
 226                     // need to truncate or it displays incorrectly 
 227                     static const size_t maxChars 
= 37; 
 228                     if ( strDir
.length() > maxChars 
) 
 230                         strDir 
= strDir
.Right(maxChars
); 
 231                         strDir 
= wxString(wxT("...")) + strDir
; 
 234                     SendMessage(hwnd
, BFFM_SETSTATUSTEXT
, 
 235                                 0, (LPARAM
)strDir
.c_str()); 
 240         //case BFFM_VALIDATEFAILED: -- might be used to provide custom message 
 241         //                             if the user types in invalid dir name 
 249     #include "../generic/dirdlgg.cpp" 
 250 #endif // compiler/platform on which the code here compiles 
 252 #endif // wxUSE_DIRDLG && !(__SMARTPHONE__ && __WXWINCE__)