In the application, I use the on-screen keyboard (OSK) when it works on the tablet. We created a class called OSK that has a show and hide method.
When the user presses 'enter' on the on-screen keyboard, osk is hiding. The problem is that the user closes the OSK with the close button (x). OSK is hiding, but some things should change in the user interface when this happens.
Is there any way (event or something like that) to know when the user clicks the close button on OSK?
I will show the code that I used to show and hide OSK. The code shown is in Oxygene (but it is very similar to C #, I think)
First we have dllImports:
[DllImport("user32.dll", SetLastError := true)] class method PostMessage(hWnd: IntPtr; Msg: UInt32; wParam, lParam: IntPtr): Boolean; external; [DllImport("user32.dll", SetLastError := true)] class method FindWindow(lpClassName, lpWindowName: String): IntPtr; external;
The show method has this code:
using p := new Process do begin p.StartInfo.UseShellExecute := true; p.StartInfo.FileName := 'C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe'; p.Start(); end;
In the Hide method, the following code is used to hide the OSK:
var oskWindow := FindWindow("IPTip_Main_Window", nil); var WM_SYSCOMMAND := 274; var SC_CLOSE := 61536; PostMessage(oskWindow, WM_SYSCOMMAND, SC_CLOSE, 0);
Update: Found a working solution for Windows 7 .... does not work for Windows 8 (What I need)
This is what I did to solve the problem on Windows 7: The main idea is that in the OSK class I run Dispatchertimer when osk is displayed. Now every second it checks to see if the splinter window is visible. If so, an event occurs that can be processed in several places. (I also check _firstshown boolean in the timer, because sometimes it takes some time for osk to appear.
Here's how I did it: first I made the dllImport of the IsWindowVisible method
[DllImport("user32.dll", CharSet:=CharSet.Auto)] class method IsWindowVisible(hWnd:IntPtr):Boolean; external;
In OSK.Show, I start the timer and set _firstShown to false (because it may take some time to display osk) Before that, I set the timer interval to 1 second and added eventhandlerf to timer.Tick:
_timer.Interval := new TimeSpan(0,0,1); _timer.Tick += new EventHandler(_timer_Tick);
This is the code in _timer_tick:
class method OSK._timer_Tick(sender: Object; e: EventArgs); begin var oskWindow := FindWindow("IPTip_Main_Window", nil); var IsOSKOpen := IsWindowVisible(oskWindow); if not _firstShown then begin if IsOSKOpen then _firstShown := true; exit; end; if not IsOSKOpen then begin OSKClosed(nil,new EventArgs()); _timer.Stop(); _firstShown := false; end; end;
It was a pleasure when it worked on my development machine (Windows 7), the joy was short-lived, because when I tested it on a tablet (window 8), it did not work. timer, etc. works great, it just looks like Windows 8 doesnβt process the iswindowVisible method.
Anyway all help is much appreciated