血恋1完整版百度影音:VS2005 纯资源DLL编写与使用【手把手系列】 - 名刀 - 秋水 - CSDN博客

来源:百度文库 编辑:九乡新闻网 时间:2024/04/25 12:45:39

问题1:纯资源DLL是什么?

答:

    只包含资源(*.rc 、resource.h 和 主工程Resource Files下面的所有东东 )的DLL。主工程在启动时通过加载这个纯资源DLL来获得所有的资源。而取代传统方式的资源在主题工程之内的形式,以达到减小主工程的体积(EXE文件大小),并实现模块化与语言国际化。

问题2:上个问题中的*.rc 、resource.h 和 主工程Resource Files下面的所有东东 是从哪里来的?

答:

    所有的一切,都来自与主工程,并且在主工程中移除这些文件(不是删除),将其加入到纯资源DLL工程。

提示:建议当主工程的所有代码及其功能已经固定,或基本完成(即将release)时,再开始制作相应的纯资源DLL。

补充说明:更深入的研究纯资源DLL,跟帖就好了,嘻嘻嘻嘻~ 找一些相关的资料吧,这里做基础的讲解。

开发环境:WINXP\VS2005\CH(中文)

主体工程完成后,开始制作纯资源DLL:

------------------------------------------------------------------------------------------

(1)新建一个win32->DLL项目,选择默认选项创建即可。

(2)一个崭新的基础DLL框架就有了。

(3)将主体工程中的(a)"源文件"下的   *.rc            添加到DLL工程的"源文件"下

                          (b)"头文件"下的  resource.h  添加到DLL工程的"头文件"下

                          (c)"资源文件"下的 所有东东     添加到DLL工程的"资源文件"下

(4)在主体工程中移除上述的文件。(最好不要删除,以备不时之需!)

(5)编译一下DLL工程,理论上是不会出错的,只要你的主体工程没有问题。好了,一个纯资源DLL就诞生了!开香槟庆祝一下!

(6)这只是一种语言的DLL

(7)把*.rc资源中的所有文字(代码除外...)改成英文的,然后编译... 哦也!一个英文版本的DLL产生了!

(8)再翻译成德文... 一个德文版本的DLL产生了!

(9)... 各种语言版本的DLL产生了... ...

(...)

(n)已经麻木了...

提示:建议将不同版本的DLL用不同的名字,并且COPY不同的*.rc版本,根据需要换着用,不用新建很多DLL工程。因为只有文字不一样嘛!

-------------------------------------------------------------------------------------------

主体工程修改,以适应新的加载资源方式:

-------------------------------------------------------------------------------------------

(1)打开主工程的"类视图",找到那个APP类(C[你的工程名字]App,例如:CabcApp)。

(2)在InitInstance(void)函数里面加入如下代码

    //read reg and get selected language EN or CH

    HKEY hKey;
    DWORD dwType;    //注册表中的值类型(REG_DWORD 、REG_BINARY等等)
    DWORD size = sizeof(DWORD);    //注册表中的值的size,单位BYTE(8bit),由于我们这里只用到DWORD值所以大小是sizeof(DWORD).
    
    if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, HKEYLANGUAGEPATH, NULL, KEY_ALL_ACCESS, &hKey))

    //#define HKEYLANGUAGEPATH "SOFTWARE\\MYPROGRAM"  注册表键路径

    //#define HKEYLANGUAGE "Language" 注册表键值名称
    {//m_language 是在App类中新建的 protected: DWORD m_hDll成员变量
        if (ERROR_SUCCESS != RegQueryValueEx(hKey, HKEYLANGUAGE, NULL, &dwtType, (LPBYTE)&m_language, &size))
        {
            MessageBox(NULL, "Can't read registration information !", NULL, MB_OK);
            RegCloseKey(hKey);
            return FALSE;
        }

        RegCloseKey(hKey);
    }
    else
    {
        hKey = HKEY_LOCAL_MACHINE;
        DWORD nbf = 0;
        DWORD size = sizeof(m_language);

        if (!LoadLibrary("EnUI.dll"))   //EnUI.dll not exist
        {
            if (!LoadLibrary("ChmUI.dll"))    //ChmUI.dll not exist
            {
                MessageBox(NULL, "Application was damaged, please reinstall !", NULL ,MB_OK);
                return FALSE;
            }
            else
            {
                m_language = DISPLAY_CHINASE;    //DISPLAY_CHINASE DWORD 1
            }

        }
        else
        {
            m_language = DISPLAY_ENGISH;     //DISPLAY_ENGISH DWORD 0    
        }

        FreeLibrary(m_hDll);
        //create new reg key
        RegCreateKeyEx(hKey, HKEYLANGUAGEPATH, 0, "", REG_OPTION_NON_VOLATILE,
            KEY_READ|KEY_WRITE, NULL, &hKey, &nbf);
        RegSetValueEx(hKey, HKEYLANGUAGE, 0, REG_DWORD, (LPBYTE)&m_language, size);
    }


    m_hDll = NULL;       //m_hDll是在App类中新建的 protected: HINSTANCE m_hDll成员变量

                                      

    //here used if..else, you can use switch..case here instead for more different language case.

    if (DISPLAY_CHINASE == m_language)    //CH
    {
        m_hDll = LoadLibrary("ChmUI.dll");    //我们刚刚制作的中文版DLL
    }
    else if (DISPLAY_ENGISH == m_language)//EN
    {
        m_hDll = LoadLibrary("EnUI.dll");    //我们刚刚制作的英文版DLL

    }

    if (NULL == m_hDll)
    {   
        MessageBox(NULL, "ChmUI.dll or EnUI.dll not exist !", NULL, MB_OK);    //警告信息
        return FALSE;
    }
    else
    {
        AfxSetResourceHandle(m_hDll);
    }

//...若干代码

    FreeLibrary(m_hDll);    //此行加在return FALSE之前

至此,DLL已经加载成功了!

然后所有的资源都会自动的关联到主程序,万事大吉!!哦也!!!

编译、调试...

等等...

貌似有些同学出现问题了,有一部分图片、图标没有加载进来?!

别急,如果你的主工程代码中有类似:
    hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 32, 32, 0);  
的代码时,只要将LoadImage的第一个参数改成::AfxGetResourceHandle()就可以了,类似的LoadIcon等等,都是如此!

编译、生成...

再等等... 主工程生成的EXE怎么没有图标了?!变成白板了...

现在在已经完全移除原有资源的工程里,向"资源文件"中添加图标资源(EXE图标),这时会自动生成新的*.rc等等(一般会是*1.rc 、recources1.h),建议把新生成的这些文件改名(比如*.rc -->ProgramIcon.rc 、resources.h-->ProgramIcon.h )。然后更改rc文件里的"#include "resources.h"--->#include "ProgramIcon.h""。当然不改也一样,只是这样容易让人理解。然后在"资源"视图将刚刚添加的图标改成"IDR_MAINFRAME"名字(我指的是图标ID)。

编译、生成...

于是和以前一样,什么都正常了~

PS:

别忘了将做好的DLL放进主工程的DEBUG目录哦~

新添加的rc资源不会与DLL中的资源冲突,放心使用吧!当然也可以继续添加比如版本信息等等。

如果发现"资源视图"有显示不正确的现象,关闭VS,重启VS就OK了!

OK,再有新的心得时继续发帖!