Add controls to CFileDialog

2.2k views Asked by At

How can I add a simple checkbox on a CFileDialog?

MFC seems to have a function CFileDialog::AddCheckButton, which unfortunately is not implemented in WTL..

These missing features (which I find elementary) are getting annoying. Or is WTL just not for me?

1

There are 1 answers

4
Roman Ryltsov On

This is not so elementary. CFileDialog is not exactly the implementation for this functionality, and instead is a wrapper over OPENFILENAME and friends standard API. It is possible to change layout and add controls, however keep in mind this is achieved by hooking/subclassing the window and adding controls and message handlers via Win32 API.

WTL does not offer you helper methods for customization, but it enables the hooking internally (initializing lpfnHook and mapping it to WTL-standard StartDialogProc dialog proc) to help you with quick start. You are supposed to derive from this class, override message handling and you can start your customization from there.

Also note that this is a wrapper over deprecated API. WTL also provides you with fresher stuff: CShellFileOpenDialog, CShellFileSaveDialog.

Code Snippet

This is how you extend the class:

#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;
    }
};

Then you do:

    CMyFileDialog Dialog;
    Dialog.DoModal(m_hWnd);

And you get your control on the bottom:

Screenshot - See Test Button