千家信息网

c++如何调用windows键盘代码

发表于:2024-10-07 作者:千家信息网编辑
千家信息网最后更新 2024年10月07日,这篇文章将为大家详细讲解有关c++如何调用windows键盘代码,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、何为windows键盘windows管这个长得有点
千家信息网最后更新 2024年10月07日c++如何调用windows键盘代码

这篇文章将为大家详细讲解有关c++如何调用windows键盘代码,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

1、何为windows键盘

windows管这个长得有点儿丑的叫屏幕键盘

windows管这个长得好看的叫触摸键盘

当然上面的截图是win10的键盘效果,在win7上是有一些差别的,这里就不截图放出来了

2、如何调用这些windows键盘

似乎很简单,我们用Spy++抓下窗口,找到窗口句柄所关联的进程句柄,再查看下是哪个进程以及命令行信息,然后我们就可以愉快地执行命令调用进程了
屏幕键盘进程信息:

触摸键盘进程信息:

命令行走起,运行exe,此时如果两个键盘你都能顺利调起的话,我只能告诉你,你被你的系统蒙蔽了双眼

3、巨(wei)硬(ruan)搞事情

当系统版本大于等于win10 10.0.14393.0时,触摸键盘你调用TabTip.exe并不会显示出来,也就是说它的内部实现方式变了。
到这里你会不会觉得很诧异,这不是标准玩法吗?为什么毫无预兆就不行了呢?
我只能说你太傻太天真,微软官网本身就没有说明键盘调用的正确姿势,也就是说触摸键盘对微软来说并非开放给你的。当然互联网无所不能,有大神还是想方法逆向了触摸键盘调用的方式

4、具体代码

// 4ce576fa-83dc-4F88-951c-9d0782b4e376DEFINE_GUID(CLSID_UIHostNoLaunch,    0x4CE576FA, 0x83DC, 0x4f88, 0x95, 0x1C, 0x9D, 0x07, 0x82, 0xB4, 0xE3, 0x76);// 37c994e7_432b_4834_a2f7_dce1f13b834bDEFINE_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{constexpr auto kKeyboardWindowClass = L"IPTip_Main_Window";constexpr auto kWindowParentClass = L"ApplicationFrameWindow";constexpr auto kWindowClass = L"Windows.UI.Core.CoreWindow";constexpr auto kWindowCaption = L"Microsoft Text Input Application";constexpr auto kTabTipPath = L"C:\\Program Files\\Common Files\\Microsoft Shared\\ink\\TabTip.exe";constexpr auto kTabletTipSubKey = "Software\\Microsoft\\TabletTip";constexpr auto kTabletTipOption = "EnableDesktopModeAutoInvoke";}

调用屏幕键盘

bool ScreenKeyBoard::OpenOskKeyboard(){    if (!PublicUtils::Process::FindProcess("osk.exe").empty())    {        return true;    }    PVOID OldValue = NULL;    //64位系统中32位程序要访问本机system32文件夹,需取消重定向到Syswow64    BOOL bRet = Wow64DisableWow64FsRedirection(&OldValue);    ShellExecuteW(NULL, L"open", L"osk.exe", NULL, NULL, SW_SHOWNORMAL);    if (bRet)    {        Wow64RevertWow64FsRedirection(OldValue);        return true;    }    else    {        std::cerr << "Wow64DisableWow64FsRedirection fail err code:" << GetLastError() << std::endl;        return false;    }}

调用触摸键盘

bool ScreenKeyBoard::OpenTabTipByProcess(const std::wstring& tabTipPath){    //将进程TabTip.exe拉起,如果是进程存在的情况下,再次调用会直接显示键盘界面    if (!ShellExecuteW(NULL, L"open", tabTipPath.c_str(), NULL, NULL, SW_SHOWNORMAL))    {        std::cerr << "ShellExecuteW tabTip err:" << GetLastError() << std::endl;        return false;    }    std::cout << "ShellExecuteW tabTip success";    return true;}

调用触摸键盘

COM调用方式,不知道COM的需要自己恶补下知识,和windows打交道还是很香的,但坑也多

bool ScreenKeyBoard::OpenTabTipByProcess(const std::wstring& tabTipPath){    //将进程TabTip.exe拉起,如果是进程存在的情况下,再次调用会直接显示键盘界面    if (!ShellExecuteW(NULL, L"open", tabTipPath.c_str(), NULL, NULL, SW_SHOWNORMAL))    {        std::cerr << "ShellExecuteW tabTip err:" << GetLastError() << std::endl;        return false;    }    std::cout << "ShellExecuteW tabTip success";    return true;}

根据系统版本选择调用触摸键盘的方式

bool ScreenKeyBoard::OpenScreenKeyboard(){    if (!IsTabTipAutoInvokeOnDesktopMode())    {        return OpenTabTip();    }     //触摸键盘有一设置项:不处于平板电脑模式且未连接键盘时显示触摸键盘,增加延迟避开系统调用键盘    std::thread([]() {        PublicUtils::Sleep(std::chrono::milliseconds(500));        OpenTabTip();    }).detach();    return true;}bool ScreenKeyBoard::OpenTabTip(){    auto version = PublicUtils::Environment::OsVersion();    std::cout << "os version:" << version.ToString() << std::endl;    if (IsNewTabTipKeyboardVisable() || IsOldTabTipKeyboardVisable())    {        std::cout << "keyboard is visible" << std::endl;        return true;    }    //系统版本大于等于win10 10.0.14393.0,需要使用com组件的接口才能将键盘界面显示出来    if (10 == version.GetMajor() && version.GetPatch() >= 14393)    {        return OpenTabTipByCom(kTabTipPath);    }    else    {        return OpenTabTipByProcess(kTabTipPath);    }}

在调用触摸键盘前有一个代码片段用来判断触摸键盘是否处于显示状态,这是为什么呢?
因为触摸键盘TabTip没有明确的接口区分显示和隐藏,当调用时会根据当前的状态决定下一个状态,即隐藏时调用会显示,显示时调用会隐藏,所以就需要我们自己判断键盘状态

  • 判断键盘状态,Spy++抓触摸键盘窗口,自己分析一些特性

  • 需要注意触摸键盘这个设置项的作用,在代码中需要做处理(这个设置开启后系统会检测到有输入框聚焦时自动调起触摸键盘,如果你在代码中去调用的话,可能会存在一些冲突)

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/233c5a6ce0804795be5ed48a207fbeb2~tplv-k3u1fbpfcp-watermark.image)bool ScreenKeyBoard::IsNewTabTipKeyboardVisable(){    //win10下父窗口是ApplicationFrameWindow子窗口是Windows.UI.Core.CoreWindow    HWND parent = FindWindowExW(NULL, NULL, kWindowParentClass, NULL);    if (!parent)    {        std::cerr << "no more windows, keyboard state is unknown. class:" << PublicUtils::CharsetUtils::UnicodeToUTF8(kWindowParentClass) << std::endl;        return false;    }    HWND wnd = FindWindowExW(parent, NULL, kWindowClass, kWindowCaption);    if (!wnd)    {        std::cerr << "it's a child of a WindowParentClass1709 window - the keyboard is open. class:" << PublicUtils::CharsetUtils::UnicodeToUTF8(kWindowClass)            << " caption" << PublicUtils::CharsetUtils::UnicodeToUTF8(kWindowCaption) << std::endl;        return false;    }    //触摸键盘显示和隐藏不能用IsWindowVisible判断,判断方式可参考 https://stackoverflow.com/questions/32149880/how-to-identify-windows-10-background-store-processes-that-have-non-displayed-wi    int cloaked = 0;    if (DwmGetWindowAttribute(wnd, DWMWA_CLOAKED, &cloaked, DWM_CLOAKED_INHERITED) != S_OK)    {        std::cerr << "DwmGetWindowAttribute err:" << GetLastError() << std::endl;        return false;    }    std::cout << "DwmGetWindowAttribute cloaked=" << cloaked;    return 0 == cloaked;}bool ScreenKeyBoard::IsOldTabTipKeyboardVisable(){    HWND touchhWnd = FindWindowW(kKeyboardWindowClass, NULL);    if (!touchhWnd)    {        std::cerr << "without window:" << PublicUtils::CharsetUtils::UnicodeToUTF8(kKeyboardWindowClass) << std::endl;        return false;    }    unsigned long style = GetWindowLong(touchhWnd, GWL_STYLE);    // 由于有的系统在键盘不显示时候只是多返回一个WS_DISABLED这个字段。所以加一个它的判断    std::cout << "WS_CLIPSIBLINGS:" << (style & WS_CLIPSIBLINGS)        << " WS_VISIBLE:" << (style & WS_VISIBLE)        << " WS_POPUP:" << (style & WS_POPUP)        << " WS_DISABLED:" << !(style & WS_DISABLED) << std::endl;    return (style & WS_CLIPSIBLINGS) && (style & WS_VISIBLE) && (style & WS_POPUP) && !(style & WS_DISABLED);}

关于"c++如何调用windows键盘代码"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

键盘 进程 系统 代码 方式 状态 信息 命令 屏幕 篇文章 c++ 也就是 也就是说 再次 句柄 情况 截图 时调 更多 版本 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 方舟怎么看服务器开了多久 购物网站数据库安全性分析 pg数据库的分区是一个字段吗 怎么查找服务器网络问题 广东销售软件开发外包 青浦区营销软件开发收费套餐 浙江常见软件开发市场价 咸宁市公安局网络安全支队 腾讯数据库面经 上汽软件开发加班多吗 数据库基本设计步骤 高并发响应最快的数据库 百川互联网络技术有限公司赵蓉 网络安全谷 压低项目软件开发定制费用 邦尼德上海网络技术有限公司 方舟 服务器互通 iis搭建web服务器 华三服务器管理口默认密码 上海注册软件开发公司费用 乐山网络技术推荐厂家 超简单的网络安全手抄报怎么画 计算机三级网络技术要思科吗 苏州电商软件开发费用是多少 服务器 安全面板 基于数据库访问类实现数据库操作 服务器隔音参数 软著mysql数据库中间件 不是信息网络技术发展 网络安全应急响应是什么意思
0