March 31st, 2022

Should I translate my window class names?

The default Windows Desktop project template used by Visual Studio loads the window class name from resources:

WCHAR szWindowClass[MAX_LOADSTRING];

LoadStringW(hInstance, IDC_PROJECTNAME, szWindowClass, MAX_LOADSTRING); 

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PROJECTNAME));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_PROJECTNAME);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

Do window class name need to be a translatable resource?

Window class names are never shown to the user, so there’s no need for them to be translated.

Okay, but even though there’s no requirement that they be translated, should they be translated?

No, they shouldn’t.

Window class names are often the subject of automation. Screen readers and other assistive technologies use class names to identify windows so that they can apply custom functionality for that window. For example, if they see a window whose class name is CabinetWClass, then they know that it is an Explorer window and can activate Explorer-specific behaviors, like maybe enabling special commands for opening and closing the Preview Pane. If the name of the window class changed as the user changed languages, the assistive technology tools would have to keep updating to catch up with the different translations.

Back in the days of 16-bit Windows, it was common for the programmatic interface to parts of the system to be based on window class names. For example, if you wanted to open a particular Control Panel, you launched control.exe, and then looked for a window whose class name is Control Panel and sent it a specific message. If these class names were translated for each locale, it would be nearly impossible to write an installer: You would have to write something like this:

HWND FindControlPanelWindow()
{
    // English?
    HWND hwnd = FindWindow("Control Panel", NULL);
    if (hwnd) return hwnd;

    // German?
    HWND hwnd = FindWindow("Systemsteuerung", NULL);
    if (hwnd) return hwnd;

    // French?
    HWND hwnd = FindWindow("Panneau de configuration", NULL);
    if (hwnd) return hwnd;

    // Vietnamese? (Điều khiển)
    // Note that Vietnamese uses code page 1258, but our source
    // code is in code page 1252, so this string is intentional
    // mojibake.¹ 
    HWND hwnd = FindWindow("ÐiêÌu khiêÒ", NULL);
    if (hwnd) return hwnd;

    //... and so on ...
}

And then each time Windows added support for another language (over 100 of them now), you’d have to ship an updated installer.

For these reasons, window class names should be treated as programmatic names and should not be localized.

¹ By an interesting coincidence, code unit D0 in code page 1258 is U+0110 (LATIN CAPITAL LETTER D WITH STROKE) “Đ” which looks very similar to code unit D0 in code page 1252: U+00D0 (LATIN CAPITAL LETTER ETH) “Д.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

8 comments

Discussion is closed. Login to edit/delete existing comments.

  • 紅樓鍮

    Does that mean windows class names are part of the public API surface of a GUI app?

    • skSdnW · Edited

      For the most part, NO! For example, APIs related to the taskbar do FindWindow+SendMessage but those are internal details, just use the documented functions. For automation, use MSAA/UI Automation.

      Of course 3rd-party apps may use their class as part of the API. The most popular mp3 player back in the day had a public SDK where the class name was part of the API and there were/are messages to send for play/pause/next/isplaying/getlength etc. But it has...

      Read more
  • skSdnW

    “if they see a window whose class name is CabinetWClass” Explorer used to be pretty special, use the /e switch and the Explorer window would change its window class. Why, I don’t actually know. I assume for compatibility but that does not make much sense either because even without the folder tree, a Win95 cabinet window is very different from what came before (ListView or even a custom NSE with custom controls).

  • George Jansen

    I don’t think I’ve ever seen a capital Eth before.

  • Marcel Transier

    That brings me to the next question: Why is it best practice to use a translatable resource to store the windowclass name?

    • Raymond ChenMicrosoft employee Author

      I just argued that they shouldn’t.

      • David N

        Shouldn’t be changed or shouldn’t be stored in a resource? That then begs the question, why does the Windows Desktop project template do it that way?

    • Solomon Ucko

      Maybe to make them easier to change in case of compatibility problems or whatnot?