如何处理MFC应用程序中动态创建的控件的消息?

时间:2009-05-13 10:10:09

标签: c++ visual-c++ mfc event-handling

想象一下,我有一个CDialog,可以在用户单击按钮时动态创建控件。它可能是这样的:

// We don't know which is the first id for the new buttons until runtime (!)
MyDialog::MyDialog(/*whatever parameters needed*/, first_id)
  : next_id_(first_id) 
{ /*...*/ }

BOOL MyDialog::OnSomeButtonClicked()
{
  CButton* new_button = new CButton;
  new_button->Create("Caption", WS_CHILD | WS_VISIBLE, this->new_button_rect_, 
                     this, this->next_id_++);
}

然后我的问题是:我怎么能处理这个按钮的消息?是否可以使用MFC消息映射工具?

解决方案应该在vs6和vs2005中都有效。

谢谢!

7 个答案:

答案 0 :(得分:6)

这些是迄今为止我发现的解决方案:

  1. 如果您可以定义要处理的控件ID的范围,请使用ON_COMMAND_RANGE

  2. 重载CWnd::PreTranslateMessage()并根据收到的消息执行您想要的任何操作。注意:处理按钮时,请考虑BN_CLICKED事件未发送到PreTranslateMessage但直接发送到窗口过程。

  3. 重载CWnd::WindowProc()并根据收到的消息执行您想要的任何操作。请注意,在处理按钮时,这是我发现处理BN_CLICKED事件的唯一方式。

  4. 有趣的链接:

    我希望这有帮助...谢谢大家的贡献。

答案 1 :(得分:5)

即使你不知道id的确切值,如果你知道ID的可能范围,那么可以使用以下宏。

BEGIN_MESSAGE_MAP(MyDialog, CDialog)
    ...
    ...
    ON_COMMAND_RANGE(1000, 5000, OnButtonDynamic)
END_MESSAGE_MAP()


void MyDialog::OnButtonDynamic(UINT nID)
{

}

这适用于1000 - 5000范围内的ID。

答案 2 :(得分:2)

我可以在这个聚会上迟到几年,但解决方法是为每个按钮分配相同的控制ID(无需在资源中保留' id。 h,并且没有人为限制可以创建的控件数量,保存窗口句柄并在该按钮的处理程序中使用GetCurrentMessage():

// resource.h
#define IDC_DYNAMIC_BUTTON 123

// In message map
ON_BN_CLICKED(IDC_DYNAMIC_BUTTON, OnDynamicButtonClicked)

// Store the window handles when creating them in a member:
std::map<HWND, SomeStruct> m_Buttons;
... fill this map when creating the buttons, presumably in OnInitDialog()

// Actual handler
void MyDialog::OnDynamicButtonClicked()
{
    const MSG* message = GetCurrentMessage();

    if (m_Buttons.find((HWND)message->lParam) != m_Buttons.end()) {
        // Do something with m_Buttons[(HWND)message->lParam]
    }
}

答案 3 :(得分:0)

我相信这篇文章很好地解释了它并且有源代码。我没有试过这个,所以我不能保证它有效,但是在我认为它可能有帮助的时候。

Article

答案 4 :(得分:0)

您可以在无模式对话框there上找到详细信息(+更多)。

答案 5 :(得分:0)

在Resouce.h中插入处理程序ID的条目 然后将该条目插入到处理程序的消息映射中,如ON_BN_CLICKED(IDC_BTNCREATE,OnBnClickedrunCreated)  或者您可以直接使用整数ID,如ON_BN_CLICKED(1200,OnBnClickedrunCreated)。如果您使用第二个版本,那么就有  无需在resource.h中插入条目。在.h和.cpp文件中给出处理程序的定义和声明。你会得到答案。

答案 6 :(得分:0)

使用这种方式:ON_CONTROL_RANGE(wNotifyCode,id1,id2,memberFxn)。 例如:

ON_CONTROL_RANGE(EN_UPDATE, IDC_EDIT_START, IDC_EDIT_END, OnEnUpdateEditParams)