MFC DLL中如何响应PreTranslateMessage消息
最近项目中使用到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消息的更多相关文章
- 如何在MFC DLL中向C#类发送消息
如何在MFC DLL中向C#类发送消息 一. 引言 由于Windows Message才是Windows平台的通用数据流通格式,故在跨语言传输数据时,Message是一个不错的选择,本文档将描述如何在 ...
- Win32 DLL和MFC DLL 中封装对话框
现在最常看见的关于DLL的问题就是如何在DLL中使用对话框,这是一个很普遍的关于如何在DLL中使用资源的问题.这里我们从Win32 DLL和MFC DLL两个方面来分析并解决这个问题. ...
- 【boost】MFC dll中使用boost thread的问题
项目需要,在MFC dll中使用了boost thread(<boost/thread.hpp>),LoadLibraryEx的时候出现断言错误,去掉thread库引用后断言消失. 百度g ...
- MFC开发中添加自定义消息和消息响应函数
(1)在.h或.cpp文件定义一个消息 #define CLICK_MESSAGE_BOX WM_USER+1001 //add by 20180612 给主窗口ctrl.cpp发送消息 //自定义消 ...
- ActiveX控件在IE中不响应Backspace消息
1.操作输入法需要导入: #include <imm.h> #pragma comment(lib, "imm32") 2.定义变量: //键盘钩子句柄 HHOOK g ...
- MFC DLL中导出函数模板
//my.h struct AFX_EXT_CLASS B { }; struct AFX_EXT_CLASS C { }; class AFX_EXT_CLASS A { public: templ ...
- MFC程序中消息以及函数的处理顺序简介[转]
MFC应用程序中处理消息的顺序 1.AfxWndProc() 该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc 2.AfxCallWndProc() 该 ...
- 在DLL中封装的VCL窗体Tab键响应的问题
在DLL中的子窗体不会响应Tab按键的,这个时候就需要手动去指定Tab键的操作,但是前提是主窗体要向这个窗体发送一个消息,一个Tab键按下的消息.基本顺序是这样的: 1. 主窗体用Hook技术捕获Ta ...
- qt 获取windows 的消息(通过MFC的DLL的透明窗体转发消息)good
qt 给win32 发送消息很简单,但是要获取windows 消息却十分复杂,最后想了一个不是很完美 但是也是以现在本人能力所能实现的唯一途径了,基本原理是 利用vc编写一个mfc 的dll ,这个d ...
随机推荐
- 虚拟化技术之kvm虚拟机创建工具qemu-kvm
在前边的博客中我们介绍了如何创建kvm虚拟机,以及一些常用的工具的介绍和使用,今天我们来了解下kvm原始工具qemu-kvm:为什么说qemu-kvm是一个原始的工具呢,如果你用kvm虚拟机,心细的你 ...
- Django万能权限框架组件
业务场景分析 假设我们在开发一个培训机构的 客户关系管理系统,系统分客户管理.学员管理.教学管理3个大模块,每个模块大体功能如下 客户管理 销售人员可以录入客户信息,对客户进行跟踪,为客户办理报名手续 ...
- SPSSAU数据分析思维培养系列3:分析思路
本文章为SPSSAU数据分析思维培养的第3期文章. 上文讲解如何选择正确的分析方法,除了有正确的分析方法外,还需要把分析方法进行灵活运用.拿到一份数据,应该如何进行分析,总共有几个步骤,第一步第二步应 ...
- Leetcode 24. Swap Nodes in Pairs(详细图解一看就会)
题目内容 Given a linked list, swap every two adjacent nodes and return its head. You may not modify the ...
- VUE+ElementUI创建项目
1.官网下载node,安装node.js环境 安装完成后进入cmd,输入node -v和npm -v查看node和npm是否安装成功及对应的版本 2.全局安装vue-cli:cnpm install ...
- python+opencv 打开网络摄像头
python+opencv 打开网络摄像头(手机)(转) #以下是最常用的读取视频流的方法import cv2url = 'rtsp://admin:admin@192.169.5.2:554/'#根 ...
- Android Weekly Notes Issue #428
Android Weekly Issue #428 Kotlin Flow Retry Operator with Exponential Backoff Delay 这是讲协程Flow系列文章中的一 ...
- 揭秘!containerd 镜像文件丢失问题,竟是镜像生成惹得祸
导语 作者李志宇,腾讯云后台开发工程师,日常负责集群节点和运行时相关的工作,熟悉 containerd.docker.runc 等运行时组件.近期在为某位客户提供技术支持过程中,遇到了 contain ...
- android开发之java的一些基础知识详解,java编程语法,扎实自己的android基本功
1.对象的初始化 (1)非静态对象的初始化 在创建对象时,对象所在类的所有数据成员会首先进行初始化. 基本类型:int型,初始化为0. 如果为对象:这些对象会按顺序初始化. ※在所有类成员初始化完成之 ...
- leetcode-双指针遍历
编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 char[] 的形式给出.不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间解决这一问题.你可以假设 ...