最近项目中使用到MFC,由于工程是DLL的,在使用ToolTip时碰到非模态对话框无法显示的问题。查了一番资料,发现原因是由于:虽然MFC Regular DLL派生了CWinApp类,并有一个theApp全局对象。但它不包含CWinApp::Run机制,主消息由exe负责接收、分发,导致DLL的PreTranslateMessage不生效。参考资料:https://www.cnblogs.com/hanford/p/6177904.html#_Toc425102281 第2.5 PreTranslateMessage小节。该文中提到使DLL调用PreTranslateMessage的方法,但对于NX二次开发来说无法实现,毕竟主exe是已经封装好的。又经过一阵搜索,发现钩子函数可以解决,具体方法如下:

第一步:在App类中定义钩子和对话框变量

class CTestApp : public CWinApp
{
public:
CTestApp();
CTestDlg* m_dlg;
HHOOK m_hHook;

第二步:构造函数中初始化成员变量

CTestApp::CTestApp():m_hHook(NULL),m_dlg(NULL)
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}

第三步:定义钩子函数

红色标识的条件千万不能省掉,否则可能导致界面卡死

class CTestApp : public CWinApp
{
public:
CTestApp();
CTestDlg* m_dlg;
HHOOK m_hHook;
// 重写
public:
virtual BOOL InitInstance(); DECLARE_MESSAGE_MAP()
virtual int ExitInstance();
static LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam);
};
LRESULT CALLBACK CTestApp::GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
LPMSG lpMsg = (LPMSG)lParam;
if( (AfxGetApp()->PreTranslateMessage(lpMsg)) && (lpMsg->hwnd == theApp.m_dlg->m_hWnd))
{
theApp.m_dlg->PreTranslateMessage(lpMsg);
}
return CallNextHookEx(theApp.m_hHook, nCode, wParam, lParam);
}

第四步:安装钩子

LRESULT CALLBACK CTestApp::GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
LPMSG lpMsg = (LPMSG)lParam;
if( (AfxGetApp()->PreTranslateMessage(lpMsg)) && (lpMsg->hwnd == theApp.m_dlg->m_hWnd))
{
theApp.m_dlg->PreTranslateMessage(lpMsg);
}
return CallNextHookEx(theApp.m_hHook, nCode, wParam, lParam);
}

第五步:卸载钩子

int CTestApp::ExitInstance()
{
// TODO: 在此添加专用代码和/或调用基类
UnhookWindowsHookEx((HHOOK)m_hHook);
return CWinApp::ExitInstance();
}

第六步:创建非模态对话框

static UF_MB_cb_status_t  test(
UF_MB_widget_t widget,
UF_MB_data_t client_data,
UF_MB_activated_button_p_t call_button )
{
if (UF_initialize() != 0)
return UF_MB_CB_ERROR; AFX_MANAGE_STATE(AfxGetStaticModuleState()); if (theApp.m_dlg == NULL)
{
theApp.m_dlg = new CTestDlg();
theApp.m_dlg->Create(CTestDlg::IDD);
} theApp.m_dlg->ShowWindow(SW_NORMAL);
UF_terminate();
return UF_MB_CB_CANCEL;
}

大功告成!测试:

MFC DLL中如何响应PreTranslateMessage消息的更多相关文章

  1. 如何在MFC DLL中向C#类发送消息

    如何在MFC DLL中向C#类发送消息 一. 引言 由于Windows Message才是Windows平台的通用数据流通格式,故在跨语言传输数据时,Message是一个不错的选择,本文档将描述如何在 ...

  2. Win32 DLL和MFC DLL 中封装对话框

    现在最常看见的关于DLL的问题就是如何在DLL中使用对话框,这是一个很普遍的关于如何在DLL中使用资源的问题.这里我们从Win32   DLL和MFC   DLL两个方面来分析并解决这个问题.     ...

  3. 【boost】MFC dll中使用boost thread的问题

    项目需要,在MFC dll中使用了boost thread(<boost/thread.hpp>),LoadLibraryEx的时候出现断言错误,去掉thread库引用后断言消失. 百度g ...

  4. MFC开发中添加自定义消息和消息响应函数

    (1)在.h或.cpp文件定义一个消息 #define CLICK_MESSAGE_BOX WM_USER+1001 //add by 20180612 给主窗口ctrl.cpp发送消息 //自定义消 ...

  5. ActiveX控件在IE中不响应Backspace消息

    1.操作输入法需要导入: #include <imm.h> #pragma comment(lib, "imm32") 2.定义变量: //键盘钩子句柄 HHOOK g ...

  6. MFC DLL中导出函数模板

    //my.h struct AFX_EXT_CLASS B { }; struct AFX_EXT_CLASS C { }; class AFX_EXT_CLASS A { public: templ ...

  7. MFC程序中消息以及函数的处理顺序简介[转]

    MFC应用程序中处理消息的顺序 1.AfxWndProc()      该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc 2.AfxCallWndProc()  该 ...

  8. 在DLL中封装的VCL窗体Tab键响应的问题

    在DLL中的子窗体不会响应Tab按键的,这个时候就需要手动去指定Tab键的操作,但是前提是主窗体要向这个窗体发送一个消息,一个Tab键按下的消息.基本顺序是这样的: 1. 主窗体用Hook技术捕获Ta ...

  9. qt 获取windows 的消息(通过MFC的DLL的透明窗体转发消息)good

    qt 给win32 发送消息很简单,但是要获取windows 消息却十分复杂,最后想了一个不是很完美 但是也是以现在本人能力所能实现的唯一途径了,基本原理是 利用vc编写一个mfc 的dll ,这个d ...

随机推荐

  1. 极简 Node.js 入门 - 3.3 文件写入

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  2. CODING DevOps 代码质量实战系列第一课:代码规范与 Git Flow

    讲师介绍 杨周 CODING DevOps 架构师 CODING 布道师 连续创业者.DIY/Linux 玩家.知乎小 V,曾在创新工场.百度担任后端开发.十余年一线研发和带队经验,经历了 ToB.T ...

  3. OpenGL学习日志(2020.4之前)

    咳咳,原本这个日志是本机上随便写的一些记录,也没怎么注意可读性和格式,有用信息密度很小,所以实用价值并不大.暂时由于不可抗因素得先鸽一段落了... 后续的日志会升格为模块化的学习记录,(应该)将会有很 ...

  4. Inno Setup Compiler 中文使用教程

    一.概要 该文章主要解决,Inno Setup Compiler工具的使用问题. 如有什么建议欢迎提出,本人及时修改.[如有任何疑惑可以加Q群:580749909] 二.步骤 (1)下载地址:http ...

  5. 【Pod Terminating原因追踪系列之一】containerd中被漏掉的runc错误信息

    前一段时间发现有一些containerd集群出现了Pod卡在Terminating的问题,经过一系列的排查发现是containerd对底层异常处理的问题.最后虽然通过一个短小的PR修复了这个bug,但 ...

  6. [apue] 一图读懂 unix 文件句柄及文件共享过程

    与文件相关的一些概念 在开始上图之前,先说明几个和 unix 文件密切相关的术语,方便后续讨论使用 文件句柄 / 文件描述符 (file descriptor 或 FD):描述一个打开文件相关属性的类 ...

  7. 【解决】虚拟windows7无法安装VMware Tools

    VMware安装虚拟windows7,在虚拟windows7上安装VMware Tools 报错VMware Alias Manager and Ticket 服务失败. Windows 无法启动 V ...

  8. Illegal instruction报错 c/c++

    报错 # ./agent Illegal instruction# 原因 myLog(log4cplus::INFO_LOG_LEVEL, g_p_debugLog, "sendLog ip ...

  9. vue 在模板template中变量和字符串拼接

    例子:  :post-action="'/api/v1/reportPage/'+this.selectedPagerId+'/saveimg/'"

  10. GET和POST的本质区别

    前言:相信小伙伴们面试时候一定都遇到过这个问题,即使没有遇到过,至少也听说过,网上资料一大片,大概每个人都能说出来一些.但是总感觉面试装逼不成功,所以就翻阅了部分资料,进一步整理了下. 一般当我们提到 ...