This article was written following a need to detect the currently used language, regardless of the currently used application. For the purpose of demonstration, the language's direciton (either left to right or right to left) is displayed.
Locales and Languages
According to Microsoft MSDN, the term "language" indicates a collection of properties used in spoken and written communication. Each language has a language name and a language identifier that indicate the particular code page (ANSI, DOS, Macintosh) used to represent the geographical location for the language on the operating system. A neutral language is indicated by a name such as "en" for English. A more geographically specific language can be indicated by a name that includes both locale and country/region information. For example, the locale English (United States) has the language name "en-US". The one used for Hebrew is He-HE. Some users can switch between two or more installed languages during their day to day work. For example, a user who writes in Arabic or Hebrew will certainly need to use Latin characters as well, so in these cases pressing Left SHIFT + ALT / Right SHIFT + ALT make this switch.
The User Interface
As a result, you will be able to view the current status (in our case, the current active language) regardless of the active application. In the example bellow, the active window is Notepad and the currently used language is Hebrew.
The Source Code
In order to detect the currently selected language, we call GetLocaleInfoW(). There is a more recent version, GetLocaleInfoEx() which is recomended if you target Windows Vista and higher. In my example, I used GetLocaleInfoW(). My example concentrate in one aspect of the locality: the direction of the text which can be either from left to right or from right to left. With the same API you can get the language name, the default currently and much more information.
auto layout = GetKeyboardLayout(GetWindowThreadProcessId(win->GetSafeHwnd(), NULL));
auto lcid = MAKELCID(LOWORD(layout), SORT_DEFAULT);
if (GetLocaleInfoW(lcid, LOCALE_FONTSIGNATURE, (LPWSTR)&localesig, sizeof(localesig) / sizeof(WCHAR)) != 0)
ret = (localesig.lsUsb & 0x08000000) != 0;
As a result, "ret" will hold either TRUE if the default text direction is from Right to Left, or FALSE, or the default text direction is from Left to Right.
There is a list of available and supported languages in this list. Each language identifier is composed of a primary language identifier indicating the language and a sublanguage identifier indicating the country/region. The language identifier corresponds to a particular locale, for example, English (United States), represented as "en-US". The language identifier is used as part of the locale identifier.
I used MFC for the interface however all API calls are pure Win32. Using MFC allows quick creation of applications, especially when user interface is needed. In my case, I create a Timer by calling
and then, I can place my code in
void CDisplayLocaleDlg::OnTimer(UINT_PTR nIDEvent)
knowing it will be called every second.
When you compile the code and run it, you can use any other software or go to any other window and still see the window's title and the currently selected language direction shown on the user interface of our program. That can be expanded to display:
- Default calendar: see: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317734(v=vs.85).aspx
- Default currency: see: https://msdn.microsoft.com/en-us/library/windows/desktop/dd318084(v=vs.85).aspx