Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find localized Windows strings

I need to find some strings that the current version of Windows is using. For example, when I create a new folder, it is initially named "New Folder" on English Vista. I need to programmatically find what that folder would be named on any language and version of Windows that I might be running on.

Anyone have any ideas how to do that?

Thanks Morinar -- I just stumbled upon that article too. Unfortunately, the stringID doesn't appear to be constant -- it's 30396 on my Vista, which isn't the same as what they show for XP. So it would appear MS didn't keep it stable.

EDIT: Looks like this isn't possible...? This apps runs on computers in Germany, The Netherlands, France, Spain, Brazil, Mexico, Vietnam, Taiwan, China, Japan, South Korea, India, Israel, Hungary ... You get the idea. It will take a very long time to install all the different language packs and find out what 'New Folder' is in every language.

Perhaps the best option is to default to "New Folder" and make the user change that value if they want to. I just prefer to have the software figure out as much as it can and spare the user from configuring _yet_another_setting_.

like image 593
DougN Avatar asked Mar 23 '10 18:03

DougN


2 Answers

Shamelessly cribbed from http://blogs.msdn.com/oldnewthing/archive/2004/01/30/65013.aspx. This is mostly correct but if there is a resource string of "New Folder something else" it will match that:

LPCWSTR FindStringResourceEx(HINSTANCE hinst,
    UINT uId, UINT langId)
{
    // Convert the string ID into a bundle number
    LPCWSTR pwsz = NULL;
    HRSRC hrsrc = FindResourceEx(hinst, RT_STRING,
        MAKEINTRESOURCE(uId / 16 + 1),
        langId);
    if (hrsrc) {
        HGLOBAL hglob = LoadResource(hinst, hrsrc);
        if (hglob) {
            pwsz = reinterpret_cast<LPCWSTR>
                (LockResource(hglob));
            if (pwsz) {
                // okay now walk the string table
                for (int i = 0; i < (uId & 15); i++) {
                    pwsz += 1 + (UINT)*pwsz;
                }

                pwsz+= 1;
            }
        }
    }
    return pwsz;
}

UINT FindResourceStringId(HMODULE resource_handle, LPCWSTR string, UINT langId)
{
    UINT resource_id= -1;

    for (int i= 0; i<65536; ++i)
    {
        LPCWSTR resource_string= FindStringResourceEx(resource_handle, i, langId);

        if (resource_string && wcsncmp(resource_string, string, wcslen(string))==0)
        {
            resource_id= i;
        }
    }

    return resource_id;
}

int main()
{
    HMODULE shell_handle= LoadLibraryW(L"shell32.dll");
    UINT new_folder_id= FindResourceStringId(shell_handle, L"New Folder", 0x409); // look for US English "New Folder" resource id.
}
like image 180
MSN Avatar answered Oct 04 '22 00:10

MSN


This is not easy. These strings are private data for Windows Explorer, and as such they can (and probably do) change between releases. You can hack something up where you do a lot of version checking and read the appropriate resource string, but that seems like a losing battle. What are you trying to accomplish?

like image 44
Luke Avatar answered Oct 04 '22 02:10

Luke