如何使用 "TCHAR maps to" 设置为 "char" 来处理 TResourceStream?

How to work with TResourceStream using "TCHAR maps to" set to "char"?

我正在处理的项目需要 TCHAR maps to 设置为 char 的资源管理,为此我使用 TResourceStream。以前我将 TCHAR maps to 设置为 wchar_t 没有问题。我没有遇到编译器错误,但是使用 char 映射时,我在尝试提取名为 "r_1"(资源标识符)的资源时总是会出错:

Error: Resource r_1 not found

我已阅读文档:

https://docwiki.embarcadero.com/Libraries/en/System.Classes.TResourceStream.Create

https://docwiki.embarcadero.com/RADStudio/en/TCHAR_Mapping

我是不是弄错了,或者它不能从这个映射中使用?

try
{
    const System::UnicodeString r1 = L"r_1";
    //int n1 = 1;
    //System::NativeInt ni;
    System::UnicodeString type ( L"RT_RCDATA" );
    wchar_t *pType = type.c_str();

    TResourceStream *pRStream = new TResourceStream((unsigned int)HInstance, r1, pType);
    ...
    delete pRStream;
    delete pType;
}
catch (const Exception &e)
{
    ...
    ShowMessage(L"Error: " + e.Message);
    return;                   
}

首先,不要使用 delete pType;,因为 pType 没有指向用 new 分配的内存。您的 UnicodeString type 变量拥有内存,因此它会在超出范围时为您释放内存。

也就是说,TCHAR maps to 设置对您显示的代码没有任何影响,因为 TCHAR 类型没有在该代码的任何地方使用。

但是,您不应该将 L"RT_RCDATA" 的字符串值用作 TResourceString 构造函数的最后一个参数。这不是 RCDATA 资源的正确资源类型。 Win32 API 将 RT_RCDATA 常量定义为 MAKEINTRESOURCE(10)(它确实使用 TCHAR,顺便说一句),这意味着资源类型是数字 10,而不是字符串 "RC_DATA".所以你需要传入一个整数 10 类型转换为 System::Char*,例如:

TResourceStream *pRStream = new TResourceStream((unsigned int)HInstance, r1, reinterpret_cast<System::Char*>(10));

或者,您可以使用 Win32 API 的 MAKEINTRESOURCEW() 宏(MAKEINTRESOURCE() 的 Unicode 版本),它将整数转换为 wchar_t*(这System::Char* 映射到 Windows):

TResourceStream *pRStream = new TResourceStream((unsigned int)HInstance, r1, MAKEINTRESOURCEW(10));

或者,您可以使用 RT_RCDATA 常量以获得更好的可读性。为了避免 TCHAR 问题,RTL 的 System.Types 单元(至少在现代 C++Builder 版本中)使用 System::Char 定义了自己的 RT_RCDATA 常量,例如:

#include <System.Types.hpp>

TResourceStream *pRStream = new TResourceStream((unsigned int)HInstance, r1, System::Types::RT_RCDATA);