• 第三十二篇:在SOUI2.0中像android一样使用资源


    SOUI2.0之前,在SOUI中使用资源通常是直接使用这个资源的name(一个字符串)来引用。使用字符串的好处在于字符串能够表达这个资源的意义,因此使用字符串也是现代UI引擎常用的方式。

    尽管直接使用字符串有意义明确的优点,它同样也有缺点:

    1、字符串写错了,编译器不知道。这可能导致一些很难发现的BUG。

    2、控件查询,比较时基于字符串,相对来说性能会差一点(好在现在CPU够强,这点性能损失通常可以忽略)。

    做过Android开发的朋友可能知道,在Android中要引用一个资源如图片、字符串、颜色等可以使用R.id.xxx, R.string.xxx,R.color.xxx这样的形式来引用。

    Android内部全部自动转换成ID,整数比较显然比字符串比较快,这里不作讨论。

    这种方式一个好处在于Android的自动补全功能能够帮助你快速的输入你需要的资源,除了加快了编码速度,还大大减少了输入错误。

    SOUI2.0把Android的这种资源引用方式引入了进来。

    关键在于uiresbuilder。原来SOUI中的uiresbuilder只提供将资源转换成.rc2功能,方便将资源编译到EXE/DLL中。

    2.0版本新增加name提取,id生成,字符串表ID生成,颜色表ID生成功能。它们会输出到一个C++头文件(由命令行参数指定)。

    要使用该功能首先要保证所有的布局XML所在的资源类型为"Layout",然后在uiresbuilder的命名行中加入: -h “输出文件名” idtable。-h 后面紧跟输出文件名,idtable指示需要给没有指定ID的控件自动生成ID,该功能默认关闭。

    生成成功后,你的“输出文件”的内容可能是下面的样子:

    //stamp:0ae7b68801b8deb8
    /*<------------------------------------------------------------------------------------------------->*/
    /*该文件由uiresbuilder生成,请不要手动修改*/
    /*<------------------------------------------------------------------------------------------------->*/
    #pragma once
    #include <res.mgr/snamedvalue.h>
    namespace SOUI
    {
        const SNamedID::NAMEDVALUE namedXmlID[]={
            {L"btnSelectGif",65540},
            {L"btn_display",65541},
            {L"btn_hidetst",65542},
            {L"btn_lrc",65543},
            {L"btn_menu",65536},
            {L"ctrl_flash",65538},
            {L"gif_test",1000},
            {L"giftest",65539},
            {L"tab_main",65537}        };
        class _R{
        public:
            class _name{
            public:
            _name(){
                btnSelectGif = namedXmlID[0].strName;
                btn_display = namedXmlID[1].strName;
                btn_hidetst = namedXmlID[2].strName;
                btn_lrc = namedXmlID[3].strName;
                btn_menu = namedXmlID[4].strName;
                ctrl_flash = namedXmlID[5].strName;
                gif_test = namedXmlID[6].strName;
                giftest = namedXmlID[7].strName;
                tab_main = namedXmlID[8].strName;
            }
             const wchar_t * btnSelectGif;
             const wchar_t * btn_display;
             const wchar_t * btn_hidetst;
             const wchar_t * btn_lrc;
             const wchar_t * btn_menu;
             const wchar_t * ctrl_flash;
             const wchar_t * gif_test;
             const wchar_t * giftest;
             const wchar_t * tab_main;
            }name;
    
            class _id{
            public:
            const static int btnSelectGif    =    65540;
            const static int btn_display    =    65541;
            const static int btn_hidetst    =    65542;
            const static int btn_lrc    =    65543;
            const static int btn_menu    =    65536;
            const static int ctrl_flash    =    65538;
            const static int gif_test    =    1000;
            const static int giftest    =    65539;
            const static int tab_main    =    65537;
            }id;
    
            class _string{
            public:
            const static int mccol_1    =    0;
            const static int mccol_2    =    1;
            const static int mccol_3    =    2;
            const static int mccol_4    =    3;
            const static int mccol_5    =    4;
            const static int mccol_6    =    5;
            const static int title    =    6;
            const static int ver    =    7;
            }string;
    
            class _color{
            public:
            const static int blue    =    0;
            const static int gray    =    1;
            const static int green    =    2;
            const static int red    =    3;
            const static int white    =    4;
            }color;
    
        };
    
         const _R R;
    }

    第一行保留的是一个时间戳,如果资源中布局相关的资源没有变化,则不再生成。

    首先会自动生成一个name, id映射表:SNamedID::NAMEDVALUE,这是一个结构体数组,保留每一个控件的名字及ID(自动生成的及XML中定义的,自动生成的ID自动从65536开始,因此自己定义时应该小于这个值)。

    接下来定义了一个类 class _R。_R中有4个子类:_name, _id, _string, _color,每个类有一个实例,对应的名字为:name, id, string, color。

    最后定义一个_R的实例R。

    到这里你应该已经知道在SOUI中R这个对象有哪几个成员了。

    那么在代码中如何使用R这个对象呢?

    如何使用name对象:

    观察R这个对象,你可能已经发现,在代码直接使用R.name.btnSelectGif就等价于在代码中输入L“btnSelectGif”,这样的好处在于你在输入R.name.btn后VS或者VA可能就给你补全后面的SelectGif,既提高了编码效率,又保证了不会出错。(对象name修改以后也可以使用VA的变量重命名功能自动批量修改)。

    如何使用ID对象:

    前面提到使用字符串来查找窗口对象相对来说较ID比较会慢一点,那么如何使用ID对象呢?要使用ID对象,有一个要求:由于自动生成的ID并没有修改到原有的XML中,直接从XML中初始化布局时是没有ID属性的。为此SOUI2.0的SApplication对象增加了一个方法:InitXmlNamedID,参见demo(注意调用位置):

            //如果需要在代码中使用R::id::namedid这种方式来使用控件必须要这一行代码:2016年2月2日,R::id::namedXmlID是由uiresbuilder 增加-h .
    es
    esource.h idtable 这3个参数后生成的。
            theApp->InitXmlNamedID(namedXmlID,ARRAYSIZE(namedXmlID),TRUE);

    在布局创建前给App对象初始化一个自动生成的Name转ID表。

    控件创建并初始化name属性时,自动从该表中查询ID。

    如此,在代码中可以直接使用R.id.btnSelectGif来查找对应的控件了。

    如何使用string, color对象:

    在布局XML中使用使用string, color对象和android一样:采用@string/str-name, @color/color-name来分别引用在string,color中定义的对应的字符串或者颜色值。

    这里重点讲一下在代码中使用这两个对象:

            //演示R.color.xxx,R.string.xxx在代码中的使用。
            COLORREF crRed = GETCOLOR(R.color.red);
            SStringW strVer = GETSTRING(R.string.ver);

    上面是demo:winmain中一个使用示例。

    R.color.red, R.string.ver是自动生成的两个整数,GETCOLOR, GETSTRING这两个宏会自动从资源中的字符串表及颜色表中获取对应的ID指定的值。

    启程软件 2016年2月22日

  • 相关阅读:
    天乙社区后台管理分析(一)
    [Android Webkit]JNI基础及Java层与C++层的交互
    1033
    pat 1049. Counting Ones (30)
    juce: 跨平台的C++用户界面库
    高性能MySql进化论(一):数据类型的优化_上
    url参数中有+、空格、=、%、&、#等特殊符号的处理
    带环单链表的问题
    在SQL Server 中启用 FileStream
    (2)入门指南——(2)jQuery可以做什么(What jQuery does)
  • 原文地址:https://www.cnblogs.com/setoutsoft/p/5207451.html
Copyright © 2020-2023  润新知