函数的基本概念
PreTranslateMessage
是 MFC 中用来提前拦截并处理消息的虚函数,常用于键盘事件(如回车、ESC)的全局控制,避免消息进入默认流程。
核心作用
- 消息处理的“安检口”:在消息进入窗口的消息循环前,提前拦截处理。
- 返回值决定消息命运:
- 返回
TRUE
:消息被“吃掉”,不再传递。 - 返回
FALSE
:消息继续走默认流程。
- 返回
使用示例
1)对话框中的回车键控制
需求:在某个编辑框按回车时执行操作,而非触发默认按钮(如OK)。
代码示例:
virtual BOOL PreTranslateMessage(MSG* pMsg) override; //头文件重写
///
BOOL CMyDialog::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
{
// 通过资源ID判断焦点控件(替代成员变量判断)
const int nCtrlID = ::GetDlgCtrlID(::GetFocus());
if (nCtrlID == IDC_EDIT_INPUT) // IDC_EDIT_INPUT为资源编辑器定义的控件ID
{
// ...执行自定义逻辑
return TRUE; // 拦截回车,不触发OK按钮
}
}
return CDialog::PreTranslateMessage(pMsg); // 其他情况正常处理
}
2)屏蔽 ESC 键关闭窗口
需求:用户按 ESC 时禁止对话框关闭。
代码片段:
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) {
return TRUE; // 直接拦截ESC
}
3)自定义快捷键
需求:在窗口中实现 Ctrl+Shift+S
快速保存。
代码片段:
if (pMsg->message == WM_KEYDOWN && GetKeyState(VK_CONTROL) < 0) {
if (pMsg->wParam == 'S' && GetKeyState(VK_SHIFT) < 0) {
OnQuickSave(); // 触发保存
return TRUE;
}
}
GetKeyState 返回值的 最高位 表示键是否被按下(1表示按下,0表示未按下)。
避坑指南
-
不要滥用:只在必要时拦截,避免破坏默认交互(如按钮回车失效)。
-
精准判断条件:务必检查焦点控件或组合键状态,防止误拦截。
-
基类调用不可少:非拦截场景必须调用基类方法(如
CDialog::PreTranslateMessage
),否则消息循环可能崩溃!
// 常用虚拟键码表(WinUser.h定义)
#define VK_RETURN 0x0D // 回车键(Enter)
#define VK_ESCAPE 0x1B // ESC键
#define VK_TAB 0x09 // Tab键
#define VK_SPACE 0x20 // 空格键
#define VK_DELETE 0x2E // Delete键
#define VK_LEFT 0x25 // ←方向键
#define VK_UP 0x26 // ↑方向键
#define VK_RIGHT 0x27 // →方向键
#define VK_DOWN 0x28 // ↓方向键
#define VK_F1 0x70 // F1功能键
#define VK_CONTROL 0x11 // Ctrl键
#define VK_SHIFT 0x10 // Shift键