码迷,mamicode.com
首页 > 其他好文 > 详细

第十一篇:SOUI系统资源管理

时间:2014-08-26 00:08:05      阅读:408      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   使用   io   文件   ar   

从前篇已经讲到在SOUI中所有资源文件通过一个uires.idx文件进行索引。

这里将介绍在程序中如何引用这些资源文件。

在SOUI系统中,资源文件通过一个统一的接口对象读取:

namespace SOUI
{
    enum BUILTIN_RESTYPE
    {
        RES_PE=0,
        RES_FILE,
    };

    /**
    * @struct     IResProvider
    * @brief      ResProvider对象
    * 
    * Describe  实现各种资源的加载
    */
    struct IResProvider : public IObjRef
    {
        /**
         * Init
         * @brief    资源初始化函数
         * @param    WPARAM wParam --  param 1 
         * @param    LPARAM lParam --  param 2
         * @return   BOOL -- true:succeed
         *
         * Describe  every Resprovider must implement this interface.
         */
        virtual BOOL Init(WPARAM wParam,LPARAM lParam) =0;
        
        /**
         * HasResource
         * @brief    查询一个资源是否存在
         * @param    LPCTSTR strType --  资源类型
         * @param    LPCTSTR pszResName --  资源名称
         * @return   BOOL -- true存在,false不存在
         * Describe  
         */    
        virtual BOOL HasResource(LPCTSTR strType,LPCTSTR pszResName)=0;

        /**
         * LoadIcon
         * @brief    从资源中加载ICON
         * @param    LPCTSTR pszResName --  ICON名称
         * @param    int cx --  ICON宽度
         * @param    int cy --  ICON高度
         * @return   HICON -- 成功返回ICON的句柄,失败返回0
         * Describe  
         */    
        virtual HICON   LoadIcon(LPCTSTR pszResName,int cx=0,int cy=0)=0;

        /**
         * LoadBitmap
         * @brief    从资源中加载HBITMAP
         * @param    LPCTSTR pszResName --  BITMAP名称
         * @return   HBITMAP -- 成功返回BITMAP的句柄,失败返回0
         * Describe  
         */    
        virtual HBITMAP    LoadBitmap(LPCTSTR pszResName)=0;

        /**
         * LoadCursor
         * @brief    从资源中加载光标
         * @param    LPCTSTR pszResName --  光标名
         * @return   HCURSOR -- 成功返回光标的句柄,失败返回0
         * Describe  支持动画光标
         */    
        virtual HCURSOR LoadCursor(LPCTSTR pszResName)=0;

        /**
         * LoadImage
         * @brief    从资源加载一个IBitmap对象
         * @param    LPCTSTR strType --  图片类型
         * @param    LPCTSTR pszResName --  图片名
         * @return   IBitmap * -- 成功返回一个IBitmap对象,失败返回0
         * Describe  如果没有定义strType,则根据name使用FindImageType自动查找匹配的类型
         */    
        virtual IBitmap * LoadImage(LPCTSTR strType,LPCTSTR pszResName)=0;

        /**
         * LoadImgX
         * @brief    从资源中创建一个IImgX对象
         * @param    LPCTSTR strType --  图片类型
         * @param    LPCTSTR pszResName --  图片名
         * @return   IImgX   * -- 成功返回一个IImgX对象,失败返回0
         * Describe  
         */    
        virtual IImgX   * LoadImgX(LPCTSTR strType,LPCTSTR pszResName)=0;

        /**
         * GetRawBufferSize
         * @brief    获得资源数据大小
         * @param    LPCTSTR strType --  资源类型
         * @param    LPCTSTR pszResName --  资源名
         * @return   size_t -- 资源大小(byte),失败返回0
         * Describe  
         */    
        virtual size_t GetRawBufferSize(LPCTSTR strType,LPCTSTR pszResName)=0;

        /**
         * GetRawBuffer
         * @brief    获得资源内存块
         * @param    LPCTSTR strType --  资源类型
         * @param    LPCTSTR pszResName --  资源名
         * @param    LPVOID pBuf --  输出内存块
         * @param    size_t size --  内存大小
         * @return   BOOL -- true成功
         * Describe  应该先用GetRawBufferSize查询资源大小再分配足够空间
         */    
        virtual BOOL GetRawBuffer(LPCTSTR strType,LPCTSTR pszResName,LPVOID pBuf,size_t size)=0;

        /**
         * FindImageType
         * @brief    查询与指定名称匹配的资源类型
         * @param    LPCTSTR pszImgName --  资源名称
         * @return   LPCTSTR -- 资源类型,失败返回NULL
         * Describe  没有指定图片类型时默认从这些类别中查找
         */    
        virtual LPCTSTR FindImageType(LPCTSTR pszImgName) =0;
    };

    /**
    * Helper_FindImageType
    * @brief    查询与指定名称匹配的资源类型
    * @param    IResProvider * pResProvider --  当前的ResProvider
    * @param    LPCTSTR pszImgName --  资源名称
    * @return   LPCTSTR -- 资源类型,失败返回NULL
    * Describe  提供一个公共的辅助函数
    */    

    
}//namespace SOUI

这个接口的实现类通过实现这些既定接口来完成图标(HICON),光标(HCURSOR),位图(HBITMAP),一般图片(IBitmap)的解码,同时也提供原始数据(RawData)的读取。

在SOUI系统中内置了两种类型的资源加载(ResProvider)模块:SResProviderPE 和 SResProviderFiles,同时也通过外置组件的形式提供了从ZIP文件加载资源的功能。

这三种资源加载方式基本上涵盖了目前常见的资源加载方式。

为了能够从PE的资源数据段中加载资源,我们需要将uires.idx中索引的文件转换成PE资源可以识别的资源类型+资源名(不是资源ID)的形式。

为了达到这个目的,我们只需要在VS的资源文件中(.rc)将SOUI的资源中定义的文件按照uires.idx定义的类型和名称加进去即可。

手工添加资源文件很难保证不写错。为此,我提供了一个工具(tools\uiresbuilder.exe),这个工具接收一组命令参数,用来将uires.idx转换成一个RC编译器可以识别的.rc2文件(命令行参见使用向导生成的工程)。要编译该.rc2文件,需要在.rc的资源包含中加上我们生成的.rc2文件。

bubuko.com,布布扣

如果程序中的资源不从PE资源加载,则不需要编译soui_res.rc2文件,以减少程序体积。

SResProviderPE, SResProviderFiles 和 SResProviderZIP分别从PE资源,文件夹及ZIP文件包中初始化资源:

#if (RES_TYPE == 0)//从文件加载
        CreateResProvider(RES_FILE,(IObjRef**)&pResProvider);
        if(!pResProvider->Init((LPARAM)_T("uires"),0))
        {
            SASSERT(0);
            return 1;
        }
#elif (RES_TYPE==1)//从EXE资源加载
        CreateResProvider(RES_PE,(IObjRef**)&pResProvider);
        pResProvider->Init((WPARAM)hInstance,0);
#elif (RES_TYPE==2)//从ZIP包加载
        bLoaded=pComMgr->CreateResProvider_ZIP((IObjRef**)&pResProvider);
        SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("resprovider_zip"));

        ZIPRES_PARAM param;
        param.ZipFile(pRenderFactory, _T("uires.zip"),"souizip");
        bLoaded = pResProvider->Init((WPARAM)&param,0);
        SASSERT(bLoaded);
#endif

资源加载成功后,调用SApplication::AddResProvider(IResProvider *)接口将创建的资源加载器交给SOUI系统管理。

SApplication::AddResProvider可以调用多次,便于加载不同的资源。

资源加载后不再需要了也可以使用SApplication::RemoveResProvider(IResProvider *)来删除。

程序中要使用一个资源时,首先调用SApplication::HasResource来查询一个资源是否存在,然后再根据资源类型选择不同的接口加载资源。

SApplication中管理着一个IResProvider列表,系统采用后进先查的算法处理资源重名,即最后调用AddResProvider加进来的资源加载器优先级最高。

 

第十一篇:SOUI系统资源管理

标签:des   style   blog   http   color   使用   io   文件   ar   

原文地址:http://www.cnblogs.com/setoutsoft/p/3936066.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!