2
votes

I'm working on the library, that wraps some MFC classes and methods. I want the user to be able to dynamically create a CDialogEx using a template in memory. For the modal dialogs, I call CDialog::InitModalIndirect and then CDialog::DoModal. For the modeless dialogs, I call CDialog::CreateIndirect and then CWnd::Show.

The code looks something like this:

// inside my library
class MyDialog : public CDialogEx
{
public:
    MyDialog(CWnd* parent) : CDialogEx()
    {
        parent_ = parent;
        my_template_data_ = CreateSomeGenericTemplate();
        // OnInitDialog should be preferably called here
    }

    void ShowModal()
    {
        InitModalIndirect(my_template_data_, parent_);
        DoModal(); // but it's called here - too late
    }

    void ShowModeless()
    {
        CreateIndirect(my_template_data_, parent_);
        Show(); // but it's called here - too late
    }

    MyButton* GetButton(int id)
    {
        // returns the instance of my MyButton, which is a subclassed CButton
    }

private:
    BOOL MyDialog::OnInitDialog() override
    {
        CDialogEx::OnInitDialog();
        
        // CWnd::Create for the UI controls can only be called here
    }
};

// user's code
// user creates the dialog - in the constructor it's not clear if modal or modeless
1. MyDialog user_dialog(some_parent); // here, I need the controls to be created
2. user_dialog.GetButton(42)->SetWindowText(L"new text"); // user wants to initialize his controls
// but he can't, because MyButton::Create was not called yet
3. user_dialog.ShowModal(); // and only then display the dialog
//by default, here the MFC calls OnInitDialog - too late,
//the SetText method needed to be set on line 2.

My problem is, that the dialog's controls (buttons etc.) can only be created inside the CDialog::OnInitDialog method, which is called automatically after DoModal (for modal)/Show (for modeless) methods. I need the controls to be created and properly initialized (with the CWnd::Create method) preferably inside the constructor. I thought about calling Show/DoModal directly inside the constructor but I don't yet know if it's going to be modal or modeless dialog. It there a solution to this? Many thanks in advance.

1

1 Answers

0
votes

Why don't you refactor your code and put the common code in a InitUI() method and call it from both sides?

And don't init interface on the constructor. Do it in OnInitDialog for modal; and in Create, or OnCreate (which implies a ON_WM_CREATE() map entry) for modeless dialogs.