模拟数字键盘的研发方法
在嵌入式开发和一些保护软件通常不通过物理数字键盘,虽然微软给屏幕键盘,但应用磁盘不能定制页面不能智能感应鼠标光标是否输入状态,所以很多时候我们仍然需要实现屏幕键盘。让我们解释一下完成屏幕键盘时涉及的许多核心技术。
一、完成波动文本框
屏幕键盘的文本框不同于普通文本框。当这个文本框成为当前文本框时,它不会影响其他进度的鼠标光标焦点。换句话说,因为这个文本框现在是当前激烈的前台文本框,但鼠标光标仍然停留在其他进度的文本框上。
如图所示,虽然屏幕键盘在文本文档的前面,但鼠标光标仍在文本文档上。
要实现这一技术,我们必须将现阶段的文本框设置为波动工具栏。在这里我得出结论 C# Winform 完成方式:
private const int WS_EX_TOOLWINDOW = 0x00000080; private const int WS_EX_NOACTIVATE = 0x08000000; protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW); cp.Parent = IntPtr.Zero; // Keep this line only if you used UserControl return cp; //return base.CreateParams; } }
以上编码就是把 Winform 确定为波动工具栏文本框。winform只需要 的类中轻载 CreateParams 根据上述代码开发函数公式。winform只需要 的类中轻载 CreateParams 根据上述代码开发函数公式。
二、如何检测当前的输入状态?
在一些嵌入式设备中,我们没有物理计算机键盘,所有的输入也是通过触摸屏和软数字键盘输入的。此时,我们必须在输入状态下弹出屏幕键盘,否则如果屏幕键盘一直在页面上,它既不好看,也会阻碍其他程序流程的正常运行。
实现隐私功能最直接的方法是 windows 在当前输入状态下会发生什么事件,或者用什么样的钩子程序来实现。但是我科学研究了很久,找不到这个方法。如果有人知道这个方法,你可以在回复中告诉我。
我现在正在寻找的方法是按时理解 windows 现阶段文本框是否为输入状态。
IntPtr hWnd = GetForegroundWindow(); uint processId; uint threadid = GetWindowThreadProcessId(hWnd, out processId); GUITHREADINFO lpgui = new GUITHREADINFO(); lpgui.cbSize = Marshal.SizeOf(lpgui); if (GetGUIThreadInfo(threadid, ref lpgui)) { if (lpgui.hwndCaret != 0) { return hWnd; } }
如上述代码所示
首先,我们需要根据 GetForegroundWindows API 获得现阶段文本框的返回值。然后我们再根据 GetGUIThreadInfo 现阶段获取文本框的一些特点。这种特性在 GUITHREADINFO 中界定
public struct GUITHREADINFO { public int cbSize; public int flags; public int hwndActive; public int hwndFocus; public int hwndCapture; public int hwndMenuOwner; public int hwndMoveSize; public int hwndCaret; public System.Drawing.Rectangle rcCaret; }
里面是 GUITHREADINFO 构造。通过这个消息,我们得到了现阶段文本框中关注的子窗口句柄,现阶段得到了鼠标光标的窗口句柄,现阶段激活的子文本框返回值等。通过这个消息,我们得到了现阶段文本框中关注的子窗口句柄,现阶段得到了鼠标光标的窗口句柄,现阶段激活的子文本框返回值等。在这里,我们只需要使用现阶段得到鼠标光标的窗口句柄,即 hwndCaret 。如果hwndcaret, 不是0,也意味着现阶段文本框处于可输入状态。
API函数 C# 定义如下:
[DllImport(user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetGUIThreadInfo(uint idThread, ref GUITHREADINFO lpgui); [DllImport(user32.dll")] public static extern IntPtr GetForegroundWindow(); [DllImport(user32.dll", SetLastError = true)] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
三、模拟数字键盘
模拟数字键盘非常简单,.Net 提供静态函数模拟数字键盘
System.Windows.Forms.SendKeys.Send
这个函数很简单,微软的支持也很全面,这里就不多说了。
此外,你也可以使用更底层的 API 模拟键盘输入的函数公式
[DllImport(user32.dll")] static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);