在某个对话框中,我希望用户按下回车键使其充当“应用”按钮。到目前为止,我至少能够通过覆盖 CWnd::PreTranslateMessage 使对话框在按 Enter 时不关闭,所以目前它什么也不做,我不确定如何从那里发送应用命令。
5 回答
每个对话框都应该有一个并且只有一个BS_DEFPUSHBUTTON
样式为 的按钮,它向对话框表明这是使用 Enter 键激活的按钮。通常这是“确定”按钮,但如果您愿意,可以将其设为“应用”按钮。
正如马克在上面指出的那样,对话框管理器已经内置了所有逻辑来Enter通过调用与默认按钮关联的命令来处理键。您可以静态分配BS_DEFPUSHBUTTON
样式或处理DM_GETDEFID
消息。
前者非常简单,而后者实现起来相当简单。确保将对话框上所有按钮的Default Button属性设置为False。现在为消息添加一个消息处理程序DM_GETDEFID
。此消息没有专用宏,因此您必须使用通用处理程序:
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
...
ON_MESSAGE(DM_GETDEFID, OnGetDefId)
END_MESSAGE_MAP()
消息处理程序同样简单,并使用默认的消息处理程序签名:
LRESULT CMyDialog::OnGetDefId(WPARAM wParam, LPARAM lParam)
{
return MAKELRESULT(ID_APPLY, DC_HASDEFID);
}
消息处理程序必须返回一个值,其高位DC_HASDEFID
字包含控件 ID,低位字包含控件 ID。
如果您浏览对话框的控件,您将看到应用按钮具有典型的默认按钮视觉提示,而焦点不在另一个命令按钮上。Enter在非按钮控件具有输入焦点时按下会调用默认按钮的命令处理程序。不需要额外的代码。
如果您的意图是在不关闭对话框的情况下处理 Enter 键,那么您可能做错了。请看一下这篇MSDN 文章。虽然使用 PreTranslateMessage 应该可以工作,但这并不是处理这些类型事件的最佳方式。
You'll need to handle the OnKeyDown message, and handle the VK_RETURN character inside that function.
void MyCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if(nChar == VK_RETURN)
{
// Do Stuff
return;
}
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}
Another way to overwrite the message.
BOOL CMyDialog::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
switch (pMsg->wParam)
{
case VK_RETURN:
{
UINT nID = ::GetDlgCtrlID(pMsg->hwnd);
if (nID == ID_APPLY)
{
//DO YOUR STUFF HERE
}
}
break;
default:
break;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
此外,如果您使用 ::OnKeyDown,则不需要使用 PreTranslateMessage