MFC中应用duilib的相关兼容性问题处理

2024-04-21 10:08

本文主要是介绍MFC中应用duilib的相关兼容性问题处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文致力于解决在MFC中应用duilib的相关兼容性问题。

 

duilib非常强大,目前已经被各大公司广泛应用,但基本都是基于win32的;一份与MFC混合使用的DEMO,使得我们这些在老的MFC项目下久经UI之苦的看到了希望。

 

然而,就在我对这个MFCDEMO进行测试时,在基本功能正常的情况下,发现还是有少许的问题的,目前我发现的问题主要集中在键按键与鼠标按键方面,具体如下:

1. VK_TAB无效

2. 如果窗口中内嵌了WebBrowser,浏览器的CTRL+CV无效,DEL无效  

3. 如果窗口中内嵌了WebBrowser,则其他部分的滚动条将失效 

 

由于我对duilib还不熟悉,当碰到这几个问题时,一下子没了主意,只好请教于群内的各路大神,可更多的得到的答复是:为什么要与MFC混用?

 

我想大家可能更多的是考虑一个项目新建立,能直接使用duilib框架,还用什么MFC,而且MFC似乎本来就不怎么受人待见;但这里我想说的是,对于若干MFC的老项目,想切换UIduilib上,难道说完全重写过么? 而且我已经做过迁移测试,将MFC项目的UI切换到duilib,可以比较简单的在duilibUI与旧的MFC窗口的逻辑中间加一层代理转发,这样的工作量还是可以控制的。

 

扯远了,最终经过多次询问,还是在群里碰到了有相关处理经验的朋友,经过他们的指点,总算对这种兼容处理有了一些思路,下面就将我目前的处理方案贴出来:

 

1. VK_TAB无效

这个需要在MFC的窗口类中处理 PreTranslateMessage ,将对于VK_TAB的处理强制交给duilib的 CPaintManagerUI::TranslateMessage 来处理 

 

2. 如果窗口中内嵌了WebBrowser,浏览器的CTRL+CV无效,DEL无效 

这个与第一点类似,将给duilib来处理即可 

 

12点代码如下:

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的相关兼容性问题处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922812

相关文章

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Springboot处理跨域的实现方式(附Demo)

《Springboot处理跨域的实现方式(附Demo)》:本文主要介绍Springboot处理跨域的实现方式(附Demo),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录Springboot处理跨域的方式1. 基本知识2. @CrossOrigin3. 全局跨域设置4.

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Python实现自动化接收与处理手机验证码

《Python实现自动化接收与处理手机验证码》在移动互联网时代,短信验证码已成为身份验证、账号注册等环节的重要安全手段,本文将介绍如何利用Python实现验证码的自动接收,识别与转发,需要的可以参考下... 目录引言一、准备工作1.1 硬件与软件需求1.2 环境配置二、核心功能实现2.1 短信监听与获取2.

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

JavaScript Array.from及其相关用法详解(示例演示)

《JavaScriptArray.from及其相关用法详解(示例演示)》Array.from方法是ES6引入的一个静态方法,用于从类数组对象或可迭代对象创建一个新的数组实例,本文将详细介绍Array... 目录一、Array.from 方法概述1. 方法介绍2. 示例演示二、结合实际场景的使用1. 初始化二

Python使用date模块进行日期处理的终极指南

《Python使用date模块进行日期处理的终极指南》在处理与时间相关的数据时,Python的date模块是开发者最趁手的工具之一,本文将用通俗的语言,结合真实案例,带您掌握date模块的六大核心功能... 目录引言一、date模块的核心功能1.1 日期表示1.2 日期计算1.3 日期比较二、六大常用方法详