Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a string resource by name in win32 or MFC?

I'd like to query if a string is in the string table prior to getting it as some of the items may not be in the string table. To make this clear, the symbol may or may not have been declared, so I cannot just specify the string id because it may or may not exist and will cause a compile error if it doesn't.

From a console application base, I tried this:

ConsoleApplication4.rc:

STRINGTABLE
BEGIN
   IDS_APP_TITLE       "ConsoleApplication4"
   IDS_TEST_Home_HERE  "Home here"
END

Resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ConsoleApplication4.rc
//

#define IDS_APP_TITLE           103
#define IDS_TEST_Home_HERE      104
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE    101
#define _APS_NEXT_COMMAND_VALUE     40001
#define _APS_NEXT_CONTROL_VALUE     1000
#define _APS_NEXT_SYMED_VALUE       101
#endif
#endif

ConsoleApplication4.cpp:

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    HMODULE hModule = ::GetModuleHandle(NULL);

    if (hModule != NULL)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
        {
            // TODO: change error code to suit your needs
            _tprintf(_T("Fatal Error: MFC initialization failed\n"));
            nRetCode = 1;
        }
        else
        {
            // TODO: code your application's behavior here.
        }
    }
    else
    {
        // TODO: change error code to suit your needs
        _tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
        nRetCode = 1;
    }

    // vvvv My code below here vvvv:

    HRSRC hResource = FindResource(hModule, _T("IDS_TEST_Home_HERE"), RT_STRING);
    HGLOBAL hgString = LoadResource(hModule, hResource);
    LPCTSTR string = (LPCTSTR)LockResource(hgString);

    cout << string << endl;

    // ^^^^ My code above here ^^^^

    return nRetCode;
}

However, the FindResource() call returns NULL. What am I missing?

Edit:

For anyone interested, I wrote a way to read in id symbol names from a file and convert them to the symbol's numerical value so long as the read in symbol is somehow based on the the original symbol id that is being queried about.

Doing this would allow me to query about an additional symbol's string resource value, which can be picked from a list of predetermined choices.

You can see the solution below.

like image 405
Adrian Avatar asked Sep 17 '25 09:09

Adrian


2 Answers

String resources cannot be identified by a name, only by an integer value. The value indicate their position within the string table.

The resource is actually the table itself (or, more precisely, the string bundles). In some sense, individual strings in the table are not resources. The fact that you can access individual strings with with the resource API functions is really a bit a special-casing on the part of those functions.

Raymond Chen covered the internal format of string tables.

like image 162
Adrian McCarthy Avatar answered Sep 18 '25 22:09

Adrian McCarthy


You can think of the string table in your resource (.rc) file as Key/Value pairs. And FindResource works by you supplying the Key and it returns the value.

The correct syntax for _T("IDS_TEST_Home_HERE") is:

MAKEINTRESOURCE(IDS_TEST_Home_HERE)

You don't need the quotes.

like image 26
Nate Clark Avatar answered Sep 18 '25 21:09

Nate Clark