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

9

假设我有一个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个回答

8

以下是我目前找到的解决方案,按相关性排序:

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

  2. 重载CWnd::PreTranslateMessage()并对接收到的消息进行处理。注意:处理按钮时,请注意BN_CLICKED事件不会发送到PreTranslateMessage而是直接发送到窗口过程中。

  3. 重载CWnd::WindowProc()并对接收到的消息进行处理。请注意,处理按钮时,这是我找到的唯一处理BN_CLICKED事件的方法。

有趣的链接:

希望这些能帮到您...感谢您所有的贡献。


7

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

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


void MyDialog::OnButtonDynamic(UINT nID)
{

}

这将适用于范围在1000-5000之间的ID。

谢谢你的回答,但我怎么能提前知道范围呢? - David

3

我虽然晚了几年才参加这个聚会,但是解决这个问题的方法是给每个按钮分配相同的控件id(无需在resource.h中“保留”id,并且没有人工限制可以创建的控件数量),保存窗口句柄并在该按钮的处理程序中使用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]
    }
}

0
使用方法:ON_CONTROL_RANGE(wNotifyCode, id1, id2, memberFxn)。 例如:
ON_CONTROL_RANGE(EN_UPDATE, IDC_EDIT_START, IDC_EDIT_END, OnEnUpdateEditParams)

0

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


0

我相信这篇文章讲得很清楚,并且提供了源代码。虽然我没有尝试过,无法保证它能够正常工作,但在我思考的时间里,它可能会有所帮助。

文章


好的,对于这种情况使用PreTranslateMessage可能是可以的,但我一直在想是否有一种方法可以使用MFC消息映射机制。 :S - David

0

您可以在此处找到有关无模式对话框的详细信息(以及更多)链接


我觉得这与此无关。 :S - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接