|
|
Comments and Discussions
|
|
 |
|

|
hello frndz
I create my application in vc++ now i have one query about SHBrowseForFolder.
I want to set the default path in that dialog that mean it can highlighted default foder insetead of my computer plz help me
|
|
|
|

|
Hi,
this works great on Win 7.
Thank you very much. This is what I need.
Best regards,
Drazen
|
|
|
|

|
Is the Borland C++ Version available for download? This is just what I am after.
|
|
|
|

|
These are the changes required:
// include Borlands stdafx.h
// Order change:
// #include "tchar.h" must precede #include "crtdbg.h"
// Include Added
// #include "shellapi.h" added
// Trace changed to following:
// #undef TRACE
// //#define TRACE __noop
// #define TRACE (void)
// Declaration added:
// #define BIF_NONEWFOLDERBUTTON 0x0200
|
|
|
|

|
Is there any way to shows the directory shortcuts when we use Win32 API (Browse for folder's (SHBrowseForFolder)).
Currently my application use BIF_NEWDIALOGSTYLE + BIF_RETURNONLYFSDIRS flags.
I tried using flag "BIF_BROWSEINCLUDEFILES" , but it no use as it shows both(files as well as folders). where I need to display/include shortcuts of a directory when user select browse for folder dialog.
|
|
|
|

|
I downloaded version 1.2 and noticed that you have commented out the option to create new folders in the call to SHGetSpecialFolderPath(). I tried setting that back to TRUE, but I am still unable to create a new folder from within the dialog. I am running VS2008 on XPsp3. It seems (from the notes on the web page) that you had it working at one time. Is that function no longer available?
Thanks for any insight you can offer, and anyway for posting this very useful piece of code.
|
|
|
|

|
The new folder button requires the BIF_NEWDIALOGSTYLE to work, but the new dialog style is not compatible with XBrowseForFolder.
|
|
|
|

|
I have a much cruder wrapper for ShBrowseForFolder() that I coded as a DLL years ago so I could call it from VBA code in MS Office applications (callback functions being something of a challenge in VBA). However both my implementation and yours seem to suffer from the same problem if you specify a UNC as the initial directory (in that it seems to be ignored).
So for instance if drive H: is mapped to "\\Server1\Users\Robert" and that folder contains a sub-folder called "Data" then although both of our implementations work correctly if the initial directory is specified as "H:\Data", neither work if the initial directory is specified as "\\Server1\Users\Robert\Data". In the second case I was expecting/hoping it would expand the "Microsoft Windows Network" pseudo object, through the domain object, down to the machine called "Server1" etc. One last thing to add to the confusion... if I use your test app to browse all the way through to the UNC noted above and click OK, further launches of the folder dialogue DO display with the correct initial folder.
Any ideas anyone?
Robert Cowan
|
|
|
|

|
What happens if you click on the "Standard SHBrowseForFolder" button?
|
|
|
|

|
Same thing Hans (i.e. it starts out at the top of the tree). I have since done some more experimentation with ShBrowseForFolder() in my own wrapper and discovered that it doesn't seem to like having a trailing backslash on the end of the initial directory if it is passed as a UNC but works OK with a trailing backslash if the initial directory is specified with a drive letter.
I'm not specifying the directory with a trailing backslash in your test application but I haven't checked your code to see whether you always append a trailing backslash if the value specified in your test application doesn't have one. Can you reproduce the problem I'm seeing?
Regards
Robert
Robert Cowan
|
|
|
|

|
Have you tried using BIF_NEWDIALOGSTYLE? This won't work with XBrowseForFolder, but I seem to recall that it will enable use of initial UNC.
|
|
|
|

|
No I haven't tried that but I'll do so sometime in the next week. Thanks for your help Hans.
Regards
Robert
Robert Cowan
|
|
|
|

|
Yes Hans I've confirmed this to be a problem with using the old style dialogue. I assume you specify the old style in your class because it means there are fewer objects to move around the screen when you resize it. Unfortunately the fact that it won't accept an initial directory if it's expressed as a UNC means I can't use it.
Never mind, it hasn't cost me anything and I've learnt something.
Regards
Robert
Robert Cowan
|
|
|
|

|
When the edit box option is selected and open the dialog, the focus always be on the edit box. I tried to modify the callback function but still failed. Any body knows how to set the focus on the tree control insteal of edit box?
Thanks in advance.
|
|
|
|

|
When I try to compile the XBrowseForFolderTest project I get:
Compiling resources...
T:\shbrowsefolder\XBrowseForFolderTest.rc(215) : fatal error RC1015: cannot open include file 'afxres.rc'.
Error executing rc.exe.
Where can I find afsres.rc?
Thanks,
Dave
|
|
|
|

|
It's your Visual Studio problem.
For Version 6 it located at
C:\Program Files\Microsoft Visual Studio\VC98\MFC\Include
by default.
For VS2005, it's at C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include folder and C:\Program Files\Microsoft Visual Studio 8\VC\ce\atlmfc\include if it's CE.
Check your Visual Studio installation.
---
Herbert Yu
Are you sure the speed of computer industry is proper? Are you sure the software you released is a bug free one?
|
|
|
|

|
Hi there,
Two tweaks for making BIF_NEWDIALOGSTYLE work with this excellent function:
First tweak:
In BFFM_INITIALIZED case-statement where the tree control's handle is retrieved. When new dialog style is used, the control's class name is "SHBrowserForFolder ShellNameSpace Control".
...
// find the folder tree and make dialog larger
HWND hwndTree = FindWindowEx( hwnd, NULL, _T("SysTreeView32"), NULL);
// Child handle is null...
if( !hwndTree )
{
// ... this usually means that BIF_NEWDIALOGSTYLE is enabled.
// Then the class name is as used in the code below.
hwndTree = FindWindowEx( hwnd, NULL, _T("SHBrowseForFolder ShellNameSpace Control"), NULL );
}
if( hwndTree )
... code continues as normal
Second tweak:
Again, in BFFM_INITIALIZED. This time where Cancel button's location is calculated. The regular -5 reposition for Cancel button isn't enough when the resize handle is visible in the dialog. Instead of using hardcoded values, I used the width of vertical scroll bar plus twice the width of dialog frame. This way I got Cancel button to line up pretty well with the scroll bar of the tree view control.
// move the Cancel button
CRect rectCancel(0, 0, 0, 0);
HWND hwndCancel = ::GetDlgItem(hwnd, IDCANCEL);
if (hwndCancel)
::GetWindowRect(hwndCancel, &rectCancel);
ScreenToClientX(hwnd, &rectCancel);
int h = rectCancel.Height();
int w = rectCancel.Width();
int scrollWidth = ::GetSystemMetrics( SM_CXVSCROLL );
int borderWidth = ::GetSystemMetrics( SM_CXDLGFRAME );
rectCancel.bottom = rectDlg.bottom - 5;
rectCancel.top = rectCancel.bottom - h;
rectCancel.right = rectDlg.right - ( scrollWidth + 2*borderWidth );
rectCancel.left = rectCancel.right - w;
--
jussi
|
|
|
|

|
Good! I like this
---
Herbert Yu
Are you sure the speed of computer industry is proper? Are you sure the software you released is a bug free one?
|
|
|
|

|
Thanks for posting this. It made me take a hard look at BIF_NEWDIALOGSTYLE, since I would love to make the dialog resizable. Unfortunately, I couldn't make this work without having various visual artifacts on the dialog - if you resize up & down you will see what I mean.
If anyone really needs a resizable folder selection dialog, I suggest taking a look at my XFolderDialog: http://www.codeproject.com/KB/dialog/XFolderDialog.aspx[^]
|
|
|
|

|
There is bug in this line to avoid a crash when compiled as unicode:-
It should be
_tcsncpy(lpszBuf, szBuffer, dwBufSize/sizeof(TCHAR) -1);
instead of
_tcsncpy(lpszBuf, szBuffer, dwBufSize -1);
Thanks,
Vipin
http://blogs.explorewindows.com
|
|
|
|

|
sdfkfggh wrote: There is bug in this line to avoid a crash when compiled as unicode:-
It should be
_tcsncpy(lpszBuf, szBuffer, dwBufSize/sizeof(TCHAR) -1);
instead of
_tcsncpy(lpszBuf, szBuffer, dwBufSize -1);
The code in the download is actually correct as is, since dwBufSize specifies the number of TCHARs, not the number of bytes.
|
|
|
|

|
Hi,
I want a dialog [like SHBrowseforFolder] for browsing for a folder with a check box for selecting/not selecting[or including/not including] subfolders.
Please anybody can tell me which funtion to use.:
palaksha@datafarminc.com
|
|
|
|
|

|
With a few minor changes I've compiled this with Borland C++ Builder.
Now my BrowseForFolder looks and works much better!
Thanks!
|
|
|
|

|
Have you got a copy of the Borland Version. Can you post the changes here, or the code.
|
|
|
|

|
Done it see posting above
|
|
|
|

|
Just what I was looking for. Worked first time!
Mark Manyen
|
|
|
|

|
I found that I can only change the initial foder that selected.
But I can't change the root folder. it is always the desktop folder.
Is there any way I can do this?
|
|
|
|

|
--> This modification is based on the previous code modification of SimpleDivX (see comment "Extra code to display custom title for the window." (14:49 2 Feb '05) below
XBrowseForFolder.h become
#ifndef XBROWSEFORFOLDER_H
#define XBROWSEFORFOLDER_H
BOOL XBrowseForFolder( HWND hWnd,
LPCTSTR lpszTitle,
LPCTSTR lpszInitialFolder,
LPTSTR lpszBuf,
DWORD dwBufSize,
int CSIDLRoot=0);
#endif //XBROWSEFORFOLDER_H
So ...
lpszTitle can be NULL (--> Default title)
lpszInitialFolder can be NULL (--> no initial folder if there is a valid CSIDLRoot, otherwize, initial folder == GetCurrentDirectory)
lpszBuf ( of size dwBufSize (must be >= MAX_PATH) will receive the choosen folder
CSIDLRoot --> default=0, otherwize, a valid value see for example http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/enums/csidl.asp
--> All values are not possible, it depends of the platform ...
If lpszInitialFolder is valid and is a subdirectory of CSIDLRoot, the dialog will show a tree, with CSIDLRoot as root and lpszInitialFolder selected
(Example: CSIDL_COMMON_PROGRAMS and ""c:\\Program Files\\Microsoft Visual Studio .NET\\Common7")
If lpszInitialFolder is not a subdirectory of CSIDLRoot, CSIDLRoot will be ignored ...
If lpszInitialFolder is NULL and CSIDLRoot is 0, lpszInitialFolder will be set to GetCurrentDirectory
XBrowseForFolder.cpp
Do the following changes ... (this changes included the previous change of SampleDivX --> apply these changes to the original file XBrowserForFolder.cpp
@@ -8,6 +8,10 @@
// wraps SHBrowseForFolder().
//
// History
+// Version 1.1 - 2005 december 05
+// - Modification by Jean-Michel Reghem (jeanmichel.reghem@gmail.com) and SampleDivX ()
+// * Possibility to add a custom title
+// * Possibility to add a different Root folder via its CSLID
// Version 1.0 - 2003 September 25
// - Initial public release
//
...
@@ -33,6 +37,12 @@
#include "io.h"
#include "XBrowseForFolder.h"
+typedef struct _FOLDER_PROPS
+{
+LPCTSTR lpszTitle;
+LPCTSTR lpszInitialFolder;
+} FOLDER_PROPS;
+
#pragma warning(disable: 4127) // conditional expression is constant (_ASSERTE)
...
@@ -93,6 +103,12 @@
{
case BFFM_INITIALIZED: // sent when the browse dialog box has finished initializing.
{
+ FOLDER_PROPS *fp = (FOLDER_PROPS*) lpData;
+
+ // Set Title
+ if((fp->lpszTitle)&&(fp->lpszTitle[0] != _T('\0')))
+ ::SetWindowText(hwnd, fp->lpszTitle);
+
// remove context help button from dialog caption
LONG lStyle = ::GetWindowLong(hwnd, GWL_STYLE);
lStyle &= ~DS_CONTEXTHELP;
...
@@ -102,7 +118,8 @@
::SetWindowLong(hwnd, GWL_EXSTYLE, lStyle);
// set initial directory
- ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
+ if((fp->lpszInitialFolder)&&(fp->lpszInitialFolder[0] != _T('\0')))
+ ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM) fp->lpszInitialFolder);
// find the folder tree and make dialog larger
HWND hwndTree = FindWindowEx(hwnd, NULL, _T("SysTreeView32"), NULL);
...
@@ -216,17 +233,18 @@
// lpszBuf.
//
// Parameters: hWnd - handle to the owner window for the dialog
+// lpszTitle - Dialog title
// lpszInitialFolder - initial folder in tree; if NULL, the initial
// folder will be the current directory.
// lpszBuf - buffer for the returned folder path
// dwBufSize - size of lpszBuf in TCHARs
+// CSIDLRoot - (optional) CSIDL of the Root tree directory
//
// Returns: BOOL - TRUE = success; FALSE = user hit Cancel
//
-BOOL XBrowseForFolder(HWND hWnd,
- LPCTSTR lpszInitialFolder,
- LPTSTR lpszBuf,
- DWORD dwBufSize)
+BOOL XBrowseForFolder(HWND hWnd,LPCTSTR lpszTitle,LPCTSTR lpszInitialFolder,
+ LPTSTR lpszBuf,DWORD dwBufSize,int CSIDLRoot /*=0*/)
+
{
...
@@ -238,7 +256,22 @@
TCHAR szInitialPath[MAX_PATH*2];
ZeroMemory(szInitialPath, sizeof(szInitialPath));
+ LPITEMIDLIST pidlRoot = NULL;
+ BROWSEINFO bi;
+ ZeroMemory(&bi, sizeof(BROWSEINFO));
+ IMalloc *pMalloc = NULL;
+ if (!(SUCCEEDED(SHGetMalloc(&pMalloc)) && pMalloc))
+ return FALSE;
+
+ //check if there is a special Root folder
+ if(CSIDLRoot!=0)
+ {
+ HRESULT tempret=SHGetSpecialFolderLocation(hWnd,CSIDLRoot,&pidlRoot);
+ if(tempret==S_OK)
+ bi.pidlRoot=pidlRoot;
+ }
+ //Initial folder???
if (lpszInitialFolder && lpszInitialFolder[0] != _T('\0'))
{
...
@@ -246,19 +279,29 @@
}
else
{
- // no initial folder, set to current directory
+
+ if(bi.pidlRoot==NULL)
+ {
+ // no initial folder, and no pidlRoot --> set to current directory
::GetCurrentDirectory(sizeof(szInitialPath)/sizeof(TCHAR)-2,
szInitialPath);
}
+ }
+
- BROWSEINFO bi;
- ZeroMemory(&bi, sizeof(BROWSEINFO));
bi.hwndOwner = hWnd;
+
+
bi.ulFlags = BIF_RETURNONLYFSDIRS; // do NOT use BIF_NEWDIALOGSTYLE,
// BIF_EDITBOX, or BIF_STATUSTEXT
bi.lpfn = BrowseCallbackProc;
- bi.lParam = (LPARAM) szInitialPath;
+
+ FOLDER_PROPS fp;
+ fp.lpszInitialFolder = szInitialPath;
+ fp.lpszTitle = lpszTitle;
+
+ bi.lParam = (LPARAM) &fp;
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
...
@@ -280,13 +323,17 @@
TRACE(_T("SHGetPathFromIDList failed\n"));
}
- IMalloc *pMalloc = NULL;
- if (SUCCEEDED(SHGetMalloc(&pMalloc)) && pMalloc)
- {
+
pMalloc->Free(pidl);
- pMalloc->Release();
+
+
}
+
+ if(pidlRoot)
+ {
+ pMalloc->Free(pidlRoot);
}
+ pMalloc->Release();
return bRet;
}
|
|
|
|

|
Can't you update the demo-download? Quite strenous to correct the code... Besides, your class is cool
|
|
|
|

|
We do need Hans Dietrich to update code in this article to put these updates in main download.
---
Herbert Yu
Are you sure the speed of computer industry is proper? Are you sure the software you released is a bug free one?
|
|
|
|

|
Hi Hans-Dietrich,
great work!
Is it possible to show that dialog modal?
Edit: have found it myself. Just give it an Owner-Window and it's modal.
Thanks,
Andreas
|
|
|
|

|
i've been looking for some time for a good wrapper class to solve the "directory-picker" problem that mfc does not seem to provide functionality for.
all-in-all, a great class!
thanks.
|
|
|
|

|
I modified the code to accept the following params :
BOOL bRet = XBrowseForFolder(m_hWnd,
strWhat, // Display title string
str_CurrentFolder, // start with current directory
szFolder,
sizeof(szFolder)/sizeof(TCHAR)-2);
See the cpp implementation : (the ... mean that the code was not changed.)
...
#include "XBrowseForFolder.h"
typedef struct _FOLDER_PROPS
{
LPCTSTR lpszTitle;
LPCTSTR lpszInitialFolder;
} FOLDER_PROPS;
...
BOOL XBrowseForFolder(HWND hWnd,
LPCTSTR lpszTitle,
LPCTSTR lpszInitialFolder,
LPTSTR lpszBuf,
DWORD dwBufSize)
{
...
FOLDER_PROPS fp;
fp.lpszInitialFolder = szInitialPath;
fp.lpszTitle = lpszTitle;
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(BROWSEINFO));
bi.lParam = (LPARAM) &fp;
...
}
static int CALLBACK BrowseCallbackProc(
...
case BFFM_INITIALIZED: // sent when the browse dialog box has finished initializing.
{
FOLDER_PROPS *fp = (FOLDER_PROPS*) lpData;
// Set Title
::SetWindowText(hwnd, fp->lpszTitle);
...
// set initial directory
::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM) fp->lpszInitialFolder);
...
}
|
|
|
|

|
good modification SimpleDivx
thanks
|
|
|
|

|
...for that extra space, and that is that there can optionally be a text box to type paths in, which I find quite helpful.
"Blessed are the peacemakers, for they shall be called sons of God." - Jesus
"You must be the change you wish to see in the world." - Mahatma Gandhi
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
XBrowseForFolder wraps the SHBrowseForFolder API, provides a way to specify an initial directory, and cleans up the SHBrowseForFolder dialog.
| Type | Article |
| Licence | CPOL |
| First Posted | 24 Sep 2003 |
| Views | 157,189 |
| Downloads | 3,746 |
| Bookmarked | 71 times |
|
|