C# 检查键盘是否唤醒到桌面上显示
大概需要的win32函数
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName)
//返回值为具有指定类名和窗体名的窗体句柄
//软键盘的类名有很多,以IPTIP_Main_Window为例子
public static extern int GetWindowLong(IntPtr window, int index); //用这个函数能够获得指定窗口的信息 //这里使用GWL_STYLE==-16, 得到窗口风格
public static extern IntPtr FindWindowEx( IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); //FindWindowEx是在窗口列表中寻找与指定条件相符的第一个子窗口
大概用到的常量
private const string CoreWindowClassName = "Windows.UI.Core.CoreWindow"; private const string ApplicationFrameHostClassName = "ApplicationFrameWindow"; private const string TextInputApplicationCaption = "Microsoft Text Input Application";
//最后一个是微软文本输入应用,其他不知道额
WS_EX_NOACTIVATE = 0x08000000; WS_VISIBLE = 0x10000000;
//窗口不会变成前台窗口(Win2000)以上
//窗口可见(感觉这个才是重点)
具体细节
以下是本来判断是32还是64位的函数,但现在是判断这个句柄是否存在
private static bool IsValidHandle(IntPtr handle) { return (IntPtr.Size == 4) ? (handle.ToInt32() > 0) : (handle.ToInt64() > 0); }
到这里,流程大概是完整了,也就是说判断软件键盘是否是窗口可见状态。
当然为了防止意外,在最后面也用以下的函数,不断的去询问窗口列表
private static IntPtr FindTextInputWindow() { IntPtr lastProbed = IntPtr.Zero; do { lastProbed = Win32.FindWindowEx(IntPtr.Zero, lastProbed, ApplicationFrameHostClassName, null); if (IsValidHandle(lastProbed)) { var textInput = Win32.FindWindowEx(lastProbed, IntPtr.Zero, CoreWindowClassName, TextInputApplicationCaption); return textInput; } } while (IsValidHandle(lastProbed)); return IntPtr.Zero; }
实际运用
有时候我们不知道键盘为什么起不来,但又想让它起来,这样通过以上的判断去发现键盘有没有显示在,没有就主动就唤醒
主要的代码,部分参数在另外的文件,需要自己添加哦
private static bool IsOpened() { return IsWin10OnScreenKeyboardVisible(); } private static bool IsWin10OnScreenKeyboardVisible() { IntPtr handle = Win32.FindWindow(TabTipWindowClassName, ""); if (!IsValidHandle(handle)) { return false; } var isVisible = IsWindowVisibleByHandle(handle); if (isVisible.HasValue) { return isVisible.Value; } var textInputHandle = FindTextInputWindow(); return IsValidHandle(textInputHandle); } private static bool IsValidHandle(IntPtr handle) { return (IntPtr.Size == 4) ? (handle.ToInt32() > 0) : (handle.ToInt64() > 0); } private static bool? IsWindowVisibleByHandle(IntPtr handle) { var style = Win32.GetWindowLong(handle, GwlStyle); if ((style & Win32.WS_EX_NOACTIVATE) != 0) { return false; } if ((style & Win32.WS_VISIBLE) != 0) { return true; } // DWM Window can be cloaked // see https://social.msdn.microsoft.com/Forums/vstudio/en-US/f8341376-6015-4796-8273-31e0be91da62/difference-between-actually-visible-and-not-visiblewhich-are-there-but-we-cant-see-windows-of?forum=vcgeneral if (Win32.DwmGetWindowAttribute(handle, DwmwaCloaked, out var cloaked, 4) == 0) { if (cloaked != 0) { return false; } } return null; } private static IntPtr FindTextInputWindow() { IntPtr lastProbed = IntPtr.Zero; do { lastProbed = Win32.FindWindowEx(IntPtr.Zero, lastProbed, ApplicationFrameHostClassName, null); if (IsValidHandle(lastProbed)) { var textInput = Win32.FindWindowEx(lastProbed, IntPtr.Zero, CoreWindowClassName, TextInputApplicationCaption); return textInput; } } while (IsValidHandle(lastProbed)); return IntPtr.Zero; }