MFC DLL中如何响应PreTranslateMessage消息

微信扫一扫,分享到朋友圈

MFC DLL中如何响应PreTranslateMessage消息

最近项目中使用到MFC,由于工程是DLL的,在使用ToolTip时碰到 非模态对话框 无法显示的问题。查了一番资料,发现原因是由于: 虽然MFC Regular DLL派生了CWinApp类,并有一个theApp全局对象。但它不包含CWinApp::Run机制,主消息由exe负责接收、分发,导致DLL的PreTranslateMessage不生效。 参考资料: https://www.cnblogs.com/hanford/p/6177904.html 第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);
}

第四步:安装钩子

BOOL CTestApp::InitInstance()
{
BOOL bInit = CWinApp::InitInstance();
if (bInit)
{
// TODO: Add your own module initialization code here.
m_hHook = ::SetWindowsHookEx(
WH_GETMESSAGE,
GetMessageProc,
AfxGetInstanceHandle(),
GetCurrentThreadId());
return CWinApp::InitInstance();
}
return bInit;
}

第五步:卸载钩子

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消息

长按储存图像,分享给朋友