请教关于浏览路径对话框该怎样创建,在<<如何调用浏览路径对话框 ShowMan(原作)>>中 BROWSEINFO bi; ITEMIDLIST*pidl是什么啊!!!

westerly 2002-01-17 12:19:00
...全文
102 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
蒋晟 2002-01-17
  • 打赏
  • 举报
回复
……
忘了……用用就知道了
westerly 2002-01-17
  • 打赏
  • 举报
回复
大哥看不懂啊能把思路说一下吗??
蒋晟 2002-01-17
  • 打赏
  • 举报
回复
怎么汉字贴出来成了乱码??:(
蒋晟 2002-01-17
  • 打赏
  • 举报
回复
//helper function of class BrowseForFolder
#define _ILSkip(pidl, cb) ((LPITEMIDLIST)(((BYTE*)(pidl))+cb))
#define _ILNext(pidl) _ILSkip(pidl, (pidl)->mkid.cb)
extern DECLARE_DLL_PUBLIC_API HRESULT FreeResources(LPVOID pData);
extern DECLARE_DLL_PUBLIC_API HRESULT TestPidl(LPITEMIDLIST pidl);
extern DECLARE_DLL_PUBLIC_API LPITEMIDLIST PidlFromVARIANT(VARIANT* pvarLoc);
extern DECLARE_DLL_PUBLIC_API LPSAFEARRAY MakeSafeArrayFromData(LPBYTE pData,DWORD cbData);
extern DECLARE_DLL_PUBLIC_API HRESULT InitVARIANTFromPidl(LPVARIANT pVar, LPITEMIDLIST pidl);
extern DECLARE_DLL_PUBLIC_API UINT ILGetSize(LPITEMIDLIST pidl);
extern DECLARE_DLL_PUBLIC_API LPITEMIDLIST GetNextItem(LPCITEMIDLIST pidl);
extern DECLARE_DLL_PUBLIC_API int CALLBACK TreeViewCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lpData);
extern DECLARE_DLL_PUBLIC_API LPITEMIDLIST CopyItemID(LPITEMIDLIST pidl);
extern DECLARE_DLL_PUBLIC_API BOOL GetName (LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPSTR lpFriendlyName);
extern DECLARE_DLL_PUBLIC_API void GetNormalAndSelectedIcons (LPITEMIDLIST lpifq, LPTV_ITEM lptvitem);
extern DECLARE_DLL_PUBLIC_API int GetIcon (LPITEMIDLIST lpi, UINT uFlags);
extern DECLARE_DLL_PUBLIC_API LPITEMIDLIST Concatenate(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
extern DECLARE_DLL_PUBLIC_API LPITEMIDLIST Copy(LPCITEMIDLIST pidlSource);
extern DECLARE_DLL_PUBLIC_API UINT GetSize(LPCITEMIDLIST pidl);
extern DECLARE_DLL_PUBLIC_API HRESULT ItemIdListFromPath( LPITEMIDLIST& pidl,LPCSTR szPath);

class DECLARE_DLL_PUBLIC_CLASS CBrowseForFolder
{
public:
CBrowseForFolder( HWND hParent = NULL, //parent window
LPITEMIDLIST pidl = NULL);//root dir
virtual ~CBrowseForFolder() ;
//Attributes
protected:
BROWSEINFO m_bi;
HWND m_hwnd;
LPITEMIDLIST m_pidlRoot;
char m_szDisplayName[MAX_PATH];
char m_szPathSelected[MAX_PATH];
CString m_strTitle;
UINT m_uFlags;
CString m_strPath;
BFFCALLBACK m_lpfn;
static int CALLBACK BrowseCallbackProc( HWND hwnd, UINT uMsg,
LPARAM lParam, LPARAM lpData);
public:
//browse flags,see SHBrowseForFolder
static const DWORD BROWSEFORCOMPUTER;
static const DWORD BROWSEFORPRINTER;
static const DWORD BROWSEINCLUDEFILES;
static const DWORD DONTGOBELOWDOMAIN;
static const DWORD EDITBOX;
static const DWORD RETURNFSANCESTORS;
static const DWORD RETURNONLYFSDIRS;
static const DWORD STATUSTEXT;
static const DWORD VALIDATE;
void SetOwner(HWND hwndOwner);
void SetRoot(LPITEMIDLIST pidl=NULL);
void SetRoot(LPCTSTR lpszRootPath=NULL);
CString GetTitle() ;
void SetTitle(LPCTSTR lpszTitle);
BOOL SetTitle(int nTitleID);
CString GetDisplayName();//if C: has label SYSTEM,the path c:\ is displayed SYSTEM(C:).
CString GetSelectedPath();
void SetFlags(UINT ulFlags);
UINT GetFlags() {return m_bi.ulFlags;};
void SetCallbackFunc(BFFCALLBACK lpfn=BrowseCallbackProc);//you can use your own hook functions.
int GetImage() { return m_bi.iImage;};//get icon index of selected item in system image list.

//Operations
public:
CTreeCtrl* m_pTree;
CEdit* m_pEdit;
BOOL Browse();//display the select folder dialog
protected:
virtual void OnInit() ;
virtual void OnSelChanged( LPITEMIDLIST pidl) ;
virtual void OnValidFailed() ;
void EnableOK(BOOL bEnable) ;
void SetSelection(LPITEMIDLIST pidl) ;
void SetSelection(LPCTSTR lpszPath) ;
void SetStatusText(LPCTSTR lpszText) ;
};
const DWORD CBrowseForFolder::BROWSEFORCOMPUTER=BIF_BROWSEFORCOMPUTER;
const DWORD CBrowseForFolder::BROWSEFORPRINTER=BIF_BROWSEFORPRINTER;
const DWORD CBrowseForFolder::BROWSEINCLUDEFILES=BIF_BROWSEINCLUDEFILES;
const DWORD CBrowseForFolder::DONTGOBELOWDOMAIN=BIF_DONTGOBELOWDOMAIN;
const DWORD CBrowseForFolder::EDITBOX=BIF_EDITBOX;
const DWORD CBrowseForFolder::RETURNFSANCESTORS=BIF_RETURNFSANCESTORS;
const DWORD CBrowseForFolder::RETURNONLYFSDIRS=BIF_RETURNONLYFSDIRS;
const DWORD CBrowseForFolder::STATUSTEXT=BIF_STATUSTEXT;
const DWORD CBrowseForFolder::VALIDATE=BIF_VALIDATE;

//////////////////////////////////////////////////////////////////////
//
// ruction/Destruction
//////////////////////////////////////////////////////////////////////

CBrowseForFolder::CBrowseForFolder( HWND hParent/*=NULL*/,
LPITEMIDLIST pidl/*=NULL*/)
{
m_hwnd = NULL;
SetOwner(hParent);
SetRoot(pidl);
m_lpfn=BrowseCallbackProc;
m_pidlRoot=pidl;
m_bi.ulFlags=EDITBOX |RETURNONLYFSDIRS|STATUSTEXT|BIF_VALIDATE;
}

CBrowseForFolder::~CBrowseForFolder()
{
}
//////////////////////////////////////////////////////////////////////
//
// Implementation
//

void CBrowseForFolder::SetOwner( HWND hwndOwner)
{
if (m_hwnd != NULL)
return;
m_bi.hwndOwner = hwndOwner;
}

void CBrowseForFolder::SetRoot( LPITEMIDLIST pidl)
{
if (m_hwnd != NULL)
return;
m_bi.pidlRoot = pidl;
}

void CBrowseForFolder::SetRoot(LPCTSTR lpszRootPath/*=NULL*/)
{
if(m_hwnd != NULL)
return;
if(lpszRootPath!=NULL){
if(FAILED(ItemIdListFromPath(m_pidlRoot,lpszRootPath))){
TRACE("Error Prasing path:%s.\n",lpszRootPath);
return;
}
m_bi.pidlRoot = m_pidlRoot;
}
else{
m_bi.pidlRoot = NULL;
}
}

CString CBrowseForFolder::GetTitle()
{return m_strTitle;}

void CBrowseForFolder::SetTitle( LPCTSTR lpszTitle)
{if (m_hwnd != NULL)return; m_strTitle=lpszTitle;}

BOOL CBrowseForFolder::SetTitle( int nTitleID)
{
if (nTitleID<= 0)return FALSE;
CString strTitle;
if(!strTitle.LoadString(nTitleID)) return FALSE;
SetTitle(strTitle);
return TRUE;
}

void CBrowseForFolder::SetFlags( UINT ulFlags)
{
if (m_hwnd != NULL) return;
m_bi.ulFlags = ulFlags;
}

CString CBrowseForFolder::GetDisplayName()
{
return m_szDisplayName;
}

CString CBrowseForFolder::GetSelectedPath()
{
return m_szPathSelected;
}

void CBrowseForFolder::SetCallbackFunc(BFFCALLBACK lpfn/*=BrowseCallbackProc*/)
{
m_lpfn=lpfn;
}

BOOL CBrowseForFolder::Browse()
{
BOOL bRet = FALSE;
m_bi.pszDisplayName = m_szDisplayName;
m_bi.lpszTitle = m_strTitle;
m_bi.lpfn=m_lpfn;
m_bi.lParam = (LPARAM)this;
LPITEMIDLIST pidl;
if ((pidl = ::SHBrowseForFolder(&m_bi)) != NULL){
m_strPath.Empty();
if (SUCCEEDED(::SHGetPathFromIDList(pidl, m_szPathSelected))){
bRet = TRUE;
m_strPath = m_szPathSelected;
}
LPMALLOC pMalloc;
//Retrieve a pointer to the shell's IMalloc interface
if (SUCCEEDED(SHGetMalloc(&pMalloc))){
pMalloc->Free(pidl);// free the PIDL that SHBrowseForFolder returned to us.
(void)pMalloc->Release();// release the shell's IMalloc interface
}
}
m_hwnd = NULL;
return bRet;
}

void CBrowseForFolder::OnInit()
{
CDialog dlg;
if(!dlg.Attach(m_hwnd)) return;
if(m_bi.ulFlags&EDITBOX){//initially,the editbox has not the same width the treectrl.Make it the same width.
m_pEdit=NULL;
m_pTree=NULL;
CWnd* pWndChild=dlg.GetWindow(GW_CHILD);
while(pWndChild!=NULL){//seek the editbox and the treectrl.
if(pWndChild->IsKindOf(RUNTIME_CLASS(CEdit)))
m_pEdit=(CEdit*)pWndChild;
if(pWndChild->IsKindOf(RUNTIME_CLASS(CTreeCtrl)))
m_pTree=(CTreeCtrl*)pWndChild;
pWndChild=pWndChild->GetWindow(GW_HWNDNEXT);
}
if(m_pEdit!=NULL&&m_pTree!=NULL){
CRect rcTree,reEdit;
m_pTree->GetWindowRect(&rcTree);
m_pEdit->GetWindowRect(&reEdit);
dlg.ScreenToClient(&rcTree);
dlg.ScreenToClient(&reEdit);
m_pEdit->MoveWindow(reEdit.left,reEdit.top,rcTree.Width(),reEdit.Height());
}
}
dlg.Detach();
}

void CBrowseForFolder::OnSelChanged( LPITEMIDLIST pidl)
{
char pszPath[MAX_PATH];
if(::SHGetPathFromIDList(pidl,pszPath)){//default action,set status text to current selection.
SetStatusText(pszPath);
}
}
void CBrowseForFolder::OnValidFailed()
{
::AfxMessageBox(IDS_INVALID_PATH,MB_TASKMODAL|MB_OK);//display a messagebox.you can provide your own validation messages.
}
void CBrowseForFolder::EnableOK( BOOL bEnable) //disable /enable the ok button
{
if (m_hwnd == NULL) return;
(void)SendMessage(m_hwnd, BFFM_ENABLEOK, (LPARAM)bEnable, NULL);
}

void CBrowseForFolder::SetSelection( LPITEMIDLIST pidl) //set current selection
{
if (m_hwnd == NULL) return;
(void)SendMessage(m_hwnd, BFFM_SETSELECTION, FALSE, (LPARAM)pidl);
}

void CBrowseForFolder::SetSelection( LPCTSTR lpszPath) //set current selection
{
if (m_hwnd == NULL) return;
(void)SendMessage(m_hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpszPath);
}

void CBrowseForFolder::SetStatusText( LPCTSTR lpszText) //set current status
{
if (m_hwnd == NULL) return;
(void)SendMessage(m_hwnd, BFFM_SETSTATUSTEXT, NULL, (LPARAM)lpszText);
}

int CALLBACK CBrowseForFolder::BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)//default hook function.
{
CBrowseForFolder* pbff = (CBrowseForFolder*)lpData;
pbff->m_hwnd = hwnd;
switch(uMsg){
case BFFM_INITIALIZED:
pbff->OnInit();
break;
case BFFM_SELCHANGED:
pbff->OnSelChanged((LPITEMIDLIST)lParam);
break;
case BFFM_VALIDATEFAILED :
pbff->OnValidFailed();
break;
}
return 0;//keep dialog displayed
}

// Exercise the PIDL by performing common operations upon it.
HRESULT TestPidl(LPITEMIDLIST pidl)//ͨ¹ýÖ´Ðг£ÓòÙ×÷²âÊÔPIDL
{
HRESULT hr;
LPSHELLFOLDER pshfDesktop = NULL, pshf = NULL;
DWORD uFlags = SHGDN_NORMAL;
STRRET strret;
if (!pidl){
return E_INVALIDARG;
}
hr = SHGetDesktopFolder(&pshfDesktop);
if (!pshfDesktop){
return hr;
}
//µÃµ½Óëpidl¶ÔÓ¦µÄpshf(ISHELLFODER¶ÔÏó)
hr = pshfDesktop->BindToObject(pidl,NULL,IID_IShellFolder,(LPVOID*)&pshf);
if (!pshf)
goto Error;
//µÃµ½Óëpidl¶ÔÓ¦µÄÏÔʾÃûstrret(·µ»Ø×Ö·û´®)
hr = pshfDesktop->GetDisplayNameOf(pidl, uFlags, &strret);
if (STRRET_WSTR == strret.uType)
FreeResources((LPVOID)strret.pOleStr);
Error:
if (pshf)
pshf->Release();
if (pshf)
pshfDesktop->Release();
return hr;
}

// Use the shell's IMalloc implementation to free resources
HRESULT FreeResources(LPVOID pData)//ʹÓÃÍâ¿ÇµÄImallocʵÏÖÊÍ·Å×ÊÔ´
{
HRESULT hr;
LPMALLOC pMalloc = NULL;

if (SUCCEEDED(hr = SHGetMalloc(&pMalloc)))
{
pMalloc->Free((LPVOID)pData);
pMalloc->Release();
}

return hr;
}

// Given a VARIANT, pull out the PIDL using brute force
LPITEMIDLIST PidlFromVARIANT(LPVARIANT pvarLoc)//´ÓVARIENT±äÁ¿Öеõ½PIDL
{
if (pvarLoc){
if (V_VT(pvarLoc) == (VT_ARRAY|VT_UI1)){
LPITEMIDLIST pidl = (LPITEMIDLIST)pvarLoc->parray->pvData;
return pidl;
}
}
return NULL;
}

// Pack a PIDL into a VARIANT
HRESULT InitVARIANTFromPidl(LPVARIANT pvar, LPITEMIDLIST pidl)//ÔÚVARIENT±äÁ¿Öдæ·ÅPIDL
{
if (!pidl || !pvar) {
return E_POINTER;
}
// Get the size of the pidl and allocate a SAFEARRAY of
// equivalent size
UINT cb = ILGetSize(pidl);
LPSAFEARRAY psa = MakeSafeArrayFromData((LPBYTE)pidl, cb);
if (!psa){
VariantInit(pvar);
return E_OUTOFMEMORY;
}
V_VT(pvar) = VT_ARRAY|VT_UI1;
V_ARRAY(pvar) = psa;
return NOERROR;
}

// Allocate a SAFEARRAY of cbData size and pack pData into it
LPSAFEARRAY MakeSafeArrayFromData(LPBYTE pData, DWORD cbData)//°²È«·ÖÅäcbData´óСµÄ°²È«Êý×飬²¢ÇÒ´æ·ÅpData¡£
{
LPSAFEARRAY psa;
if (!pData || 0 == cbData){
return NULL; // nothing to do
}
// create a one-dimensional safe array of BYTEs
psa = SafeArrayCreateVector(VT_UI1, 0, cbData);
if (psa){
// copy data into the area in safe array reserved for data
// Note we party directly on the pointer instead of using locking/
// unlocking functions. Since we just created this and no one
// else could possibly know about it or be using it, this is okay.
memcpy(psa->pvData,pData,cbData);
}
return psa;
}

// Get the size of the PIDL by walking the item id list
UINT ILGetSize(LPITEMIDLIST pidl)//ͨ¹ý±éÀúÏîÄ¿ÁбíµÃµ½PIDLµÄ´óС
{
UINT cbTotal = 0;
if (pidl){
cbTotal += sizeof(pidl->mkid.cb); // Null terminator
while (pidl->mkid.cb){
cbTotal += pidl->mkid.cb;
pidl = _ILNext(pidl);
}
}
return cbTotal;
}

HRESULT ItemIdListFromPath( LPITEMIDLIST& pidl,LPCSTR szPath)
//szPath is assumpted MAX_PATH size
{
LPSHELLFOLDER pDesktopFolder;
OLECHAR olePath[MAX_PATH];
ULONG chEaten;
ULONG dwAttributes;
HRESULT hr;
//
// Get a pointer to the Desktop's IShellFolder interface.
//
if (FAILED(SHGetDesktopFolder(&pDesktopFolder))){
return -1;
}
//
// IShellFolder::ParseDisplayName requires the file name be in
// Unicode.
//
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, -1, olePath, MAX_PATH);
// Convert the path to an ITEMIDLIST.
hr = pDesktopFolder->ParseDisplayName(NULL,NULL,olePath,&chEaten,
&pidl,&dwAttributes);
if (FAILED(hr)){
// Handle error.
::AfxMessageBox (IDS_FAIL_PARSING_PATH);
}
// pidl now contains a pointer to an ITEMIDLIST for .\readme.txt.
// This ITEMIDLIST needs to be freed using the IMalloc allocator
// returned from SHGetMalloc().
//release the desktop folder object
pDesktopFolder->Release();
return 0;
}

LPITEMIDLIST GetNextItem(LPCITEMIDLIST pidl)
{
if(pidl)
return (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
else
return (NULL);
}
// CopyItemID - creates an item identifier list containing the first
// item identifier in the specified list.
// Returns a PIDL if successful, or NULL if out of memory.
LPITEMIDLIST CopyItemID(LPITEMIDLIST pidl)
{
// Get the size of the specified item identifier.
int cb = pidl->mkid.cb;
LPMALLOC pMalloc;
// Allocate a new item identifier list.
if(::SHGetMalloc (&pMalloc)!=S_OK)
return NULL;
LPITEMIDLIST pidlNew = (LPITEMIDLIST) pMalloc->Alloc(cb + sizeof(USHORT));
if (pidlNew == NULL)
return NULL;
// Copy the specified item identifier.
CopyMemory(pidlNew, pidl, cb);
// Append a terminating zero.
*((USHORT *) (((LPBYTE) pidlNew) + cb)) = 0;
pMalloc->Release ();
return pidlNew;
}

BOOL GetName (LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPSTR lpFriendlyName)
{
BOOL bSuccess = TRUE;
STRRET str;
if (NOERROR == lpsf->GetDisplayNameOf (lpi, dwFlags, &str)){
switch (str.uType){
case STRRET_WSTR:
WideCharToMultiByte ( CP_ACP, // code page
0 ,// dwFlags
str.pOleStr, // lpWideCharStr
-1, // cchWideChar
lpFriendlyName, // lpMultiByteStr
sizeof (lpFriendlyName), // cchMultiByte
NULL, // lpDefaultChar
NULL); // lpUsedDefaultChar
break;
case STRRET_OFFSET:
lstrcpy (lpFriendlyName, (LPSTR)lpi + str.uOffset);
break;
case STRRET_CSTR:
lstrcpy (lpFriendlyName, (LPSTR) str.cStr);
break;
default:
bSuccess = FALSE;
break;
}
}
else
bSuccess = FALSE;
return bSuccess;
}

void GetNormalAndSelectedIcons (LPITEMIDLIST lpifq, LPTV_ITEM lptvitem)
{
// Don't check the return value here.
// If GetIcon() fails, you're in big trouble.
lptvitem->iImage = GetIcon (lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);

lptvitem->iSelectedImage = GetIcon (lpifq,
SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON);

return;
}

int GetIcon (LPITEMIDLIST lpi, UINT uFlags)
{
SHFILEINFO sfi;

SHGetFileInfo ((LPCSTR)lpi, 0, &sfi, sizeof (SHFILEINFO), uFlags);

return sfi.iIcon;
}

int CALLBACK TreeViewCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
{
LPSHELLFOLDER lpsf = (LPSHELLFOLDER)lpData;
if(!lpsf)
return 0;
return (int)lpsf->CompareIDs(0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);
}
LPITEMIDLIST Concatenate(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
LPITEMIDLIST pidlNew;
UINT cb1 = 0,cb2 = 0;
//are both of these NULL?
if(!pidl1 && !pidl2)
return NULL;
//if pidl1 is NULL, just return a copy of pidl2
if(!pidl1)
{
pidlNew = Copy(pidl2);
return pidlNew;
}
//if pidl2 is NULL, just return a copy of pidl1
if(!pidl2)
{
pidlNew = Copy(pidl1);
return pidlNew;
}
cb1 = GetSize(pidl1) - sizeof(ITEMIDLIST);
cb2 = GetSize(pidl2);
//create the new PIDL
LPMALLOC pMalloc;
if(::SHGetMalloc (&pMalloc)!=S_OK)
return NULL;
pidlNew = (LPITEMIDLIST)pMalloc->Alloc(cb1 + cb2);
if(pidlNew)
{
//copy the first PIDL
CopyMemory(pidlNew, pidl1, cb1);
//copy the second PIDL
CopyMemory(((LPBYTE)pidlNew) + cb1, pidl2, cb2);
}
pMalloc->Release ();
return pidlNew;
}
LPITEMIDLIST Copy(LPCITEMIDLIST pidlSource)
{
LPITEMIDLIST pidlTarget = NULL;
UINT cbSource = 0;
if(NULL == pidlSource)
return (NULL);
LPMALLOC pMalloc;
if(::SHGetMalloc (&pMalloc)!=S_OK)
return NULL;
// Allocate the new pidl
cbSource = GetSize(pidlSource);
pidlTarget = (LPITEMIDLIST)pMalloc->Alloc(cbSource);
if(!pidlTarget)
return (NULL);
// Copy the source to the target
CopyMemory(pidlTarget, pidlSource, cbSource);
pMalloc->Release ();
return pidlTarget;
}
UINT GetSize(LPCITEMIDLIST pidl)
{
UINT cbTotal = 0;
LPITEMIDLIST pidlTemp = (LPITEMIDLIST) pidl;
if(pidlTemp)
{
while(pidlTemp->mkid.cb)
{
cbTotal += pidlTemp->mkid.cb;
pidlTemp = GetNextItem(pidlTemp);
}
//add the size of the NULL terminating ITEMIDLIST
cbTotal += sizeof(ITEMIDLIST);
}
return (cbTotal);
}

1,658

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 非技术类
社区管理员
  • 非技术类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧