一个MFC风格的BrowseForFolder 封装类

原文链接:CYABFFW: Yet Another BrowseForFolder Wrapper

以良好的MFC风格将Shell API函数SHBrowseForFolder()封装为一个CWnd子类。

使用示例1

CYABFFWdlg();
if (IDOK == dlg.DoModal())
{
CStrings
=dlg.GetPath();
//Dosomethingwith`s'

使用示例 2
CYABFFWdlg(_T( " Pleaseselectadirectory " ), // Hinttouser

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;

}
;

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
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值