唤醒windows内嵌键盘
通过com组件与进程TabTip.exe的结合
system_tool.h
#pragma once class SystemTool { public: SystemTool &Instance(); bool OpenScreenKeyboard(); private: SystemTool() = default; ~SystemTool() = default; // \brief 打开系统内置osk应用键盘 bool OpenOSK(); // \brief 打开系统触摸键盘 bool OpenTabTip(); // \brief win10判断触摸键盘是否已显示 bool IsWin10KeyboardVisable(); // \brief win7判断触摸键盘是否已显示 bool IsWin7KeyboardVisable(); // \brief 判断系统版本是否大于或等于win10 10.0.14393.0 bool IsNewVersion(); };
system_tool.cpp
#include "system_tools.h" #include <iostream> #include <windows.h> #include <filesystem> #include <algorithm> #include <initguid.h> #include <Objbase.h> #include <atlbase.h> #pragma hdrstop // 4ce576fa-83dc-4F88-951c-9d0782b4e376 DEFINE_GUID(CLSID_UIHostNoLaunch, 0x4CE576FA, 0x83DC, 0x4f88, 0x95, 0x1C, 0x9D, 0x07, 0x82, 0xB4, 0xE3, 0x76); // 37c994e7_432b_4834_a2f7_dce1f13b834b DEFINE_GUID(IID_ITipInvocation, 0x37c994e7, 0x432b, 0x4834, 0xa2, 0xf7, 0xdc, 0xe1, 0xf1, 0x3b, 0x83, 0x4b); struct ITipInvocation : IUnknown { virtual HRESULT STDMETHODCALLTYPE Toggle(HWND wnd) = 0; }; namespace { const char* KeyboardWindowClass = "IPTip_Main_Window"; const char* WindowParentClass = "ApplicationFrameWindow"; const char* WindowClass = "Windows.UI.Core.CoreWindow"; const char* WindowCaption = "Microsoft Text Input Application"; } SystemTool &SystemTool::Instance() { static SystemTool instance; return instance; } bool SystemTool::OpenScreenKeyboard() { return OpenTabTip(); } bool SystemTool::OpenOSK() { PVOID OldValue = NULL; //64位系统中32位程序要访问本机system32文件夹,需取消重定向到Syswow64 BOOL bRet = Wow64DisableWow64FsRedirection(&OldValue); ShellExecuteA(NULL, "open", "osk.exe", NULL, NULL, SW_SHOWNORMAL); if (bRet) { Wow64RevertWow64FsRedirection(OldValue); return true; } else { std::cout << "Wow64DisableWow64FsRedirection fail err code:" << GetLastError(); return false; } } bool SystemTool::OpenTabTip() { if (IsWin10KeyboardVisable() || IsWin7KeyboardVisable()) { std::cout << "keyboard is visible"; return true; } std::string tabTipPath = "C:\\Program Files\\Common Files\\Microsoft Shared\\ink\\TabTip.exe"; std::error_code err; if (!std::experimental::filesystem::exists(tabTipPath, err)) { std::cout << "wrong path,err:" << err << " path:" << tabTipPath; return false; } //系统版本大于win10 10.0.14393.0,需要使用com组件的接口才能将键盘界面显示出来 if (IsNewVersion()) { //判断进程是否已经存在,不存在的话拉起进程即可,存在的话调用com组件 //自行遍历进程,查询对应的进程。 process = FindProcess("TabTip.exe", tabTipPath); if (process.empty()) { std::cout << "IsNewVisable start process TabTip.exe"; ShellExecuteA(NULL, "open", tabTipPath.c_str(), NULL, NULL, SW_SHOWNORMAL); Sleep(600);//第一次启动需要等待TabTip初始化完成 } if (IsWin10KeyboardVisable() || IsWin7KeyboardVisable()) { std::cout << "keyboard is visible"; return true; } std::cout << "IsNewVisable show TabTip"; CoInitialize(nullptr); CComPtr<ITipInvocation> _tip; CoCreateInstance(CLSID_UIHostNoLaunch, 0, CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER, IID_ITipInvocation, (void**)&_tip); if (!_tip) { std::cout << "tip is nullptr"; CoUninitialize(); return false; } else { _tip->Toggle(GetDesktopWindow());//显示触摸键盘 } } else { //将进程TabTip.exe拉起,如果是进程存在的情况下,再次调用会直接显示键盘界面 ShellExecuteA(NULL, "open", tabTipPath.c_str(), NULL, NULL, SW_SHOWNORMAL); } CoUninitialize(); return true; } bool SystemTool::IsWin10KeyboardVisable() { //win10下父窗口是ApplicationFrameWindow子窗口是Windows.UI.Core.CoreWindow HWND parent = FindWindowExA(NULL, NULL, WindowParentClass, NULL); if (!parent) { std::cout << "without parent window:" << WindowParentClass; return false; } HWND wnd = FindWindowExA(parent, NULL, WindowClass, WindowCaption); if (!wnd) { std::cout << "without child window class:" << WindowClass << " caption" << WindowCaption; return false; } return true; } bool SystemTool::IsWin7KeyboardVisable() { HWND touchhWnd = FindWindowA(KeyboardWindowClass, NULL); if (!touchhWnd) { std::cout << "without window:" << KeyboardWindowClass; return false; } unsigned long style = GetWindowLong(touchhWnd, GWL_STYLE); // 由于有的系统在键盘不显示时候只是多返回一个WS_DISABLED这个字段。所以加一个它的判断 std::cout << "WS_CLIPSIBLINGS " << (style & WS_CLIPSIBLINGS); std::cout << "WS_VISIBLE " << (style & WS_VISIBLE); std::cout << "WS_POPUP " << (style & WS_POPUP); std::cout << "WS_DISABLED " << (style & WS_VISIBLE); return (style & WS_CLIPSIBLINGS) && (style & WS_VISIBLE) && (style & WS_POPUP) && !(style & WS_DISABLED); } bool SystemTool::IsNewVersion() { //获取当前的系统版本,与10.0.14393.0比较 // 自行去获取,version="10.0.19042.0" std::string version = ""; std::cout << "compare version 10.0.14393,current windows version:" << version; auto versionList = Split(version, "."); int compareVersion[] = { 10, 0, 14393 }; for (int i = 0; i < versionList.size(); ++i) { switch (i) { case 0: case 1: case 2: if (std::stoi(versionList[i]) > compareVersion[i]) { return true; } else if (std::stoi(versionList[i]) < compareVersion[i]) { return false; } break; case 3: return true; } } return true; }