对于Metro应用程序,存在Windows.Devices.Input.KeyboardCapabilities.KeyboardPresent。 Windows 8桌面程序是否有办法检测物理键盘是否存在?在Windows 8桌面程序中检测键盘存在
2
A
回答
0
这是一个有点繁琐,我不知道是否我提议将在所有的情况下工作,但这是我最终使用的办法的办法:
- 使用SetupDiGetClassDevs找到所有的键盘设备。
- 使用SetupDiGetDeviceRegistryProperty阅读一些键盘设备属性忽略PS/2键盘
- 检查,因为赢8触摸设备触摸支持似乎总是有一个额外的HID键盘设备。
PS/2端口的问题之一是,即使没有插入任何东西,它们仍然是键盘设备。我只是通过假设没有人会使用PS/2来解决问题键盘和我过滤出来。我已经包括两个单独的检查来尝试并确定键盘是否为PS/2。我不知道任何一方的可靠程度,但对于我测试过的机器来说,这两者似乎都可以正常工作。
另一个问题(#3)是,当Windows 8计算机有触摸支持时,他们有一个额外的HID键盘设备,您需要忽略。 PS:我刚刚意识到的东西,我的代码使用“缓冲”类来进行属性查询。为了保留相关的代码,我把它放在了外面,但是你需要用一些适当的缓冲区/内存管理来替换它。
#include <algorithm>
#include <cfgmgr32.h>
#include <Setupapi.h>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>
struct KeyboardState
{
KeyboardState() : isPS2Keyboard(false)
{ }
std::wstring deviceName; // The name of the keyboard device.
bool isPS2Keyboard; // Whether the keyboard is a PS/2 keyboard.
};
void GetKeyboardState(std::vector<KeyboardState>& result)
{
LPCWSTR PS2ServiceName = L"i8042prt";
LPCWSTR PS2CompatibleId = L"*PNP0303";
const GUID KEYBOARD_CLASS_GUID = { 0x4D36E96B, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } };
// Query for all the keyboard devices.
HDEVINFO hDevInfo = SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
return;
}
//
// Enumerate all the keyboards and figure out if any are PS/2 keyboards.
//
bool hasKeyboard = false;
for (int i = 0;; ++i)
{
SP_DEVINFO_DATA deviceInfoData = { 0 };
deviceInfoData.cbSize = sizeof (deviceInfoData);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &deviceInfoData))
{
break;
}
KeyboardState currentKeyboard;
// Get the device ID
WCHAR szDeviceID[MAX_DEVICE_ID_LEN];
CONFIGRET status = CM_Get_Device_ID(deviceInfoData.DevInst, szDeviceID, MAX_DEVICE_ID_LEN, 0);
if (status == CR_SUCCESS)
{
currentKeyboard.deviceName = szDeviceID;
}
//
// 1) First check the service name. If we find this device has the PS/2 service name then it is a PS/2
// keyboard.
//
DWORD size = 0;
if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_SERVICE, NULL, NULL, NULL, &size))
{
try
{
buffer buf(size);
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_SERVICE, NULL, buf.get(), buf.size(), &size))
{
LPCWSTR serviceName = (LPCWSTR)buf.get();
if (boost::iequals(serviceName, PS2ServiceName))
{
currentKeyboard.isPS2Keyboard = true;
}
}
}
catch (std::bad_alloc)
{
}
}
//
// 2) Fallback check for a PS/2 keyboard, if CompatibleIDs contains *PNP0303 then the keyboard is a PS/2 keyboard.
//
size = 0;
if (!currentKeyboard.isPS2Keyboard && !SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_COMPATIBLEIDS, NULL, NULL, NULL, &size))
{
try
{
buffer buf(size);
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_COMPATIBLEIDS, NULL, buf.get(), buf.size(), &size))
{
std::wstring value = (LPCWSTR)buf.get();
// Split the REG_MULTI_SZ values into separate strings.
boost::char_separator<wchar_t> sep(L"\0");
typedef boost::tokenizer< boost::char_separator<wchar_t>, std::wstring::const_iterator, std::wstring > WStringTokenzier;
WStringTokenzier tokens(value, sep);
// Look for the "*PNP0303" ID that indicates a PS2 keyboard device.
for (WStringTokenzier::iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
{
if (boost::iequals(itr->c_str(), PS2CompatibleId))
{
currentKeyboard.isPS2Keyboard = true;
break;
}
}
}
}
catch (std::bad_alloc)
{
}
}
result.push_back(currentKeyboard);
}
}
bool IsNonPS2Keyboard(const KeyboardState& keyboard)
{
return !keyboard.isPS2Keyboard;
}
bool HasKeyboard()
{
std::vector<KeyboardState> keyboards;
GetKeyboardState(keyboards);
int countOfNonPs2Keyboards = std::count_if(keyboards.begin(), keyboards.end(), IsNonPS2Keyboard);
// Win 8 with touch support appear to always have an extra HID keyboard device which we
// want to ignore.
if ((NID_INTEGRATED_TOUCH & GetSystemMetrics(SM_DIGITIZER)) == NID_INTEGRATED_TOUCH)
{
return countOfNonPs2Keyboards > 1;
}
else
{
return countOfNonPs2Keyboards > 0;
}
}
-1
简单:看到HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \服务\ kbdclass
相关问题
- 1. 如何在桌面应用程序中调出Windows 8屏幕键盘
- 2. 在桌面应用程序中检测Windows 7和8中的3G连接
- 3. Windows 8在WPF桌面应用程序中的漫游存储?
- 4. (在Windows 7 \ 8 \ 8.1)桌面
- 5. 的Windows 8从桌面应用程序
- 6. 打开和关闭桌面下的Windows 8触摸键盘tabtip
- 7. 在JavaScript中设置桌面墙纸Windows 8应用程序
- 8. 如何检测键盘在iOS 8中按下“PAGE UP”键?
- 9. libgdx如何检测键盘存在
- 10. 如何检测键盘是否存在
- 11. Windows 8商店应用程序和Windows 8桌面应用程序的区别
- 12. windows中的键盘程序
- 13. wpf触摸桌面应用程序在Windows 8
- 14. 推送通知在Windows 8桌面应用程序
- 15. 使用Perl脚本从Windows 8桌面调用键盘快捷键
- 16. 检查软件键盘是否在Windows Phone 8中打开?
- 17. WIndows服务在远程桌面运行桌面程序
- 18. 检查缓存中是否存在页面,Windows 8应用程序
- 19. 在Windows Phone 8应用程序中的文件存在检查
- 20. 如何检测Windows 8是否显示桌面
- 21. Windows 8从桌面应用程序启动“metro”应用程序?
- 22. 提供Windows 8应用程序和桌面应用程序
- 23. 将桌面应用程序嵌入Windows 8应用程序
- 24. 在Silverlight应用程序中检测键盘焦点丢失
- 25. 如何在Metro(Windows 8)应用程序中检测Alt?
- 26. 如何检测SettingsFlyout已在Windows 8应用程序中关闭
- 27. 在Windows 8 Metro应用程序中检测设计时间?
- 28. 关闭在桌面上敲击键盘
- 29. 键盘检测
- 30. 在android软键盘中禁用/检测键盘解锁键
复制的[Win32的确定何时键盘连接/断开(http://stackoverflow.com/questions/9930958/win32-确定何时键盘连接断开) – 2012-08-16 19:43:05
@JamesMcNellis,这个问题是关于连接/断开键盘,而这一个是关于是否有一个可用的键盘。不完全相同,即使答案完全相关。 – 2012-08-16 19:55:17
使用WMI,Win32_Keyboard类。 – 2012-08-16 20:51:06