最近在写视频嵌入的插件,其实就是在dll中去实现exe中需要的视频功能,好处是,可以同时支持多厂家的视频设备。需要 做的是制订好exe与dll的接口,然后针对该接口开发出调用各个厂家视频功能的dlls。
最常用的功能大概就是视频实时预览了,设计的目标是在dll中弹出一个非模态对话框,其上面显示视频以 及必要的控制,如云镜控制、录像抓图、灯光控制等等。之所以要非模态的对话框,是因为exe界面上还有很多功能,不能因为弹出了视频窗口而无法使用。
就是这样一个小case,却出了问题:dll弹出非模态对话框后,无法通过按ESC键将其关闭,TAB 键也无法使用。因为对话框上尚无过多控件,还没去测试其他按键消息能否响应。
测试软件界面如图:
仔细检查了对话框的消息响应函数,没有问题。也试过重载其PreTranslateMessage() 函数,发现按键消息根本不能进入此函数来处理! 既然它没有处理按键消息,那应该是exe的框架 处理了按键消息?试了一下,果然,对话框得到焦点时,按键消息却被exe处理了。
回忆了一下以前做过的程序,也常会用到非模态的对话框,可从来没遇到此问题啊。。。再经过仔细的思索, 发现从前使用过非模态对话框,也在dll中弹出过对话框(模态),可却从未将两者结合起来使用,即:从来还没有在dll中弹出过非模态对话框!看来是首次 遇到的问题了。
在网上搜索了一下,确实有人曾经遇到过相同的问题,竟然据称是用hook来解决的!~杀鸡焉用牛 刀。。。
又经过一番search,最终目光定位到一个Windows API上:IsDialogMessage(),----- 利用它解决了此问题:在exe的PreTranslateMessage()中,看看pMsg的接收窗口,如果是对话框或对话框的控件,则调用它来处理此 条消息,一切OK了!
还没有去深究产生这个现象的原因,猜测和MFC封装的消息流程有关,手头还有不少活要忙,先不求甚解 了。
评论 想第一时间抢沙发么?
搜狐网友 在上文中提到:
大侠 你的QQ是多少啊 我也遇到了相同的问题 想请教您。。
请在这里说就可以了。
发布者 搜狐网友 (未验证) (http://blog.sohu.com/)
2009-10-12 08:50
发布者 搜狐网友 (未验证) (http://blog.sohu.com/)
2009-10-13 18:55
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
//
// 以下代码为了解决在dll弹出的非模态对话框上不接受按键消息的问题。
//
char szClassName[128];
// 看当前接收消息的窗口是不是对话框
HWND hwnd = pMsg->hwnd;
::GetClassName(hwnd, szClassName, 128);
if (strcmp(szClassName, "#32770") == 0)
{
if (::IsDialogMessage(hwnd, pMsg)) return TRUE;
}
else
{
// 看当前接收消息的窗口的父窗口是不是对话框
::GetClassName(::GetParent(hwnd), szClassName, 128);
if (strcmp(szClassName, "#32770") == 0)
{
if (::IsDialogMessage(::GetParent(hwnd), pMsg)) return TRUE;
}
}
}
return CFrameWnd::PreTranslateMessage(pMsg);
}
另外,我建 议你最好通过发消息的方式来显示dll中的对话框,而不是在某个线程中直接调用dll导出函数来创建对话框。