界面库的六大关键技术之资源管理

0 引言

颜色、字体、图片、字符串都可以作为界面库的资源文件。资源管理的好坏,关系到界面库的性能和易用性。好的资源管理需要做到合理缓存、取用方便。缓存提高性能、取用方便提高易用性。

1 颜色管理

颜色资源可以保存在xml文件中,具体文件格式如下:

<ColorTable>

<Color Id="ID_COLOR_BLACK">255,60,60,60</Color>

<Color Id="ID_COLOR_SEARCH_TIPS">255,210,205,202</Color>

<Color Id="ID_COLOR_CAPTURE_IMAGE_BKG">150,0,0,0</Color>

<Color Id="ID_COLOR_CAPTURE_IMAGE_BORDER">255,248,100,24</Color>

<Color Id="ID_COLOR_MENU_BKG">255,244,244,244</Color>

<Color Id="ID_COLOR_CHAT_LINE">255,194,194,194</Color>

<Color Id="ID_COLOR_MENU_TEXT_CHECKED">255,85,195,236</Color>

<Color Id="ID_COLOR_BLUE_FONT">255,96,198,236</Color>

</ColorTable>

我们可以写一个颜色管理的单例类,通过ID获得颜色。具体代码如下:

#pragma once

class CColorManager

{

private:

CColorManager();

~CColorManager();

public:

static CColorManager* GetInstance();

static void ReleaseInstance();

public:

Color GetColor(const tstring& strColor);

protected:

void Load(const tstring& strXml);

private:

static CColorManager* s_inst;

private:

map<tstring, Color> m_mapColor;

};

CColorManager* CColorManager::s_inst = NULL;

CColorManager::CColorManager()

{

}

CColorManager::~CColorManager()

{

}

CColorManager* CColorManager::GetInstance()

{

if(!s_inst)

{

s_inst = new CColorManager();

if(s_inst)

{

s_inst->Load();

}

}

return s_inst;

}

void CColorManager::ReleaseInstance()

{

if(s_inst)

{

delete s_inst;

s_inst = NULL;

}

}

void CColorManager::Load(const tstring& strXml)

{

//从xml加载颜色值

}

Color CColorManager::GetColor(const tstring& strColor)

{

map<tstring, Color>::iterator iter = m_mapColor.find(strColor);

if(iter != m_mapColor.end())

{

return iter->second;

}

return Color::Red;

}

2 字体管理

字体资源可以保存在xml文件中,具体文件格式如下:

<FontFamily>

<Familys>

<Family>微软雅黑</Family>

<Family>新宋体</Family>

<Family>宋体</Family>

</Familys>

<Fonts>

<Font Id="ID_FONT_SMALL" Size="9" Bold="false" Italic="false" Strikeout="false" Underline="false"/>

<Font Id="ID_FONT_NORMAL" Size="10" Bold="false" Italic="false" Strikeout="false" Underline="false"/>

<Font Id="ID_FONT_HYPERLINK" Size="10" Bold="false" Italic="false" Strikeout="false" Underline="true"/>

<Font Id="ID_FONT_BOLD" Size="10" Bold="true" Italic="false" Strikeout="false" Underline="false"/>

<Font Id="ID_FONT_11" Size="11" Bold="false" Italic="false" Strikeout="false" Underline="false"/>

<Font Id="ID_FONT_BIG" Size="14" Bold="false" Italic="false" Strikeout="false" Underline="false"/>

<Font Id="ID_FONT_BOLD_BIG" Size="14" Bold="true" Italic="false" Strikeout="false" Underline="false"/>

<Font Id="ID_FONT_BOLD_BIG_BIG" Size="18" Bold="true" Italic="false" Strikeout="false" Underline="false"/>

</Fonts>

</FontFamily>

为了一致性的考虑,一个应用程序最好只用一种字体。这里定义了一个字体家族的列表,根据操作系统字体的安装情况,优先选择靠前的字体。字体的其他属性,比如大小、是否加粗、是否斜体、是否有下划线、是否有删除线,通过xml的节点属性指定。

我们可以写一个字体管理的单例类,通过ID获得字体。具体代码如下:

#pragma once

class CFontManager

{

private:

CFontManager();

~CFontManager();

public:

static CFontManager* GetInstance();

static void ReleaseInstance();

public:

Font* GetFont(const tstring& strFont);

protected:

void Load();

private:

static CFontManager* s_inst;

private:

tstring                               m_strFamily;

map<tstring, Font*>        m_mapFont;

};

CFontManager* CFontManager::s_inst = NULL;

CFontManager* CFontManager::GetInstance()

{

if(!s_inst)

{

s_inst = new CFontManager();

if(s_inst)

{

s_inst->Load();

}

}

return s_inst;

}

void CFontManager::ReleaseInstance()

{

if(s_inst)

{

delete s_inst;

s_inst = NULL;

}

}

CFontManager::CFontManager()

{

}

CFontManager::~CFontManager()

{

}

void CFontManager::Load()

{

//从xml加载字体

}

Font* CFontManager::GetFont(const tstring& strFont)

{

map<tstring, Font*>::iterator iter = m_mapFont.find(strFont);

if(iter != m_mapFont.end())

{

return iter->second;

}

assert(false);

return NULL;

}

3 图片管理

png格式体积小、清晰度高、支持透明通道,是图片资源的不二之选。应用程序可能还需要一些gif格式的图片。

为了减少图片的数量,可以将一些相似的图片合在一起,组成一张图片。例如按钮背景,通常需要四种状态:正常、鼠标移上去、鼠标按下、禁用。这四张图片就可以合为一张图片。

我们还需要一个xml的索引文件,用来记录图片是由多少张图片合在一起的、绘制图时怎样去九宫格拉伸图片。

索引文件的格式如下:

<Images>

<Image Name="Button.png" Frame="4" Patch=”7,7,7,7”/>

<Image Name="IconButton.png" Frame="3" Patch=”7,7,7,7”/>

<Image Name="ComboArrow.png" Frame="4" Patch=”7,7,7,7”/>

<Image Name="CheckBox.png" Frame="12" Patch=”7,7,7,7”/>

<Image Name="Close.png" Frame="3" Patch=”7,7,7,7”/>

</Images>

我们可以写一个字体管理的单例类,通过ID获得字体。具体代码如下:

#pragma once

class CImageManager

{

private:

CImageManager();

~CImageManager();

public:

static CImageManager* GetInstance();

static void ReleaseInstance();

public:

Image* GetImage(const tstring& strId);

LONG GetFrameCount(const tstring& strId);

const CSize& GetSize(const tstring& strId);

const CPatch& GetPatch(const tstring& strId);

protected:

void Load();

private:

map<tstring, LONG>                                m_mapImageFrame;

map<tstring, pair<CSize, CPatch>>        m_mapImageInfo;

map<tstring, Image*>                           m_mapImage;

static CImageManager*                     s_inst;

};

CImageManager* CImageManager::s_inst = NULL;

CImageManager::CImageManager()

{

}

CImageManager::~CImageManager()

{

}

CImageManager* CImageManager::GetInstance()

{

if(!s_inst)

{

s_inst = new CImageManager();

if(s_inst)

{

s_inst->Load();

}

}

return s_inst;

}

void CImageManager::ReleaseInstance()

{

if(s_inst)

{

delete s_inst;

s_inst = NULL;

}

}

void CImageManager::Load()

{

//从xml加载图片资源

}

LONG CImageManager::GetFrameCount(const tstring& strId)

{

map<tstring, LONG>::iterator iter = m_mapFrame.find(strId);

if(iter == m_mapFrame.end())

{

AddImage(strId);

}

return m_mapFrame[strId];

}

const CSize& CImageManager::GetSize(const tstring& strId)

{

map<tstring, pair<CSize, CPatch>>::iterator iter = m_mapResImage.find(strId);

if(iter == m_mapResImage.end())

{

AddImage(strId);

}

return m_mapResImage[strId].first;

}

const CPatch& CImageManager::GetPatch(const tstring& strId)

{

map<tstring, pair<CSize, CPatch>>::iterator iter = m_mapResImage.find(strId);

if(iter != m_mapResImage.end())

{

AddImage(strId);

}

return m_mapResImage[strId].second;

}

4 字符串管理

字符串资源可以保存在xml文件中,具体文件格式如下:

<StringTable>

<String Id="IDS_MEMU_TIPS">主菜单</String>

<String Id="IDS_SKIN_TIPS">更换皮肤</String>

<String Id="IDS_MIN_TIPS">最小化</String>

<String Id="IDS_MAX_TIPS">最大化</String>

<String Id="IDS_MENU_TIPS">主菜单</String>

<String Id="IDS_CLOSE_TIPS">关闭</String>

<String Id="IDS_RESTORE_TIPS">还原</String>

<String Id="IDS_TOP_MOST_TIPS">此窗口总在最前</String>

<String Id="IDS_NO_TOP_MOST_TIPS">取消总在最前</String>

<String Id="IDS_MAKE_SKIN_TIPS1">滚动鼠标滚轮,缩放图片</String>

<String Id="IDS_MAKE_SKIN_TIPS2">试试拖动主面板</String>

<String Id="IDS_YES">是</String>

<String Id="IDS_NO">否</String>

<String Id="IDS_OK">确定</String>

<String Id="IDS_CANCEL">取消</String>

</StringTable>

我们可以写一个字符串管理的单例类,通过ID获得字符串。具体代码如下:

#pragma once

class CStringManager

{

private:

CStringManager(){}

public:

static CStringManager* GetInstance();

static void ReleaseInstance();

public:

tstring GetString(const tstring& strId);

protected:

void Load(const tstring& strXml);

private:

static CStringManager* s_inst;

private:

map<tstring, tstring> m_mapString;

};

CStringManager* CStringManager::s_inst = NULL;

CStringManager* CStringManager::GetInstance()

{

if(!s_inst)

{

s_inst = new CStringManager();

if(s_inst)

{

s_inst->Load(_T("value\\string.xml"));

s_inst->Load(_T("value\\system\\string.xml"));

}

}

return s_inst;

}

void CStringManager::ReleaseInstance()

{

if(s_inst)

{

delete s_inst;

s_inst = NULL;

}

}

void CStringManager::Load(const tstring& strXml)

{

//从xml文件加载字符串资源

}

tstring CStringManager::GetString(const tstring& strId)

{

map<tstring, tstring>::iterator iter = m_mapString.find(strId);

if(iter != m_mapString.end())

{

return iter->second;

}

return strId;

}

5 结束语

可以定义一个公共类,用来获取界面的各种资源,方便取用,代码如下:

class SkinUI

{

public:

static LONG GetFrameCount(const tstring& strImage);

static CSize GetImageSize(const tstring& strImage);

static CPatch GetImagePatch(const tstring& strImage);

static CImage* LoadImage(const tstring& strImage);

static Image* GetImage(const tstring& strImage);

static Font* GetFont(const tstring& strFont);

static Color GetColor(const tstring& strColor);

static tstring GetString(const tstring& strString);

};

inline tstring SkinUI::GetString(const tstring& strString)

{

return CStringManager::GetInstance()->GetString(strString);

}

inline Color SkinUI::GetColor(const tstring& strColor)

{

return CColorManager::GetInstance()->GetColor(strColor);

}

inline LONG SkinUI::GetFrameCount(const tstring& strImage)

{

return CImageManager::GetInstance()->GetFrameCount(strImage);

}

inline CSize SkinUI::GetImageSize(const tstring& strImage)

{

return CImageManager::GetInstance()->GetSize(strImage);

}

inline CPatch SkinUI::GetImagePatch(const tstring& strImage)

{

return CImageManager::GetInstance()->GetPatch(strImage);

}

inline Image* SkinUI::GetImage(const tstring& strImage)

{

return CResourceManager::GetInstance()->GetImage(strImage);

}

inline Font* SkinUI::GetFont(const tstring& strFont)

{

return CFontManager::GetInstance()->GetFont(strFont);

}

获取资源的示例代码如下:

获取字符串:

tstring str = SkinUI::GetString(_T(“IDS_OK”));

获取颜色

Color color = SkinUI::GetColor(_T(“ID_COLOR_RED”));

获取图片

Image* pImg = SkinUI::GetImage(_T(“button.png”));

获取字体

Font* pFont = SkinUI::GetFont(_T(“ID_FONT_BOLD”));

时间: 2024-08-10 21:51:16

界面库的六大关键技术之资源管理的相关文章

MFC六大关键技术

视频教程地址观看:http://pan.baidu.com/s/1mhKQ6kK 1.MFC六大关键技术sada)MFC程序的初始化过程:从CWinApp类派生一个应用程序类:使用派生类定义的全局变量(theApp):在预定义头文件"stdafx.h"中,禁用"windows.h"取而代之afx开头的MFC头文件:编译设置中选择用"Use MFC in a Static Library":在CWinApp生类中,重写InitInstance函数作

MFC的六大关键技术

1.MFC程序的初始化过程:消息映射机制:运行时类型识别:动态创建:永久保存:消息传送 2.SendMessage()和PostMessage()向本进程窗口或者其他进程窗口发送消息的 区别:SendMessage():阻塞函数:用于调用指定窗口的内部程序,直到处理完成以后才返回   PostMessage():非阻塞函数;将一个消息发送到一个窗口的消息队列后立即返回 3. 系统消息(0~0x3ff): 非系统消息(大于等于0x400)一般用于传送数据的 4.FindWindow()查找窗口 5

Caffe关键技术之仿真(一)

源 从当年流行的”编程高手必读Linux源码“,到市面上各色各样的XXX源码解析.剖析,我们已经看过太多太烂的源码分析. 读一份源码最痛之处在于,突然蹦出一大段代码,数据结构一个认不得,也不知道变量从何而来,函数更看都不懂. 似乎,那些很烂的作者,总喜欢迎难而上,你越不喜欢大段代码,他就每次首先贴一大段代码. 丝毫不对顺序做优化,也不知道标记出什么是重要的,什么是不重要的,连一份概况都没有. 这不叫源码分析,这叫随堂笔记. 高中时候,曾经拜读过侯捷老师的<深入浅出MFC>,其中最有趣的是它的第

各种界面库介绍及比較

具体界面库列表见http://home.pacbell.net/atai/guitool/ 怎样选择界面库 产品易用性 是否easy整合到现有应用程序中?是否easy在新的应用程序项目中应用? 开发者是否能及时掌握并使用 产品稳定性 是否有足够多的演示样例演示控件库各个方面的功能特性 是否有众多的成功案例 是否一直有持续更新 界面库高效性 拖拽窗体,观察是否有明显的停顿感. 可在一个系统下,找一些知名软件比較,如QQ/MSN等.假设有明显差异 拖拽窗体,观察界面控件是否有明显闪烁 . 软件启动速

国内各个界面库比较

国内各个界面库比较 目前网络上的界面库多彩多样.这里以个人的观点,来评价一下界面库.如果有不当的地方望批评指出. 1 Skin++(www.uipower.com) 该界面库是基于WIN32的界面库,以上海勇进公司的形式来运作,公司规模10人内,开发人员5人左右.05年发布第一个版本以来,运作时间较长.但是产 品和目前最新出的界面库比较起来,略显逊色.(可能不了解的朋友不信,呵呵--)可以去下载他们的成功案例来看看.比如:呱呱聊天室(www.17guagua.com).PPS(http://dl

小梅科普:Unity客户端架构设计与网络游戏关键技术

目前利用Unity开发移动端游戏越来越多,不论是游戏公司还是独立开发者都需要在移动互联网时代发挥各自的技术优势,把自己的产品做到最好占领市场.本课程介绍的是基于Unity客户端框架设计以及关键技术3DAvatar换装和热更新技术实现以及Protobuf-net序列化和反序列化的运用,只有掌握了Unity开发的关键技术才能将其运用在游戏开发中,对于快速的开发游戏占领市场至关重要. 本课程以此项目的开发为讲解内容,以目前游戏开发的关键技术为依据,由浅入深循序渐进进行介绍,绝大部分的代码的编写都有相应

Unity客户端架构设计与网络游戏关键技术(Avatar,热更新,Protobuf)

·  课程讲师:海洋 ·  课程分类:游戏开发 ·  适合人群:中级 ·  课时数量:20(42节)课时 ·  更新程度:完毕 ·  服务类型:C类(普通服务类课程) ·  用到技术:Unity客户端,UI设计框架,Avatar换装,Protobuf-net等 ·  涉及项目:搭建Unity客户端 UI设计框架以及Avatar换装和移动端热更新技术实现以及Protobuf-net在Unity中运用 对这个课程有兴趣的可以加我qq2748165793 1.课程研发环境 开发工具:Unity4.6和

大数据引发混合云井喷,了解四大场景与三大关键技术

进入2018年,我国大数据应用产业正在迎来爆发式增长的一年.作为第五次进入政府工作报告的关键词,大数据已经从国家战略高度到产业发展规划再到具体的发展行动,形成了系统布局.全面扩散.整体爆发之势.2017年底,在"大数据是信息化发展新阶段"的论断下,作为底层技术平台的混合云即将在2018年迎来井喷式发展. 赛迪顾问在"2018中国IT市场年会"上预测,混合云.Docker等技术在2018年将进入规模化部署期.而混合云技术的灵活性可极大提高工作负载,很多大型企业希望私有

C++界面库(十几种,很全),当然Delphier有FMX

刚开始用C++做界面的时候,根本不知道怎么用简陋的MFC控件做出比较美观的界面,后来就开始逐渐接触到BCG  Xtreme ToolkitPro v15.0.1,Skin++,等界面库,以及一些网友自己写的界面库,开始对于C++软件界面美化有了一点点的心得.不敢藏私,希望和一些新手朋友们分享交流. 一.  开源C++界面库 1.RingSdk Ringsdk是CSDN上一个前辈自己写的界面库,这个界面库很轻而易举实现QQ2009的界面效果.链接见 http://blog.csdn.net/rin