📜 ⬆️ ⬇️

One of the ways to adapt desktop applications under the touch screen

After working for a while with Windows 8 on a tablet and ultrabook with a touch screen, I came across one interesting feature. When working with input fields in desktop applications, the on-screen keyboard does not appear automatically, you have to call each time by tapping the icon in the system tray, and then close it by pressing the close button.
In Windows UI applications, there is no such problem; the keyboard automatically appears as soon as the input field receives focus and disappears when it is no longer necessary - for example, the control has lost the input focus, or the user has started typing text from the “iron” keyboard.
Since I am not only a user, but also a developer, I thought: what if I transfer this behavior of the on-screen keyboard and into my desktop applications? Task set, looking for a solution.
Congratulations habrachiteli with the upcoming holidays! Anyone who has read to the end - a ready-to-use code as a gift! :)

Task number 1 is to display the keyboard.


Tablet PC Input Panel is an application included in the standard delivery of Windows 8, which actually displays an on-screen keyboard. Run it and see what happens. After starting the application, we see that a keyboard has appeared on the screen. Therefore, to display the keyboard, we implement a software launch.

TCHAR kbdPath[MAX_PATH] = {0}; ExpandEnvironmentStrings(_T("%CommonProgramW6432%"), kbdPath, _countof(kbdPath)); wcscat_s(kbdPath, _countof(kbdPath), _T("\\microsoft shared\\ink\\tabtip.exe")); ShellExecute(NULL, _T("open"), kbdPath, NULL, NULL, SW_SHOWNORMAL); 


If you execute this code on-screen keyboard appears, then what was achieved.
')

Task number 2 - hide keyboard


After the user has pressed Enter or the input field has lost focus, it would be nice to hide the keyboard so that he would not have to do it on his own. To make it even easier, since the keyboard is displayed in the window, you can accomplish this by programmatically closing or minimizing the window. But first you need to find it somehow.

I ran the keyboard and checked the properties of the window using the Spy ++ utility included with Visual Studio and found what I was interested in, namely the IPTip_Main_Window window class . The rest is a matter of technology, using the name of the class, we find the window and minimize it by sending the appropriate message.

 HWND kbd = ::FindWindow(_T("IPTip_Main_Window"), NULL); if(kbd != NULL) { ::PostMessage(kbd, WM_SYSCOMMAND, SC_CLOSE, 0); } 


Task number 3 - expand to the full width of the screen, minimize the keyboard


The on-screen keyboard can have a standard size on the screen, or it can be expanded to the full width of the screen. To change the width of the keyboard, you can send a message to it, which it receives when you click on the maximize button in the upper left corner.

 DWORD msgSwitchTo = ::RegisterWindowMessage(_T("IPTipDockButtonPressed")); HWND kbd = ::FindWindow(_T("IPTip_Main_Window"), NULL); if(kbd != NULL) { ::PostMessage(kbd, msgSwitchTo, 0x891, 0); } 

It would also be good to understand the state of the keyboard. Here I decided to do just that - determine the screen width, then the keyboard width and compare these two values.

 HWND kbd = ::FindWindow(_T("IPTip_Main_Window"), NULL); int screenWidth = GetSystemMetrics(SM_CXSCREEN); RECT touchWindow = {0}; if(GetWindowRect(kbd, &touchWindow) == false) { return false; } int touchWidth = touchWindow.right - touchWindow.left; return (screenWidth <= touchWidth); 

For ease of use in my projects, I wrapped all the functions I got into the CTouchKeyboard class .

 class CTouchKeyboard { public: static bool IsVisible(); static bool Show(); static bool Hide(); static bool Dock(); static bool IsDocked(); private: static HWND FindKeyboardWindow(); static bool PostMessageToKeyboard(DWORD msg, WPARAM wParam, LPARAM lParam); }; 


How to use in applications


When working with text fields, the user expects an on-screen keyboard to appear in the field. How to implement it? When the input text field is received, the parent window receives an EN_SETFOCUS notification, accordingly we add a handler and in the handler for this notification we call

 CTouchKeyboard::Show(); 

If the input focus is lost, the parent window receives a notification EN_KILLFOCUS , accordingly there will be called

 CTouchKeyboard::Hide(); 

We collect, run, enjoy the result - if you select the text field, the keyboard appears, press the Tab key - the keyboard disappears.



Example usage and source code are available here .

Source: https://habr.com/ru/post/163333/


All Articles