控制的window8, window8.1,window10系统中的虚拟键盘。通过分析虚拟键盘,发现TabTip.exe就是虚拟键盘服务,所以只要启动这个程序,就实现了键盘的显示。该功能中也实现了通过active插件来控制键盘,但在实际测试中发现,该控制不是很精准。
待改进,通过active插件控制键盘,如果你有好的方法,欢迎拍砖!
头文件 VirtualKeyboard.h:
#ifndef VIRTUALKEYBOARD_H #define VIRTUALKEYBOARD_H #include <QAxObject> class VirtualKeyboard { public: /// Shows on-screen keyboard. Implementation is different for each platform. /// @warning Currently works only in windows 8,win8.1 win10 static void show(); static void close(); private: static void showWindowsKeyboard(); static void showTapTip(); static void showByCom(); static bool isVisible(int style); static bool isOpened(); static bool closeWindowKeyboard(); static QAxObject *kbaxObject(); // static const int GWL_STYLE = -16; // static const int WM_SYSCOMMAND = 0x0112; // static const int SC_CLOSE = 0xF060; // static const int WS_DISABLED = 0x08000000; // static const int WS_VISIBLE = 0x10000000; static QAxObject *axObject; class VkbAxGarbage { ~VkbAxGarbage() { if (VirtualKeyboard::axObject != NULL) { delete VirtualKeyboard::axObject; } } }; static VkbAxGarbage vkbAxGarbage; }; #endif // VIRTUALKEYBOARD_H
代码实现VirtualKeyboard.cpp
#include "virtualkeyboard.h" #include <QtCore/QSysInfo> #include <QtCore/QFileInfo> #include <QtCore/QUrl> #include <QDesktopServices> #include <QMessageBox> #include <QVariant> #include <QDebug> #include <QThread> #include <QUuid> #ifdef Q_OS_WIN #include <qt_windows.h> struct ITipInvocation //: public IUnknown { virtual HRESULT STDMETHODCALLTYPE Toggle(HWND hwnd) = 0; }; #endif QAxObject *VirtualKeyboard::axObject = NULL;//new QAxObject("{4ce576fa-83dc-4f88-951c-9d0782b4e376}"); void VirtualKeyboard::show() { #ifdef Q_OS_WIN switch (QSysInfo::windowsVersion()) { case QSysInfo::WV_WINDOWS8: case QSysInfo::WV_WINDOWS8_1: case QSysInfo::WV_WINDOWS10: showWindowsKeyboard(); break; default: break; } #endif } void VirtualKeyboard::close() { #ifdef Q_OS_WIN switch (QSysInfo::windowsVersion()) { case QSysInfo::WV_WINDOWS8: case QSysInfo::WV_WINDOWS8_1: case QSysInfo::WV_WINDOWS10: closeWindowKeyboard(); break; default: break; } #endif } void VirtualKeyboard::showWindowsKeyboard() { //if (isOpened()) { // return; //} // show every time showTapTip(); //showByCom(); return; //HWND handle = ::FindWindow("IPTIP_Main_Window", NULL); //if (handle > 0 && !kbaxObject()->isNull()) { // LONG style = ::GetWindowLong(handle, GWL_STYLE); // if (!isVisible(style)) { // showByCom(); // } //} //else { // showTapTip(); // if (!isOpened()) { // showByCom(); // } //} } void VirtualKeyboard::showTapTip() { static const QString programFilesPath(qgetenv("PROGRAMFILES").replace("\\", "/")); static const QString tabTipPath = QString("%1/Common Files/microsoft shared/ink/TabTip.exe").arg(programFilesPath); if (QFileInfo(tabTipPath).exists()) { QDesktopServices::openUrl(QUrl("file:///" + tabTipPath)); } else { const QString windowsDirectoryPath(qgetenv("WINDIR").replace("\\", "/")); const QString oskPath = QString("%1/system32/osk.exe").arg(windowsDirectoryPath); if (QFileInfo(oskPath).exists()) { QDesktopServices::openUrl(QUrl("file:///" + oskPath)); } } HWND handle = 0; while ((handle = ::FindWindow("IPTIP_Main_Window", NULL)) <= 0) { QThread::msleep(500); } } void VirtualKeyboard::showByCom() { ITipInvocation *tipInvocation = NULL; kbaxObject()->queryInterface(QUuid("37c994e7-432b-4834-a2f7-dce1f13b834b"), (void **)&tipInvocation); if (NULL != tipInvocation) { tipInvocation->Toggle(GetDesktopWindow()); } } bool VirtualKeyboard::isVisible(int style) { if ((style & WS_DISABLED) != 0) { return false; } if ((style & WS_VISIBLE) != 0) { return true; } return false; } bool VirtualKeyboard::isOpened() { HWND handle = ::FindWindow("IPTIP_Main_Window", NULL); if (handle <= 0) { return false; } LONG style = ::GetWindowLong(handle, GWL_STYLE); return isVisible(style); } bool VirtualKeyboard::closeWindowKeyboard() { HWND handle = ::FindWindow("IPTIP_Main_Window", NULL); bool active = handle > 0; if (active) { // don't check style - just close ::SendMessage(handle, WM_SYSCOMMAND, SC_CLOSE, 0); } return active; } QAxObject *VirtualKeyboard::kbaxObject() { if (NULL == axObject) { axObject = new QAxObject(); if (!axObject->setControl("{4CE576FA-83DC-4f88-951C-9D0782B4E376}")) { QMessageBox::warning(NULL, "keyboard com error", QStringLiteral("虚拟键盘com加载失败")); } } return axObject; }