The Wayback Machine - https://web.archive.org/web/20100213180947/http://www.codeguru.com:80/cpp/com-tech/shell/article.php/c1325

    A COMPLETE SHBrowseForFolder wrapper class

    • 1
    Download Source Code and Example Download Source Code Only


    This is the CBrowseForFolder class. I looked high and low to find a COMPLETE wrapper for the call to SHBrowseForFolder, and I couldn't find one, so I wrote my own. The idea is to derive from CBrowseForFolder to create a folder browser that behaves the way you want.

    In the demo project, CSBDestination shows a really good example of what you can do.

    -- BrowseForfolder.h --
    
    //////////////////////////////////////////////////////////////////////
    //
    // ShellBrowser.h: interface for the CShellBrowser class.
    //
    // Copyright 1998 Scott D. Killen
    //
    //////////////////////////////////////////////////////////////////////
    
    #ifndef __SHELLBROWSER_H__
    #define __SHELLBROWSER_H__
    
    #if _MSC_VER >= 1000
    #pragma once
    #endif // _MSC_VER >= 1000
    
    #include 
    #include 
    
    //////////////////////////////////////////////////////////////////////
    //
    // CShellBrowser
    //
    
    class CBrowseForFolder
    {
    public:
    	CBrowseForFolder(const HWND hParent = NULL,
    			 const LPITEMIDLIST pidl = NULL,
    			 const int nTitleID = 0);
    
    	CBrowseForFolder(const HWND hParent,
    			 const LPITEMIDLIST pidl,
    			 const CString& strTitle);
    
    	virtual ~CBrowseForFolder() = 0;
    
    	//
    	// Set the handle of the owner window for the dialog box.
    	//
    	void SetOwner(const HWND hwndOwner);
    
    	//
    	// Set the root of the heirarchy that will be browsed.  Get pidl from
    	// SHGetSpecialFolderLocation.  This can be set to NULL to use the Virtual Folder
    	// that represents the Windows Desktop.
    	//
    	void SetRoot(const LPITEMIDLIST pidl);
    
    	//
    	// Access a string that is displayed above the tree view control in the dialog box.
    	// This string can be used to specify instructions to the user.  strTitle is a
    	// CString containing the text to be displayed.  nTitle is the index of a string
    	// resource to be loaded.  The return value is false if the resource could not be
    	// loaded.
    	//
    	CString GetTitle() const;
    	void SetTitle(const CString& strTitle);
    	bool SetTitle(const int nTitle);
    
    	//
    	// ulFlags = Value specifying the types of folders to be listed in the dialog box
    	// as well as other options. This member can include zero or more of the following
    	// values:
    	//
    	//          BIF_BROWSEFORCOMPUTER    Only returns computers. If the user selects
    	//                                   anything other than a computer, the OK button
    	//                                   is grayed.
    	//
    	//          BIF_BROWSEFORPRINTER     Only returns printers. If the user selects
    	//                                   anything other than a printer, the OK button
    	//                                   is grayed.
    	//
    	//          BIF_DONTGOBELOWDOMAIN    Does not include network folders below the
    	//                                   domain level in the tree view control.
    	//
    	//          BIF_RETURNFSANCESTORS    Only returns file system ancestors. If the user
    	//                                   selects anything other than a file system
    	//                                   ancestor, the OK button is grayed.
    	//
    	//          BIF_RETURNONLYFSDIRS     Only returns file system directories. If the
    	//                                   user selects folders that are not part of the
    	//                                   file system, the OK button is grayed.
    	//
    	//          BIF_STATUSTEXT           Includes a status area in the dialog box. The
    	//                                   callback function can set the status text by
    	//                                   sending messages to the dialog box. 
    	//
    	UINT GetFlags() const;
    	void SetFlags(const UINT ulFlags);
    
    	//
    	// Call GetSelectedFolder to retrieve the folder selected by the user.
    	//
    	CString GetSelectedFolder() const;
    
    	//
    	// Function to retreive the image associated with the selected folder. The image is
    	// specified as an index to the system image list. 
    	//
    	int GetImage() const;
    
    	//
    	// Call SelectFolder to display the dialog and get a selection from the user.  Use
    	// GetSelectedFolder and GetImage to get the results of the dialog.
    	//
    	bool SelectFolder();
    
    protected:
    	//
    	// OnInit is called before the dialog is displayed on the screen.
    	//
    	virtual void OnInit() const;
    
    	//
    	// OnSelChanged is called whenever the user selects a different directory.  pidl is
    	// the LPITEMIDLIST of the new selection.  Use SHGetPathFromIDList to retrieve the
    	// path of the selection.
    	//
    	virtual void OnSelChanged(const LPITEMIDLIST pidl) const;
    
    	//
    	// Call EnableOK to enable the OK button on the active dialog.  If bEnable is true
    	// then the button is enabled, otherwise it is disabled.
    	// NOTE -- This function should only be called within overrides of OnInit and
    	// OnSelChanged.
    	//
    	void EnableOK(const bool bEnable) const;
    
    	//
    	// Call SetSelection to set the selection in the active dialog.  pidl is the
    	// LPITEMIDLIST
    	// of the path to be selected.  strPath is a CString containing the path to be
    	// selected.
    	// NOTE -- This function should only be called within overrides of OnInit and
    	// OnSelChanged.
    	//
    	void SetSelection(const LPITEMIDLIST pidl) const;
    	void SetSelection(const CString& strPath) const;
    
    	//
    	// Call SetStatusText to set the text in the Status area in the active dialog.
    	// strText is the text to be displayed.
    	// NOTE -- This function should only be called within overrides of OnInit and
    	// OnSelChanged.
    	//
    	void SetStatusText(const CString& strText) const;
    
    private:
    	static int __stdcall BrowseCallbackProc(HWND hwnd,
    						UINT uMsg,
    						LPARAM lParam,
    						LPARAM lpData);
    
    	typedef std::auto_ptr AUTO_STR;
    	AUTO_STR m_pchTitle;
    
    	BROWSEINFO m_bi;
    	char m_szSelected[MAX_PATH];
    	CString m_strPath;
    	HWND m_hwnd;
    };
    
    inline UINT CBrowseForFolder::GetFlags() const
    {
    	return m_bi.ulFlags;
    }
    
    inline int CBrowseForFolder::GetImage() const
    {
    	return m_bi.iImage;
    }
    
    #endif // __SHELLBROWSER_H__
    
    -- BrowseForFolder.cpp -- ////////////////////////////////////////////////////////////////////// // // ShellBrowser.cpp: implementation of the CShellBrowser class. // #include "stdafx.h" #include "BrowseForFolder.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // // Construction/Destruction // CBrowseForFolder::CBrowseForFolder(const HWND hParent /*= NULL*/, const LPITEMIDLIST pidl /*= NULL*/, const int nTitleID /*= 0*/) { m_hwnd = NULL; SetOwner(hParent); SetRoot(pidl); SetTitle(nTitleID); m_bi.lpfn = BrowseCallbackProc; m_bi.lParam = reinterpret_cast(this); m_bi.pszDisplayName = m_szSelected; } CBrowseForFolder::CBrowseForFolder(const HWND hParent, const LPITEMIDLIST pidl, const CString& strTitle) { m_hwnd = NULL; SetOwner(hParent); SetRoot(pidl); SetTitle(strTitle); m_bi.lpfn = BrowseCallbackProc; m_bi.lParam = reinterpret_cast(this); m_bi.pszDisplayName = m_szSelected; } CBrowseForFolder::~CBrowseForFolder() { } ////////////////////////////////////////////////////////////////////// // // Implementation // void CBrowseForFolder::SetOwner(const HWND hwndOwner) { if (m_hwnd != NULL) return; m_bi.hwndOwner = hwndOwner; } void CBrowseForFolder::SetRoot(const LPITEMIDLIST pidl) { if (m_hwnd != NULL) return; m_bi.pidlRoot = pidl; } CString CBrowseForFolder::GetTitle() const { return m_bi.lpszTitle; } void CBrowseForFolder::SetTitle(const CString& strTitle) { if (m_hwnd != NULL) return; m_pchTitle = std::auto_ptr(new char [static_cast(strTitle.GetLength()) + 1]); strcpy(m_pchTitle.get(), strTitle); m_bi.lpszTitle = m_pchTitle.get(); } bool CBrowseForFolder::SetTitle(const int nTitle) { if (nTitle <= 0) return false; CString strTitle; if(!strTitle.LoadString(static_cast(nTitle))) { return false; } SetTitle(strTitle); return true; } void CBrowseForFolder::SetFlags(const UINT ulFlags) { if (m_hwnd != NULL) return; m_bi.ulFlags = ulFlags; } CString CBrowseForFolder::GetSelectedFolder() const { return m_szSelected; } bool CBrowseForFolder::SelectFolder() { bool bRet = false; LPITEMIDLIST pidl; if ((pidl = ::SHBrowseForFolder(&m;_bi)) != NULL) { m_strPath.Empty(); if (SUCCEEDED(::SHGetPathFromIDList(pidl, m_szSelected))) { bRet = true; m_strPath = m_szSelected; } LPMALLOC pMalloc; //Retrieve a pointer to the shell's IMalloc interface if (SUCCEEDED(SHGetMalloc(&pMalloc;))) { // free the PIDL that SHBrowseForFolder returned to us. pMalloc->Free(pidl); // release the shell's IMalloc interface (void)pMalloc->Release(); } } m_hwnd = NULL; return bRet; } void CBrowseForFolder::OnInit() const { } void CBrowseForFolder::OnSelChanged(const LPITEMIDLIST pidl) const { (void)pidl; } void CBrowseForFolder::EnableOK(const bool bEnable) const { if (m_hwnd == NULL) return; (void)SendMessage(m_hwnd, BFFM_ENABLEOK, static_cast(bEnable), NULL); } void CBrowseForFolder::SetSelection(const LPITEMIDLIST pidl) const { if (m_hwnd == NULL) return; (void)SendMessage(m_hwnd, BFFM_SETSELECTION, FALSE, reinterpret_cast(pidl)); } void CBrowseForFolder::SetSelection(const CString& strPath) const { if (m_hwnd == NULL) return; (void)SendMessage(m_hwnd, BFFM_SETSELECTION, TRUE, reinterpret_cast(LPCTSTR(strPath))); } void CBrowseForFolder::SetStatusText(const CString& strText) const { if (m_hwnd == NULL) return; (void)SendMessage(m_hwnd, BFFM_SETSTATUSTEXT, NULL, reinterpret_cast(LPCTSTR(strText))); } int __stdcall CBrowseForFolder::BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { CBrowseForFolder* pbff = reinterpret_cast(lpData); pbff->m_hwnd = hwnd; if (uMsg == BFFM_INITIALIZED) pbff->OnInit(); else if (uMsg == BFFM_SELCHANGED) pbff->OnSelChanged(reinterpret_cast(lParam)); return 0; }

    Last updated: 5 June 1998

    • 1

    IT Offers






    The Network for Technology Professionals

    About Internet.com

    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers