最近项目中使用到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. 团队作业5:Alpha版本测试和发布(歪瑞古德小队)

    目录 一.项目文档和代码 二.Alpha版本测试报告 2.1 功能测试 2.1.1 功能列表 2.1.2 场景测试 2.1.3 测试结果 2.1.4 bug清单 2.2 兼容性测试 2.3 性能测试 ...

  2. 【Flutter 实战】自定义动画-涟漪和雷达扫描

    老孟导读:此篇文章是 Flutter 动画系列文章第五篇,本文介绍2个自定义动画:涟漪和雷达扫描效果. 涟漪 实现涟漪动画效果如下: 此动画通过 CustomPainter 绘制配合 Animatio ...

  3. vim缩写

    vim缩写可以简化输入,如在Python调试中的logging.warning可以缩写为lgw,在使用时会提高效率. 一.设置缩写 在~/.vimrc增加: :abbreviate lgw loggi ...

  4. 从零开始的SpringBoot项目 ( 五 ) 整合 Swagger 实现在线API文档的功能

    综合概述 spring-boot作为当前最为流行的Java web开发脚手架,越来越多的开发者选择用其来构建企业级的RESTFul API接口.这些接口不但会服务于传统的web端(b/s),也会服务于 ...

  5. AlexNet实现cifar10数据集分类

    import tensorflow as tf import os from matplotlib import pyplot as plt import tensorflow.keras.datas ...

  6. Selenium多浏览器处理

    当我们在执行自动化测试过程中,往往会针对不同的浏览器做兼容性测试,那么我们在代码中,可以针对执行命令传过来的参数,选择对应的浏览器来执行测试用例 代码如下: 在终端中执行命令如上图红框中所示: bro ...

  7. 复杂一点的SQL语句:Oracle DDL和DML

    DDL:对表或者表的属性进行了改变 create:创建表创建用户创建视图 创建表 create table student(id int,score int) ; student后面与括号之间可以有空 ...

  8. oeasy教您玩转linux010109clear清屏

     回忆上次内容 上次讲了灵魂三问 whatis whereis which 通过这三个问题,可以对命令基本了解,我们来试一下!!

  9. Oracle WITH 语句 语法

    With语句可以在查询中做成一个临时表/View,用意是在接下来的SQL中重用,而不需再写一遍. With Clause方法的优点: 增加了SQL的易读性,如果构造了多个子查询,结构会更清晰. 示例: ...

  10. leetcode刷题-47全排列2

    题目 给定一个可包含重复数字的序列,返回所有不重复的全排列. 思路 其思路与46题完全一致,但是需要与组合总和2题一般,在同一层取出重复元素.因此可以在每一层设置一个set()类型,将访问过的元素放入 ...