由于公司的项目软件一直都在Windows的平板电脑上运行,所以当用户点击了输入框之类的控件时,就要在代码中主动让Windows的虚拟键盘启动并显示出来。这个功能分了几步的开发过程,现在来总结一下。

项目使用的界面库都是SoUI2。

一、通过在WM_LBUTTONUP中判断是否应该使用shellexecute启动虚拟键盘

一开始的解决方法是在窗体的WM_LBUTTONUP中处理,就是查看是否是需要输入的控件获取到当前焦点,是的话就用shellexecute启动虚拟键盘,然后再把WM_LBUTTONUP交回给窗体处理。

这种做法有以下的坏处:

  1. 当需要输入的控件增加或减少时,处理WM_LBUTTONUP的函数相应的需要修改代码中的控件列表。
  2. 关闭虚拟键盘后再点击窗体空白处时,焦点会自动锁定为刚刚的输入控件,即WM_LBUTTONUP中又会判断为打开虚拟键盘,形成死循环,需要点击到窗体上的其它控件才能打破死循环。
  3. shellexecute函数启动虚拟键盘速度慢,会出现程序卡死的情况。

所以第一种方法不予采用。

二、派生SoUI2的控件,在控件的WM_LBUTTONUP中使用shellexecute启动虚拟键盘

这种方法解决了第一种方法的第一个缺点,因为只要在xml中把需要弹出虚拟键盘的控件替换为派生的控件即可。而且由于需要点击到相应的控件才会弹出虚拟键盘,所以第一种方法的第二个缺点也解决了。

但是在实际使用中发现,由于 shellexecute函数启动虚拟键盘速度慢,有一定的几率导致窗体卡死。而且有时还会出现输入框点击无反应或输入焦点跳转失败的问题的问题。所以急需一种方法来替换掉shellexecute函数启动虚拟键盘。

三、派生SoUI2的控件,在控件的WM_LBUTTONUP中使用窗口消息点击托盘栏来启动Windows的虚拟键盘

本方法的代码参考https://stackoverflow.com/questions/38774139/show-touch-keyboard-tabtip-exe-in-windows-10-anniversary-edition。代码如下

HWND trayWnd = FindWindow(_T("Shell_TrayWnd"), NULL);if (trayWnd != NULL)
{HWND trayNotifyWnd = FindWindowEx(trayWnd, NULL, _T("TrayNotifyWnd"), NULL);if (trayNotifyWnd != NULL){HWND tIPBandWnd = FindWindowEx(trayNotifyWnd, NULL, _T("TIPBand"), NULL);if (tIPBandWnd != NULL){PostMessage(tIPBandWnd, WM_LBUTTONDOWN, 1, 65537);PostMessage(tIPBandWnd, WM_LBUTTONUP, 1, 65537);}}
}

经测试,该代码可以成功地打开虚拟键盘,并完美解决第二种方法引起的问题。但是这种方法存在的第一个问题为,需要设置Windows显示虚拟键盘托盘图标才能使该方法生效。
而且不止上面这个问题,不过我们先来看看第四种方法。

四、派生SoUI2的控件,在控件的WM_LBUTTONUP中使用COM启动Windows的虚拟键盘

本方法的代码参考https://stackoverflow.com/questions/38774139/show-touch-keyboard-tabtip-exe-in-windows-10-anniversary-edition。代码如下

#include <initguid.h>
#include <Objbase.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;
};int WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{HRESULT hr;hr = CoInitialize(0);ITipInvocation* tip;hr = CoCreateInstance(CLSID_UIHostNoLaunch, 0, CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER, IID_ITipInvocation, (void**)&tip);tip->Toggle(GetDesktopWindow());tip->Release();return 0;
}

经测试,该代码可以成功地打开虚拟键盘,并完美解决第二种方法引起的问题。但是该方法和第三种方法都引入了一个新问题,就是如果当前虚拟键盘是隐藏的,则弹出虚拟键盘,否则隐藏虚拟键盘。所以就出现在使用时,点击第一个输入框,虚拟键盘弹出了,输入完毕后,点击第二个输入框,虚拟键盘却隐藏了的问题。

解决上述问题的办法,网上说有以下几种:

  1. 获取虚拟键盘窗口的style,当WS_VISIBLE为真和WS_DISABLED为假时,不需要弹出虚拟键盘,其他情况下代表虚拟键盘已经隐藏,需要重新弹出虚拟键盘。
    但是我在Windows10的1909版本上测试的时候,上述方法没有成功。
  2. 使用COM来获取当前虚拟键盘的长和宽,本方法的代码参考https://stackoverflow.com/questions/47187216/determine-if-windows-10-touch-keyboard-is-visible-or-hidden。代码如下
        IFrameworkInputPane *pInputPane = NULL;RECT prcInputPaneScreenLocation = { 0,0,0,0 };HRESULT hr = CoCreateInstance(CLSID_FrameworkInputPane, NULL, CLSCTX_INPROC_SERVER, IID_IFrameworkInputPane, (LPVOID*)&pInputPane);if (FAILED(hr)){return -1;}hr = pInputPane->Location(&prcInputPaneScreenLocation);if (FAILED(hr)){return -2;}pInputPane->Release();if ((prcInputPaneScreenLocation.right - prcInputPaneScreenLocation.left == 0)|| (prcInputPaneScreenLocation.bottom - prcInputPaneScreenLocation.top == 0)){//弹出虚拟键盘}
    

    在Windows10上实测这个方法可行。

弹出一个虚拟键盘的功能完成还真是不容易啊。

以上就是本博客的全文,本人限于能力,上文中难免有错误的地方,若读者发现上文的错误,请于评论区中指出,本人看到之后会立即修改的,谢谢。

弹出Windows10的虚拟键盘总结相关推荐

  1. android 弹出对话框时显示键盘

    今天,简单讲讲如何在弹出自定义的对话框时,弹出软键盘. 之前,我讲了如何制作自定义的对话框,现在,如果在弹出对话框时,自动弹出软键盘,将光标直接聚焦到自定义对话框的输入框内,那该怎么做呢? 在网上搜索 ...

  2. android实现软键盘弹出,editText随键盘上移,背景不动

    android实现软键盘弹出,editText随键盘上移,背景不动 前段时间有个妹子问我如题的需求,我就想,这种东西网上不是很多吗,自己试过才发现,基本都不行,各种设置配置文件的windowSoftI ...

  3. android实现底部弹出框与软键盘冲突(全面屏虚拟键适配)

    普通的底部弹出框大家都可以很熟练的使用了,无非是一个diaolog的事情,但是当dialog中含有输入框之后,软键盘与dialog的冲突可以说是十分坑了...更别说加上底部虚拟键了,这么一个小功能磨得 ...

  4. android 设置键盘弹出动画,Android实现键盘弹出界面上移的实现思路

    1.首先说一下思路: 基本就是结合layout中ScrollView视图和AndroidManifest.xml中activity中的android:windowSoftInputMode属性配置实现 ...

  5. 键盘按8怎么弹出计算机,win8系统键盘太过灵敏打一个字母键出来多个字母怎么办...

    最近有win8系统用户反映说他使用的键盘太过灵敏了,轻轻敲打键盘的一个字母键,却总是弹出一长串多个字母,经常会打错字,想必有很多用户遇到过这样的问题吧,要如何处理呢,现在小编就给大家介绍一下win8系 ...

  6. android弹出和关闭软键盘

    之前的写法有问题,这里记下免得以后再用错: /*** 显示键盘** @param et 输入焦点*/public void showInput(final EditText et) {et.reque ...

  7. Android之popWindows底部弹出挡住了华为虚拟键盘问题

    1.问题 使用popWindows的时候底部弹出遮挡华为虚拟键盘 2.解决办法 在调用下面代码之前 popupWindow.showAtLocation 加上如下的代码进行设置 popupWindow ...

  8. iOS键盘弹出时动画时长失效问题

    iOS键盘弹出动画问题 今天在写键盘弹出时遇见一个问题.监听UIKeyboardWillShowNotification通知让Label做一个移动的动画,指定duration为15,但动画实际完成时间 ...

  9. vue点击input弹出带搜索键盘并监听该元素

    1.遇到问题: 需要做一个点击input弹出带搜索的键盘. 解决: input的type="search",可弹出带搜索的键盘.并监听搜索按钮,请求数据 <input @ke ...

最新文章

  1. Spring微服务视频免费发放
  2. python跨文件全局变量_Python 进程之间共享数据(全局变量)的方法
  3. 聊聊EIGRP的自动汇总与手工汇总
  4. 个人阅读作业Week7
  5. 图片转LaTex公式神器软件
  6. 闲话高并发的那些神话,看京东架构师如何把它拉下神坛
  7. ActiveMQ(一)
  8. 查看tomcat服务器返回的响应消息,Tomcat上的WebSocket握手返回意外响应代码500
  9. 基于Spring Boot的“课程设计”的设计与实现
  10. leetcode976. 三角形的最大周长(又是你得不到的简单题)
  11. harfbuzz安装位置 linux_最新Ubuntu 20.04 LTS已发布,在Win10中该如何进行安装和使用?...
  12. 阿里程序员转行公务员,工资少了40万,只留一句话惊醒众人
  13. 数学物理方法pdf_中考状元笔记九科(语文+数学+物理+化学+英语+历史+地理+政治+生物)(高清PDF);...
  14. [解题报告]1005 - Number Sequence
  15. [C++] - 纯虚函数 抽象基类 接口类
  16. 简单几何(线段相交) POJ 2653 Pick-up sticks
  17. Mybatis工作中常用动态SQL总结
  18. 华为云主机被植入挖矿,主机变肉鸡破解实录。
  19. nginx: [emerg] could not build server_names_hash
  20. 珍珠项链(洛谷-P2768)(Dp矩阵加速)

热门文章

  1. Quantopian教程系列三
  2. 微信开放平台之公众号第三方平台开发及全网发布验证
  3. 计算机桌面文件能单独设密码吗,电脑上文件夹怎么加密_桌面文件夹怎么加密码...
  4. 微型计算机技术中 通过系统把CPU,【单选题】在微型计算机技术中,通过系统   把CPU、存储器、输入设备和输出设备连接起来,实现信息交换。...
  5. 韩松手机摄影笔记第三课--经营画面的原则
  6. 没有项目管理经验,可以参加PMP考试吗?
  7. 长平之战后的秦赵又一次决战——邯郸保卫战_我是亲民_新浪博客
  8. opencv处理图像数据时候,出现图像全黑
  9. 逍遥模拟器连接不到android,逍遥模拟器不能连上网怎么办?两招解决问题
  10. html实现点赞效果,HTML+CSS入门 点赞功能实现 $(tag).css('属性', '样式')