_ SHBrowseForFolder Shell API call.

Hi I am using C++Builder 5.

And I would like to call up the dialog that retrieves the folder path.

So I tried SHBrowseForFolder.

However, during compilation, the IDE gives me an error that many things in the shlobj.h are redifined...

(ex : FVSHOWINFO)

Maybe it's because I have to put something in my program to define API.. or WIN32... or...

But I don't know too much about making a shell call.

Can anyone teach me how to call SHBrowseForFolder successfully ?.
WeinAsked:
Who is Participating?
 
Meir RivkinConnect With a Mentor Full stack Software EngineerCommented:
Wein:
here is a wrapper class for SHBrowseForFolder, hope it would help u....

//Header file
//*-
//
// MODULE NAME:   SHBrowseDlg.h
//
// DESCRIPTION:   CSHBrowseDlg class declaration
//
// AUTHOR     :   Stefano Passiglia, March 1998
//                passig@geocities.com
//                You can reuse and redistribute this code, provided this header is
//                kept as is.
//+*/

#ifndef __SHBROWSEDLG_H
#define __SHBROWSEDLG_H

//
// Include Files
//
#include "stdafx.h"

#include <winnetwk.h>
#include <shlobj.h>

class CSHBrowseDlg
{
private:
   
   char m_szHint[MAX_PATH];
   char m_szDisplayName[MAX_PATH];
   char m_szDirFullPath[MAX_PATH];
   
   HWND m_hWndOwner;
   HWND m_hWndTreeView;

   // Shell's OLE interfaces
   IShellFolder *m_pSHFolder;
   IMalloc      *m_pMalloc;

private:

   void GetNames( LPCITEMIDLIST pidl );

   static int WINAPI SHBrowseCallBack( HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData );

protected:
   

public:
   
   // Constructor
   CSHBrowseDlg( HWND   hWndOwner = NULL,
                 LPCSTR szHint    = "\nPlease Select Folder:" );
   // Destructor
   ~CSHBrowseDlg();
   
public:
   
   // Shows the dialog
   BOOL DoModal( LPSTR lpszInitialDir = NULL,
                 UINT  uRoot          = CSIDL_DESKTOP,
                 UINT  uFlags         = BIF_STATUSTEXT );
   
   // Path selection helpers
   char *GetFullPath();
   char *GetFolderName();
   
};


#endif // __SHBROWSEDLG_H



//implementation file
//*-
//
// MODULE NAME:   SHBrowseDlg.cpp
//
// DESCRIPTION:   CSHBrowseDlg class implementation
//
// AUTHOR     :   Stefano Passiglia, January 1998
//                passig@geocities.com
//                You can reuse and redistribute this code, provided this header is
//                kept as is.
//+*/


//
// Include Files
//
#include "stdafx.h"

#include "SHBrowseDlg.h"


//
// Global variables.
//


//
// Local constant definitions.
//
#ifdef _DEBUG
#  define new DEBUG_NEW
#  undef THIS_FILE
   static char THIS_FILE[] = __FILE__;
#endif

//
// Local type definitions.
//

// Struct used by the callback function
typedef struct _SB_INITDATA
{
   char         *lpszInitialDir;
   CSHBrowseDlg *pSHBrowseDlg;
} SB_INITDATA, *LPSB_INITDATA;


//
// Local defines
//



//
// Local function declarations.
//

// Dialog callback


//
// Local class declarations.
//
// None.


   
               ///////////////////////////////////////////////
               //          CONSTRUCTORS/DESTRUCTOR          //
               ///////////////////////////////////////////////



///*-
// FUNCTION NAME: CSHBrowseDlg::CSHBrowseDlg
//
// DESCRIPTION:   CSHBrowseDlg class constructor
//
// PARAMETER(S):
//                hwndParent:
//                   TYPE:          HWND
//                   MODE:          In
//                   MECHANISM:     By value
//                   DESCRIPTION:   Dialog parent window handle
//
//                szHint:
//                   TYPE:          char
//                   MODE:          In
//                   MECHANISM:     By reference
//                   DESCRIPTION:   Pointer to the dialog hint
//
// RETURN:        None
//
// NOTES:         None
//+*/
CSHBrowseDlg::CSHBrowseDlg( HWND   hWndOwner,
                            LPCSTR szHint ) :
   m_hWndOwner(hWndOwner)
{
   if ( szHint )
   {
      lstrcpy( m_szHint, szHint );
   }

   // Initialize path strings
   m_szDirFullPath[0] = m_szDisplayName[0] = 0;

   // Retrieve IShellFolder interface
   SHGetDesktopFolder( &m_pSHFolder );

   // Retrieve IMalloc
   SHGetMalloc( &m_pMalloc );
} // CSHBrowseDlg::CSHBrowseDlg()

   
///*-
// FUNCTION NAME: CSHBrowseDlg::~CSHBrowseDlg
//
// DESCRIPTION:   CSHBrowseDlg class destructor
//
// PARAMETER(S):  None.
//
// RETURN:        None
//
// NOTES:         None
//+*/
CSHBrowseDlg::~CSHBrowseDlg()
{
   // Release ISHFolder/IMalloc interfaces
   m_pSHFolder->Release();
   m_pMalloc->Release();
} // CSHBrowseDlg::~CSHBrowseDlg()


   
               ///////////////////////////////////////////////
               //             PUBLIC FUNCTIONS              //
               ///////////////////////////////////////////////



///*-
// FUNCTION NAME: CSHBrowseDlg::DoModal
//
// DESCRIPTION:   Shows the dialog
//
// PARAMETER(S):
//                lpszInitialDir:
//                   TYPE:          char
//                   MODE:          In
//                   MECHANISM:     By reference
//                   DESCRIPTION:   Pointer to the string containing
//                                  the initial path
//                uRoot:
//                   TYPE:          UINT
//                   MODE:          In
//                   MECHANISM:     By value
//                   DESCRIPTION:   Root of the browsing tree
//                                  (default: desktop)
//
//                uFlags:
//                   TYPE:          UINT
//                   MODE:          In
//                   MECHANISM:     By value
//                   DESCRIPTION:   Specifies additional flags
//                                  (see SHBrowseForFolder help)
//
// RETURN:        None
//
// NOTES:         None
//+*/
BOOL CSHBrowseDlg::DoModal( LPSTR lpszInitialDir,
                            UINT  uRoot,
                            UINT  uFlags
                          )
{
   BOOL bResult = TRUE;

   SB_INITDATA sbInit = { lpszInitialDir, this };

   // Get tree root
   LPITEMIDLIST lpidList;
   SHGetSpecialFolderLocation( m_hWndOwner, uRoot, &lpidList );
   
   // Initialize BROWSEINFO structure
   BROWSEINFO biInfo;
   biInfo.hwndOwner      = m_hWndOwner;
   biInfo.pidlRoot       = lpidList;
   biInfo.pszDisplayName = m_szDisplayName;
   biInfo.lpszTitle      = m_szHint;
   biInfo.ulFlags        = BIF_STATUSTEXT | uFlags;
   biInfo.lpfn           = BFFCALLBACK( SHBrowseCallBack );
   biInfo.lParam         = LPARAM( &sbInit );
   biInfo.iImage         = 0;
   
   // Show the dialog
   LPITEMIDLIST pidl = SHBrowseForFolder( &biInfo );
   
   bResult = (pidl != NULL);
   if ( bResult )
   {
      // "OK" pressed
      // Try to retrieve path name
      if ( !SHGetPathFromIDList(pidl, m_szDirFullPath) && (*m_szDisplayName == 0) )
      {
         bResult = FALSE;
      }
     
      // Give memory back to the system using IMalloc interface
      m_pMalloc->Free( reinterpret_cast< void * >( pidl ) );
     
   }

   return bResult;
} // CSHBrowseDlg::DoModal()



///*-
// FUNCTION NAME: CSHBrowseDlg::GetFullPath
//
// DESCRIPTION:   Retrieves selected folder full path
//
// PARAMETER(S):  None.
//
// RETURN:        CString object.
//
// NOTES:         None.
//+*/
char *CSHBrowseDlg::GetFullPath()
{
   return &m_szDirFullPath[0];
} // CSHBrowseDlg::GetFullPath()


///*-
// FUNCTION NAME: CSHBrowseDlg::GetFolderName
//
// DESCRIPTION:   Retrieves selected folder name
//
// PARAMETER(S):  None.
//
// RETURN:        char *.
//
// NOTES:         None.
//+*/
char *CSHBrowseDlg::GetFolderName()
{
   return &m_szDisplayName[0];
} // CSHBrowseDlg::GetFolderName()


   
               ///////////////////////////////////////////////
               //             BROWSE CALLBACK               //
               ///////////////////////////////////////////////



///*-
// FUNCTION NAME: CSHBrowseDlg::SHBrowseCallBack
//
// DESCRIPTION:   Browse dialog callback
//
// PARAMETER(S):
//                hWnd:
//                   TYPE:          HWND
//                   MODE:          In
//                   MECHANISM:     By value
//                   DESCRIPTION:   Handle of the dialog
//
//                uMsg:
//                   TYPE:          UIN
//                   MODE:          In
//                   MECHANISM:     By value
//                   DESCRIPTION:   Message identifier
//
//                lParam:
//                   TYPE:          LPARAM
//                   MODE:          In
//                   MECHANISM:     By value
//                   DESCRIPTION:   Message-dependent value
//
//
//                lpData:
//                   TYPE:          LPARAM
//                   MODE:          In
//                   MECHANISM:     By value
//                   DESCRIPTION:   Application-dependent value
//
//
// RETURN:        Zero, always
//
// NOTES:         Used only to set initial dir and initialize subclassing.
//+*/
int WINAPI CSHBrowseDlg::SHBrowseCallBack( HWND   hWnd,
                                           UINT   uMsg,
                                           LPARAM lParam,
                                           LPARAM lpData )
{
   static CSHBrowseDlg *pSBDlg = reinterpret_cast< LPSB_INITDATA >(lpData)->pSHBrowseDlg;

   if ( uMsg == BFFM_INITIALIZED )
   {
      // Set initial directory
      if ( lpData && *(char *)lpData )
      {
         ::SendMessage( hWnd,
                        BFFM_SETSELECTION,
                        TRUE,
                        LPARAM(LPSB_INITDATA(lpData)->lpszInitialDir)
                      );
      }
      pSBDlg->m_hWndTreeView = FindWindowEx( hWnd, NULL, WC_TREEVIEW, NULL );
   }
   else
   if ( uMsg == BFFM_SELCHANGED )
   {
      pSBDlg->GetNames( LPCITEMIDLIST(lParam) );

      // Update status text
      if ( *pSBDlg->m_szDirFullPath )
      {
         ::SendMessage( hWnd,
                        BFFM_SETSTATUSTEXT,
                        0,
                        LPARAM(pSBDlg->m_szDirFullPath) );
      }
      else
      {
         ::SendMessage( hWnd,
                        BFFM_SETSTATUSTEXT,
                        0,
                        LPARAM(pSBDlg->m_szDisplayName) );
      }

   }
     

   return 0;
} // SHBrowseCallBack()


   
               ///////////////////////////////////////////////
               //             PRIVATE FUNCTIONS             //
               ///////////////////////////////////////////////



///*-
// FUNCTION NAME: CSHBrowseDlg::GetNames
//
// DESCRIPTION:   Retrieves full path and display name of the selected treeview item
//
// PARAMETER(S):  
//                pidl:
//                   TYPE:          ITEMIDLIST
//                   MODE:          In
//                   MECHANISM:     By reference
//                   DESCRIPTION:   Pointer to the item identifier list
//
// RETURN:        None.
//
// NOTES:         None.
//+*/
void CSHBrowseDlg::GetNames( LPCITEMIDLIST pidl )
{
   HTREEITEM hSelected;
   TV_ITEM   tvSelected;

   // Get full path
   SHGetPathFromIDList( pidl, m_szDirFullPath );

   // Now retrieve display name.
   hSelected = TreeView_GetSelection( m_hWndTreeView );
   tvSelected.mask       = TVIF_HANDLE | TVIF_TEXT;
   tvSelected.hItem      = hSelected;
   tvSelected.pszText    = m_szDisplayName;
   tvSelected.cchTextMax = MAX_PATH;
   TreeView_GetItem( m_hWndTreeView, &tvSelected );
} // CSHBrowseDlg::GetNames()



good luck
0
 
jhanceCommented:
Does C++ Builder have pre-compiled header files like VC++ does?  (I think it has a similar feature.)  If so, you are probably including shlobj.h once by default in there and then again explicitly in your source code.

I'd suggest taking a look at what is being included where and making sure you have it right.

You may also be mixing your Windows SDK versions.  If you have one that came with C++ Builder as well as one from MS, then you can get into this mess.

I don't think this necessarily has anything to do with SHBrowseForFolder, but rather is an issue with your project setup in C++ Builder.
0
 
intheCommented:
Hi,
this may help:

http://www.bcbdev.com/faqs/faq62.htm

or at least you can compare your code to it to see if anythings wrong .
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
WeinAuthor Commented:
Thank you, inthe, for the useful information on SHBrowseForFolder.
It will really help my project for going on.

However, the focus of my problem is that i can't compile the file.

I included shlobj.h

Why does it show an error during compilation about ambiguish declaration ?

wein.
0
 
AlexVirochovskyCommented:
Wein, do you saw my reply to your same Q. in C++ area?
0
 
AlexVirochovskyCommented:
I quotate my reply:

From: AlexVirochovsky  Date: 08/11/2001 08:52AM PST  
Select Projects | Options.
Click the "Directories/Conditionals" tab on the dialog box.
Add NO_WIN32_LEAN_AND_MEAN to the list of conditionals.
Rebuild the entire project.

Alex
 
0
 
Meir RivkinFull stack Software EngineerCommented:
its usage:

CSHBrowseDlg dlg;


if(m_dlgBrowse.DoModal() == IDOK)
{
     m_dlgBrowse.GetFullPath(); //the selected path
}

cheers
0
 
Meir RivkinFull stack Software EngineerCommented:
its usage:

CSHBrowseDlg dlg;


if(dlg.DoModal() == IDOK)
{
    dlg.GetFullPath(); //the selected path
}

cheers
0
 
WeinAuthor Commented:
0
 
WeinAuthor Commented:
0
 
WeinAuthor Commented:
Thanx everybody,
now it works like i wanted..
0
 
WeinAuthor Commented:
How should i give the points ?

I think NO_WIN32_LEAN_AND_MEAN did what I wanted...

but the others' comment help out too...
0
 
WeinAuthor Commented:
However, Alex, can you explain that conditional parameter ?

NO_WIN32_LEAN_AND_MEAN

I would like to know more about these flags...

0
 
AlexVirochovskyCommented:
1.
From Borland Doc:
...
Header file optimization and failed builds
-----------------------------------------------
(Enterprise and Professional editions only)

If a build fails with "can't find symbol" or
"multiple declaration" errors or with errors
that suggest that windows structures can't
be defined, you may need to add the following:
NO_WIN32_LEAN_AND_MEAN
to your project defines. This forces the .HPP
files in your project to include more of the Win32
header files, and should correct the build errors.

Such errors may be encountered if your project
includes a Pascal component that uses structures
from the ActiveX or shell object libraries
ACTIVEX.HPP, SHLOBJ.HPP, or URLMON.HPP.
(Structures were removed from these files to
reduce overall build times).

These errors may also be encountered when
compiling applications that include both
a windows header and the VCL version of
the same windows header. For example, including
both SHLOBJ.H and SHLOBJ.HPP will result in
compile time errors like the following:
 Multiple declaration for 'FVSHOWINFO'
 Multiple declaration for 'FOLDERSETTINGS'
 Multiple declaration for 'DESKBANDINFO'
 Multiple declaration for 'SHELLFLAGSTATE'

[CF81437]
....
2. About pts: If you want get points to me and
someone other, you can accept my comment as reply to your same Q. in "c++" area, and in this thread accept comment of other expert. Good Luck, Alex
0
 
WeinAuthor Commented:
where are located these documents ?
0
 
Meir RivkinFull stack Software EngineerCommented:
u can splityour points
0
 
AlexVirochovskyCommented:
>>where are located these documents ?
This in
http://www.borland.com/devsupport/bcppbuilder/patches/bcpp5/Upd1rdme.txt
0
 
WeinAuthor Commented:
how to split points sedgwick ?
0
 
Meir RivkinFull stack Software EngineerCommented:
go to "Community support", set "splitting points" as the title and write inside the link to the relevant question and the usernames to whom u wanna give the points.

good luck

0
 
Meir RivkinFull stack Software EngineerCommented:
the support will probably decrease the points from 100 to 50, so u can accept one anwser from one of the usernames and for the other ask new question adn in the title write
"points for ..."
0
All Courses

From novice to tech pro — start learning today.