控制windows 8,win8.1 win10 虚拟键盘

         控制的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;
}


猜你喜欢

转载自blog.csdn.net/wyhjia/article/details/79758520