金山卫士UI原理解析(1)
2011-08-15 19:46 Clingingboy 阅读(1576) 评论(1) 编辑 收藏 举报
Skin结构图
一.CBkObject
有点跟CObject,可以根据类名结合宏来动态创建Skin
#define BKOBJ_DECLARE_CLASS_NAME(theclass, classname) \
public: \
static theclass* CheckAndNew(LPCSTR lpszName) \
{ \
if (strcmp(GetClassName(), lpszName) == 0) \
return new theclass; \
else \
return NULL; \
} \
\
static LPCSTR GetClassName() \
{ \
return classname; \
} \
\
virtual LPCSTR GetObjectClass() \
{ \
return classname; \
} \
\
virtual BOOL IsClass(LPCSTR lpszName) \
{ \
return strcmp(GetClassName(), lpszName) == 0; \
}
CheckAndNew方法用来动态创建Skin
二.CBkSkinBase
定义了控件的Skin基类,定义了一个Draw方法,这个好比css样式一般,Draw方法来定义各个控件的呈现样式
三.根据xml载入skin样式
这里以button为例子,xml示例
<skins>
<button name="normalbtn" border="7D9EBC" bg="FBFCFD" bgup="FEFEFE" bgdown="C6E2FD"
bguphover="FEFEFE" bgdownhover="DBEDFE" bguppush="C6E2FD" bgdownpush="FEFEFE"/>
</skins>
四.给载入的xml属性赋值
这次再次使用宏
#define BKWIN_DECLARE_ATTRIBUTES_BEGIN() \
public: \
virtual HRESULT SetAttribute( \
CStringA strAttribName, \
CStringA strValue, \
BOOL bLoading) \
{ \
HRESULT hRet = __super::SetAttribute( \
strAttribName, \
strValue, \
bLoading \
); \
if (SUCCEEDED(hRet)) \
return hRet; \
#define BKWIN_DECLARE_ATTRIBUTES_END() \
return E_FAIL; \
\
return hRet; \
}
然后根据不同数据类型,定义多个赋值的宏
// DWORD = %u StringA
#define BKWIN_DWORD_ATTRIBUTE(attribname, varname, allredraw) \
if (attribname == strAttribName) \
{ \
varname = (DWORD)::StrToIntA(strValue); \
hRet = allredraw ? S_OK : S_FALSE; \
} \
else \
// StringA = StringA
#define BKWIN_STRING_ATTRIBUTE(attribname, varname, allredraw) \
if (attribname == strAttribName) \
{ \
varname = strValue; \
hRet = allredraw ? S_OK : S_FALSE; \
} \
else
Button控件示例
class CBkSkinButton : public CBkSkinBase
{
BKOBJ_DECLARE_CLASS_NAME(CBkSkinButton, "button")
public:
CBkSkinButton()
: m_crBorder(RGB(0x70, 0x70, 0x70))
, m_crBg(RGB(0xEE, 0xEE, 0xEE))
, m_crBgUpNormal(RGB(0xEE, 0xEE, 0xEE))
, m_crBgUpHover(RGB(0xEE, 0xEE, 0xEE))
, m_crBgUpPush(RGB(0xCE, 0xCE, 0xCE))
, m_crBgDownNormal(RGB(0xD6, 0xD6, 0xD6))
, m_crBgDownHover(RGB(0xE0, 0xE0, 0xE0))
, m_crBgDownPush(RGB(0xC0, 0xC0, 0xC0))
{
}
virtual void Draw(CDCHandle dc, CRect rcDraw, DWORD dwState)
{
…
}
protected:
COLORREF m_crBg;
COLORREF m_crBorder;
COLORREF m_crBgUpNormal;
COLORREF m_crBgUpHover;
COLORREF m_crBgUpPush;
COLORREF m_crBgDownNormal;
COLORREF m_crBgDownHover;
COLORREF m_crBgDownPush;
public:
BKWIN_DECLARE_ATTRIBUTES_BEGIN()
BKWIN_COLOR_ATTRIBUTE("bg", m_crBg, TRUE)
BKWIN_COLOR_ATTRIBUTE("border", m_crBorder, TRUE)
BKWIN_COLOR_ATTRIBUTE("bgup", m_crBgUpNormal, TRUE)
BKWIN_COLOR_ATTRIBUTE("bguphover", m_crBgUpHover, TRUE)
BKWIN_COLOR_ATTRIBUTE("bguppush", m_crBgUpPush, TRUE)
BKWIN_COLOR_ATTRIBUTE("bgdown", m_crBgDownNormal, TRUE)
BKWIN_COLOR_ATTRIBUTE("bgdownhover", m_crBgDownHover, TRUE)
BKWIN_COLOR_ATTRIBUTE("bgdownpush", m_crBgDownPush, TRUE)
BKWIN_DECLARE_ATTRIBUTES_END()
};
五.重写Draw方法
这里不列代码了,这样一个控件的整个skin流程就完成了,当然其相关方法还需要其他地方来调
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2010-08-15 数据结构-图(带权图)(js)
2010-08-15 数据结构-图(非带权图)(js)