消息映射如何与 SendMessage() 方法交互?
How do message maps interface with the SendMessage() method?
尽管阅读了大量 MSDN 文章,但我似乎无法完全理解 MFC 的消息映射和 SendMessage()
函数。现在我有一个名为 IDC_IPADDRESS_MYADDRESS
的 IP 控件,我想为其设置值。我知道 IPM_SETADDRESS
是正确的消息类型,但我不知道如何成功发送消息并更新 ip 控件的值。
我需要将什么添加到我的消息映射中,
BEGIN_MESSAGE_MAP(myDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &myDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
以及如何正确使用该映射条目来更新 ip 地址控件的值?下面是我尝试在对话框初始化方法中使用 SendMessage() 调用更新它。
// myDlgmessage handlers
BOOL myDlg::OnInitDialog()
{
myDlg::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
//set default IP address
DWORD IP = MAKEIPADDRESS(192, 168, 0, 254);
SendMessage(IPM_SETADDRESS, 0, IP);
return TRUE; // return TRUE unless you set the focus to a control
}
SendMessage(IPM_SETADDRESS, 0, IP);
IPM_SETADDRESS
是正确的消息,但它被发送到主对话框。对话框不查找此消息并忽略它。
您想改为将消息发送到 IP 控件。这意味着您需要 IP 地址控制的 window 句柄:
CWnd *ptr_ip_address = GetDlgItem(IDC_IPADDRESS_MYADDRESS);
if (ptr_ip_address)
ptr_ip_address->SendMessage(IPM_SETADDRESS, 0, IP);
在 MFC 中,您可以使用 CIPAddressCtrl
class 代替。你必须用 DoDataExchange
声明 m_ip_address
和 subclass 它。这个class还有SetAddress
方法。
class CMyDialog : public CDialogEx
{
...
CIPAddressCtrl m_ip_address;
void DoDataExchange(CDataExchange* pDX);
};
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_IPADDRESS_MYADDRESS , m_ip_address);
}
BOOL myDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_ip_address.SetAddress(192, 168, 0, 254);
...
}
MFC 消息映射与您的问题没有直接关系。消息映射用于响应 windows 消息。例如,您想回复 ON_BN_CLICKED
。但是这里你是向控件发送消息,而不是接收消息。
您可以在有关 WinAPI 编程的书籍中阅读更多相关信息。在普通 windows 编程中,有一个 "message loop" 和一个 "windows procedure",您可以在其中回复消息。 MFC 使用消息映射来简化此过程。
BOOL myDlg::OnInitDialog()
{
myDlg::OnInitDialog(); <- recursive
...
}
顺便说一句,把myDlg::OnInitDialog
放在myDlg::OnInitDialog
里会导致栈溢出。改为调用基数 class,CDialogEx::OnInitDialog();
尽管阅读了大量 MSDN 文章,但我似乎无法完全理解 MFC 的消息映射和 SendMessage()
函数。现在我有一个名为 IDC_IPADDRESS_MYADDRESS
的 IP 控件,我想为其设置值。我知道 IPM_SETADDRESS
是正确的消息类型,但我不知道如何成功发送消息并更新 ip 控件的值。
我需要将什么添加到我的消息映射中,
BEGIN_MESSAGE_MAP(myDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &myDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
以及如何正确使用该映射条目来更新 ip 地址控件的值?下面是我尝试在对话框初始化方法中使用 SendMessage() 调用更新它。
// myDlgmessage handlers
BOOL myDlg::OnInitDialog()
{
myDlg::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
//set default IP address
DWORD IP = MAKEIPADDRESS(192, 168, 0, 254);
SendMessage(IPM_SETADDRESS, 0, IP);
return TRUE; // return TRUE unless you set the focus to a control
}
SendMessage(IPM_SETADDRESS, 0, IP);
IPM_SETADDRESS
是正确的消息,但它被发送到主对话框。对话框不查找此消息并忽略它。
您想改为将消息发送到 IP 控件。这意味着您需要 IP 地址控制的 window 句柄:
CWnd *ptr_ip_address = GetDlgItem(IDC_IPADDRESS_MYADDRESS);
if (ptr_ip_address)
ptr_ip_address->SendMessage(IPM_SETADDRESS, 0, IP);
在 MFC 中,您可以使用 CIPAddressCtrl
class 代替。你必须用 DoDataExchange
声明 m_ip_address
和 subclass 它。这个class还有SetAddress
方法。
class CMyDialog : public CDialogEx
{
...
CIPAddressCtrl m_ip_address;
void DoDataExchange(CDataExchange* pDX);
};
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_IPADDRESS_MYADDRESS , m_ip_address);
}
BOOL myDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
m_ip_address.SetAddress(192, 168, 0, 254);
...
}
MFC 消息映射与您的问题没有直接关系。消息映射用于响应 windows 消息。例如,您想回复 ON_BN_CLICKED
。但是这里你是向控件发送消息,而不是接收消息。
您可以在有关 WinAPI 编程的书籍中阅读更多相关信息。在普通 windows 编程中,有一个 "message loop" 和一个 "windows procedure",您可以在其中回复消息。 MFC 使用消息映射来简化此过程。
BOOL myDlg::OnInitDialog() { myDlg::OnInitDialog(); <- recursive ... }
顺便说一句,把myDlg::OnInitDialog
放在myDlg::OnInitDialog
里会导致栈溢出。改为调用基数 class,CDialogEx::OnInitDialog();