This article was written following a need to detect the currently used language, regardless of the currently used application. For demonstration purposes, the language's direction (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 indicates 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
In terms of user interface, since our goal would be to detect the language used in the currently active screen, our small program should be passive. Stay behind and yet appear on top (so you can see the indication it provides).
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 below, 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 concentrates on 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);
LOCALESIGNATURE localesig;
if (GetLocaleInfoW(lcid, LOCALE_FONTSIGNATURE,
(LPWSTR)&localesig, sizeof(localesig) / sizeof(WCHAR)) != 0)
ret = (localesig.lsUsb[3] & 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.
Language Identifiers
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.
Why MFC
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:
SetTimer(TIMER_EVENT_SHOWLANG, 1000,NULL);
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:
History
- 21st September, 2017: Initial version