gpt4 book ai didi

winapi - 屏幕键盘关闭按钮事件?

转载 作者:行者123 更新时间:2023-12-04 15:23:41 24 4
gpt4 key购买 nike

在应用程序中,我在平板电脑上运行时使用屏幕键盘 (OSK)。
我们创建了一个名为 OSK 的类,它有一个显示和隐藏方法。

当用户在屏幕键盘上按下“回车”时,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 bool 值,因为有时 osk 出现需要一段时间。

这是我如何做到的:
首先我做了一个 IsWindowVisible 方法的 dllImport
[DllImport("user32.dll", CharSet:=CharSet.Auto)]
class method IsWindowVisible(hWnd:IntPtr):Boolean; external;

在 OSK.Show 中,我启动计时器并将 _firstShown 设置为 false(因为 osk 可能需要一段时间才能出现)
在此之前,我将计时器间隔设置为 1 秒,并向 timer.Tick 添加了一个 eventhandlerf:
  _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 方法。

无论如何,非常感谢所有帮助

最佳答案

老实说,我不知道 Oxygene,但它看起来像 .NET 的 Pascal :)

由于您的程序本身会启动 OSK,您只需订阅 Process.Exited 当用户关闭 OSK 时将调用的事件。

所以,让 p全局变量并订阅 Exited

p.Exited += new EventHandler(_osk_Exited);

class method OSK._osk_Exited(sender: Object; e: EventArgs);
begin
// will be called when OSK gets closed
end;

另外,我不明白你为什么需要 FindWindow , 你不能用 p.MainWindowHandle反而?

更新2

以前的更新没有用,但突然我想:为什么不使用微软的 Ink API 而不是 hacking?

添加对 Microsoft.Ink 的引用程序集到您的项目,您需要浏览到该文件,因为默认情况下它不在列表中(在 microsoft.ink.dll 下搜索 Program Files )。

然后创建一个 TextInputPanel 需要 OSK 的每个输入的对象:
tip = new TextInputPanel(textBox1);
tip.InPlaceVisibleOnFocus = true;
tip.DefaultInPlaceState = InPlaceState.Expanded;

现在,文本输入面板将在 textBox1 时出现。获得焦点并在失去焦点时隐藏。您甚至可以将处理程序附加到 InPlaceVisibilityChanged事件,如果您对用户何时隐藏面板感兴趣:
tip.InPlaceVisibilityChanged += tip_InPlaceVisibilityChanged;

void tip_InPlaceVisibilityChanged(object sender, InPlaceVisibilityChangeEventArgs e)
{
// do something with e.Visible
}

如果您使用 WPF,您可以使用此方法获取 HWNDTextBox :
HwndSource textHandle = (HwndSource)PresentationSource.FromVisual(wpfTextBox);
tip = new TextInputPanel();
tip.AttachedEditWindow = textHandle.Handle;
tip.InPlaceVisibleOnFocus = true;
tip.DefaultInPlaceState = InPlaceState.Expanded;

关于winapi - 屏幕键盘关闭按钮事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17484545/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com