TA的每日心情 | 奋斗 2022-7-4 09:45 |
---|
签到天数: 28 天 [LV.4]偶尔看看III
版主
- 积分
- 5481
|
本帖最后由 setoutsoft 于 2020-1-8 10:22 编辑
SOUI可以使用SetAttribute来改变窗口的属性,经常有人问起有没有GetAttribute。
3.0.0.23前,SWindow::GetAttribute是protected的,继承的子类可以自己实现GetAttribute,不过目前看来用处不大。
新版本将GetAttribute变成了public,并且调整了IAttrStorageFactory这个接口。用户可以通过给SApplication::SetAttrStrorageFactory来确实如何存储窗口的属性信息,以便后面使用它们。
要使用3.0.0.23的GetAttribute,需要以下步骤:
首先,自己实现一个IAttrStorageFactory,例如:
- class CAttrStorage: public TObjRefImpl<IAttrStorage>
- {
- typedef SMap<SStringW,SStringW> ATTRMAP;
- ATTRMAP m_mapAttr;
- public:
- virtual void OnSetAttribute(const SStringW & strName, const SStringW & strValue,bool bHandled)
- {
- m_mapAttr[strName]=strValue;
- }
- virtual SStringW OnGetAttribute(const SStringW & strName) const
- {
- const ATTRMAP::CPair *p = m_mapAttr.Lookup(strName);
- if(p)
- return p->m_value;
- else
- return SStringW();
- }
- };
- class CAttrStorageFactory : public TObjRefImpl<IAttrStorageFactory>
- {
- public:
- virtual HRESULT CreateAttrStorage(IAttrStorage** ppAttrStorage) const
- {
- *ppAttrStorage = new CAttrStorage;
- return S_OK;
- }
- };
复制代码 上面的Factory使用一个简单的SMap来保存窗口的属性。
如果只需要保留自定义的属性,可以在virtual void OnSetAttribute(const SStringW & strName, const SStringW & strValue,bool bHandled)这个方法中只保存bHandled为TRUE的属性。
然后,在SApplication创建以后,调用以下代码:
- CAttrStorageFactory * attrFac = new CAttrStorageFactory;
- m_theApp->SetAttrStorageFactory(attrFac);
- attrFac->Release();
复制代码 这样处理以后,系统会为每一个SWindow对象创建一个CAttrStorage对象用来保存属性表。
在代码中即可使用SWindow::GetAttribute来获取属性。
下面是demo中的布局XML,我给edit_output这个richedit指定了一个user_attr属性。
- <SOUI name="mainWindow" title="@string/title" bigIcon="ICON_LOGO:32" smallIcon="ICON_LOGO:16" margin="5,5,5,5" resizable="1" wndType="appMain"
- appWnd="1"
- translucent="1"
- >
- <root skin="_skin.sys.wnd.bkgnd" cache="1" width="600" height="400" >
- <caption pos="0,0,-0,30" show="1" font="adding:0">
- <icon pos="10,8" src="ICON_LOGO:16"/>
- <text pos="29,9">@string/title</text>
- <imgbtn name="btn_close" skin="_skin.sys.btn.close" pos="-45,0" tip="close" animate="1"/>
- <imgbtn name="btn_max" skin="_skin.sys.btn.maximize" pos="-83,0" animate="1" />
- <imgbtn name="btn_restore" skin="_skin.sys.btn.restore" pos="-83,0" show="0" animate="1" />
- <imgbtn name="btn_min" skin="_skin.sys.btn.minimize" pos="-121,0" animate="1" />
- </caption>
- <window pos="5,[2,-5,-5" layout="vbox" interval="5">
- <window layout="hbox" size="-2,-1" interval="5">
- <edit name="edit_input" size="0,30" text="user_attr" weight="1"/>
- <button name="btn_get_attr" text="GetAttribute" size="100,30"/>
- </window>
- <richedit name="edit_output" size="-2,0" readOnly="1" multilines="1" weight="1" user_attr="hello, I'm user defined attribute"/>
- </window>
- </root>
- </SOUI>
复制代码 然后我在btn_get_attr这个按钮的响应事件中使用如下方法来获取这个属性:
- void CMainDlg::OnGetAttr()
- {
- SWindow *pInput =FindChildByID(R.id.edit_input);
- SWindow *pOutput = FindChildByID(R.id.edit_output);
- SStringW strAttr = pInput->GetWindowText();
- SStringW strValue = pOutput->GetAttribute(strAttr);
- if(strValue.IsEmpty()) strValue=L"undefined attribute";
- pOutput->SetWindowText(strValue);
- }
复制代码
结果如下图:
代码见附件。
GetAttrDemo.zip
(34.16 KB, 下载次数: 5)
|
|