2 SkinUI应用程序的基本结构

SkinUI应用程序结构简单,主要由源文件、资源文件和皮肤文件组成。本文将简要介绍各种文件的格式,让大家对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。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容