您的位置:首页 > 运维架构 > Shell

Shell函数;COM对象;浏览文件夹;SHBrowseForFolder;BROWSEINFO;SHGetPathFromIDList

2016-12-19 12:44 567 查看
转自:http://blog.csdn.net/tcjiaan/article/details/8683056

浏览目录我们同样有两个规矩,用托管类库的我
4000
就不说了,相信大家两分钟就能弄好。重点还是说说第二个规矩,用API方式。我们用到的是Shell函数,一提到Shell,可能有朋友会感到痛苦,因为它很多函数涉及到COM,不过,也没什么了,反正我的哲学理念是立足于实战。所以,我给大家总结了思路。

就拿今天我们要用到的SHBrowseForFolder函数来说吧,先说说这个函数的用途吧,一句话概括:显示一个对话框,让你可以选择一个目录

COM对象需要先初始化,再用,用完了释放,根据这个思路,大的步骤如下:

1、CoInitialize(NULL); //初始化。

2、调用函数。

3、CoUninitialize(); //释放。

这个动作就好比你去租用商家的自行车去游玩,别人只是把资源(自行车)借给你用,你给押金(引用计数),等到你耍完了,再去把资源还给人家。

要调用SHBrowseForFolder函数,先初始化它的参数,也就是BROWSEINFO结构体,这个家伙初始化后,将地址传给SHBrowseForFolder的lpbi参数。BROWSEINFO结构你得设置以下成员。

[cpp] view
plain copy

 print?

PIDLIST_ABSOLUTE pIDLIST;//函数返回的值存在这里  

BROWSEINFO brsInfo;  

WCHAR fdpath[MAX_PATH]; //接收选择目录的字符数组  

  

。。。。。。。。。。。。。。。。。。。  

brsInfo.hwndOwner = hWnd; //拥有者窗口  

brsInfo.pidlRoot = NULL; //根目录为桌面  

brsInfo.pszDisplayName = fdpath; //返回的被选择的路径  

brsInfo.lpszTitle = L"请选择目录"; //对话框标题  

brsInfo.ulFlags= BIF_RETURNONLYFSDIRS | BIF_DONTGOBELOWDOMAIN | BIF_NEWDIALOGSTYLE; //不显示网络路径  

brsInfo.lpfn = NULL; //没有回调  

brsInfo.lParam = NULL; //没有额外参数  

之后就可以调用函数了。

[cpp] view
plain copy

 print?

// 初始化COM组件,用完后记得释放  

CoInitialize(NULL);  

pIDLIST = SHBrowseForFolder(&brsInfo);  

if(pIDLIST)  

{  

    //取出对话框中用来显示结果的控件  

    HWND hStatic = GetDlgItem(hfDlg, IDC_DISPLAY);  

    SendMessage(hStatic,WM_SETTEXT, NULL, 
16b62
(LPARAM)fdpath);  

}  

CoUninitialize();  

// 释放IDLIST  

CoTaskMemFree((LPVOID)pIDLIST);  

由于PIDLIST也是COM对象资源,通过调用CoTaskMemFree函数将其释放。

现在,运行一下应用程序。



 



 

聪明的你会发现,虽然我们得到了选择的目录名字,但不是完整路径,通常我们是需要完整的路径的。这个也不难,我们再请出另一个函数——SHGetPathFromIDList,它可以帮我们得出完整的路径。

所以,我们把上面的代码修改一下。

[cpp] view
plain copy

 print?

if(pIDLIST)  

{  

    //得到完整路径  

    SHGetPathFromIDList(pIDLIST, fullPath);  

    //取出对话框中用来显示结果的控件  

    HWND hStatic = GetDlgItem(hfDlg, IDC_DISPLAY);  

    SendMessage(hStatic, WM_SETTEXT, NULL, (LPARAM)fullPath);  

    //SendMessage(hStatic,WM_SETTEXT, NULL, (LPARAM)fdpath);  

}  

现在再看看结果,这回你肯定满意了。



 

-------------- 【C++ Code】 -------------------------

[cpp] view
plain copy

 print?

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  

{  

    int wmId, wmEvent;  

    PAINTSTRUCT ps;  

    HDC hdc;  

  

    PIDLIST_ABSOLUTE pIDLIST;//函数返回的值存在这里  

    BROWSEINFO brsInfo;  

    WCHAR fdpath[MAX_PATH]; //接收选择目录的字符数组  

    WCHAR fullPath[MAX_PATH]; //完整路径  

  

    static HWND hfDlg;  

  

    switch (message)  

    {  

    case WM_CREATE:  

        hfDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_FORMVIEW), hWnd, NULL);  

        ShowWindow(hfDlg,SW_SHOW);  

        break;  

    case WM_COMMAND:  

        wmId    = LOWORD(wParam);  

        wmEvent = HIWORD(wParam);  

        // 分析菜单选择:  

        switch (wmId)  

        {  

        case IDM_ABOUT:  

            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);  

            break;  

        case IDM_EXIT:  

            DestroyWindow(hWnd);  

            break;  

        case IDM_BROWSFOLDER:  

            brsInfo.hwndOwner = hWnd; //拥有者窗口  

            brsInfo.pidlRoot = NULL; //根目录为桌面  

            brsInfo.pszDisplayName = fdpath; //返回的被选择的路径  

            brsInfo.lpszTitle = L"请选择目录"; //对话框标题  

            brsInfo.ulFlags= BIF_RETURNONLYFSDIRS | BIF_DONTGOBELOWDOMAIN | BIF_NEWDIALOGSTYLE; //不显示网络路径  

            brsInfo.lpfn = NULL; //没有回调  

            brsInfo.lParam = NULL; //没有额外参数  

            // 初始化COM组件,用完后记得释放  

            CoInitialize(NULL);  

            pIDLIST = SHBrowseForFolder(&brsInfo);  

            if(pIDLIST)  

            {  

                //得到完整路径  

                SHGetPathFromIDList(pIDLIST, fullPath);  

                //取出对话框中用来显示结果的控件  

                HWND hStatic = GetDlgItem(hfDlg, IDC_DISPLAY);  

                SendMessage(hStatic, WM_SETTEXT, NULL, (LPARAM)fullPath);  

                //SendMessage(hStatic,WM_SETTEXT, NULL, (LPARAM)fdpath);  

            }  

            CoUninitialize();  

            // 释放IDLIST  

            CoTaskMemFree((LPVOID)pIDLIST);  

            break;  

        default:  

            return DefWindowProc(hWnd, message, wParam, lParam);  

        }  

        break;  

    case WM_PAINT:  

        hdc = BeginPaint(hWnd, &ps);  

        // TODO: 在此添加任意绘图代码...  

        EndPaint(hWnd, &ps);  

        break;  

    case WM_DESTROY:  

        PostQuitMessage(0);  

        break;  

    default:  

        return DefWindowProc(hWnd, message, wParam, lParam);  

    }  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: