问题提出: http://www.codeproject.com/miscctrl/XInfotip/XInfotip_demo.zip 这个下载类使用过程遇到在Dll中的无模式对话框无法执行PreTranslateMessage函数的问题。后在网上找到解决方案可以解决从主程序调用动态库产生一个DLL中无模式对话框调用PreTranslateMessage的方法。但是再在这个DLL中调用一次DLL中无模式对话框用这个方法就不能实现提示框就是该问题的出现。
摘录:[开始]
关于PreTranslateMessage有一个常见的问题就是与此有关:如果编写了一个MFC DLL并从另外的一个MFC主工程之中调用这个MFC DLL中的Modeless Dialog的话,Modeless Dialog的PreTranslateMessage不会被调。因为MFC DLL和这个MFC工程拥有不同的AfxModuleThreadState,因此在MFC DLL中创建的modeless CDialog对象不在MFC工程的句柄表中(CWnd::FromhandlePermanent返回NULL),因此虽然MFC主工程中的CWinApp的Pretranslatemessage会被调(注意此时Dialog的消息循环在MFC主工程里面),但是不会调用MFC DLL中创建的那个modeless CDialog的PreTranslateMessage函数。因此需要特殊处理。一般有两种方法,一种是直接在MFC主工程中的CWinApp::PreTranslatemessage里面调用MFC DLL的CWinApp::PreTranslateMessage(可以专门在MFC DLL中export一个专门的函数来做这件事情)。另外的方法是使用钩子,在钩子消息处理函数之中,判断目标窗口是否是当前具有焦点的窗口,如果是,则直接调用目标窗口的PreTranslateMessage函数(前提是你有要保存这个对象的指针)。
1、CMusicWnd *ListWnd;
在DLL-CXXWNDAPP中用个全局的窗口指针
2、DLL中需要导出该一个接口涵数-
extern "C" _declspec(dllexport) BOOL List_PreTM(MSG *pMsg)//PreTranslateMessage
{
//AFX_MANAGE_STATE(AfxGetStaticModuleState());
if(ListWnd!=NULL)
return ListWnd->PreTranslateMessage(pMsg);
return false;
}
3、主程序中用typedef BOOL(_cdecl *List_PreTM)(MSG *pMsg);//导出函数
List_PreTM m_pList_PreTM;//导出函数指针
在BOOL CXXXDlg::OnInitDialog()中(主程序的对话框)
m_pList_PreTM = (List_PreTM)GetProcAddress(hinstDll_List,"List_PreTM");
4、在主程序的
BOOL CXXXDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if(m_pList_PreTM(pMsg))
return true;
return CDialog::PreTranslateMessage(pMsg);
}
所有即可成功完成该过程。
摘录 [结束]
解决[原创http://blog.csdn.net/hongjie7117/]:
作者修改了CXInfoTip类中代码使其能够支持在多重界面都可以使用的方法。RelayEvent
重载CXInfoTip中的RelayEvent函数;
函数如下
{
CString szTooltipText;
TipToolInfo Info;
// GetCursorPos(&point); // 获得光标处的坐标
if (point != m_ptOrigin)
{ // Find the tool
if (NULL != pWnd)
{
if (m_TipToolsMap.Lookup(pWnd -> m_hWnd, Info))
{ // 查找 // Display the tooltip
m_ptOrigin = point;
SetIcon(Info.hIcon);
Show(Info.szText, & point);
}
}
}
// Hide the tooltip
if (point != m_ptOrigin)
{
ShowWindow(SW_HIDE);
}
}
在调用处 或是主程序或是DLL中的无模式对话框中响应WM_SETCURSOR消息;
BOOL 类名::OnSetCursor(CWnd * pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
POINT point;
GetCursorPos( & point);
m_TipTools.RelayEvent(pWnd, point); // 调用了重载的函数
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
问题终于解决了。发出以便大家参考,其他CXInfoTip类使用方法等信息
请参考 http://www.codeproject.com/miscctrl/xinfotip.asp
有不足之处请给出指正 QQ:191429982 欢迎共同研究进步