SOUI控件注册机制¶
本文详细介绍SOUI框架中的控件注册机制,包括控件的注册方式、内存管理及扩展方法。
控件注册概述¶
控件注册是SOUI系统中一个重要的机制,它使得: - 系统能够通过XML描述创建控件 - 保证控件内存的正确分配和释放 - 支持控件的扩展和自定义
注册控件¶
1. 基本注册方法¶
// 注册窗口控件
theApp->RegisterWndFactory(TplSWindowFactory<SMyWindow>());
// 注册皮肤对象
theApp->RegisterSkinFactory(TplSkinFactory<SMySkin>());
2. 注册示例¶
// 注册各种控件
void RegisterControls()
{
// 注册GIF播放器
theApp->RegisterWndFactory(TplSWindowFactory<SGifPlayer>());
// 注册IP地址控件
theApp->RegisterWndFactory(TplSWindowFactory<SIPAddressCtrl>());
// 注册属性表控件
theApp->RegisterWndFactory(TplSWindowFactory<SPropertyGrid>());
// 注册动画控件(条件注册)
if(SUCCEEDED(CUiAnimation::Init()))
{
theApp->RegisterWndFactory(TplSWindowFactory<SUiAnimationWnd>());
}
}
工厂模式实现¶
1. 窗口工厂基类¶
class SWindowFactory
{
public:
virtual ~SWindowFactory() {}
virtual SWindow* NewWindow() = 0;
virtual LPCWSTR SWindowBaseName() = 0;
virtual const SStringW & getWindowType() = 0;
virtual SWindowFactory* Clone() const = 0;
};
2. 模板工厂实现¶
template <typename T>
class TplSWindowFactory : public SWindowFactory
{
public:
TplSWindowFactory()
: m_strTypeName(T::GetClassName())
{
}
// 获取基类名称
LPCWSTR SWindowBaseName()
{
return T::BaseClassName();
}
// 创建新窗口
virtual SWindow* NewWindow()
{
return new T;
}
// 获取窗口类型
virtual const SStringW & getWindowType()
{
return m_strTypeName;
}
// 克隆工厂对象
virtual SWindowFactory* Clone() const
{
return new TplSWindowFactory();
}
protected:
SStringW m_strTypeName;
};
内存管理机制¶
1. 引用计数基类¶
template<class T>
class TObjRefImpl : public T
{
public:
TObjRefImpl() : m_cRef(1) {}
// 增加引用计数
virtual void AddRef()
{
InterlockedIncrement(&m_cRef);
}
// 释放引用
virtual void Release()
{
InterlockedDecrement(&m_cRef);
if(m_cRef == 0)
{
OnFinalRelease();
}
}
// 最终释放
virtual void OnFinalRelease()
{
delete this;
}
protected:
volatile LONG m_cRef;
};
2. 双继承引用计数实现¶
template<class T, class T2>
class TObjRefImpl2 : public TObjRefImpl<T>
{
public:
virtual void OnFinalRelease()
{
delete static_cast<T2*>(this);
}
};
自定义控件实现¶
1. 标准实现方式¶
// 定义控件类
class SMyControl : public SWindow
{
SOUI_CLASS_NAME(SMyControl, L"mycontrol")
public:
SMyControl() {}
~SMyControl() {}
protected:
// 控件实现
};
// 注册控件
theApp->RegisterWndFactory(TplSWindowFactory<SMyControl>());
2. 自管理内存方式¶
class SCustomControl : public SWindow
{
public:
// 重写OnFinalRelease实现自己的内存管理
virtual void OnFinalRelease()
{
delete this;
}
};
// 直接创建控件
SCustomControl* pCtrl = new SCustomControl();
最佳实践¶
1. 控件注册规范¶
class MyApp
{
public:
bool InitControls()
{
// 1. 基础控件注册
RegisterBasicControls();
// 2. 条件控件注册
if(CheckDependency())
{
RegisterOptionalControls();
}
// 3. 自定义控件注册
RegisterCustomControls();
return true;
}
};
2. 内存管理¶
class SMyControl : public SWindow
{
SOUI_CLASS_NAME(SMyControl, L"mycontrol")
public:
SMyControl()
{
// 资源初始化
}
~SMyControl()
{
// 资源清理
}
protected:
// 使用智能指针管理资源
CAutoRefPtr<IResource> m_pResource;
};
3. 扩展性设计¶
// 基础接口
struct IMyControlCallback
{
virtual void OnCustomEvent() = 0;
};
// 控件实现
class SMyControl : public SWindow
{
public:
void SetCallback(IMyControlCallback* pCallback)
{
m_pCallback = pCallback;
}
protected:
IMyControlCallback* m_pCallback;
};
调试技巧¶
1. 控件注册验证¶
void VerifyControlRegistration()
{
// 验证控件是否注册成功
SWindow *pWnd = SApplication::getSingleton()
.CreateWindowByName(L"mycontrol");
SASSERT(pWnd);
}
2. 内存泄漏检测¶
void CheckMemoryLeak()
{
#ifdef _DEBUG
// 创建控件
SWindow *pWnd = new SMyControl();
// 检查引用计数
SASSERT(pWnd->GetRef() == 1);
// 释放控件
pWnd->Release();
#endif
}
注意事项¶
- 内存管理
- 正确使用引用计数
- 避免循环引用
-
及时释放资源
-
控件注册
- 在应用初始化时注册
- 确保注册顺序正确
-
处理依赖关系
-
扩展开发
- 遵循SOUI设计规范
- 合理使用内存管理机制
- 注意模块间的内存分配