MFC 有输入键作为“应用”按钮

Posted

技术标签:

【中文标题】MFC 有输入键作为“应用”按钮【英文标题】:MFC Have enter key act as "apply" button 【发布时间】:2013-09-06 15:14:59 【问题描述】:

在某个对话框中,我希望用户按下回车键使其充当“应用”按钮。到目前为止,我至少能够通过覆盖 CWnd::PreTranslateMessage 使对话框在按 Enter 时不关闭,所以目前它什么也不做,我不知道如何从那里发送应用命令。

【问题讨论】:

【参考方案1】:

每个对话框都应该有一个且只有一个带有BS_DEFPUSHBUTTON style 的按钮,这向对话框表明这是使用 Enter 键激活的按钮。通常这是 OK 按钮,但如果您愿意,也可以将其设为 Apply 按钮。

【讨论】:

【参考方案2】:

正如 Mark 在上面指出的那样,对话框管理器已经内置了所有逻辑来通过调用与默认按钮关联的命令来处理 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。

如果您浏览对话框的控件,您会看到 Apply 按钮具有典型的默认按钮视觉提示,而焦点不在另一个命令按钮上。在非按钮控件具有输入焦点时按 Enter 会调用默认按钮的命令处理程序。不需要额外的代码。

【讨论】:

如何设置 BS_DEFPUSHBUTTON 样式?有这样的功能吗? @bob 有多种方法可以做到这一点:在使用CreateWindow 动态创建控件时传递标志,如果您有对话框资源,则在 .rc 脚本中添加样式,或使用资源编辑器。【参考方案3】:

如果您的意图是在不关闭对话框的情况下处理 Enter 键,那么您可能做错了。请查看this MSDN 文章。虽然使用 PreTranslateMessage 应该可以工作,但这并不是处理这些类型事件的最佳方式。

【讨论】:

【参考方案4】:

您需要处理 OnKeyDown 消息,并在该函数中处理 VK_RETURN 字符。

void MyCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 

    if(nChar == VK_RETURN)  
           
        // Do Stuff 
        return; 
       

    CWnd::OnKeyDown(nChar, nRepCnt, nFlags);

【讨论】:

我还应该在 PreTranslateMessage 中处理它吗?【参考方案5】:
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

【讨论】:

处理PreTranslateMessageOnKeyDown 中的按键将无法显示默认按钮的视觉提示。此外,您建议的实现将执行 两个 操作以响应按 Enter 键。 谢谢。是的,我应该指定,一旦处理完消息,就会从循环中返回 TRUE(如果(nID == ID_APPLY) //DO YOUR STUFF HERE )。因此,我不了解视觉提示。是不是如果我覆盖则不会显示默认提示? 默认按钮具有独特的视觉表示(请参阅Command Buttons 上的默认命令按钮)。对话框管理器的默认实现查找具有BS_DEFPUSHBUTTON 样式的按钮并提供视觉提示。自定义实现可以实现 DM_GETDEFID 消息处理程序以报告默认按钮 ID。对话框管理器不会分析PreTranslateMessage 实现来推断默认按钮ID。

以上是关于MFC 有输入键作为“应用”按钮的主要内容,如果未能解决你的问题,请参考以下文章

在mfc中如何使用按钮依次输入数据

MFC入门

mfc中如何设置编辑框\按钮的外观

在工作线程完成 MFC 时禁用控制变量

MFC中在指定的文档搜索 输入框中的指定内容并显示到指定的文本框中的按钮代码该怎么写啊?在线等

在 mfc 的 cedit 控制中处理箭头键