等了整整一天了,饥寒交迫呀!在win2000下用vc编了一段代码,用来打开系统的浏览对话框,一直运行的很好,但是昨天装了winxp后,系统就报错了.谁能帮我解决?程序很简单,一个基于对话框的程序,一个按钮,button1,一个编辑框,设ID为IDC_EDIT_FILEPATH,在OnButton1() 中写代码如下:void CUpdate1Dlg::OnButton1() 
{
// TODO: Add your control notification handler code here
   BROWSEINFO bi;
  char  path[MAX_PATH];
  ITEMIDLIST* pidl;
  bi.hwndOwner=0;
  bi.pidlRoot=0;
  bi.lpszTitle=_T("请选择目录:");
  bi.ulFlags=BIF_RETURNONLYFSDIRS;
  bi.lpfn=0;
  bi.iImage=0;
  if(pidl=SHBrowseForFolder(&bi))
  SHGetPathFromIDList(pidl,(unsigned short*)path);  CWnd* ptext=GetDlgItem(IDC_EDIT_FILEPATH);
  ptext->SetWindowText((const unsigned short *)path);   UpdateData();
}

解决方案 »

  1.   

    就是这一行,有办法解决吗?SHGetPathFromIDList(pidl,(unsigned short*)path);
      

  2.   

    上面的方法有内存泄漏。 关键是获得Shell的IMalloc接口指针,因为系统已经在调用函数时为你分配好了内存,这个内存需要调用者去释放,你的代码没有错,但是
    pidl分配的内存没有回收,它应该获得IMalloc接口指针,调用其Free方法以便释放它分配的内存.
    下面是MSDN的描述,我就不再给你翻译了.
    不是没有人回答你的问题,只是因为CSDN比龟爬还慢,你的问题的主题也不明确,通过主题很难知道你的问题是关于哪方面的,感不感兴趣,能不能回答.为回答一个问题等待5到6分钟是不划算的.WINSHELLAPI LPITEMIDLIST WINAPI 
         SHBrowseForFolder(LPBROWSEINFO lpbi);
    typedef struct _browseinfo { 
    HWND hwndOwner;
    LPCITEMIDLIST pidlRoot; 
    LPSTR pszDisplayName; 
    LPCSTR lpszTitle; 
    UINT ulFlags; 
    BFFCALLBACK lpfn; 
    LPARAM lParam; 
    int iImage; 
    } BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO; 
    char szDisplayName[_MAX_PATH];
    BROWSEINFO browseInfo;
    ...
    // initialize structure members...
    ...
    browseInfo.pszDisplayName = szDisplayName;
    // initialize other structure members...
    .CString& BrowseForFolder(HWND hWnd, LPCSTR lpszTitle,
                            UINT nFlags);
    CString strDir = pApp->BrowseForFolder(m_hWnd, 
                                    "Hello, world!", 0);
    CString& CBrowseForFolderApp::BrowseForFolder(
               HWND hWnd, LPCSTR lpszTitle, UINT nFlags)
    {
      // We're going to use the shell to display a 
      // "Choose Directory" dialog box for the user.
      
      CString strResult = ";
      
      LPMALLOC lpMalloc;  // pointer to IMalloc
      if (::SHGetMalloc(&lpMalloc) != NOERROR)
         return strResult; // failed to get allocator  char szDisplayName[_MAX_PATH];
      char szBuffer[_MAX_PATH];
      BROWSEINFO browseInfo;
      browseInfo.hwndOwner = hWnd;
      // set root at Desktop
      browseInfo.pidlRoot = NULL; 
      browseInfo.pszDisplayName = szDisplayName;
      browseInfo.lpszTitle = lpszTitle;   // passed in
      browseInfo.ulFlags = nFlags;   // also passed in
      browseInfo.lpfn = NULL;      // not used
      browseInfo.lParam = 0;      // not used
         LPITEMIDLIST lpItemIDList;
    if ((lpItemIDList = ::SHBrowseForFolder(&browseInfo)) 
           != NULL)
      {
         // Get the path of the selected folder from the
         // item ID list.
    if (::SHGetPathFromIDList(lpItemIDList, szBuffer))
         {
            // At this point, szBuffer contains the path 
            // the user chose.
            if (szBuffer[0] == '\0')
            {
               // SHGetPathFromIDList failed, or
               // SHBrowseForFolder failed.
               AfxMessageBox(IDP_FAILED_GET_DIRECTORY,
                  MB_ICONSTOP|MB_OK);
               return strResult;
            }
         
            // We have a path in szBuffer!
            // Return it.
            strResult = szBuffer;
            return strResult;
         }
         else
         {
            // The thing referred to by lpItemIDList 
            // might not have been a file system object.
            // For whatever reason, SHGetPathFromIDList
            // didn't work!
            AfxMessageBox(IDP_FAILED_GET_DIRECTORY,
               MB_ICONSTOP|MB_OK);
            return strResult; // strResult is empty 
         }
      lpMalloc->Free(lpItemIDList);
      lpMalloc->Release();      
    }// If we made it this far, SHBrowseForFolder failed.
    return strResult;
    }
    不过你完全可以通过COM的方法实现:
    IShellDispatch* disp;
    HRESULT hr;
    hr=CoInitialize(NULL);
    if(FAILED(hr)){
    return S_FALSE;
    }
    hr=CoCreateInstance(CLSID_Shell,NULL,CLSCTX_SERVER,IID_IDispatch,(void**)&disp);
    if(FAILED(hr))
    {
    CoUninitialize();
    return S_FALSE;
    }
    disp->BrowseForFolder (  /* [in] */ long Hwnd,
                /* [in] */ BSTR Title,
                /* [in] */ long Options,
                /* [optional][in] */ VARIANT RootFolder,
                /* [retval][out] */ Folder __RPC_FAR *__RPC_FAR *ppsdf);
    CoUninitialize();