简体   繁体   English

如何在 Visual C++ 2010 中打开资源字符串?

[英]How do you open a resource string in Visual C++ 2010?

I created a basic stringtable resource in Visual C++.我在 Visual C++ 中创建了一个基本的字符串表资源。 I am trying to access that resource.我正在尝试访问该资源。 However, my program can't seem to find the resource.但是,我的程序似乎找不到资源。 Here:这里:

int main(int argc, char* argv[])
{
    HRSRC hRsrc;
    hRsrc = FindResource(NULL, MAKEINTRESOURCE(IDS_STRING102), RT_STRING);
    if (hRsrc == NULL) {
        printf("Not found\n");
    } else {
        printf("Found\n");
    }
}

This program can't find the resource and always returns null.该程序找不到资源,总是返回 null。

I created a simple bitmap resource and this new program identifies that just fine.我创建了一个简单的 bitmap 资源,这个新程序可以很好地识别它。 Here:这里:

int main(int argc, char* argv[])
{
    HRSRC hRsrc;
    hRsrc = FindResource(NULL, MAKEINTRESOURCE(IDB_BITMAP1), RT_BITMAP);
    if (hRsrc == NULL) {
        printf("Not found\n");
    } else {
        printf("Found\n");
    }
}

This finds the bitmap.这会找到 bitmap。

Do stringtable resources get handled somehow differently? stringtable 资源的处理方式是否有所不同?

Assuming you do not want to use LoadString() this should help...假设您不想使用 LoadString() 这应该会有所帮助...

Strings and string tables are indeed treated differently when using FindResource() and FindResourceEx().在使用 FindResource() 和 FindResourceEx() 时,字符串和字符串表的处理方式确实不同。 From this KB article:这篇知识库文章:

String resources are stored as blocks of strings.字符串资源存储为字符串块。 Each block can have up to sixteen strings and represents the smallest granularity of string resource that can be loaded/updated.每个块最多可以有 16 个字符串,代表可以加载/更新的字符串资源的最小粒度。 Each block is identified by an identifier (ID), starting with one (1).每个块由一个标识符 (ID) 标识,从一 (1) 开始。 We use this ID when calling the FindResource, LoadResource and UpdateResource functions.我们在调用 FindResource、LoadResource 和 UpdateResource 函数时使用此 ID。

A string with ID, nStringID, is located in the block with ID, nBlockID, given by the following formula: ID 为 nStringID 的字符串位于 ID 为 nBlockID 的块中,由以下公式给出:

nBlockID = (nStringID / 16) + 1; nBlockID = (nStringID / 16) + 1; // Note integer division. //注意integer除法。

The lower 4 bits of nStringID indicates which entry in the block contains the actual string. nStringID 的低 4 位指示块中的哪个条目包含实际字符串。 Once you have calculated the block ID to pass to FindResource() and the index in the block where the string exists you have to scan through it's contents to find the string you are looking for.一旦您计算出要传递给 FindResource() 的块 ID 和存在字符串的块中的索引,您必须扫描它的内容以找到您要查找的字符串。

The following code should get you started.以下代码应该可以帮助您入门。

const WCHAR *stringPtr;
WCHAR stringLen;

//  Get the id of the string table block containing the target string
const DWORD blockID = (nID >> 4) + 1;

//  Get the offset of teh target string in the block
const DWORD itemID = nID % 0x10;

//  Find the resource
HRSRC hRes = FindResourceEx(
    hInst,
    RT_STRING,
    MAKEINTRESOURCE(blockID),
    wLanguage);
if (hRes)
{
    HGLOBAL hBlock = LoadResource(hInst, hRes);
    const WCHAR *tableDataBlock = reinterpret_cast<LPCWSTR>(LockResource(hBlock));
    const DWORD tableBlockSize = SizeofResource(hInst, hRes);
    DWORD searchOffset = 0;
    DWORD stringIndex = 0;

    //  Search through the section for the appropriate entry.
    //  The first two bytes of each entry is the length of the string
    //  followed by the Unicode string itself. All strings entries 
    //  are stored one after another with no padding.
    while(searchOffset < tableBlockSize)
    {
        if (stringIndex == itemID)
        {
            //  If the string has size. use it!
            if (tableDataBlock[searchOffset] != 0x0000)
            {
                stringPtr = &tableDataBlock[searchOffset + 1];
                stringLen = tableDataBlock[searchOffset];
            }
            //  Nothing there -
            else
            {
                stringPtr = NULL;
                stringLen = 0;
            }

            //  Done
            break;
        }

        //  Go to the next string in the table
        searchOffset += tableDataBlock[searchOffset] + 1;

        //  Bump the index
        stringIndex++;
    }
}

You could use LoadString directly instead.您可以直接使用LoadString代替。 Here's some text from the MSDN FindResource documentation...这是 MSDN FindResource文档中的一些文本...

An application can use FindResource to find any type of resource, but this function should be used only if the application must access the binary resource data by making subsequent calls to LoadResource and then to LockResource.应用程序可以使用 FindResource 来查找任何类型的资源,但只有当应用程序必须通过随后调用 LoadResource 然后调用 LockResource 来访问二进制资源数据时,才应使用此 function。

To use a resource immediately...要立即使用资源...

...use LoadString! ...使用加载字符串!

After 2 days of research I found this(it works:):经过2天的研究,我发现了这个(它有效:):

#include <atlstr.h>

......

ATL::CString str;
WORD LangID = MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT); 
str.LoadString(NULL,IDS_STRING101, LangID);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM