MFC中应用duilib的相关兼容性问题处理
来源:互联网 发布:2017淘宝c店还会存在吗 编辑:程序博客网 时间:2024/05/06 19:38
本文致力于解决在MFC中应用duilib的相关兼容性问题。
duilib非常强大,目前已经被各大公司广泛应用,但基本都是基于win32的;一份与MFC混合使用的DEMO,使得我们这些在老的MFC项目下久经UI之苦的看到了希望。
然而,就在我对这个MFCDEMO进行测试时,在基本功能正常的情况下,发现还是有少许的问题的,目前我发现的问题主要集中在键按键与鼠标按键方面,具体如下:
1. VK_TAB无效
2. 如果窗口中内嵌了WebBrowser,浏览器的CTRL+C、V无效,DEL无效
3. 如果窗口中内嵌了WebBrowser,则其他部分的滚动条将失效
由于我对duilib还不熟悉,当碰到这几个问题时,一下子没了主意,只好请教于群内的各路大神,可更多的得到的答复是:为什么要与MFC混用?
我想大家可能更多的是考虑一个项目新建立,能直接使用duilib框架,还用什么MFC,而且MFC似乎本来就不怎么受人待见;但这里我想说的是,对于若干MFC的老项目,想切换UI到duilib上,难道说完全重写过么? 而且我已经做过迁移测试,将MFC项目的UI切换到duilib,可以比较简单的在duilib的UI与旧的MFC窗口的逻辑中间加一层代理转发,这样的工作量还是可以控制的。
扯远了,最终经过多次询问,还是在群里碰到了有相关处理经验的朋友,经过他们的指点,总算对这种兼容处理有了一些思路,下面就将我目前的处理方案贴出来:
1. VK_TAB无效
这个需要在MFC的窗口类中处理 PreTranslateMessage ,将对于VK_TAB的处理强制交给duilib的 CPaintManagerUI::TranslateMessage 来处理
2. 如果窗口中内嵌了WebBrowser,浏览器的CTRL+C、V无效,DEL无效
这个与第一点类似,将给duilib来处理即可
第1与2点代码如下:
BOOL CMFCTestDlg::PreTranslateMessage( MSG* pMsg ){if( pMsg->message == WM_KEYDOWN){{if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN || pMsg->wParam == VK_TAB || pMsg->wParam == VK_DELETE){if(m_dlgWnd.TranslateMessage(pMsg))return TRUE;}else if (pMsg->wParam == 'C' || pMsg->wParam == 'V'){if( (GetKeyState(VK_CONTROL) & 0x8000)){m_dlgWnd.TranslateMessage(pMsg);}}}}return CDialog::PreTranslateMessage(pMsg); //TranslateMessage方法仅是转而调用CPaintManagerUI::TranslateMessage bool MainFrame::TranslateMessage( MSG* pMsg ){return m_PaintManager.TranslateMessage(pMsg);}
这里其实根本原因,原理我还没搞清楚,请知道的补充一下。
3. 如果窗口中内嵌了WebBrowser,则其他部分的滚动条将失效
这个问题以前就发现了,但在昨天才发现,如果将内嵌的浏览器拿掉的话,滚动条又正常了,进行了跟踪,发现是由于当窗口中未选中任何的Edit或其他可操作的控件时,默认的焦点是在这个 WebBrowser 上[原因不详],这样鼠标中键滚轮滚动时,WM_MOUSEWHEEL消息会被路由到 LRESULT CActiveXWnd::HandleMessage,而此处对于消息 WM_MOUSEWHEEL是直接丢弃,导致了滚动条消息丢失了,按如下处理可以解决这个问题:
将WM_MOUSEWHEEL消息发给主窗口进行处理:
LRESULT CActiveXWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam){ LRESULT lRes=0; BOOL bHandled = TRUE; switch( uMsg ) { case WM_PAINT: lRes = OnPaint(uMsg, wParam, lParam, bHandled); break; case WM_SETFOCUS: lRes = OnSetFocus(uMsg, wParam, lParam, bHandled); break; case WM_KILLFOCUS: lRes = OnKillFocus(uMsg, wParam, lParam, bHandled); break; case WM_ERASEBKGND: lRes = OnEraseBkgnd(uMsg, wParam, lParam, bHandled); break; case WM_MOUSEACTIVATE: lRes = OnMouseActivate(uMsg, wParam, lParam, bHandled); break;case WM_MOUSEWHEEL: {::PostMessage(::GetParent(GetHWND()), uMsg, wParam, lParam);return 0;}break; default: bHandled = FALSE; } if( !bHandled ) return CWindowWnd::HandleMessage(uMsg, wParam, lParam); return lRes;}
按上述处理,目前这几个问题基本得到了处理,我也敢在项目中应用了,但其实这里还是有细节问题的,比如:
1. 按TAB键后,如果没有WebBrowser,则按到最后,TAB就没办法切换有焦点的控件了,一直出现叮叮的系统声音[不可操作]
2. 按TAB键,如果有WebBrowser,则最终焦点进入WebBrowser后,不能切换出来了,只能通过鼠标来调整焦点;另外如果当前窗口没选中任何控件,默认焦点在 WebBrowser 中,按TAB键则直接进入了WebBrowser 中。
3. 另外还有一个问题duilib的问题,我这边暂时简单处理了一下
所有的button类[button,check,option等]均会响应TABSTOP,这个可以在XML文件中通过keyboard属性来设置,但库中的CTreeViewUI中创建节点中会自动添加按钮,这种需要手动将其设置为不响应TABSTOP:
pFolderButton->SetKeyboardEnabled(false);pDottedLine->SetKeyboardEnabled(false);pCheckBox->SetKeyboardEnabled(false);pItemButton->SetKeyboardEnabled(false);
我目前直接将所有按钮的默认接受属性设置成了false,需要的时候针对需要的按钮设置 keyboard属性。
4. 其他未知问题,欢迎补充
注:
我的测试基于duilib svn 中的 MFCdemo 改编而来,目前已经是在自己的项目中来做实测,这个代码暂时不便上传
- MFC中应用duilib的相关兼容性问题处理
- MFC中使用duilib
- duilib的相关信息
- MFC中使用Duilib DuiLib_Mfc
- MFC中使用Duilib--1
- MFC中使用Duilib--2
- MFC中使用Duilib DuiLib_Mfc
- Duilib在MFC中使用
- duilib中使用MFC控件
- Duilib在MFC中使用
- duilib对MFC的支持
- DuiLib 与 MFC的结合
- duilib对MFC的支持
- duilib进阶教程 -- 在duilib中使用MFC (2)
- duilib进阶教程 -- 在MFC中使用duilib (1)
- duilib中CListUI控件消息处理的方法与技巧
- VS2008编译的MFC兼容性问题
- MFC项目中加入DuiLib改造界面
- 从两个方向来理解一个概念
- 微软2014实习生及秋令营技术类职位在线测试: Reduce inversion count
- spring整合jdbc
- PAT 1004. 成绩排名 (20)
- 联通先锋卡流量免费升级,天上掉馅饼了?
- MFC中应用duilib的相关兼容性问题处理
- 调用系统相册相机,然后裁剪
- 由玩游戏想到的
- 路由器与主机间的Telnet
- Android按钮隐藏
- 关于PHP中唯一标识符的问题
- C# SaveFileDialog +FileStream+StreamWriter 创建或者覆盖一个文件,并且写入
- 大势所趋 HTML5成Web开发者最关心的技术
- 嫁给软件工程师(程序员)的好处