Ger*_*ans 6 winapi dllimport tablet on-screen-keyboard windows-8
在应用程序中,我在平板电脑上运行时使用屏幕键盘(OSK).我们创建了一个名为OSK的类,它有一个show和hide方法.
当用户按下屏幕键盘上的"输入"时,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;
Run Code Online (Sandbox Code Playgroud)
在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;
Run Code Online (Sandbox Code Playgroud)
在Hide方法中,下一个代码用于隐藏OSK:
var oskWindow := FindWindow("IPTip_Main_Window", nil);
var WM_SYSCOMMAND := 274;
var SC_CLOSE := 61536;
PostMessage(oskWindow, WM_SYSCOMMAND, SC_CLOSE, 0);
Run Code Online (Sandbox Code Playgroud)
更新:找到一个适用于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;
Run Code Online (Sandbox Code Playgroud)
在OSK.Show我启动计时器并将_firstShown设置为false(因为它可能需要一段时间才能显示osk)在此之前我将计时器间隔设置为1秒并向timer.Tick添加了一个eventhandlerf:
_timer.Interval := new TimeSpan(0,0,1);
_timer.Tick += new EventHandler(_timer_Tick);
Run Code Online (Sandbox Code Playgroud)
这是_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;
Run Code Online (Sandbox Code Playgroud)
很高兴当我的开发机器(Windows 7)工作时,快乐是短暂的,因为当我在平板电脑(Windows 8)上测试时,它无法正常工作.计时器等工作正常,它看起来像Windows 8不处理iswindowVisible方法.
无论如何所有的帮助非常感谢
终于找到了使用注册表解决我的问题的方法。osk 使用名为 UserClosed 的注册表项。如果用户关闭操作系统,则用户关闭的注册表项将为 1。
因此,首先要做的就是将此注册表项设置为 0(在 App.Xaml.cs 中重写 OnStartup)
var regKeyUserClosed := Registry.CurrentUser.OpenSubKey("Software\Microsoft\TabletTip\1.7",true);
regKeyUserClosed.SetValue("UserClosed",0);
Run Code Online (Sandbox Code Playgroud)
现在,当应用程序启动时,注册表项设置为 0。
现在,当调用 osk 时,计时器就会启动,在每次滴答时,我们需要查看注册表项是否为 1(用户已关闭 OSK),如果是,我们会触发事件,停止计时器并将注册表项设置回 0。
这是我的新timer_tick方法:
class method OSK._timer_Tick(sender: Object; e: EventArgs);
begin
var regKeyUserClosed := Registry.CurrentUser.OpenSubKey("Software\Microsoft\TabletTip\1.7",true);
var UserClosed := Convert.ToInt32(regKeyUserClosed.GetValue("UserClosed"));
if UserClosed.Equals(1) then begin
OSKClosed(nil,new EventArgs());
_timer.Stop();
regKeyUserClosed.SetValue("UserClosed",0);
end;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4083 次 |
| 最近记录: |