现象
最近基于网易开源维护的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 [email protected] 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中,有需要的请移步: