SkinUI应用程序结构简单,主要由源文件、资源文件和皮肤文件组成。本文将简要介绍各种文件的格式,让大家对SkinUI应用程序的基本结构有个初步的了解。
2.1 SkinUI应用程序的文件结构
使用SkinUI Sln++工具,新建工程【Hello World】。可以看到整个工程的文件结构如下:
I----【bin】 //可执行文件和资源文件
I I----【debug】 //Debug版本的可执行文件和自由文件
I I----【cef】 //Debug版本的cef控件支持文件
I I----【res】 //所有资源文件
I I----【HelloWorld】 //HelloWorld的资源文件
I I----【skin】 //所有皮肤文件
I I----【HelloWorld】 //HelloWorld的皮肤文件
I I----【release】 //cef控件支持文件
I I----【cef】 //Release版本的cef控件支持文件
I I----【res】 //所有资源文件
I I----【HelloWorld】 //HelloWorld的资源文件
I I----【skin】 //所有皮肤文件
I I----【HelloWorld】 //HelloWorld的皮肤文件
I----【src】 //所有源码文件
I I----【HelloWorld】 //HelloWorld源码文件
I I----【Include】 //所有头文件
I I----【SkinUI】 //SkinUI的头文件
如果不需要支持CEF控件,发布时可以删除【cef】文件夹。
2.2 源码文件
SkinUI应用程序需要一个应用程序入口函数、一个应用程序类和若干对话框类。如果需要自定义控件,还会有一些自定义控件类。
2.2.1 应用程序入口
Win32窗口程序的入口函数为WinMain,SkinUI应用程序也是。不需要自定义函数体,直接使用工具生成的代码即可。
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
return SkinUI::WinMain(hInstance, lpCmdLine, nCmdShow);
}
2.2.2 应用程序类
SkinUI程序在整个生命周期只会实例化一个应用程序类。
我们需要继承CSkinApp,实现两个接口,完成初始化操作并弹出主窗口。
应用程序类的生命周期为整个程序的生命周期,我们可以在此缓存数据。
例如,可以在此处缓存用户名和用户ID。
具体代码如下:
头文件
class CHelloWorld : public CSkinApp
{
public:
CHelloWorld();
public:
virtual BOOL InitInstance(ResType& resType);
virtual void Run(const tstring& strCmdLine, int nCmdShow);
};
源文件
CHelloWorld theApp;
CHelloWorld::CHelloWorld()
{
}
BOOL CHelloWorld::InitInstance(ResType& resType)
{
SkinUI::LoadMySkin(_T("C:\\MySkin\\HelloWorld\\")); //加载自定义皮肤
resType = RT_FILE; //资源类型为文件资源
//resType = RT_FILE_PACKAGE; //资源类型为文件资源包
//resType = RT_RC_PACKAGE; //资源类型为RC资源包
return TRUE;
}
void CHelloWorld::Run(const tstring& strCmdLine, int nCmdShow)
{
CMainDialog dlg;
SkinUI::SetMainWnd(&dlg);//设置主窗口
dlg.DoModal(NULL);//弹出主对话框
}
2.2.3 主对话框类
主对话框是程序弹出的第一个窗口。
窗口的布局由xml格式的布局文件指定,需要在构造函数处传递给基类。
主窗口的布局文件通常为"MainDialog.xml"。
可以通过布局文件指定一些窗口的基本属性,例如窗口大小,标题栏高度等。
头文件
class CMainDialog : public CSkinDialog
{
public:
CMainDialog();
public:
virtual void OnInitDialog();
protected:
void OnNcDestroy(BOOL& bHandle);
SKINUI_DECLARE_MESSAGE_MAP()
};
源文件
//此处是消息映射后,这里只处理WM_NCDESTROY
SKINUI_BEGIN_MESSAGE_MAP(CMainDialog, CSkinDialog)
ON_SKINUI_WM_NCDESTROY()
SKINUI_END_MESSAGE_MAP()
CMainDialog::CMainDialog()
: CSkinDialog(_T("MainDialog.xml"))//设置主对话框的布局文件
{
}
void CMainDialog::OnInitDialog()
{
CSkinDialog::OnInitDialog();
//可以在此处添加初始化代码
}
void CMainDialog::OnNcDestroy(BOOL& bHandle)
{
bHandle = FALSE;
PostQuitMessage(0);//发送这条消息后,应用程序进程退出
}
2.3 资源文件
整个资源的文件结构如下:
I----【res】 //所有资源文件
I I----【HelloWorld】 //HelloWorld的资源文件
I I----【image】 //所有图片文件
I I----【system】 //系统图片文件
I I----【Button.png】 //系统图片Button.png
I I----【MyButton.png】 //用户图片MyButton.png
I I----【layout】 //所有布局文件
I I----【system】 //系统布局文件
I I----【Button.xml】 //系统布局文件Button.xml
I I----【MainDialog.xml】 //用户布局文件MainDialog.xml
I I----【menu】 //所有菜单文件
I I----【MainMenu.xml】 //菜单文件MainMenu.xml
I I----【value】 //所有配置文件
I I----【system】 //系统配置文件
I I----【color.xml】 //系统颜色配置文件
I I----【image.xml】 //系统图片配置文件
I I----【font.xml】 //系统字体配置文件
I I----【color.xml】 //用户颜色配置文件
I I----【image.xml】 //用户图片配置文件
I I----【font.xml】 //用户字体配置文件
I I----【config.xml】 //用户全局配置文件
I I----【string】 //所有字符串文件
I I----【2052】 //简体字符串文件
I I----【system】 //系统字符串目录
I I----【string.xml】 //系统字符串文件
I I----【string.xml】 //用户字符串文件
I I----【1033】 //简体字符串文件
I I----【system】 //系统字符串目录
I I----【string.xml】 //系统字符串文件
I I----【string.xml】 //用户字符串文件
I I----【1028】 //繁体字符串文件
I I----【system】 //系统字符串目录
I I----【string.xml】 //系统字符串文件
I I----【string.xml】 //用户字符串文件
2.3.1 图片文件
系统相关图片放在文件夹【image】下的【system】文件夹,业务相关的图片放在文件夹【image】根目录。
另外,需要在图片配置文件指定图片的九宫格拉伸范围和多态图片的帧数。
不在配置文件指定的情况下,图片默认情况下不支持九宫格拉伸,只有一帧。
图片推荐使用png格式,当然也支持其他图片格式。
2.3.2 布局文件
为了实现最大可能的扩展性,不仅对话框可以设置布局文件,其他任何控件都可以设置布局文件。
例如,我们可以给按钮类设置不同的布局文件得到各式各样的按钮,可以给列表项设置不同的布局文件,得到不同的列表项。
对话框的布局文件以"SkinDialog"为根节点,这个节点的属性可以指定对话框的属性。
下面是一个对话框的布局文件:
<SkinDialog DefaultWidth="800" //默认宽度为800像素
DefaultHeight="540" //默认高度为540像素
MinWidth="600" //最小宽度为600像素
MinHeight="400" //最小高度为400像素
TitleHeight="32" //标题高度为32像素
ThemeHeight="100" //主题高度为100像素
Icon="128" //图标使用Id为128的ico文件
AllowMove="true" //允许窗口拖动
OpenAreo="true" //允许毛玻璃效果
Resize="true" //允许改变大小
SysButton="SKIN;MENU;MIN;CLOSE" //四个系统按钮:皮肤、主菜单、最小化、关闭
Caption="IDS_APP_NAME" //标题为字符串IDS_APP_NAME
Animation="SizeChange" //窗口动画类型为SizeChange
Menu="MainMenu.xml"> //点击主菜单按钮,弹出的菜单由MainMenu.xml指定
</SkinDialog>
2.3.3 菜单文件
菜单文件的格式如下:
<Menu>
<MenuItem Id="1003" Text="IDS_ABOUT" Icon="about.png"/>
<MenuItem Id="1004" Text="IDS_HELP" Icon="help.png"/>
<MenuItem Separator="true"/>
<MenuItem Id="2" Text="IDS_QUIT" Icon="quit.png"/>
</Menu>
2.3.3.1 菜单文件
<MenuItem Id="1003" Text="IDS_ABOUT" Icon="about.png"/>表示菜单项。
- 通过属性[id],指定菜单的Id
【Id="1003"】表示菜单项Id为1003。 - 通过属性[Text],指定菜单的文本
【Text="IDS_ABOUT"】表示菜单项文本为IDS_ABOUT。 - 通过属性[Icon],指定菜单的图标
【Icon="about.png"】表示菜单项图标为about.png。
点击菜单项后,会给当前窗口发送WM_COMMAND消息。
可以通过UI更新消息禁用菜单或者选中菜单,还可以通过全局配置文件设置菜单项的高度。
2.3.3.2 菜单分割条
<MenuItem Separator="true"/>表示菜单分割条。
可以通过全局配置文件设置菜单分割条的高度。
2.3.4 配置文件
2.3.4.1 颜色配置文件
系统相关颜色配置文件为文件夹【value】下的【system】文件夹下的【color.xml】,业务相关颜色配置文件为文件夹【value】根目录下的【color.xml】。
文件的格式如下:
<ColorTable>
<Color Id="ID_COLOR_BLACK">255,0,0,0</Color>
<Color Id="ID_COLOR_WHITE">255,255,255,255</Color>
<Color Id="ID_COLOR_TEXT">255,64,64,64</Color>
</ColorTable>
<Color Id="ID_COLOR_BLACK">255,0,0,0</Color>表示一种颜色。
- 通过属性[id],指定颜色的Id
【Id="1003"】表示颜色Id为ID_COLOR_BLACK。 - 通过节点值,指定颜色的ARGB
【255,0,0,0】表示颜色的Alpha为255,Red为0,Green为0,Blue为0。
颜色可以在代码中使用,也可以直接在布局文件中使用。
可以作为背景颜色,也可以作为字体颜色,还可以用来绘制线条、绘制矩形、填充矩形。
2.3.4.2 图片配置文件
系统相关图片配置文件为文件夹【value】下的【system】文件夹下的【image.xml】,业务相关图片配置文件为文件夹【value】根目录下的【image.xml】。
图片配置文件文件的格式如下:
<ImageTable>
<Image Name="Progress.png" Frame="2" Patch="7,2,7,2"/>
<Image Name="Button.png" Frame="4"/>
<Image Name="Edit.png" Frame="4"/>
</ImageTable>
<Image Name="Progress.png" Frame="2" Patch="7,2,7,2"/>表示一张图片。
- 通过属性[Name],指定图片的名字
【Name="Progress.png"】表示图片名字为Progress.png。 - 通过属性[Frame],指定图片的态数
【Frame="2"】表示图片为两态合并为一张图片。 - 通过属性[Patch],指定图片的九宫格拉伸范围
【Patch="7,2,7,2"】表示图片不拉伸范围为距左边7像素,距上边2像素,距右边7像素,距下边2像素。
图片可以在代码中使用,也可以直接在布局文件中使用。
可以作为背景、也可以成为ImageView的展示。
2.3.4.3 字符串文件
系统相关字符串文件为文件夹【xxx】下的【system】文件夹下的【string.xml】,业务相关字符串文件为文件夹【xxx】根目录下的【string.xml】。SkinUI支持多语言,xxx表示语言代码,例如:
- 2052表示简体中文
- 1033表示英文
- 1028表示繁体中文
文件的格式如下:
<StringTable>
<String Id="IDS_MIN_TIPS">最小化</String>
<String Id="IDS_MAX_TIPS">最大化</String>
<String Id="IDS_MENU_TIPS">主菜单</String>
</StringTable>
<String Id="IDS_MEMU_TIPS">主菜单</String>表示一个字符串。
- 通过属性[id],指定字符串的Id
【Id="IDS_MEMU_TIPS">】表示字符串Id为IDS_MEMU_TIPS。 - 通过节点值,指定字符串的值
【主菜单】表示字符串的值为"主菜单"。
字符串可以在代码中使用,也可以直接在布局文件中使用。
2.3.4.4 字体配置文件
系统相关字体配置文件为文件夹【value】下的【system】文件夹下的【font.xml】,业务相关字体配置文件为文件夹【value】根目录下的【font.xml】。
文件的格式如下:
<FontFamily>
<Familys>
<Family>微软雅黑</Family>
<Family>新宋体</Family>
<Family>宋体</Family>
</Familys>
<Fonts>
<Font Id="ID_FONT_SMALL" Size="8" Bold="false" Italic="false" Strikeout="false" Underline="false"/>
<Font Id="ID_FONT_BOLD" Size="9" Bold="true" Italic="false" Strikeout="false" Underline="false"/>
<Font Id="ID_FONT_BIG" Size="12" Bold="false" Italic="false" Strikeout="false" Underline="false"/>
</Fonts>
</FontFamily>
字体家族
<Familys>
<Family>微软雅黑</Family>
<Family>新宋体</Family>
<Family>宋体</Family>
</Familys>
上面指定了三种字体家族,程序优先使用"微软雅黑",如果系统没有安装,则使用"新宋体",如果依然没安装,则使用"宋体"。如果宋体也没有安装,则会使用系统默认字体。
<Font Id="ID_FONT_BOLD" Size="9" Bold="true" Italic="false" Strikeout="false" Underline="false"/>表示一种字体。
- 通过属性[id],指定字体的Id
【Id="ID_FONT_BOLD"】表示字体Id为ID_FONT_BOLD。 - 通过属性[Size],指定字体的大小
【Size="9"】表示字体为9号字体。 - 通过属性[Bold="true"],指定字体是否加粗
【Bold="true"】表示字体加粗。 - 通过属性[Italic="false"],指定字体是否为斜体
【Italic="false"】表示字体不是斜体。 - 通过属性[Strikeout="false"],指定字体是否需要加删除线
【Strikeout="false"】表示字体不加删除线。 - 通过属性[Underline="false"],指定字体是否需要加下划线
【Underline="false"】表示字体不加下划线。
字体可以在代码中使用,也可以直接在布局文件中使用。
2.3.4.5 全局配置文件
全局配置文件为文件夹【value】根目录下的【config.xml】。
文件的格式如下:
<Configs>
<DialogRadius>8</DialogRadius>
<DialogBorderColor>ID_COLOR_BORDER</DialogBorderColor>
<DialogCaptionFontColor>ID_COLOR_CAPTION</DialogCaptionFontColor>
<DialogCaptionFontStyle>ID_FONT_BOLD</DialogCaptionFontStyle>
<DialogShadowPatch>12,12,12,12</DialogShadowPatch>
<DialogSysButtonRightOffset>10</DialogSysButtonRightOffset>
<MenuMinWidth>150</MenuMinWidth>
<MenuItemHeight>24</MenuItemHeight>
<MenuSeparatorHeight>5</MenuSeparatorHeight>
<FullTransparentSkin>true</FullTransparentSkin>
</Configs>
上面的配置表示一下信息:
- <DialogRadius>8</DialogRadius>
对话框为圆角矩形,圆角半径为8 - <DialogBorderColor>ID_COLOR_BORDER</DialogBorderColor>
对话框边框颜色为ID_COLOR_BORDER - <DialogCaptionFontColor>ID_COLOR_CAPTION</DialogCaptionFontColor>
对话框标题栏颜色为ID_COLOR_CAPTION - <DialogCaptionFontStyle>ID_FONT_BOLD</DialogCaptionFontStyle>
对话框标题栏字体为ID_FONT_BOLD - <DialogShadowPatch>12,12,12,12</DialogShadowPatch>
对话框阴影范围为左边12像素,上边12像素,右边12像素,下边12像素 - <DialogSysButtonRightOffset>10</DialogSysButtonRightOffset>
对话框系统按钮距右边10个像素 - <MenuMinWidth>150</MenuMinWidth>
菜单最小宽度为150像素 - <MenuItemHeight>24</MenuItemHeight>
菜单项高度为24像素 - <MenuSeparatorHeight>5</MenuSeparatorHeight>
菜单分隔条高度为5像素 - <FullTransparentSkin>true</FullTransparentSkin>
对话框支持全透明皮肤
2.4 皮肤文件
整个皮肤目录的文件结构如下:
I----【skin】 //所有皮肤文件
I I----【HelloWorld】 //HelloWorld的皮肤文件
I I----【default】 //默认皮肤
I I----【theme.png】 //皮肤文件
I I----【thumb.png】 //皮肤缩略图
I I----【1】 //系统自带皮肤1
I I----【theme.png】 //皮肤文件
I I----【thumb.png】 //皮肤缩略图
I I----【2】 //系统自带皮肤2
I I----【theme.png】 //皮肤文件
I I----【thumb.png】 //皮肤缩略图
I I----【3】 //系统自带皮肤3
I I----【theme.png】 //皮肤文件
I I----【thumb.png】 //皮肤缩略图
I I----【skin.xml】 //皮肤配置文件
皮肤配置文件的格式如下:
<Skins>
<Skin Name="default" Color="254,255,187,3"/>
<Skin Name="1" Color="254,82,207,209"/>
<Skin Name="2" Color="254,170,202,53"/>
<Skin Name="3" Color="254,248,251,220"/>
<Skin Name="4" Color="254,107,71,18"/>
<Skin Name="5" Color="254,118,176,252"/>
<Skin Name="6" Color="254,70,140,240"/>
<Skin Name="7" Color="254,195,221,212"/>
<Skin Name="8" Color="254,75,87,101"/>
<Skin Name="9" Color="254,83,178,16"/>
<Skin Name="10" Color="254,67,103,163"/>
<Skin Name="11" Color="254,187,224,243"/>
<Skin Name="101" Color="255,22,154,218"/>
<Skin Name="102" Color="255,40,138,221"/>
<Skin Name="103" Color="255,49,166,107"/>
<Skin Name="104" Color="255,218,67,78"/>
<Skin Name="105" Color="255,229,98,129"/>
<Skin Name="106" Color="255,177,99,159"/>
<Skin Name="107" Color="255,89,92,160"/>
<Skin Name="108" Color="255,48,116,193"/>
<Skin Name="109" Color="255,0,130,154"/>
<Skin Name="110" Color="255,79,176,172"/>
<Skin Name="111" Color="255,112,197,196"/>
<Skin Name="112" Color="255,128,77,77"/>
<Skin Name="113" Color="255,240,188,89"/>
<Skin Name="114" Color="255,207,186,170"/>
<Skin Name="115" Color="255,72,72,200"/>
<Skin Name="116" Color="255,104,72,200"/>
<Skin Name="117" Color="255,136,72,200"/>
</Skins>
<Skin Name="default" Color="254,255,187,3"/>表示一张皮肤。
- 通过属性[Name],指定皮肤的名字
【Name="default"】表示皮肤的名字为default。 - 通过属性[Color],指定皮肤的基准色
【Color="254,255,187,3"】表示皮肤的基准色为ARGB(254,255,187,3)。
皮肤文件尺寸不足时,会使用基准色补全。
2.4.1 主题色
15种主题色ID_COLOR_DEFAULT1 ~ ID_COLOR_DEFAULT15,通过基准色算出。算法为:
- ID_COLOR_DEFAULT1 ~ ID_COLOR_DEFAULT7
透明度不同的基准色,ID_COLOR_DEFAULT1透明度最高。 - ID_COLOR_DEFAULT8
等同于基准色。 - ID_COLOR_DEFAULT9 ~ ID_COLOR_DEFAULT15
基准色覆盖透明度不同的黑色,ID_COLOR_DEFAULT9覆盖的黑色透明度最高。
2.4.1 标题颜色
如果基准色为深色系,ID_COLOR_CAPTION = ID_COLOR_WHITE;
如果基准色为浅色系,ID_COLOR_CAPTION = ID_COLOR_TEXT。