【问题标题】:Add controls to CFileDialog向 CFileDialog 添加控件
【发布时间】:2013-12-22 10:40:55
【问题描述】:

如何在 CFileDialog 上添加一个简单的复选框?

MFC好像有个函数CFileDialog::AddCheckButton,可惜WTL中没有实现..

这些缺失的功能(我认为这些功能很基础)越来越烦人。还是 WTL 不适合我?

【问题讨论】:

    标签: c++ winapi wtl


    【解决方案1】:

    这不是那么简单。 CFileDialog 不完全是此功能的实现,而是对 OPENFILENAME 和朋友标准 API 的包装。可以更改布局和添加控件,但请记住,这是通过挂钩/子类化窗口并通过 Win32 API 添加控件和消息处理程序来实现的。

    WTL 不为您提供自定义帮助方法,但它在内部启用挂钩(初始化 lpfnHook 并将其映射到 WTL 标准 StartDialogProc 对话过程)以帮助您快速启动。你应该从这个类派生,覆盖消息处理,你可以从那里开始你的定制。

    另请注意,这是对已弃用 API 的封装。 WTL 还为您提供更新鲜的东西:CShellFileOpenDialogCShellFileSaveDialog

    代码片段

    这是扩展类的方式:

    #include <atlmisc.h>
    
    class CMyFileDialog :
        public CFileDialogImpl<CMyFileDialog>
    {
    public:
    
    BEGIN_MSG_MAP(CMyFileDialog)
        CHAIN_MSG_MAP(CFileDialogImpl<CMyFileDialog>)
        MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
        COMMAND_HANDLER(123, BN_CLICKED, OnTestClicked)
    END_MSG_MAP()
    
    private:
        CButton m_Button;
    
    public:
    // CMyFileDialog
        CMyFileDialog() :
            CFileDialogImpl<CMyFileDialog>(TRUE)
        {
        }
    
    // Window Message Handler
        LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL& bHandled)
        {
            CRect Position;
            ATLVERIFY(GetWindowRect(Position));
            ATLVERIFY(SetWindowPos(NULL, 0, 0, Position.Width(), Position.Height() + 50, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE));
            CRect ButtonPosition;
            ButtonPosition.left = 10;
            ButtonPosition.top = Position.Height() + 10;
            ButtonPosition.right = 90;
            ButtonPosition.bottom = ButtonPosition.top + 20;
            m_Button.Create(m_hWnd, ButtonPosition, _T("Test"), CControlWinTraits::GetWndStyle(0), CControlWinTraits::GetWndExStyle(0), 123);
            bHandled = FALSE;
            return 0;
        }
        LRESULT OnTestClicked(UINT, INT, HWND, BOOL&)
        {
            AtlMessageBox(m_hWnd, _T("Test"), _T("Debug"), MB_ICONINFORMATION | MB_OK);
            return 0;
        }
    };
    

    然后你做:

        CMyFileDialog Dialog;
        Dialog.DoModal(m_hWnd);
    

    您可以控制底部:

    【讨论】:

    • 好的,这是有道理的。我应该从哪个类派生? (CFileDialogImpl?)我也尝试了CShellFileOpenDialog,但出现“未声明的标识符”错误;包括 atldlgs.h (WTL 8.0)。另外,对于消息处理覆盖,我不知道该怎么做。你是在谈论OnInitDoneOnFolderChange等函数吗?
    • 感谢您的大力帮助。该按钮正在工作,但仅在调整对话框大小后才会出现,并且当我更改文件夹时所有控件都会消失(i.stack.imgur.com/CL9ES.png)。我使用的是 WinXP,这有什么不同吗?
    • 我没有回答你的最后一个问题。我的运行是在 Win 7 上运行的,显然存在差异(UI 本身也不同)。正如 UI 挂钩经常发生的那样,答案可能很容易找到,但需要动手调试:使用 Spy++ 检查当前窗口状态、消息跟踪。
    • 也许您没有回复某些消息,或者您需要在完成初始化添加后发布额外的虚假调整大小通知。或者,您可能需要先添加控件,然后调整容器窗口的大小,或者您需要自己额外处理大小通知并更新控件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 2022-01-23
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多