3

I have a GUI project at work that uses MFC.

The widgets (controls) have message processing in a compile-time message map table.

I want to conditionally add controls to the form during runtime, but I'm stuck on how to append message handlers to the message map during runtime.

How do I add message handlers to the MFC message map during runtime?

Is there an alternate process that I should use?

See MFC Message Maps documentation for information about message maps.

Environment:
Windows 7 or Windows 10 (The application works on both OS)
Visual Studio 2017

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • Yes, I know there are other GUI frameworks out there, but I don't have time in the schedule to switch the GUI to another framework, like wxWidgets. – Thomas Matthews Apr 10 '20 at 16:38
  • I haven't tried this, but you might be able to derive another class from your class with the message map you want to change, override the undocumented `virtual const AFX_MSGMAP* GetMessageMap() const;` function, and return a pointer to a message map that you can construct. – 1201ProgramAlarm Apr 10 '20 at 17:15
  • @1201ProgramAlarm Another roadblock I had earlier was how to define a message map for a custom (inherited) control. Still haven't found an example. – Thomas Matthews Apr 10 '20 at 17:16
  • You can (maybe) set up your custom controls to post `WM_NOTIFY` messages, which can handle a whole host of different things, depending on how you customize the associated `NMHDR` strcuture. – Adrian Mole Apr 10 '20 at 17:36

1 Answers1

2

If you know the range of the "ID" values you give to your added controls (as you should), then you can use the ON_CONTROL_RANGE entry in your message map, rather than the ON_CONTROL (which is typically used for a specific, single control). For example, for a button click on one of your controls (which has an ID in the range IDC_FIRST thru IDC_LAST, you can add the following message map entry:

    ON_CONTROL_RANGE(BN_CLICKED, IDC_FIRST, IDC_LAST, OnButtonClick)

The message handler, OnButtonClick, has a very similar format to that for a single control, but with a UINT parameter that is the ID of the control that sent the message:

void MyDialog::OnButtonClick(UINT nID)
{
    int button_number = static_cast<int>(nID - IDC_FIRST);
    // .. do something
    return;
}

Feel free to ask for further clarification and/or explanation.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83