如何在 IWindow 中支持 GetAttribute¶
Warning
The current page still doesn't have a translation for this language.
You can read it through google translate.
SOUI 框架为 SObject 提供了 SetAttribute 接口用于设置对象属性值,但 GetAttribute 接口虽然在接口定义中存在,却没有提供具体实现。不过,SOUI 提供了在业务层实现 GetAttribute 接口的完整方案。
IAttrStorage 接口介绍¶
SOUI 通过 IAttrStorage 接口来支持属性值的存储和获取功能。该接口专门用于存储 IWindow 对象的属性值,目前仅 IWindow 对象支持此功能。
IAttrStorage 接口定义¶
SNSBEGIN
typedef struct IWindow IWindow;
#undef INTERFACE
#define INTERFACE IAttrStorage
DECLARE_INTERFACE_(IAttrStorage, IObjRef)
{
/**
* @brief 添加引用
* @return long -- 引用计数
*/
STDMETHOD_(long, AddRef)(THIS) PURE;
/**
* @brief 释放引用
* @return long -- 引用计数
*/
STDMETHOD_(long, Release)(THIS) PURE;
/**
* @brief 释放对象
* @return void
*/
STDMETHOD_(void, OnFinalRelease)(THIS) PURE;
//////////////////////////////////////////////////////////////////////////
/**
* @brief 响应 IObject::SetAttribute 的时保存 attribute 值的方法
* @param strName const IStringW* -- 属性名
* @param strValue const IStringW* -- 属性值
* @param bHandled BOOL -- 该属性是否已经被处理
* @return void
*/
STDMETHOD_(void, OnSetAttribute)
(THIS_ const IStringW *strName, const IStringW *strValue, BOOL bHandled) PURE;
/**
* @brief 响应 IObject::GetAttribute 调用
* @param strName const IStringW* -- 属性名
* @param[out] strValue IStringW* -- 返回的属性值
* @return BOOL -- TRUE: 成功
*/
STDMETHOD_(BOOL, OnGetAttribute)(CTHIS_ const IStringW *strName, IStringW *strValue) SCONST PURE;
};
#undef INTERFACE
#define INTERFACE IAttrStorageFactory
DECLARE_INTERFACE_(IAttrStorageFactory, IObjRef)
{
/**
* @brief 添加引用
* @return long -- 引用计数
*/
STDMETHOD_(long, AddRef)(THIS) PURE;
/**
* @brief 释放引用
* @return long -- 引用计数
*/
STDMETHOD_(long, Release)(THIS) PURE;
/**
* @brief 释放对象
* @return void
*/
STDMETHOD_(void, OnFinalRelease)(THIS) PURE;
//////////////////////////////////////////////////////////////////////////
/**
* @brief 创建 IAttrStorage 对象
* @param owner IWindow* -- IAttrStorage 的宿主
* @param[out] ppAttrStorage IAttrStorage** -- 返回值
* @return HRESULT -- S_OK: 成功
*/
STDMETHOD_(HRESULT, CreateAttrStorage)
(CTHIS_ IWindow * owner, IAttrStorage * *ppAttrStorage) SCONST PURE;
};
SNSEND
核心概念说明¶
IAttrStorage 接口¶
- 用于存储和获取 IWindow 对象的属性值
- 提供 OnSetAttribute 和 OnGetAttribute 两个核心方法
- OnSetAttribute 在设置属性时被调用,用于保存属性值
- OnGetAttribute 在获取属性时被调用,用于返回属性值
IAttrStorageFactory 接口¶
- 用于创建 IAttrStorage 对象的工厂接口
- 通过 CreateAttrStorage 方法为指定的 IWindow 对象创建属性存储器
实现步骤¶
要在 SOUI 应用中支持 GetAttribute 功能,需要完成以下步骤:
1. 实现 IAttrStorage 接口¶
创建一个类来实现 IAttrStorage 接口,用于存储和获取属性值:
class CAttrStorageImpl : public TObjRefImpl<IAttrStorage>
{
SWindow * m_pOwner;
SMap<SStringW, SStringW> m_mapAttr;
public:
CAttrStorageImpl(SWindow * pOwner) : m_pOwner(pOwner) {}
void OnSetAttribute(const IStringW *strName, const IStringW *strValue, BOOL bHandled)
{
m_mapAttr[SStringW(strName)] = SStringW(strValue);
}
BOOL OnGetAttribute(const IStringW *strName, IStringW *strValue)
{
SStringW strVal;
if(auto it = m_mapAttr.Lookup(SStringW(strName)))
{
strVal = it->Value();
strValue->Assign(strVal); // 注意:原文中的 Asign 应为 Assign
return TRUE;
}
return FALSE;
}
};
2. 实现 IAttrStorageFactory 接口¶
创建工厂类来负责创建 IAttrStorage 对象:
class CAttrStorageFactory : public TObjRefImpl<IAttrStorageFactory>
{
public:
HRESULT CreateAttrStorage(IWindow * owner, IAttrStorage **ppAttrStorage)
{
// 这里可以根据 owner 来确定是否需要创建 AttrStorage
*ppAttrStorage = new CAttrStorageImpl(owner);
return S_OK;
}
};
3. 注册工厂对象¶
在应用程序初始化时注册属性存储工厂:
int main(){
SApplication app;
// ...
// 创建并注册属性存储工厂
CAttrStorageFactory * pAttrStorageFactory = new CAttrStorageFactory;
app.SetAttrStorageFactory(pAttrStorageFactory);
pAttrStorageFactory->Release();
// ...
app.Run();
return 0;
}
使用示例¶
完成上述配置后,就可以在代码中使用 GetAttribute 方法获取属性值:
// 设置属性
pWindow->SetAttribute(L"name", L"test_window");
// 获取属性
SStringW strValue;
if(pWindow->GetAttribute(L"name", &strValue))
{
// 成功获取属性值
SLOG_INFO("属性值: " << strValue);
}
else
{
// 属性不存在
SLOG_INFO("属性不存在");
}
注意事项¶
- 适用范围:目前仅 IWindow 对象支持 IAttrStorage 接口
- 内存管理:注意正确管理 IAttrStorageFactory 对象的引用计数
- 性能考虑:属性存储会占用额外内存,应根据实际需求决定是否启用
- 拼写修正:接口中的 Asign 方法应为 Assign
最佳实践¶
- 按需创建:在 CreateAttrStorage 方法中可以根据 owner 对象的类型决定是否创建属性存储器
- 资源释放:确保在适当的时候释放相关资源
- 错误处理:在实际应用中添加适当的错误处理机制
- 日志记录:在调试阶段可以添加日志记录来跟踪属性的设置和获取过程