在一个应用程序中,当它在平板电脑上运行时,我使用屏幕键盘 (OSK)。我们创建了一个名为 OSK 的类,它有一个显示和隐藏方法。
当用户在屏幕键盘上按下“enter”时,osk 会隐藏。问题是当用户使用关闭 (x) 按钮关闭 OSK 时。OSK 隐藏,但发生这种情况时需要在 UI 中更改某些内容。
有没有办法(事件或类似的东西)知道用户何时按下 OSK 上的关闭按钮?
我将展示一些用于显示和隐藏 OSK 的代码。显示的代码在 Oxygene 中(但我认为它看起来很像 C#)
首先我们有一些 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;
在 show 方法中有这样的代码:
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;
在 Hide 方法中,下一个代码用于隐藏 OSK:
var oskWindow := FindWindow("IPTip_Main_Window", nil);
var WM_SYSCOMMAND := 274;
var SC_CLOSE := 61536;
PostMessage(oskWindow, WM_SYSCOMMAND, SC_CLOSE, 0);
更新:找到适用于 Windows 7 的工作解决方案....不适用于 Windows 8(我需要什么)
这就是我在 Windows 7 中解决问题的方法:主要思想是在 OSK 类中,当显示 osk 时我启动一个 Dispatchertimer。现在每秒检查 osk 窗口是否可见。如果是这样,则会触发一个事件,该事件可以在多个地方进行处理。(我还检查了计时器中的 _firstshown 布尔值,因为有时 osk 需要一段时间才能出现。
我是这样做的:首先我创建了 IsWindowVisible 方法的 dllImport
[DllImport("user32.dll", CharSet:=CharSet.Auto)]
class method IsWindowVisible(hWnd:IntPtr):Boolean; external;
在 OSK.Show 中,我启动计时器并将 _firstShown 设置为 false(因为 osk 可能需要一段时间才能出现)在此之前,我将计时器间隔设置为 1 秒,并将 eventhandlerf 添加到 timer.Tick:
_timer.Interval := new TimeSpan(0,0,1);
_timer.Tick += new EventHandler(_timer_Tick);
这是 _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;
当它在我的开发机器(windows 7)上工作时很高兴,这种喜悦是短暂的,因为当我在平板电脑(windows 8)上测试它时它不起作用。计时器等工作正常,看起来 Windows 8 不处理 iswindowVisible 方法。
无论如何,非常感谢所有帮助