Q: How can I handle notifications for dynamically created controls, such as BN_CLICKED for a button?
A: When you are creating controls dynamically (not by using a dialog template) you have to do the work the wizard does for you. It involves:
- defining a control ID (should be done in resource.h)
- defining a handler with the correct signature
- adding an entry to the message map of the class
When you define a button ID, make sure the ID is unique, otherwise you could get into problems.
Code:
#define IDC_MY_BUTTON 1234
Of course, the ID is used as argument to the Create() method. Suppose you do that in OnInitDialog():
Code:
BOOL CSampleDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_pMyButton->Create("Dyn Button", WS_CHILD|BS_PUSHBUTTON, CRect(100,100, 28, 100), this, IDC_MY_BUTTON);
return TRUE;
};
In this simplified case, CSampleDialog is a dialog class, that should have at least this declaration:
Code:
class CSampleDialog : public CDialog
{
public:
CSampleDialog(CWnd* pParent = NULL);
protected:
virtual void DoDataExchange(CDataExchange* pDX);
DECLARE_MESSAGE_MAP()
};
You should add here a function that will be the handler of the event. Notice that different handlers could have different signatures.
Code:
afx_msg void OnMyButtonClicked();
You should also provide a body for this function:
Code:
void CSampleDialog::OnMyButtonClicked()
{
}
The whole trick of ensuring the handler is called when the notification arrives is adding an entry to the message map of the CSampleDialog class, specifying the ID of the control and the function to handle the notification:
Code:
BEGIN_MESSAGE_MAP(CSampleDialog, CDialog)
ON_BN_CLICKED(IDC_MY_BUTTON, &CSampleDialog::OnMyButtonClicked)
END_MESSAGE_MAP()