封装一个路径选择对话框

本文详细解析了CPathDialog类的实现,该类用于创建路径选择对话框,包括初始化、模态显示及路径获取等功能。文章深入介绍了成员变量的作用及构造函数、析构函数、DoModal方法和GetPathName方法的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class CPathDialog : public CObject
{
public:
    CPathDialog(LPCTSTR lpszTitle, LPCTSTR pszInitPath=NULL,HWND hParent=NULL);
    virtual ~CPathDialog();
    
    int DoModal();
    CString GetPathName() const;
    static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData);

private:
    HWND m_hParentWnd;
    CString m_strTitle;
    int m_nRootFolder;
    TCHAR m_szPathName[MAX_PATH];
};

CPathDialog::CPathDialog(LPCTSTR lpszTitle, LPCTSTR pszInitPath,HWND hParent):
    m_hParentWnd(hParent),m_strTitle(lpszTitle)
{
    if (pszInitPath)
        _tcscpy(m_szPathName, pszInitPath);
    else
        m_szPathName[0] = '\0';
    m_nRootFolder = CSIDL_DRIVES;
}

CPathDialog::~CPathDialog()
{
}

int CPathDialog::DoModal()
{
    int ret = IDCANCEL;
    LPITEMIDLIST pid1 = NULL, pid2 = NULL;
    LPMALLOC pMalloc = NULL;
    VERIFY(SUCCEEDED(::CoInitialize(NULL)));
    if (m_nRootFolder == 0)
    {
        pid1 = NULL;
    }
    else
    {
        if (!SUCCEEDED(SHGetSpecialFolderLocation(m_hParentWnd, m_nRootFolder, &pid1)))
            goto Done;
    }
    
    if (NOERROR == ::SHGetMalloc(&pMalloc))
    {
        BROWSEINFO bi;
        bi.hwndOwner = m_hParentWnd;
        bi.lpfn = &BrowseCallbackProc;
        bi.pszDisplayName = m_szPathName;
        bi.ulFlags = BIF_STATUSTEXT|BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS;
        bi.lpszTitle = (LPCTSTR)m_strTitle;
        bi.pidlRoot = pid1;
        bi.lParam = (LPARAM)m_szPathName;
        if ((pid2 = ::SHBrowseForFolder(&bi)) != NULL)
        {
            if (::SHGetPathFromIDList(pid2, m_szPathName))
                ret = IDOK;
            pMalloc->(Free(pid2));
        }
    }
    
    if (NULL != pMalloc && pid1 != NULL)
    {
        pMalloc->Free(pid1);
    }
    if (pMalloc != NULL)
    {
        pMalloc->Release();
    }
Done:
    CoUninitialize();
    return ret;
}

CString CPathDialog::GetPathName() const
{
    return m_szPathName;
}

int CALLBACK CPathDialog::BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)
{
    TCHAR szPath[MAX_PATH] = {'\0'};
    switch (uMsg)
    {
    case BFFM_INITIALIZED:
        PostMessage(hwnd, BFFM_SETSELECTION, (WPARAM)1, (LPARAM)lpData);
        break;
    case BFFM_SELCHANGED:
        ::SHGetPathFromIDList((LPITEMIDLIST)lParam, szPath);
        SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0L, (LPARAM)szPath);
        break;
    default:
        break;
    }
    return 0;
}

### 在 IDL 中实现文件选择对话框以让用户选择文件路径 为了在 IDL 中提供一种机制使用户可以选择文件路径,可以借助于 Windows API 或者通过调用外部程序来实现。虽然 IDL 自身并没有内置的文件选择对话框功能,但是可以通过以下两种主要途径达成目的: #### 方法一:使用 `DIALOG_PICKFILE` 实现简单文件选择 IDL 提供了一个名为 `DIALOG_PICKFILE` 的函数,可以直接弹出一个标准的文件选择对话框[^5]。该方法适用于大多数基本场景下的文件选取操作。 下面是一段示例代码演示如何运用 `DIALOG_PICKFILE` 让用户挑选单个或多份文档: ```idl pro pick_files_example result = DIALOG_PICKFILE(/MULTIPLE_FILES, TITLE='Select Files') IF N_ELEMENTS(result) GT 0 THEN BEGIN PRINT, 'Selected files:' FOREACH filename IN result DO BEGIN PRINT, filename ENDFOR ENDIF ELSE BEGIN PRINT, 'No file selected.' ENDELSE end ``` 在此案例中,我们设置了 `/MULTIPLE_FILES` 关键字以便允许多重选择;同时也定制化了窗口标题栏文字为 "Select Files" 。最终打印所选中的全部档案名称列表。 #### 方法二:调用 Windows API 创建更高级别的交互体验 对于更加复杂的要求——例如需要支持新建立资料夹等功能时,则可能需要用到更为底层的技术手段即直接操控操作系统所提供的服务接口。这便涉及到之前提及过的有关 Windows 下创建文件(夹)选择/打开对话框的知识点[^1]^。 具体做法如下所示: ```idl function get_filepath_via_windows_api compile_opt idl2 ; Define necessary constants and types from windows headers. const MAX_PATH = 260 typedef struct { ptr hwndOwner str pszDisplayName[MAX_PATH] ptr pidlRoot str lpszTitle[] uint ulFlags } browseinfo_t common com_browse_info, bi bi = {browseinfo_t, $ hwndOwner: !null, $ ;; Handle to owner window (can set as null). pszDisplayName: replicate(' ',MAX_PATH),$;; Buffer containing address of string to receive item identifier list corresponding to folder selcted by user. pidlRoot: !null,$ ;; Pointer to root PIDL (set this value according to your needs). lpszTitle:"Choose Folder",$ ulFlags:BIF_RETURNONLYFSDIRS OR BIF_NEWDIALOGSTYLE} ;; Flags determining behavior/style of dialog box. extern c_func_shbrowseforfolder : func([ptr],return=ptr) extern c_func_shgetpathfromidlist : func(ptr,str) local_idl=c_func_shbrowseforfolder(addr_of(bi)) if (!local_idl) then return '' filepath=strarr(MAX_PATH) c_func_shgetpathfromidlist(local_idl,filepath) return join(filepath,'') end ``` 上述脚本定义了一种基于 Windows Shell 浏览器的服务来获取目录地址的新方式。其中包含了必要的常量定义以及数据类型的描述,并且还封装成了易于使用的子例行程序形式方便后续重复利用。 --- ### 注意事项 无论采取哪种解决方案,在实际部署过程中都需要考虑到跨平台兼容性问题以及其他细节上的差异调整。另外值得注意的是第二种方案相对较为繁琐而且容易受到环境变动影响因此除非必要一般推荐优先考虑第一类轻量化处理办法即可满足大部分日常需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值