Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Using SHBrowseForFolder

dboggs
New Contributor I
2,312 Views

Based on the sample program supplied by Intel, I learned how to use the API function GetOpenFilename and GetSaveFilename and wrote a wrapper around them to enable simple use in a Quickwin application. Now, I would like to use SHBrowseForFolder. But there is no sample program that demonstrates this, and I find the Windows instructions for using it to be daunting in comparison. Does anybody have an example of use, ideally illustrating a wrapper that could be used for simple Quickwin calling? In other words, so that non windows programmers can use it?

0 Kudos
13 Replies
SergeyKostrov
Valued Contributor II
2,312 Views
I use that function to select a CD-ROM drive during processing and here is a C/C++ example: ... bool bOk = false; BROWSEINFO m_bi = { 0x0 }; ITEMIDLIST *m_pIdl = RTNULL; RTUINT uiDriveType = DRIVE_UNKNOWN; while( true ) { if( pszPathSelected == NULL ) break; if( pszPathSelected[0] == 0x0 ) break; m_bi.hwndOwner = ::GetActiveWindow(); m_bi.pszDisplayName = pszPathSelected; m_bi.lpszTitle = _T(">> Select a CDROM Drive <<"); m_bi.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; m_pIdl = SHBrowseForFolder( &m_bi ); if( m_pIdl == NULL ) break; if( SHGetPathFromIDList( m_pIdl, pszPathSelected ) == FALSE ) break; uiDriveType = ::GetDriveType( pszPathSelected ); if( uiDriveType != DRIVE_CDROM ) break; bOk = true; break; } if( m_pIdl != NULL ) { CoTaskMemFree( m_pIdl ); m_pIdl = NULL; } ...
0 Kudos
SergeyKostrov
Valued Contributor II
2,312 Views
That is strange and I can not edit my previous post! Here is an updated example: ... bool bOk = false; BROWSEINFO m_bi = { 0x0 }; ITEMIDLIST *m_pIdl = NULL; unsigned int uiDriveType = DRIVE_UNKNOWN; while( true ) { if( pszPathSelected == NULL ) break; if( pszPathSelected[0] == 0x0 ) break; m_bi.hwndOwner = ::GetActiveWindow(); m_bi.pszDisplayName = pszPathSelected; m_bi.lpszTitle = _T("** Select a CDROM Drive **"); m_bi.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; m_pIdl = SHBrowseForFolder( &m_bi ); if( m_pIdl == NULL ) break; if( SHGetPathFromIDList( m_pIdl, pszPathSelected ) == FALSE ) break; uiDriveType = ::GetDriveType( pszPathSelected ); if( uiDriveType != DRIVE_CDROM ) break; bOk = true; break; } if( m_pIdl != NULL ) { CoTaskMemFree( m_pIdl ); m_pIdl = NULL; } ...
0 Kudos
dboggs
New Contributor I
2,312 Views

Thanks Sergey. This helps, but not enough (I need a lot). What module do I USE to get access to the function, and how do I declare the structure m_bi and the return status m_pldl? (I'm not good at translating C to Fortran.)

0 Kudos
SergeyKostrov
Valued Contributor II
2,312 Views
Application of the function should be similar to what you've already done with GetOpenFilename function. >>... What module do I USE to get access to the function... Header: Shlobj.h Library: Shell32.lib Binary DLL: Shell32.dll
0 Kudos
Les_Neilson
Valued Contributor II
2,312 Views

You may be able to find what you need here http://software.intel.com/en-us/forums/topic/275039
This was a thread posted back in 2012
(I googled for "shbrowseforfolder fortran" and this was the first result.)

Les

 

0 Kudos
SergeyKostrov
Valued Contributor II
2,312 Views
>>...I googled for "shbrowseforfolder fortran"... Mighty Google! How many of us started programming before Google.com was created? I think a few... How were we solving problems without Google? Sometimes I was spending days and days to understand how to do something really small! I'm also using Google now and it is a real time saver. However, modern software developers Do Not Fight problems as we Did in the past! Am I wrong? I also know that science guys really need help with some over complicated software stuff. By the way, about 7 years ago working on a Geomatics project as a C++ Software Engineer in one case, when there was some internal problem with codes, I was told by a person with PhD degree in Geomatics: '...Just Google It...'
0 Kudos
Les_Neilson
Valued Contributor II
2,312 Views

<Enters nostalgia mode>

I was programming before there was an internet! Computer room the size of a small warehouse. 9-track tapes. Overnight test runs. Core dumps on mountains of paper. Ah those were the days.
"Real programmers don't eat quiche" (just Google it!)
:-)

</Leaves nostalgia mode and returns to day job>
Les

0 Kudos
onkelhotte
New Contributor II
2,312 Views

Haha... Instantly wrote that on a Post-It and sticked it below my screen!

o Real Programmers don't comment their code.
If it was hard to write, it should be hard to understand and harder to modify.

0 Kudos
dboggs
New Contributor I
2,312 Views

Back on the topic: Using SHBrowseForFolder

Thanks Les for the link. I did find it useful. After some effort, I was able to get the routine working (thanks to suggestions by Anthony Richards) but there are still two problems: (1) there is no apparent way to specify an initial folder; (2) the csidl_flag_create attribute to SHILCreateFromPath, which is supposed to allow user to specify a non-existing path which will then be created, does not work.

Is there any further development here? And, I observe from MSN documentation:

To enable the user to navigate the namespace and select a folder, your application can use the IFileDialog interface. Calling this interface with the FOS_PICKFOLDERS flag launches the Open Files common dialog box in "pick folders" mode.

For Windows Vista and later, this is the recommended way to pick folders.

So maybe there is a better (new,improved!?) method of handling this now?

0 Kudos
SergeyKostrov
Valued Contributor II
2,312 Views
>>...Now, I would like to use SHBrowseForFolder... In the example I provided BROWSEINFO structure controls lots of input parameters for SHBrowseForFolder Win32 API function. Here are all members of the structure: typedef struct _browseinfo { HWND hwndOwner; LPCITEMIDLIST pidlRoot; LPTSTR pszDisplayName; LPCTSTR lpszTitle; UINT ulFlags; BFFCALLBACK lpfn; LPARAM lParam; int iImage; } BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO; and, you possibly read on MSDN, LPCITEMIDLIST pidlRoot controls '...the root folder from which to start browsing...'. However, if you see that it is difficult to implement all that support in Fortran language then I would suggest to implement simple additional C/C++ DLL ( let's call it HelperDLL ) that could provide such functionality for your Fortran application. In general, a workflow could look like: - FortranApp loads HelperDLL - FortranApp calls BrowseForFolder ( implemented in C/C++ in HelperDLL ) with some simple input parameters - BrowseForFolder calls SHBrowseForFolder - SHBrowseForFolder allows to select a user some folder - Folder name selected by the user is returned by BrowseForFolder to FortranApp Does it make sence?
0 Kudos
IanH
Honored Contributor III
2,312 Views

There's no need for the helper to be in a DLL!

0 Kudos
SergeyKostrov
Valued Contributor II
2,312 Views
>>...There's no need for the helper to be in a DLL! There is No need to throw just a statement without explaining to everybody how else it can be done.
0 Kudos
IanH
Honored Contributor III
2,312 Views

Write some C/C++ code, compile it, link it with your Fortran ;)

Pet peeve of mine - unnecessary DLL's.

0 Kudos
Reply