现在的位置: 首页 > 综合 > 正文

SHBrowseForFolder 函数

2011年07月15日 ⁄ 综合 ⁄ 共 6512字 ⁄ 字号 评论关闭

 

示例代码: 

CString BrowseDirectory(LPCTSTR title) 
{  
    
char dir[MAX_PATH];
    dir[
0]='"0';

    BROWSEINFO bi;  
    bi.hwndOwner=NULL;  
    bi.pidlRoot
=NULL;  
    bi.pszDisplayName
=dir;  
    bi.lpszTitle
=title;  
    bi.ulFlags
=0;  
    bi.lpfn
=NULL;  
    bi.lParam
=NULL;  
    bi.iImage
=NULL;  
    
    SHGetPathFromIDList(SHBrowseForFolder(
&bi),dir);
    
return dir; 
}

显示一个用于选择文件夹的对话框.

语法

    PIDLIST_ABSOLUTE SHBrowseForFolder(      
        LPBROWSEINFO lpbi
    );

参数

    lpbi
        [in]  一个指向BROWSEINFO结构的指针,该指针包含了文件夹选择对话框显示的信息。

返回值

    Returns a pointer to an item identifier list (PIDL) that specifies the location of the selected folder relative to the root of the namespace. If the user chooses the Cancel button in the dialog box, the return value is NULL.

    It is possible that the PIDL returned is that of a folder shortcut rather than a folder. For a full discussion of this case, see the Remarks section.

备注

    You must initialize Component Object Model (COM) before you call SHBrowseForFolder. If you initialize COM using CoInitializeEx, you must set the COINIT_APARTMENTTHREADED flag in its dwCoInit parameter. You can also use CoInitialize or OleInitialize, which always use apartment threading. If you require drag-and-drop functionality, OleInitialize is recommended because it initializes the required OLE as well as COM.
    Note  If COM is initialized using CoInitializeEx with the COINIT_MULTITHREADED flag, SHBrowseForFolder fails if the calling application uses the BIF_USENEWUI or BIF_NEWDIALOGSTYLE flag in the BROWSEINFO structure.

    It is the responsibility of the calling application to call CoTaskMemFree to free the IDList returned by SHBrowseForFolder when it is no longer needed.

    There are two styles of dialog box available. The older style is displayed by default and is not resizable. The newer style provides a number of additional features, including drag-and-drop capability within the dialog box, reordering, deletion, shortcut menus, the ability to create new folders, and other shortcut menu commands. Initially, it is larger than the older dialog box, but the user can resize it. To specify a dialog box using the newer style, set the BIF_USENEWUI flag in the ulFlags member of the BROWSEINFO structure.

    If you implement a callback function, specified in the lpfn member of the BROWSEINFO structure, you receive a handle to the dialog box. One use of this window handle is to modify the layout or contents of the dialog box. Because it is not resizable, modifying the older style dialog box is relatively straightforward. Modifying the newer style dialog box is much more difficult, and not recommended. Not only does it have a different size and layout than the old style, but its dimensions and the positions of its controls change every time it is resized by the user.

    If the BIF_RETURNONLYFSDIRS flag is set in the ulFlags member of the BROWSEINFO structure, the OK button remains enabled for """server" items, as well as """server"share" and directory items. However, if the user selects a """server" item, passing the PIDL returned by SHBrowseForFolder to SHGetPathFromIDList fails.

    SHBrowseForFolder does not display libraries.

    Custom Filtering

    As of Microsoft Windows XP, SHBrowseForFolder supports custom filtering on the contents of the dialog box. To create a custom filter, follow these steps.

       1. Set the BIF_NEWDIALOGSTYLE flag in the ulFlags member of the BROWSEINFO structure pointed to by the lpbi parameter.
       2. Specify a callback function in the lpfn member of that same BROWSEINFO structure.
       3. Code the callback function to receive the BFFM_INITIALIZED and BFFM_IUNKNOWN messages. On receipt of the BFFM_IUNKNOWN message, the callback function's lParam parameter contains a pointer to the dialog box's implementation of IUnknown. Call QueryInterface on that IUnknown to obtain a pointer to an instance of IFolderFilterSite.
       4. Create an object that implements IFolderFilter.
       5. Call IFolderFilterSite::SetFilter, passing to it a pointer to your IFolderFilter. IFolderFilter methods can then be used to include and exclude items from the tree.
       6. Once the filter is created, the IFolderFilterSite interface is no longer needed. Call IFolderFilterSite::Release if you have no further use for it.

    Dealing With Shortcuts
    Note  This section applies to only Windows 2000 and earlier systems. By default, Windows XP and later systems return the PIDL of a shortcut's target rather than the shortcut itself, as long as the BIF_NOTRANSLATETARGETS flag is not set in the BROWSEINFO structure.

    If SHBrowseForFolder returns a PIDL to a shortcut, sending that PIDL to SHGetPathFromIDList returns the path of the shortcut itself rather than the path of its target. The path to the shortcut's target can be obtained by using the IShellLink interface as shown in this example.

    #include
    // Macros for interface casts

    #ifdef __cplusplus
    #define IID_PPV_ARG(IType, ppType) IID_##IType, reinterpret_cast(static_cast(ppType))
    #else
    #define IID_PPV_ARG(IType, ppType) &IID_##IType, (void**)(ppType)
    #endif

    // Retrieves the UIObject interface for the specified full PIDL
    STDAPI SHGetUIObjectFromFullPIDL(LPCITEMIDLIST pidl, HWND hwnd, REFIID riid, void **ppv)
    {
    LPCITEMIDLIST pidlChild;
    IShellFolder* psf;
    *ppv = NULL;
    HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlChild);
    if (SUCCEEDED(hr))
    {
    hr = psf->GetUIObjectOf(hwnd, 1, &pidlChild, riid, NULL, ppv);
    psf->Release();
    }
    return hr;
    }

    #define ILSkip(pidl, cb)       ((LPITEMIDLIST)(((BYTE*)(pidl))+cb))
    #define ILNext(pidl)           ILSkip(pidl, (pidl)->mkid.cb)

    HRESULT SHILClone(LPCITEMIDLIST pidl, LPITEMIDLIST *ppidl)
    {
    DWORD cbTotal = 0;
    if (pidl)
    {
    LPCITEMIDLIST pidl_temp = pidl;
    cbTotal += sizeof (pidl_temp->mkid.cb);
    while (pidl_temp->mkid.cb)
    {
    cbTotal += pidl_temp->mkid.cb;
    pidl_temp += ILNext (pidl_temp);
    }
    }
    *ppidl = (LPITEMIDLIST)CoTaskMemAlloc(cbTotal);
    if (*ppidl)
    CopyMemory(*ppidl, pidl, cbTotal);
    return  *ppidl ? S_OK: E_OUTOFMEMORY;
    }

    // Get the target PIDL for a folder PIDL. This also deals with cases of a folder  
    // shortcut or an alias to a real folder.
    STDAPI SHGetTargetFolderIDList(LPCITEMIDLIST pidlFolder, LPITEMIDLIST *ppidl)
    {
    IShellLink *psl;
    *ppidl = NULL;
    HRESULT hr = SHGetUIObjectFromFullPIDL(pidlFolder, NULL, IID_PPV_ARG(IShellLink, &psl));
    if (SUCCEEDED(hr))
    {
    hr = psl->GetIDList(ppidl);
    psl->Release();
    }

    // It's not a folder shortcut so get the PIDL normally.
    if (FAILED(hr))
    hr = SHILClone(pidlFolder, ppidl);
    return hr;
    }

    // Get the target folder for a folder PIDL. This deals with cases where a folder
    // is an alias to a real folder, folder shortcuts, the My Documents folder, etc.
    STDAPI SHGetTargetFolderPath(LPCITEMIDLIST pidlFolder, LPWSTR pszPath, UINT cchPath)
    {
    LPITEMIDLIST pidlTarget;
    *pszPath = 0;
    HRESULT hr = SHGetTargetFolderIDList(pidlFolder, &pidlTarget);
    if (SUCCEEDED(hr))
    {
    SHGetPathFromIDListW(pidlTarget, pszPath);   // Make sure it is a path
    CoTaskMemFree(pidlTarget);
    }
    return *pszPath ? S_OK : E_FAIL;
    }

    Windows 95/98/Me: SHBrowseForFolder is supported by the Microsoft Layer for Unicode (MSLU). To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems.

抱歉!评论已关闭.