MFC中非模态对话框不响应PreTranslateMessage函数的解决方法
MFC回车键不关闭对话框

MFC回车键不关闭对话框以及变成TAB键效果之前在弄完这个十六进制字符串异或的工具后,发现直接按回车键就直接关闭了工具。
网上搜了下解决方案,然后自己的总结如下4种方法:1 设置一个默认按钮(不推荐)如前文小节5中所述,只要将“进行异或”这个按钮属性中的Default Button设置为"TRUE"就行了。
但是这样就直接触发这个按钮对应的事件OnBnClickedButton1,而不是对输入的数据进行合法性检查。
2 比较推荐的是重载OnOK()函数或者PreTranslateMessage()函数首先我们需要找到这两个函数的位置,方法有两种,效果都是殊途同归:在类视图中点击对话框类(CHexStrXorDlg),然后在“属性”中点击菜单栏上的“重写”按钮,可以选择需要重写的函数。
或者直接点击“项目”——“类向导”,“类名”选择对话框类(CHexStrXorDlg),点击“虚函数”就可以看到可以被重载的函数了,右侧是已经被重载了的函数。
3 取消回车的效果通过重载OnOK()函数,然后函数体内不做任何处理,这样就可以直接屏蔽回车键的效果了。
void CHexStrXorDlg::OnOK(){//CDialog::OnOK();return;}4 获取焦点位置,根据是否在Button按钮资源上做相应处理通过重载PreTranslateMessage()消息函数,可以改变MFC的消息控制流程,能自主处理键盘和鼠标消息。
于是,先捕捉到回车键所在的控件焦点,然后判断是否是Button按钮。
如果焦点在Button按钮上,则给资源ID为i的Button按钮发送点击消息,否则设置下一个控件得到输入焦点。
BOOL CHexStrXorDlg::PreTranslateMessage(MSG* pMsg){// TODO: 在此添加专用代码和/或调用基类if ((pMsg->message == WM_KEYDOWN && (int)pMsg->wParam == VK_RETURN)) {CWnd * wind = GetFocus();if (wind){//判断焦点是否在Button按钮上char str[50];CString ClassName = _T("Button");GetClassName(wind->m_hWnd, str, 50);if (ClassName == str){UINT i = wind->GetDlgCtrlID();SendMessage(WM_COMMAND, i, (LPARAM)wind->m_hWnd);return TRUE;}}//获取当前焦点所在控件的下一个控件的句柄wind = GetNextDlgTabItem(GetFocus());if (wind){//设置下一个控件得到输入焦点wind->SetFocus();return TRUE;}}return CDialogEx::PreTranslateMessage(pMsg);}5 直接把回车键的效果替换成TAB键的效果同小节4中一样,先要获取焦点位置信息,但是直接将回车的效果替换成TAB键的效果。
VS2010MFC编程入门之十一(对话框:模态对话框及其弹出过程)

加法计算器对话框程序大家照着做一遍后,相信对基于对话框的程序有些了解了,有个好的开始对于以后的学习大有裨益。
趁热打铁,鸡啄米这一节讲讲什么是模态对话框和非模态对话框,以及模态对话框怎样弹出。
一.模态对话框和非模态对话框Windows对话框分为两类:模态对话框和非模态对话框。
模态对话框是这样的对话框,当它弹出后,本应用程序其他窗口将不再接受用户输入,只有该对话框响应用户输入,在对它进行相应操作退出后,其他窗口才能继续与用户交互。
非模态对话框则是,它弹出后,本程序其他窗口仍能响应用户输入。
非模态对话框一般用来显示提示信息等。
大家对Windows系统很了解,相信这两种对话框应该都遇到过。
之前的加法计算器对话框其实就是模态对话框。
二.模态对话框是怎样弹出的毕竟加法计算器程序大部分都是MFC自动生成的,对话框怎么弹出来的大家可能还不是很清楚。
鸡啄米下面简单说说它是在哪里弹出来的,再重新建一个新的对话框并弹出它,这样大家实践以后就能更灵活的使用模态对话框了。
大家打开Addition.cpp文件,可以看到CAdditionApp类有个InitInstance()函数,在M FC应用程序框架分析中提到过此函数,不过那是单文档应用程序App类中的,函数体不太相同,但都是进行App类实例的初始化工作。
InitInstance()函数的后半部分有一段代码就是定义对话框对象并弹出对话框的,鸡啄米下面给出这段代码并加以注释:弹出对话框比较关键的一个函数,就是对话框类的DoModal()函数。
CDialog::DoModa l()函数的原型为:virtual INT_PTR DoModal();返回值:整数值,指定了传递给CDialog::EndDialog(该函数用于关闭对话框)的nR esult参数值。
如果函数不能创建对话框,则返回-1;如果出现其它错误,则返回IDABOR T。
调用了它对话框就会弹出,返回值是退出对话框时所点的按钮的ID,比如,我们点了“退出”按钮,那么DoModal返回值为IDCANCEL。
MFC编程小技巧

static UINT Thread1在源文件中定义 UINT CDemoDlg::Thread1(void *param) {
CDemoDlg *dlg = (CDemoDlg*)param; CEdit *randBox = (CEdit*)dlg->GetDlgItem(IDC_Random); CString str; while (dlg->flag) {
MFC 编程小技巧
1、 如何处理对话框按下 enter 或 esc 后自动退出的问题? 在类向导中添加 PreTranslateMessage 函数,重写函数如下:
BOOL CCopleymotorcontrolDlg::PreTranslateMessage(MSG* pMsg) {
// TODO: 在此添加专用代码和/或调用基类 switch (pMsg->wParam) { case VK_RETURN: case VK_ESCAPE:
8、 固定对话框大小,将属性 Border 改为 Dialog Frame
9、 软件自启动 void CDemoDlg::OnBnClickedAutostart() {
// TODO: 在此添加控件通知处理程序代码 HKEY hKey; CString strRegPath = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"); //找到系统的启动项 if (m_autoStart.GetCheck()) {
RegDeleteValue(hKey, _T("Demo")); RegCloseKey(hKey); } } }
模式对话框和非模式对话框

模式对话框和⾮模式对话框下是在百度空间中再录的内容:在WIN32中,模式对话框的创建⼀般是使⽤DialogBox来进⾏创建的。
⽽⾮模式对话框则是利⽤CreateWindow来创建的。
在MFC或是WTL中,模式对话框⼀般是使⽤DoModal,⽽⾮模式对话框的创建则是使⽤Create。
模式对话框创建后,程序的其他窗⼝便不能进⾏操作,必须将该窗⼝关闭后,其他窗⼝才能进⾏操作。
⽽⾮模式对话框则⽆需这样,它不强制要求⽤户⽴即反应,⽽是与其他窗⼝同时接受⽤户操作。
⼆、消息响应的区别在消息响应⽅⾯,模式对话框和⾮模式对话框之间⼜有着很⼤的区别。
模式对话框⼯作的时候,它有内部的消息泵机制,控件之间的交互不⽤我们⼈为的去控制,系统会帮助我们去处理。
⾮模式对话框则像普通窗⼝⼀样,则由WinMain中书写的消息循环驱动。
但由于是对话框,它对⼀些消息有特殊的处理。
因此,在消息循环中,需要先对对话框提供截获消息的机会。
While (GetMessage(&msg, NULL, 0, 0)){if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg)){TranslateMessage(&msg);DispatchMessage( &msg);}}如果当前取得的消息是对话框的消息,IsDialogMessage 将它交由对话消息处理函数处理,并返回TRUE。
不需要再派发了。
注意:这个⽅法并不是很好⽤,因为当对话框过多的时候,处理起来就⽐较⿇烦了。
另⼀种处理的⽅法是利⽤⼦类化控件的⽅法,来处理控件间的交互。
三、销毁的区别模式对话框的销毁是使⽤EndDialog,⽽⾮模式对话框的销毁是使⽤DestroyWindow.。
所以我们在销毁对话框的时候,也要对其进⾏区别。
⾮模式对话框,⽤户关闭对话框时,对话框消息处理函数将收到WM_CLOSE消息,接到后调⽤DestroyWindow以销毁⾮模式对话框。
MFC之模态与非模态对话框的创建与销毁

的话,则把消息返回到WindowProc()函数,由它将消息发送给DefWindowProc()函数;
5、OnCommand() 该函数查看这是不是一个控件通知(lParam参数不为NULL,如果lParam参数为空的话,说明该消息不是控件通知),如果它是,OnCommand()函数会试图将消
======================================================================
MFC非模态窗口的创建过程:
1、PreCreateWindow() 该函数是一个重载函数,在窗口被创建前,可以在该重载函数中改变创建参数 (可以设置窗口风格等);
5、PostNcDestroy() 重载函数,作为处理OnNcDestroy()函数的最后动作被CWnd调用。
##############################################################################
附:MFC应用程序中处理消息的顺序
6、OnSetFont() 消息响应函数,响应WM_SETFONT消息,发送此消息,以允许改变对话框中控件的字体;
7、OnInitDialog() 源自 消息响应函数,响应WM_INITDIALOG消息,发送此消息以允许初始化对话框中的控件,或者是创建新控件;
8、OnShowWindow() 消息响应函数,响应WM_SHOWWINDOW消息,该函数被ShowWindow()函数调用;
8、OnMove() 消息响应函数,响应WM_MOVE消息,发送此消息说明窗口在移动;
9、OnChildNotify() 该函数为重载函数,作为部分消息映射被调用,告诉父窗口即将被告知一个窗口刚刚被创建。
pre不能用的解决方法

pre不能用的解决方法摘要:一、问题概述二、解决方法1.更换预处理器2.调整代码格式3.检查依赖库4.修改配置文件5.更新软件版本6.寻求技术支持正文:在编程过程中,我们可能会遇到pre不能用的问题,这会影响到代码的编译和运行。
为了解决这个问题,我们可以尝试以下几种方法:一、问题概述pre标签通常用于预处理代码,例如在HTML中使用CSS预处理器(如Sass、Less等)或JavaScript预处理器(如TypeScript、Babel等)。
当pre 标签内的代码无法正常预处理时,可能会导致pre标签失效,表现为预处理后的代码无法正常展示或运行。
二、解决方法1.更换预处理器如果当前使用的预处理器存在问题,可以尝试更换为其他可靠的预处理器。
例如,在CSS方面,可以考虑使用Sass、Less等替代品;在JavaScript 方面,可以尝试使用TypeScript、Babel等。
2.调整代码格式检查pre标签内的代码格式是否正确,确保符合预处理器的要求。
例如,确保使用了正确的语法糖、注释风格等。
对于JavaScript,可以使用统一的代码格式规范,如Airbnb、Standard等。
3.检查依赖库确保预处理器及其依赖库已正确安装并加载。
在项目中加入相应的依赖文件,如CSS预处理器所需的编译器、JavaScript预处理器所需的转换器等。
4.修改配置文件根据预处理器和项目的需求,修改相应的配置文件。
例如,在Sass中,可以修改`sass.config.js`文件,设置输出目录、压缩选项等。
在TypeScript中,可以修改`tsconfig.json`文件,设置编译选项、目标版本等。
5.更新软件版本确保使用的预处理器和相关库是最新版本。
更新软件版本可能会解决已知的问题和漏洞,提高代码的兼容性和性能。
6.寻求技术支持如果以上方法都无法解决问题,可以尝试在社区、官方文档等渠道寻求技术支持。
在提问时,务必提供详细的问题描述、错误日志等信息,以便他人更容易地定位和解决问题。
VC MFC 键盘消息的截取与响应

#define VK_MEDIA_STOP 0xB2
#if(_WIN32_WINNT >= 0x0500)
#define VK_XBUTTON1 0x05
#define VK_XBUTTON2 0x06
#endif
#define VK_BACK 0x08
#define VK_TAB 0x09
#define VK_PAUSE 0x13
#define VK_CAPITAL 0x14
#define VK_KANA 0x15
#define VK_HANGEUL 0x15
#define VK_HANGUL 0x15
#define VK_MULTIPLY 0x6A
#define VK_ADD 0x6B
#define VK_SEPARATOR 0x6C
#define VK_SUBTRACT 0x6D
#define VK_DECIMAL 0x6E
#define VK_CLEAR 0x0C
#define VK_RETURN 0x0D
#define VK_SHIFT 0x10
#define VK_CONTROL 0x11
#define VK_MENU 0x12
#define VK_NUMLOCK 0x90
#define VK_SCROLL 0x91
#define VK_OEM_NEC_EQUAL 0x92 // '=' key on numpad
#define VK_OEM_FJ_JISHO 0x92 // 'Dictionary' key
mfc form中的 textboxwndproc焦点 -回复

mfc form中的textboxwndproc焦点-回复MFC (Microsoft Foundation Class) 是一种用于开发Windows 应用程序的C++类库。
在MFC 中,控件是界面的重要组成部分,TextBox 是其中一个常用的控件,用于接收和显示用户输入的文本。
当用户与TextBox 进行交互时,焦点成为一个关键点。
本文将详细讨论在MFC 中TextBox 的焦点处理。
为了理解TextBox 的焦点处理机制,我们首先需要了解TextBox 的消息处理过程。
MFC 中的TextBox 是通过其窗口过程(WndProc) 来接收并处理消息的。
WndProc 是一个回调函数,用于处理特定窗口的消息。
当TextBox 获得焦点时,它将接收到焦点相关的消息,并相应地处理这些消息。
在MFC 中,焦点是通过发送WM_SETFOCUS 和WM_KILLFOCUS 消息来表示的。
当TextBox 获得焦点时,它将接收到WM_SETFOCUS 消息。
在这个时候,我们可以执行一些与焦点相关的操作,比如改变外观或执行某些特定行为。
同样地,当TextBox 失去焦点时,它将接收到WM_KILLFOCUS 消息。
在这个时候,我们可以进行一些清理工作,如验证用户输入或执行其他必要的处理。
要对TextBox 的焦点进行处理,在MFC 中常用的方法是重写TextBox 的PreTranslateMessage 函数。
PreTranslateMessage 函数是一个预处理函数,用于拦截并处理特定消息。
通过重写PreTranslateMessage 函数,我们可以拦截WM_SETFOCUS 和WM_KILLFOCUS 消息,并在这个时候执行我们所需的操作。
在PreTranslateMessage 函数中,我们可以使用以下代码来捕获WM_SETFOCUS 和WM_KILLFOCUS 消息:cppBOOL CMyTextBox::PreTranslateMessage(MSG* pMsg){if (pMsg->message == WM_SETFOCUS){当TextBox 获得焦点时的处理逻辑}else if (pMsg->message == WM_KILLFOCUS){当TextBox 失去焦点时的处理逻辑}return CTextBox::PreTranslateMessage(pMsg);}在上述代码中,我们可以根据需要在WM_SETFOCUS 和WM_KILLFOCUS 消息的处理逻辑中添加相应的代码。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MFC中非模态对话框不响应PreTranslateMessage函数的解决方法
程序员真心不容易啊,为了一个好的用户体验真可谓是操碎了心。
今天由于项目需要,需要在非模态对话框上,当鼠标处于某个位置的时候有提示框显示。
实现这个功能本来很简单,但是却遇到了一个郁闷的问题:PreTranslateMessage函数没响应。
于是各种度娘,可惜度娘非谷歌,找了一个小时终于在一个隐蔽的地方找到了解决方法。
首先我介绍下当鼠标处于特定位置的时候有提示信息显示的实现方法。
需要使用MFC的CToolTipCtrl控件。
1.首先在Dialog类中添加一个成员对象
[cpp]view plain copy
1.//消息提示框
2. CToolTipCtrl m_toolTip;</span></span>
1.//创建消息提示框
2. EnableToolTips(TRUE);//enable use it
3.BOOL bRet = m_toolTip.Create(this, TTS_ALWAYSTIP | WS_CHILD | WS_VISIBLE
);
4. m_toolTip.AddTool(this);
5. m_toolTip.Activate(TRUE);
6. m_toolTip.SetDelayTime(150);</span></span>
3.捕获鼠标的移动消息OnMouseMove,当鼠标处在某一特定区域的时候,弹出消息提示框。
切换消息内容使用CToolTipCtrl::UpdateTipText函数。
[cpp]view plain copy
1.void CDisplayPicDlg::OnMouseMove(UINT nFlags, CPoint point)
2.{
3.//如果鼠标在矩形所在区域,需要把箭头鼠标变成手型的
4.int iSel = GetSelectCameraNo(point);
5.if(-1 != iSel)
6. {
7. SetCursor(LoadCursor(NULL, IDC_HAND));
8. m_toolTip.UpdateTipText(m_stMonitorCamera[iSel].szCamereName, this);
9. }
10.else//还原成箭头鼠标形式
11. {
12. SetCursor(LoadCursor(NULL, IDC_ARROW));
13. m_toolTip.UpdateTipText("", this);
14. }
15.if(-1 != m_lCameraIdPre)
16. {
17. SetCursor(LoadCursor(NULL, IDC_ARROW) );
18. }
19.//.....................
20.}
1.BOOL CDisplayPicDlg::PreTranslateMessage(MSG* pMsg)
2.{
3. m_toolTip.RelayEvent(pMsg);
4.return CDialog::PreTranslateMessage(pMsg);
5.}
6.<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
好了,做到这四部就基本完成了。
当自己满怀信息一运行发现根本没有弹出提示信息。
经过调试发现,PreTranslateMessage函数并没有被调用,于是引出了重要的主题,非模态对话框如何响应PreTranslateMessage函数的问题。
经过一番百度,终于找到了解决方法。
在MFC的App类中需要用Hook来勾取消息,需要注意的是GetMessageProc是个回调函数,所以我们需要将它设成类的静态成员函数。
即:
[cpp]view plain copy
1.class CStaticMapGPSApp : public COleControlModule
2.{
3.public:
4.BOOL InitInstance();
5.int ExitInstance();
6.static LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM
lParam);
7.
8.HHOOK m_hHook;
9.protected:
10.
11.};
1.LRESULT CALLBACK CStaticMapGPSApp::GetMessageProc(int nCode, WPARAM wParam,
LPARAM lParam)
2.{
3. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
4. LPMSG lpMsg = (LPMSG) lParam;
5.
6.if(AfxGetApp()->PreTranslateMessage(lpMsg))
7. {
8. lpMsg->message = WM_NULL;
9. lpMsg->lParam = 0L;
10. lpMsg->wParam = 0;
11. }
12.
13.// Passes the hook information to the next hook procedure in
14.// the current hook chain.
15.return ::CallNextHookEx(theApp.m_hHook, nCode, wParam, lParam);
16.}
17.
18.// CStaticMapGPSApp::InitInstance - DLL initialization
19.
20.BOOL CStaticMapGPSApp::InitInstance()
21.{
22.BOOL bInit = COleControlModule::InitInstance();
23.
24.if (bInit)
25. {
26.// TODO: Add your own module initialization code here.
27. m_hHook = ::SetWindowsHookEx(
28. WH_GETMESSAGE,
29. GetMessageProc,
30. AfxGetInstanceHandle(),
31. GetCurrentThreadId());
32.
33. ASSERT (hHook);
34.return CWinApp::InitInstance();
35. }
36.
37.return bInit;
38.}
39.
40.
41.
42.// CStaticMapGPSApp::ExitInstance - DLL termination
43.
44.int CStaticMapGPSApp::ExitInstance()
45.{
46.// TODO: Add your own module termination code here.
47. UnhookWindowsHookEx((HHOOK)m_hHook);
48.return COleControlModule::ExitInstance();
49.}
此时才算是打工告成,信息弹出框如愿以偿的弹出了。