解决网易开源duilib自带RichEdit在部分系统下键盘无法输入的问题

现象

最近基于网易开源维护的duilib做了一款客户端,上线后,用户反馈了一系列问题,其中最诡异的问题就是RichEdit有时候无法输入。
在这里插入图片描述

调查

使用官方自带的例子进行测试后,发现同样存在问题:

这2个RichEdit的XML如下:

<!-- 单行文本 -->
<RichEdit class="simple input" height="30" margin="0,3" padding="6,6,6" promptmode="true" prompttext="Single line text control" promptcolor="lightcolor"/>

<!-- 多行文本 -->
<RichEdit class="prompt" name="edit" bkcolor="bk_wnd_lightcolor" width="stretch" height="stretch" 
            multiline="true" vscrollbar="true" hscrollbar="true" autovscroll="true" 
            normaltextcolor="darkcolor" wantreturnmsg="true" rich="true"/>

解决方法

经过不停的改样式测试,有2个办法:

  • 把单行文本中的class="simple input"改成class=“input”
  • simple的样式在global.xml中定义,在该文件里面找到simple的定义,去掉wanttab=“false”
<Class name="simple" multiline="false" autohscroll="true" wantreturnmsg="true" rich="false" normaltextcolor="darkcolor" disabledtextcolor="textdefaultdisablecolor"/>
<!-- <Class name="simple" multiline="false" autohscroll="true" wantreturnmsg="true" wanttab="false" rich="false" normaltextcolor="darkcolor" disabledtextcolor="textdefaultdisablecolor"/> -->

所以,最终确定和wanttab="false"有关系。

后续问题

去掉wanttab="false"后,我发现用户名和密码输入框,在用户名的时候按Tab,会追加1个\t制表符而不是换行,故需要继续解决。

经过仔细阅读网易修改后duilib的相关代码,在RichEdit手动处理一下\t换行即可。

void RichEdit::OnChar(EventArgs& event)
{
	//TAB
	if (::GetKeyState(VK_TAB) < 0) {
		if (!m_bWantTab) {
			if (m_pWindow != NULL)
				m_pWindow->SendNotify((Control*)this, kEventTab);
			return;
		}

		// added_by xmcy0011@sina.com 2021-01-28 tab ignore
		// m_bWantTabEx是新增的属性,需要外部主动赋值。
		if (!m_bWantTabEx) {
			if (m_pWindow != NULL)
				m_pWindow->SetNextTabControl(::GetKeyState(VK_SHIFT) >= 0);
			return;
		}
	}
	//Number
	if (m_bNumberOnly) {
		if (event.wParam < '0' || event.wParam > '9')
			return;
	}

	TxSendMessage(WM_CHAR, event.wParam, event.lParam, NULL);
}

假设登录界面叫LoginForm,在InitWindow中,调用SetWantTabEx(为了解决部分电脑无法输入问题新增的额外函数)设置一下即可。

void LoginForm::InitWindow() {
	// ...
    passwd_ = static_cast<ui::RichEdit*>(FindControl(L"passwd"));
    ed_phone_ = static_cast<ui::RichEdit*>(FindControl(L"ed_phone"));
    ed_sms_ = static_cast<ui::RichEdit*>(FindControl(L"ed_sms"));

    // SetWantTabEx是新增的函数,自己可以在RichEdit.h中新增即可。
	ed_phone_->SetWantTabEx(false);
	passwd_->SetWantTabEx(false);
	ed_sms_->SetWantTabEx(false);
	
	// ...
}

后记

官方1年多没更新了,发现的问题我都维护在了这个分支的README.md中,有需要的请移步:

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.duilib简介 duilib是一个开源的DirectUI界面库,简洁但是功能强大。而且还是BSD的license,所以即便是在商业上,大家也可以安心使用。 现在大家可以从这个网站获取到他们所有的源码:/p/duilib/ 为了让我们能更简单的了解其机制,我们按照如下顺序一步一步的来对他进行观察: 工具库:用于支撑整个项目的基础 控件库:这是dui最关键的部分之一,相信也是大家最关注的部分之一,另外这里也来看看它是如何管理这些控件的 消息流转:有了控件库,我们需要将Windows窗口的原生消息流转给这些控件,另外在这里也来看看Focus,Capture等等的实现 资源组织和皮肤加载:有了上面所有的这些,我们再来看看它是如何自动创建皮肤的 简单使用:最后,来看看到底要如何使用它 以下是duilib工程带的一副总体设计图,在看代码之前看看这幅图,对看代码会很有帮助。 duilib: 2.工具库 由于duilib没有对外部的任何库进行依赖,所以在其内部实现了很多用于支撑项目的基础类,这些类分布在Util文件夹中: UI相关:CPoint/CSize/CDuiRect 简单容器:CStdPtrArray/CStdValArray/CStdString/CStdStringPtrMap 上面这些类看名字就基本能够理解其具体的含义了,当然除了基本的基础库,还有一些和窗口使用相关的工具的封装: 窗口工具:WindowImplBase,这个工具我们在这里不详述,后面会再次提到。 3.控件库 控件库在duilib的实现中被分为了两块:Core和Control: Core中包含的是所有控件公用的部分,里面主要是一些基类和绘制的封装。 Control中包含的就是各个不同的控件的行为了。 Core部分和控件相关的类图非常简单: duilib-core: 3.1.控件基类:CControlUI CControlUI在整个控件体系中非常重要,它是所有控件的基类,也是组成控件树的基本元素,控件树中所有的节点都是一个CControlUI。 他基本包括了所有控件公共的属性,如:位置,大小,颜色,是否有焦点,是否被启用,等等等等。当然这个类中还提供了非常多的基础函数,用于重载来实现子控件,如获取控件名称和ClassName,是否显示,等等等等。 另外为了方便从XML中直接解析出控件的各个属性,这个类中还在提供了一个SetAttribute的方法,传入字符串的属性名称和值对特定的属性进行设置,内部其实就是挨个比较字符串去完成的,所以平时使用的时候就还是不要使用的...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值