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

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”));

你可能感兴趣的:(管理)