TA的每日心情 | 奋斗 2022-7-4 09:45 |
---|
签到天数: 28 天 [LV.4]偶尔看看III
版主
- 积分
- 5481
|
最近做启程输入法,在输入法皮肤中增加高分屏支持。
原来启程输入法是计划不同dpi的屏幕就让用户切换到不同的皮肤,这样我的代码比较省事,但是增加了用户的学习成本,也增加了皮肤的配置复杂度(为了适配不同的屏幕需要为一个主题制作多款皮肤)。
为此花了一天时间让一款皮肤支持多个DPI。
SOUI原来就考虑好了皮肤资源在高分屏上的放大处理。也有一个demo: multilang_demo,那个demo最开始是演示多语言动态切换的,后来又加上了窗口放大(适配dpi)的演示。不过可能很多人并不知道,而且那个demo由于没有加上dpiaware的清单文件,在用户在高分屏下启用放大后,窗口会变模糊,也误导了部分小白。
这里这个demo是专门演示怎么使用高分屏的,配置好了dpiaware的清单文件,windows系统不会放大我的窗口,但是当打开支持缩放的窗口时,窗口会根据当前的屏幕放大系数自动放大窗口,使窗口放大但界面不模糊。
代码很简单,先看一下两个布局XML文件:
- <SOUI name="dlg_scale" title="@string/title" bigIcon="ICON_LOGO:32" smallIcon="ICON_LOGO:16" margin="5,5,5,5" resizable="1"
- appWnd="1"
- translucent="1"
- >
- <user autoScale="true"/>
- <root skin="_skin.sys.wnd.bkgnd" cache="1" width="300" height="200" layout="vbox">
- <caption size="-2,30" font="adding:0">
- <icon pos="10,8" src="ICON_LOGO:16"/>
- <text pos="29,9">@string/title</text>
- <imgbtn id="IDCANCEL" skin="_skin.sys.btn.close" pos="-45,0" tip="close" animate="1"/>
- </caption>
- <window size="-2,0" weight="1" gravity="center" layout="hbox">
- <text text="自动DPI缩放窗口" colorText="@color/green"/>
- </window>
- </root>
- </SOUI>
复制代码- <SOUI name="dlg_scale" title="@string/title" bigIcon="ICON_LOGO:32" smallIcon="ICON_LOGO:16" margin="5,5,5,5" resizable="1"
- appWnd="1"
- translucent="1"
- >
- <user autoScale="false"/>
- <root skin="_skin.sys.wnd.bkgnd" cache="1" width="300" height="200" layout="vbox">
- <caption size="-2,30" font="adding:0">
- <icon pos="10,8" src="ICON_LOGO:16"/>
- <text pos="29,9">@string/title</text>
- <imgbtn id="IDCANCEL" skin="_skin.sys.btn.close" pos="-45,0" tip="close" animate="1"/>
- </caption>
- <window size="-2,0" weight="1" gravity="center" layout="hbox">
- <text text="禁用自动DPI缩放窗口" colorText="@color/red"/>
- </window>
- </root>
- </SOUI>
复制代码 上面两个布局,最重要的区别是和root节点平行的user节点中的autoScale属性。
user节点不是SOUI处理的布局节点,3.0.0.15碰到这些非布局节点会通过SHostWnd::onUserXmlNode虚方法传递到应用层。应用层实现该方法来处理XML中的特定配置信息。
下面看一下主要的窗口类:
- class CScaleDlg : public SHostDialog, public SDpiHandler<CScaleDlg>
- {
- bool m_bDpiAware;
- public:
- CScaleDlg(LPCTSTR pszLayout);
- ~CScaleDlg(void);
- protected:
- void OnUserXmlNode(pugi::xml_node xmlUser) override;
- bool IsDpiAware() const override;
-
- BEGIN_MSG_MAP_EX(CScaleDlg)
- CHAIN_MSG_MAP(SDpiHandler<CScaleDlg>)
- CHAIN_MSG_MAP(SHostDialog)
- END_MSG_MAP()
- };
- CScaleDlg::CScaleDlg(LPCTSTR pszLayout):SHostDialog(pszLayout),m_bDpiAware(false)
- {
- }
- CScaleDlg::~CScaleDlg(void)
- {
- }
- void CScaleDlg::OnUserXmlNode(pugi::xml_node xmlUser)
- {
- if(wcsicmp(xmlUser.name(),L"user")==0)
- {
- m_bDpiAware = xmlUser.attribute(L"autoScale").as_bool();
- }
- }
- bool CScaleDlg::IsDpiAware() const
- {
- return m_bDpiAware;
- }
复制代码 dpi消息处理相关的代码已经包装到SDpiHandler这个模板中了,使用时继承它即可。
SDpiHandler会调用IsDpiAware这个虚方法来判断窗口是否需要自动处理dpi。
源代码如下:
|
|