硬编码应用程序中的资源

时间:2010-06-09 22:47:22

标签: c++ winapi resources

我有一些代码显示一个简单的对话框并处理用户操作(使用普通的WinAPI编写)。

// Display dialog and handle user action
LRESULT choice = DialogBoxParam(NULL, MAKEINTRESOURCE(AP_IDD_DIALOG), NULL, (DLGPROC)DialogCallback, NULL);

有没有办法硬编码资源文件dialog.rc,用于构建对话框?(我想摆脱.rc个文件而且我很确定有办法,但我不知道它是什么:)

修改

此外,是否有人对将现有.rc文件转换为硬编码资源有任何想法?这可能吗?

5 个答案:

答案 0 :(得分:3)

* .rc(资源)文件是源代码,它们使用资源编译器编译并链接到您的对象(.exe / .dll)

您无需发送资源文件或将其与应用程序一起运行即可运行。

如果你想转向以编程方式定义的窗口而不是模板,那么你可能想要查看QT / wxWidgets。但这对于1个对话来说是相当大的开销!

答案 1 :(得分:2)

可以使用

DialogBoxParamIndirect代替。它将对话框模板作为参数。 Raymond Chen的博客有一个example在运行时构建一个对话框,而不是使用DialogBox * Indirect API的资源。

Per MSDN,对话框资源基本上由DLGTEMPLATE和DLGITEMTEMPLATE结构组成。因此,您应该能够使用资源API(FindResource,LoadResource和LockResource)来获取现有对话框资源的基础位,并将其嵌入到您的代码中。

请注意,这比使用.rc文件要痛苦得多。对布局进行更改要困难得多,并且它的本地化程度也要低得多,因为本地化现在需要更改代码才能在代码中更新模板。

答案 2 :(得分:2)

我很惊讶我找不到现有的应用程序来做这类事情,谷歌上有足够的点击试图做到这一点。

好的,所以DLGTEMPLATE是一个可变长度的数据blob,通常你让对话框函数从你的资源包中提取它,而不是你想把它存储在你的程序中。

您需要更改静态库以使用新函数将某些“blob”解码回dlgtemplate,并且需要生成blob。 (或者在代码中添加blob而不进行解码,我现在不想考虑)

以下代码将为您提供嵌入应用程序所需的DLGTemplate数据。 (从较大的项目中删除)

HGLOBAL LoadResourceImpl(wchar_t *resource, wchar_t *type)
{
    HRSRC handle = FindResource(hInstance, resource,type);
    if (handle)
    {
        HGLOBAL hResource = LoadResource(hInstance, handle);
        if (hResource)
            return LockResource(hResource);  
    }
    return 0;
}

DLGTEMPLATE * LoadDialog(wchar_t *resource)
{
    return (DLGTEMPLATE *) LoadResourceImpl(resource,RT_DIALOG);
}

DLGTEMPLATE * LoadDialog(int resource)
{
    return (DLGTEMPLATE *) LoadResourceImpl(MAKEINTRESOURCE(resource),RT_DIALOG);
}

创建包含您的资源的应用程序 - 使用适当的LoadDialog来获取数据。

现在以一种格式“写出”该blob以包含在您的应用中 - 第1步 - 通过遍历结构来查找包含所有控件的总大小(控制计数在DLGTEMPLATE :: cdit中),找出有多少数据

第2步 - 将数据转换为可编译成代码的内容 - 如HEX

向您的静态库添加一个新的'HEX'到DLGTEMPLATE方法和使用另一个应用程序创建的十六进制字符串。

答案 3 :(得分:1)

我们可以将.res文件硬编码到程序中吗?

  1. 资源编译器将.rc转换为.res
  2. 使用十六进制转储工具(例如winhex)将.res转换为字节数组 (用C源代码表示)。
  3. 在项目中添加源代码文件并编译可执行文件。
  4. 从数组中找到对话框资源位置并使用DialogBoxIndirect。

答案 4 :(得分:0)

如果这是一个简单的对话框,为什么要使用DLGTEMPLATE?

没有什么可以阻止你直接执行:: CreateWindow直接控制这些控件。如果它是一个带2-3个按钮和几个文本字段的简单对话框,只需调用:: CreateWindow,传入你正在使用的任何常用控件的窗口类。

这基本上就是DialogXxxxx的功能。 DLGTEMPLATE可以方便地声明性地布置表单,并使样板文件进行相应的CreateWindow调用等。