原文链接:CYABFFW: Yet Another BrowseForFolder Wrapper
以良好的MFC风格将Shell API函数SHBrowseForFolder()
封装为一个
CWnd
子类。
使用示例1
:
CYABFFWdlg();
if (IDOK == dlg.DoModal())
{
CStrings=dlg.GetPath();
//Dosomethingwith`s'
使用示例
2
:if (IDOK == dlg.DoModal())
{
CStrings=dlg.GetPath();
//Dosomethingwith`s'
CYABFFWdlg(_T(
"
Pleaseselectadirectory
"
),
//
Hinttouser
BIF_USE_NEWUI, // Flagsforthedlg
this , // Parentwindow
CSIDL_DRIVES); // Rootofsearch
if (IDOK == dlg.DoModal())
{
CStrings=dlg.GetPath();
//Dosomethingwith`s'
BIF_USE_NEWUI, // Flagsforthedlg
this , // Parentwindow
CSIDL_DRIVES); // Rootofsearch
if (IDOK == dlg.DoModal())
{
CStrings=dlg.GetPath();
//Dosomethingwith`s'
YABFFW.h
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->classCYABFFW:publicCWnd
{
//Construction
public:
/**////Constructwithatextualhint,BFFflags,parentwindow,a
///rootfolderexpressedasaCSIDLvalue,andadefault
///selectionexpressedasatextualpath
CYABFFW(constCString&strHint=CString(),UINTnFlags=0U,
CWnd*pParentWnd=NULL,intnRootFolder=CSIDL_DESKTOP,
constCString&strDefaultSel=CString());
/**////ConstructwithadefaultselectionexpressedasaCSIDL
///value,atextualhint,BFFflags,parentwindow,&aroot
///folderexpressedasaCSIDLvalue
CYABFFW(intnDefaultSel,constCString&strHint=CString(),
UINTnFlags=0U,CWnd*pParentWnd=NULL,
intnRootFolder=CSIDL_DESKTOP);
/**////ConstructwithahintfromResource,BFFflags,parent
///window,arootfolderexpressedasaCSIDLvalue,anda
///defaultselectionexpressedasatextualpath
CYABFFW(intnHint,UINTnFlags=0U,CWnd*pParentWnd=NULL,
intnRootFolder=CSIDL_DESKTOP,
constCString&strDefaultSel=CString());
/**////ConstructwithahintfromResource,adefaultselection
///expressedasaCSIDLvalue,BFFflags,parentwindow,&a
///rootfolderexpressedasaCSIDLvalue
CYABFFW(intnDefaultSel,intnHint,UINTnFlags=0U,
CWnd*pParentWnd=NULL,intnRootFolder=CSIDL_DESKTOP);
/**////Constructwithatextualhint,anarbitraryrootfolder,
///BFFflags,aparentwindow,andadefaultselection
///expressedasatextualpath
CYABFFW(constCString&strHint,constCString&strRoot,
UINTnFlags=0U,CWnd*pParentWnd=NULL,
constCString&strDefaultSel=CString());
/**////Constructwithatextualhint,adefaultselection
///expressedasaCSIDLvalue,anarbitraryrootfolder,BFF
///flags,&aparentwindow
CYABFFW(intnDefaultSel,constCString&strHint,constCString&strRoot,
UINTnFlags=0U,CWnd*pParentWnd=NULL);
/**////ConstructwithahintfromResource,anarbitraryroot
///folder,BFFflags,aparentwidnow,andatextualdefault
///selection
CYABFFW(intnHint,constCString&strRoot,UINTnFlags=0U,
CWnd*pParentWnd=NULL,
constCString&strDefaultSel=CString());
/**////ConstructwithahintfromResource,adefaultselection
///expressedasaCSIDLvalue,anarbitraryrootfolder,BFF
///flags,&aparentwidnow
CYABFFW(intnDefaultSel,intnHint,constCString&strRoot,
UINTnFlags=0U,CWnd*pParentWnd=NULL);
//Attributes
public:
/**////Retrievethedisplaynameoftheselecteditem
CStringGetDisplayName()const;
/**////RetrievetheITEMIDLISToftheselecteditem
LPCITEMIDLISTGetItemIdList()const;
/**////Retrievethepathtotheselecteditem
CStringGetPath()const;
//Operations
public:
/**////DisplaytheDialog-returnsIDOKorIDCANCEL
intDoModal();
//Overrides
public:
/**////CalledwhentheBFFDialoghasinitialized
virtualvoidOnInitBFFDialog();
/**////Calledwhentheselectionhaschangedinthetreecontrol
virtualvoidOnBFFSelChanged(LPITEMIDLISTpNewSel);
/**////Calledwhentheusertypesaninvalidname
virtualBOOLOnBFFValidateFailed(constCString&strBadName);
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CYABFFW)
//}}AFX_VIRTUAL
//Implementation
public:
virtual~CYABFFW();
//Generatedmessagemapfunctions
protected:
//{{AFX_MSG(CYABFFW)NOTE-theClassWizardwilladdandremove
//memberfunctionshere.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
/**////StaticmethodtobeusedfortheSHBFFcallback
staticintCALLBACKBrowseCallbackProc(HWNDhWnd,UINTnMsg,
LPARAMlParam,
LPARAMlpData);
private:
/**////Freethememoryreferencedbym_pItemIdList
voidFreeItemIdList(IMalloc*pMalloc=NULL);
/**////CSIDL=>ITEMIDLIST
LPITEMIDLISTResolveCsidl(intnCsidl)const;
/**////Textualfilesystempath=>ITEMIDLIST
LPITEMIDLISTResolveFsPath(constCString&strPath)const;
private:
/**////Displaynameoftheselecteditem
CStringm_strDisplayName;
/**////Flagstobepassedtothebrowsedialog
UINTm_nFlags;
/**////"Hint"tobedisplayedabovethetreecontrol
CStringm_strHint;
/**////ITEMIDLISTidentifyingtheselectedShellitem
LPITEMIDLISTm_pItemIdList;
/**////ParentCWnd(NULL=>Appmainwindow)
CWnd*m_pParentWnd;
/**////Selectedpath
CStringm_strPath;
/**////ITEMIDLISTidentifyingtheroot
LPITEMIDLISTm_pRoot;
/**////Defaultselection,ifgivenastext(emptyifnone)
CStringm_strDefaultSel;
/**////Defaultselection,ifgivenasaCSIDLvalue(NULLifnone)
LPITEMIDLISTm_pDefaultSel;
};
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->classCYABFFW:publicCWnd
{
//Construction
public:
/**////Constructwithatextualhint,BFFflags,parentwindow,a
///rootfolderexpressedasaCSIDLvalue,andadefault
///selectionexpressedasatextualpath
CYABFFW(constCString&strHint=CString(),UINTnFlags=0U,
CWnd*pParentWnd=NULL,intnRootFolder=CSIDL_DESKTOP,
constCString&strDefaultSel=CString());
/**////ConstructwithadefaultselectionexpressedasaCSIDL
///value,atextualhint,BFFflags,parentwindow,&aroot
///folderexpressedasaCSIDLvalue
CYABFFW(intnDefaultSel,constCString&strHint=CString(),
UINTnFlags=0U,CWnd*pParentWnd=NULL,
intnRootFolder=CSIDL_DESKTOP);
/**////ConstructwithahintfromResource,BFFflags,parent
///window,arootfolderexpressedasaCSIDLvalue,anda
///defaultselectionexpressedasatextualpath
CYABFFW(intnHint,UINTnFlags=0U,CWnd*pParentWnd=NULL,
intnRootFolder=CSIDL_DESKTOP,
constCString&strDefaultSel=CString());
/**////ConstructwithahintfromResource,adefaultselection
///expressedasaCSIDLvalue,BFFflags,parentwindow,&a
///rootfolderexpressedasaCSIDLvalue
CYABFFW(intnDefaultSel,intnHint,UINTnFlags=0U,
CWnd*pParentWnd=NULL,intnRootFolder=CSIDL_DESKTOP);
/**////Constructwithatextualhint,anarbitraryrootfolder,
///BFFflags,aparentwindow,andadefaultselection
///expressedasatextualpath
CYABFFW(constCString&strHint,constCString&strRoot,
UINTnFlags=0U,CWnd*pParentWnd=NULL,
constCString&strDefaultSel=CString());
/**////Constructwithatextualhint,adefaultselection
///expressedasaCSIDLvalue,anarbitraryrootfolder,BFF
///flags,&aparentwindow
CYABFFW(intnDefaultSel,constCString&strHint,constCString&strRoot,
UINTnFlags=0U,CWnd*pParentWnd=NULL);
/**////ConstructwithahintfromResource,anarbitraryroot
///folder,BFFflags,aparentwidnow,andatextualdefault
///selection
CYABFFW(intnHint,constCString&strRoot,UINTnFlags=0U,
CWnd*pParentWnd=NULL,
constCString&strDefaultSel=CString());
/**////ConstructwithahintfromResource,adefaultselection
///expressedasaCSIDLvalue,anarbitraryrootfolder,BFF
///flags,&aparentwidnow
CYABFFW(intnDefaultSel,intnHint,constCString&strRoot,
UINTnFlags=0U,CWnd*pParentWnd=NULL);
//Attributes
public:
/**////Retrievethedisplaynameoftheselecteditem
CStringGetDisplayName()const;
/**////RetrievetheITEMIDLISToftheselecteditem
LPCITEMIDLISTGetItemIdList()const;
/**////Retrievethepathtotheselecteditem
CStringGetPath()const;
//Operations
public:
/**////DisplaytheDialog-returnsIDOKorIDCANCEL
intDoModal();
//Overrides
public:
/**////CalledwhentheBFFDialoghasinitialized
virtualvoidOnInitBFFDialog();
/**////Calledwhentheselectionhaschangedinthetreecontrol
virtualvoidOnBFFSelChanged(LPITEMIDLISTpNewSel);
/**////Calledwhentheusertypesaninvalidname
virtualBOOLOnBFFValidateFailed(constCString&strBadName);
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CYABFFW)
//}}AFX_VIRTUAL
//Implementation
public:
virtual~CYABFFW();
//Generatedmessagemapfunctions
protected:
//{{AFX_MSG(CYABFFW)NOTE-theClassWizardwilladdandremove
//memberfunctionshere.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
/**////StaticmethodtobeusedfortheSHBFFcallback
staticintCALLBACKBrowseCallbackProc(HWNDhWnd,UINTnMsg,
LPARAMlParam,
LPARAMlpData);
private:
/**////Freethememoryreferencedbym_pItemIdList
voidFreeItemIdList(IMalloc*pMalloc=NULL);
/**////CSIDL=>ITEMIDLIST
LPITEMIDLISTResolveCsidl(intnCsidl)const;
/**////Textualfilesystempath=>ITEMIDLIST
LPITEMIDLISTResolveFsPath(constCString&strPath)const;
private:
/**////Displaynameoftheselecteditem
CStringm_strDisplayName;
/**////Flagstobepassedtothebrowsedialog
UINTm_nFlags;
/**////"Hint"tobedisplayedabovethetreecontrol
CStringm_strHint;
/**////ITEMIDLISTidentifyingtheselectedShellitem
LPITEMIDLISTm_pItemIdList;
/**////ParentCWnd(NULL=>Appmainwindow)
CWnd*m_pParentWnd;
/**////Selectedpath
CStringm_strPath;
/**////ITEMIDLISTidentifyingtheroot
LPITEMIDLISTm_pRoot;
/**////Defaultselection,ifgivenastext(emptyifnone)
CStringm_strDefaultSel;
/**////Defaultselection,ifgivenasaCSIDLvalue(NULLifnone)
LPITEMIDLISTm_pDefaultSel;
};
YABFFW.cpp
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->CYABFFW::CYABFFW(constCString&strHint/**//*=CString()*/,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
intnRootFolder/**//*=CSIDL_DESKTOP*/,
constCString&strDefault/**//*=CString()*/):
m_nFlags(nFlags),
m_strHint(strHint),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_strDefaultSel(strDefault),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
m_pRoot=ResolveCsidl(nRootFolder);
}
CYABFFW::CYABFFW(intnDefaultSel,
constCString&strHint/**//*=CString()*/,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
intnRootFolder/**//*=CSIDL_DESKTOP*/):
m_nFlags(nFlags),
m_strHint(strHint),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
m_pRoot=ResolveCsidl(nRootFolder);
m_pDefaultSel=ResolveCsidl(nDefaultSel);
}
CYABFFW::CYABFFW(intnHint,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
intnRootFolder/**//*=CSIDL_DESKTOP*/,
constCString&strDefaultSel/**//*=CString()*/):
m_nFlags(nFlags),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_strDefaultSel(strDefaultSel),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
if(!m_strHint.LoadString(nHint))
AfxThrowResourceException();
m_pRoot=ResolveCsidl(nRootFolder);
}
CYABFFW::CYABFFW(intnDefaultSel,
intnHint,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
intnRootFolder/**//*=CSIDL_DESKTOP*/):
m_nFlags(nFlags),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
if(!m_strHint.LoadString(nHint))
AfxThrowResourceException();
m_pRoot=ResolveCsidl(nRootFolder);
m_pDefaultSel=ResolveCsidl(nDefaultSel);
}
CYABFFW::CYABFFW(constCString&strHint,
constCString&strRoot,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
constCString&strDefaultSel/**//*=CString()*/):
m_nFlags(nFlags),
m_strHint(strHint),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_strDefaultSel(strDefaultSel),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
m_pRoot=ResolveFsPath(strRoot);
}
CYABFFW::CYABFFW(intnDefaultSel,
constCString&strHint,
constCString&strRoot,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/):
m_nFlags(nFlags),
m_strHint(strHint),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
m_pRoot=ResolveFsPath(strRoot);
m_pDefaultSel=ResolveCsidl(nDefaultSel);
}
CYABFFW::CYABFFW(intnHint,
constCString&strRoot,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
constCString&strDefaultSel/**//*=CString()*/):
m_nFlags(nFlags),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_strDefaultSel(strDefaultSel),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
if(!m_strHint.LoadString(nHint))
AfxThrowResourceException();
m_pRoot=ResolveFsPath(strRoot);
}
CYABFFW::CYABFFW(intnDefaultSel,
intnHint,
constCString&strRoot,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/):
m_nFlags(nFlags),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
if(!m_strHint.LoadString(nHint))
AfxThrowResourceException();
m_pRoot=ResolveFsPath(strRoot);
m_pDefaultSel=ResolveCsidl(nDefaultSel);
}
#ifdef_DEBUG
CStringCYABFFW::GetDisplayName()const
{
returnm_strDisplayName;
}
LPCITEMIDLISTCYABFFW::GetItemIdList()const
{
returnm_pItemIdList;
}
CStringCYABFFW::GetPath()const
{
returnm_strPath;
}
#endif//_DEBUG
intCYABFFW::DoModal()
{
//We'llneedthiseventually
HRESULThr;
IMalloc*pMalloc;
if(FAILED(hr=::SHGetMalloc(&pMalloc)))
AfxThrowOleException(hr);
//Fillouta'BROWSEINFO'structuretohandto'SHBrowseFor-
//Folder':
BROWSEINFObrowseInfo;
::ZeroMemory(&browseInfo,sizeof(BROWSEINFO));
browseInfo.hwndOwner=(NULL==m_pParentWnd?NULL:
m_pParentWnd->m_hWnd);
browseInfo.pidlRoot=m_pRoot;
//UseaCStringformemorymanagement
browseInfo.pszDisplayName=
m_strDisplayName.GetBufferSetLength(MAX_PATH);
browseInfo.lpszTitle=m_strHint;
browseInfo.ulFlags=m_nFlags;
browseInfo.lpfn=BrowseCallbackProc;
browseInfo.lParam=(long)this;
if(NULL!=m_pItemIdList)
FreeItemIdList();//Probablyneverhappen,but
if(NULL==(m_pItemIdList=::SHBrowseForFolder(&browseInfo)))
{
//UserCancelledout-cleanup&bail.
m_strDisplayName.ReleaseBuffer();
pMalloc->Release();
returnIDCANCEL;
}
//Right-ifwe'rehere,theuseractuallyselectedanitem.
//Trytogetafullpath.Thiswillfailiftheselecteditem
//isnotpartoftheFileSystem.
::SHGetPathFromIDList(m_pItemIdList,
m_strPath.GetBufferSetLength(MAX_PATH));
//Cleanuptime
m_strPath.ReleaseBuffer();
m_strDisplayName.ReleaseBuffer();
pMalloc->Release();
//Note:m_pItemIdListhas*not*beenfreed!Wekeeparoundin
//casethecallerwantstoretrieveitlater.Itwill
//ultimatelybefree-dinthedestructor.
returnIDOK;
}
voidCYABFFW::OnInitBFFDialog()
{
if(!m_strDefaultSel.IsEmpty())
{
TRACE(_T("Settingthedefaultselectionto%s./n"),
(LPCTSTR)m_strDefaultSel);
SendMessage(BFFM_SETSELECTION,TRUE,(LPARAM)(LPCTSTR)m_strDefaultSel);
}
elseif(m_pDefaultSel)
{
SendMessage(BFFM_SETSELECTION,FALSE,(LPARAM)m_pDefaultSel);
}
}
voidCYABFFW::OnBFFSelChanged(LPITEMIDLIST/**//*pNewSel*/)
{/**//*Nohandlingbydefault*/}
BOOLCYABFFW::OnBFFValidateFailed(constCString&/**//*strBadName*/)
{returnTRUE;/**//*Nohandlingbydefault*/}
CYABFFW::~CYABFFW()
{
HRESULThr;
IMalloc*pMalloc;
if(FAILED(hr=::SHGetMalloc(&pMalloc)))
AfxThrowOleException(hr);
pMalloc->Free(m_pRoot);
FreeItemIdList(pMalloc);
}
BEGIN_MESSAGE_MAP(CYABFFW,CWnd)
//{{AFX_MSG_MAP(CYABFFW)
//NOTE-theClassWizardwilladdandremovemappingmacroshere.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
intCYABFFW::BrowseCallbackProc(HWNDhWnd,
UINTnMsg,
LPARAMlParam,
LPARAMlpData)
{
CYABFFW*pWnd=reinterpret_cast<CYABFFW*>(lpData);
ASSERT_VALID(pWnd);
ASSERT(NULL==pWnd->m_hWnd||hWnd==pWnd->m_hWnd);
if(NULL==pWnd->m_hWnd&&!pWnd->SubclassWindow(hWnd))
AfxThrowOleException(HRESULT_FROM_WIN32(::GetLastError()));
switch(nMsg)
{
caseBFFM_INITIALIZED:
//Indicatesthebrowsedialogboxhasfinished
//initializing.ThelParamvalueiszero.
pWnd->OnInitBFFDialog();
return0;
caseBFFM_SELCHANGED:
//Indicatestheselectionhaschanged.ThelParamparameter
//pointstotheitemidentifierlistforthenewlyselected
//item.
{
LPITEMIDLISTp=reinterpret_cast<LPITEMIDLIST>(lParam);
ASSERT_POINTER(p,ITEMIDLIST);
pWnd->OnBFFSelChanged(p);
return0;
}
caseBFFM_VALIDATEFAILED:
//Indicatestheusertypedaninvalidnameintotheeditbox
//ofthebrowsedialogbox.ThelParamparameteristhe
//addressofacharacterbufferthatcontainstheinvalid
//name.Anapplicationcanusethismessagetoinformthe
//userthatthenameenteredwasnotvalid.Returnzeroto
//allowthedialogtobedismissedornonzerotokeepthe
//dialogdisplayed.
{
LPTSTRp=reinterpret_cast<LPTSTR>(lParam);
ASSERT(!::IsBadStringPtr(p,UINT_MAX));
BOOLbDismissOk=pWnd->OnBFFValidateFailed(CString(p));
returnbDismissOk?0:1;
}
default:
TRACE(_T("WARNING:Unknownmessage0x%08x(0x%08x)")
_T("passedtoCYABFFW::BrowseCallbackProc!/n"),
nMsg,lParam);
return0;
}//EndswitchonnMsg.
}
voidCYABFFW::FreeItemIdList(IMalloc*pMalloc/**//*=NULL*/)
{
if(NULL==m_pItemIdList)
return;
boolbWeRelease=false;
if(NULL==pMalloc)
{
bWeRelease=true;
HRESULThr;
IMalloc*pMalloc;
if(FAILED(hr=::SHGetMalloc(&pMalloc)))
AfxThrowOleException(hr);
}
pMalloc->Free(m_pItemIdList);
if(bWeRelease)
pMalloc->Release();
m_pItemIdList=NULL;
}
LPITEMIDLISTCYABFFW::ResolveCsidl(intnCsidl)const
{
//Short-circuitspecialcase
if(CSIDL_DESKTOP==nCsidl)
returnNULL;
LPITEMIDLISTpidlRoot;
HRESULThr=::SHGetFolderLocation(NULL,nCsidl,NULL,0U,
&pidlRoot);
if(FAILED(hr))
{
ASSERT(NULL==pidlRoot);
AfxThrowOleException(hr);
}
returnpidlRoot;//Callerassumesresponsibility
}
LPITEMIDLISTCYABFFW::ResolveFsPath(constCString&strPath)const
{
USES_CONVERSION;
#ifdef_DEBUG
DWORDdwFileAttrs=::GetFileAttributes(strPath);
ASSERT(0xffffffff!=dwFileAttrs&&
FILE_ATTRIBUTE_DIRECTORY&dwFileAttrs);
#endif//_DEBUG
HRESULThr;
IShellFolder*pDesktop;
if(FAILED(hr=::SHGetDesktopFolder(&pDesktop)))
AfxThrowOleException(hr);
//Unfortunately,T2OLEexpectsanon-conststring,so
LPOLESTRp2=T2OLE(const_cast<LPTSTR>(
static_cast<LPCTSTR>(strPath)));
LPITEMIDLISTpItemIdList;
if(FAILED(hr=pDesktop->ParseDisplayName(NULL,NULL,
p2,
NULL,
&pItemIdList,
NULL)))
{
pDesktop->Release();
AfxThrowOleException(hr);
}
pDesktop->Release();
returnpItemIdList;//Callerassumesresponsibility
}
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->CYABFFW::CYABFFW(constCString&strHint/**//*=CString()*/,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
intnRootFolder/**//*=CSIDL_DESKTOP*/,
constCString&strDefault/**//*=CString()*/):
m_nFlags(nFlags),
m_strHint(strHint),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_strDefaultSel(strDefault),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
m_pRoot=ResolveCsidl(nRootFolder);
}
CYABFFW::CYABFFW(intnDefaultSel,
constCString&strHint/**//*=CString()*/,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
intnRootFolder/**//*=CSIDL_DESKTOP*/):
m_nFlags(nFlags),
m_strHint(strHint),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
m_pRoot=ResolveCsidl(nRootFolder);
m_pDefaultSel=ResolveCsidl(nDefaultSel);
}
CYABFFW::CYABFFW(intnHint,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
intnRootFolder/**//*=CSIDL_DESKTOP*/,
constCString&strDefaultSel/**//*=CString()*/):
m_nFlags(nFlags),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_strDefaultSel(strDefaultSel),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
if(!m_strHint.LoadString(nHint))
AfxThrowResourceException();
m_pRoot=ResolveCsidl(nRootFolder);
}
CYABFFW::CYABFFW(intnDefaultSel,
intnHint,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
intnRootFolder/**//*=CSIDL_DESKTOP*/):
m_nFlags(nFlags),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
if(!m_strHint.LoadString(nHint))
AfxThrowResourceException();
m_pRoot=ResolveCsidl(nRootFolder);
m_pDefaultSel=ResolveCsidl(nDefaultSel);
}
CYABFFW::CYABFFW(constCString&strHint,
constCString&strRoot,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
constCString&strDefaultSel/**//*=CString()*/):
m_nFlags(nFlags),
m_strHint(strHint),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_strDefaultSel(strDefaultSel),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
m_pRoot=ResolveFsPath(strRoot);
}
CYABFFW::CYABFFW(intnDefaultSel,
constCString&strHint,
constCString&strRoot,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/):
m_nFlags(nFlags),
m_strHint(strHint),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
m_pRoot=ResolveFsPath(strRoot);
m_pDefaultSel=ResolveCsidl(nDefaultSel);
}
CYABFFW::CYABFFW(intnHint,
constCString&strRoot,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/,
constCString&strDefaultSel/**//*=CString()*/):
m_nFlags(nFlags),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL),
m_strDefaultSel(strDefaultSel),
m_pDefaultSel(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
if(!m_strHint.LoadString(nHint))
AfxThrowResourceException();
m_pRoot=ResolveFsPath(strRoot);
}
CYABFFW::CYABFFW(intnDefaultSel,
intnHint,
constCString&strRoot,
UINTnFlags/**//*=0U*/,
CWnd*pParentWnd/**//*=NULL*/):
m_nFlags(nFlags),
m_pItemIdList(NULL),
m_pParentWnd(pParentWnd),
m_pRoot(NULL)
{
ASSERT_NULL_OR_VALID(pParentWnd);//Paranoia
if(!m_strHint.LoadString(nHint))
AfxThrowResourceException();
m_pRoot=ResolveFsPath(strRoot);
m_pDefaultSel=ResolveCsidl(nDefaultSel);
}
#ifdef_DEBUG
CStringCYABFFW::GetDisplayName()const
{
returnm_strDisplayName;
}
LPCITEMIDLISTCYABFFW::GetItemIdList()const
{
returnm_pItemIdList;
}
CStringCYABFFW::GetPath()const
{
returnm_strPath;
}
#endif//_DEBUG
intCYABFFW::DoModal()
{
//We'llneedthiseventually
HRESULThr;
IMalloc*pMalloc;
if(FAILED(hr=::SHGetMalloc(&pMalloc)))
AfxThrowOleException(hr);
//Fillouta'BROWSEINFO'structuretohandto'SHBrowseFor-
//Folder':
BROWSEINFObrowseInfo;
::ZeroMemory(&browseInfo,sizeof(BROWSEINFO));
browseInfo.hwndOwner=(NULL==m_pParentWnd?NULL:
m_pParentWnd->m_hWnd);
browseInfo.pidlRoot=m_pRoot;
//UseaCStringformemorymanagement
browseInfo.pszDisplayName=
m_strDisplayName.GetBufferSetLength(MAX_PATH);
browseInfo.lpszTitle=m_strHint;
browseInfo.ulFlags=m_nFlags;
browseInfo.lpfn=BrowseCallbackProc;
browseInfo.lParam=(long)this;
if(NULL!=m_pItemIdList)
FreeItemIdList();//Probablyneverhappen,but
if(NULL==(m_pItemIdList=::SHBrowseForFolder(&browseInfo)))
{
//UserCancelledout-cleanup&bail.
m_strDisplayName.ReleaseBuffer();
pMalloc->Release();
returnIDCANCEL;
}
//Right-ifwe'rehere,theuseractuallyselectedanitem.
//Trytogetafullpath.Thiswillfailiftheselecteditem
//isnotpartoftheFileSystem.
::SHGetPathFromIDList(m_pItemIdList,
m_strPath.GetBufferSetLength(MAX_PATH));
//Cleanuptime
m_strPath.ReleaseBuffer();
m_strDisplayName.ReleaseBuffer();
pMalloc->Release();
//Note:m_pItemIdListhas*not*beenfreed!Wekeeparoundin
//casethecallerwantstoretrieveitlater.Itwill
//ultimatelybefree-dinthedestructor.
returnIDOK;
}
voidCYABFFW::OnInitBFFDialog()
{
if(!m_strDefaultSel.IsEmpty())
{
TRACE(_T("Settingthedefaultselectionto%s./n"),
(LPCTSTR)m_strDefaultSel);
SendMessage(BFFM_SETSELECTION,TRUE,(LPARAM)(LPCTSTR)m_strDefaultSel);
}
elseif(m_pDefaultSel)
{
SendMessage(BFFM_SETSELECTION,FALSE,(LPARAM)m_pDefaultSel);
}
}
voidCYABFFW::OnBFFSelChanged(LPITEMIDLIST/**//*pNewSel*/)
{/**//*Nohandlingbydefault*/}
BOOLCYABFFW::OnBFFValidateFailed(constCString&/**//*strBadName*/)
{returnTRUE;/**//*Nohandlingbydefault*/}
CYABFFW::~CYABFFW()
{
HRESULThr;
IMalloc*pMalloc;
if(FAILED(hr=::SHGetMalloc(&pMalloc)))
AfxThrowOleException(hr);
pMalloc->Free(m_pRoot);
FreeItemIdList(pMalloc);
}
BEGIN_MESSAGE_MAP(CYABFFW,CWnd)
//{{AFX_MSG_MAP(CYABFFW)
//NOTE-theClassWizardwilladdandremovemappingmacroshere.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
intCYABFFW::BrowseCallbackProc(HWNDhWnd,
UINTnMsg,
LPARAMlParam,
LPARAMlpData)
{
CYABFFW*pWnd=reinterpret_cast<CYABFFW*>(lpData);
ASSERT_VALID(pWnd);
ASSERT(NULL==pWnd->m_hWnd||hWnd==pWnd->m_hWnd);
if(NULL==pWnd->m_hWnd&&!pWnd->SubclassWindow(hWnd))
AfxThrowOleException(HRESULT_FROM_WIN32(::GetLastError()));
switch(nMsg)
{
caseBFFM_INITIALIZED:
//Indicatesthebrowsedialogboxhasfinished
//initializing.ThelParamvalueiszero.
pWnd->OnInitBFFDialog();
return0;
caseBFFM_SELCHANGED:
//Indicatestheselectionhaschanged.ThelParamparameter
//pointstotheitemidentifierlistforthenewlyselected
//item.
{
LPITEMIDLISTp=reinterpret_cast<LPITEMIDLIST>(lParam);
ASSERT_POINTER(p,ITEMIDLIST);
pWnd->OnBFFSelChanged(p);
return0;
}
caseBFFM_VALIDATEFAILED:
//Indicatestheusertypedaninvalidnameintotheeditbox
//ofthebrowsedialogbox.ThelParamparameteristhe
//addressofacharacterbufferthatcontainstheinvalid
//name.Anapplicationcanusethismessagetoinformthe
//userthatthenameenteredwasnotvalid.Returnzeroto
//allowthedialogtobedismissedornonzerotokeepthe
//dialogdisplayed.
{
LPTSTRp=reinterpret_cast<LPTSTR>(lParam);
ASSERT(!::IsBadStringPtr(p,UINT_MAX));
BOOLbDismissOk=pWnd->OnBFFValidateFailed(CString(p));
returnbDismissOk?0:1;
}
default:
TRACE(_T("WARNING:Unknownmessage0x%08x(0x%08x)")
_T("passedtoCYABFFW::BrowseCallbackProc!/n"),
nMsg,lParam);
return0;
}//EndswitchonnMsg.
}
voidCYABFFW::FreeItemIdList(IMalloc*pMalloc/**//*=NULL*/)
{
if(NULL==m_pItemIdList)
return;
boolbWeRelease=false;
if(NULL==pMalloc)
{
bWeRelease=true;
HRESULThr;
IMalloc*pMalloc;
if(FAILED(hr=::SHGetMalloc(&pMalloc)))
AfxThrowOleException(hr);
}
pMalloc->Free(m_pItemIdList);
if(bWeRelease)
pMalloc->Release();
m_pItemIdList=NULL;
}
LPITEMIDLISTCYABFFW::ResolveCsidl(intnCsidl)const
{
//Short-circuitspecialcase
if(CSIDL_DESKTOP==nCsidl)
returnNULL;
LPITEMIDLISTpidlRoot;
HRESULThr=::SHGetFolderLocation(NULL,nCsidl,NULL,0U,
&pidlRoot);
if(FAILED(hr))
{
ASSERT(NULL==pidlRoot);
AfxThrowOleException(hr);
}
returnpidlRoot;//Callerassumesresponsibility
}
LPITEMIDLISTCYABFFW::ResolveFsPath(constCString&strPath)const
{
USES_CONVERSION;
#ifdef_DEBUG
DWORDdwFileAttrs=::GetFileAttributes(strPath);
ASSERT(0xffffffff!=dwFileAttrs&&
FILE_ATTRIBUTE_DIRECTORY&dwFileAttrs);
#endif//_DEBUG
HRESULThr;
IShellFolder*pDesktop;
if(FAILED(hr=::SHGetDesktopFolder(&pDesktop)))
AfxThrowOleException(hr);
//Unfortunately,T2OLEexpectsanon-conststring,so
LPOLESTRp2=T2OLE(const_cast<LPTSTR>(
static_cast<LPCTSTR>(strPath)));
LPITEMIDLISTpItemIdList;
if(FAILED(hr=pDesktop->ParseDisplayName(NULL,NULL,
p2,
NULL,
&pItemIdList,
NULL)))
{
pDesktop->Release();
AfxThrowOleException(hr);
}
pDesktop->Release();
returnpItemIdList;//Callerassumesresponsibility
}