
Keyboard layout indicator with the color of the taskbar and window title in modern versions of Windows using DWM
The keyboard layout indicator in Windows is a pretty inconspicuous thing. The letters typed on the machine in the wrong layout are always frustrating. At least me. Therefore, I always wanted to have such a noticeable indicator of the current keyboard layout as possible. Well, at least one with which you do not need to run your eyes across the screen.
An ideal option would be to attach a small indicator right next to the cursor in the input field, but this turned out to be a difficult task: some applications do not use the system cursor at all. A simple and fairly convenient solution to the problem was to change the color of the taskbar and window title throughout the system. As it turned out, this can be done programmatically using the undocumented features of the Desktop Window Manager API ...
So, we want to change the color of the Windows theme (the color of the taskbar and window titles) in order to maximally visually see the current keyboard layout. We will change the color of the Aero theme, that is, only versions starting with Vista are supported.
First of all, we launch the monitor of the current keyboard layout. He sets up a Windows Shell Hook (WH_SHELL) in order to track layout changes. To be precise, it is not a layout change that is tracked, but a change in the input language. Unfortunately, this solution is not suitable for people who use several different layouts for one (for example, Japanese) language. In the handler, we only respond to the HSHELL_LANGUAGE event and send our main application information about the newly selected language with a simple Windows message.
A small technical feature is that the shell hook handler must be placed in the DLL, and not in the executable file. Therefore, the installation of the handler has been moved to a small Hooker library written in C ++.
There are several important points regarding, firstly, 32- and 64-bit versions of Windows, and secondly, UAC and “administrator mode”.
The fact is that in order to intercept the language change event in both 32-bit and 64-bit applications in the 64-bit version of Windows, it is necessary to separately install 32-bit and 64-bit handlers. Therefore, the Hooker library and its controlling HookerWatcher application are built for both architectures, and the main application launches both versions.
A separate problem is the “administrator mode”. In fact, applications running as administrator are completely separate from applications without elevated privileges. Therefore, in order for the highlighting of the current input language to work in this isolated environment, in the administrator mode, shell hooks for both architectures must be set again. I didn’t do this anymore: if necessary, you can simply launch the second instance of the entire application “on behalf of the administrator”, and everything will work as it should.
In order to control the color of the Windows theme, we will use the Desktop Window Manager API that appeared in Vista . It is this library that controls the display of windows in recent versions of Windows.
The color setting is determined by the WDM_COLORIZATION_PARAMS structure, not described in the DWM documentation and found in the German section of the MSDN forum. For simplicity, in the application settings, we suggest the user to change the colors of the Windows theme themselves and indicate that the current color should be used for one main language, or for all others. That is, in the application settings, we store only two instances of the WDM_COLORIZATION_PARAMS structure - for the "main" language and for everyone else.
The main application uses Windows Forms, consists of one form with the overloaded WndProc method, in which the messages received from the monitor of the current language are processed. After receiving a notification of a language change, the application sets the color of the Windows theme using the DwmSetColorizationParameters method.
By the way, in Windows 7 one could observe a rather funny behavior of the indicator of the current language in a quick search in the Start menu: after entering a character in the Russian layout, the language momentarily switched to English and vice versa. And, accordingly, when entering the next letter, the indicator blinked. And the built-in layout indicator reacted with a noticeable delay, and he did not have such a problem with blinking. In Windows 8, the built-in indicator already works instantly.
The source code can be found on GitHub here , and the release version can be downloaded here .
An ideal option would be to attach a small indicator right next to the cursor in the input field, but this turned out to be a difficult task: some applications do not use the system cursor at all. A simple and fairly convenient solution to the problem was to change the color of the taskbar and window title throughout the system. As it turned out, this can be done programmatically using the undocumented features of the Desktop Window Manager API ...
So, we want to change the color of the Windows theme (the color of the taskbar and window titles) in order to maximally visually see the current keyboard layout. We will change the color of the Aero theme, that is, only versions starting with Vista are supported.
First of all, we launch the monitor of the current keyboard layout. He sets up a Windows Shell Hook (WH_SHELL) in order to track layout changes. To be precise, it is not a layout change that is tracked, but a change in the input language. Unfortunately, this solution is not suitable for people who use several different layouts for one (for example, Japanese) language. In the handler, we only respond to the HSHELL_LANGUAGE event and send our main application information about the newly selected language with a simple Windows message.
A small technical feature is that the shell hook handler must be placed in the DLL, and not in the executable file. Therefore, the installation of the handler has been moved to a small Hooker library written in C ++.
There are several important points regarding, firstly, 32- and 64-bit versions of Windows, and secondly, UAC and “administrator mode”.
The fact is that in order to intercept the language change event in both 32-bit and 64-bit applications in the 64-bit version of Windows, it is necessary to separately install 32-bit and 64-bit handlers. Therefore, the Hooker library and its controlling HookerWatcher application are built for both architectures, and the main application launches both versions.
A separate problem is the “administrator mode”. In fact, applications running as administrator are completely separate from applications without elevated privileges. Therefore, in order for the highlighting of the current input language to work in this isolated environment, in the administrator mode, shell hooks for both architectures must be set again. I didn’t do this anymore: if necessary, you can simply launch the second instance of the entire application “on behalf of the administrator”, and everything will work as it should.
In order to control the color of the Windows theme, we will use the Desktop Window Manager API that appeared in Vista . It is this library that controls the display of windows in recent versions of Windows.
- DwmIsCompositionEnabled - check that DWM is working;
- DwmGetColorizationParameters - get the current colors of the Windows theme;
- DwmSetColorizationParameters - set the current colors of the Windows theme.
The color setting is determined by the WDM_COLORIZATION_PARAMS structure, not described in the DWM documentation and found in the German section of the MSDN forum. For simplicity, in the application settings, we suggest the user to change the colors of the Windows theme themselves and indicate that the current color should be used for one main language, or for all others. That is, in the application settings, we store only two instances of the WDM_COLORIZATION_PARAMS structure - for the "main" language and for everyone else.
The main application uses Windows Forms, consists of one form with the overloaded WndProc method, in which the messages received from the monitor of the current language are processed. After receiving a notification of a language change, the application sets the color of the Windows theme using the DwmSetColorizationParameters method.
By the way, in Windows 7 one could observe a rather funny behavior of the indicator of the current language in a quick search in the Start menu: after entering a character in the Russian layout, the language momentarily switched to English and vice versa. And, accordingly, when entering the next letter, the indicator blinked. And the built-in layout indicator reacted with a noticeable delay, and he did not have such a problem with blinking. In Windows 8, the built-in indicator already works instantly.
The source code can be found on GitHub here , and the release version can be downloaded here .