QT监视USB-HID设备

zhaoyinfei 2011-06-28 09:08:02
大家好,本人因业务需要,使用qt在windows下监视USB-HID设备的插入和拔出(非U盘)。QWidget重写了winEvent()函数,发现只有U盘的插入和拔出才可以收到有效的事件,网上查了资料说要使用RegisterDeviceNotification来注册通知。我在winmain()里面createwindow,可以成功接收到消息,但是融合到Qwidget的时候,winEvent还是不起作用。哪位大牛做过usb-hid设备的通信,希望指教一下小弟
...全文
1063 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhaoyinfei 2011-07-19
  • 打赏
  • 举报
回复
问题已经解决了。
对QWinHost注册RegisterDeviceNotification,在它本身的winEvent里面可以截获到usb-hid设备的的插入和拔出,此时要注意一点,不同类型的设备有不同的Guid(NotificationFilter.dbcc_classguid)。
rollingrock 2011-07-14
  • 打赏
  • 举报
回复
我用如下方法注册消息:
bool MainWindow::doRegisterForDevNotification(void)
{
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory( ¬ificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;

hDevNotify = RegisterDeviceNotification( this->winId(), ¬ificationFilter,DEVICE_NOTIFY_WINDOW_HANDLE);
return(NULL != hDevNotify);
}

但是编译的时候老是提示错误:
debug/mainwindow.o:D:\Code\QT\DevMonitor-build-desktop/../DevMonitor/mainwindow.cpp:24: undefined reference to `GUID_DEVINTERFACE_USB_DEVICE'

这个GUID_DEVINTERFACE_USB_DEVICE在usbiodef.h头文件里是能够找到定义的,哪位老大帮我看看到底是哪里出了问题?谢谢了
zxjask 2011-07-13
  • 打赏
  • 举报
回复
换个思路,也可以通过监视设备在注册表的变化来判断设备的插拔。
rollingrock 2011-07-13
  • 打赏
  • 举报
回复
楼主,问题解决了吗?

能把你的代码贴出来吗,学习学习,我是个QT的初学者,正在研究类似的东西
zhaoyinfei 2011-06-30
  • 打赏
  • 举报
回复
不要沉啊,大家帮帮忙
就想叫yoko 2011-06-29
  • 打赏
  • 举报
回复
论坛有QT区
上那边问问看~~
zhaoyinfei 2011-06-29
  • 打赏
  • 举报
回复
主要是我现在已经实现了windows GUI下已经实现了,但是在QT里面注册设备通知却没作用,甚是郁闷啊。
#include <windows.h>
#include <Dbt.h>
/* 全局变量 */
HINSTANCE hinst;
HWND hWnd;
HDEVNOTIFY hDevNotify;// NOTIFY
int YStart = 10;// 用于TextOut时定位输出位置
/* 全局变量 */
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
InitApplication(HINSTANCE);
InitInstance(HINSTANCE, int);
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
void OnDeviceChange (HWND hwnd, WPARAM wParam, LPARAM lParam);
char FirstDriveFromMask (ULONG unitmask);
BOOL DoRegisterDeviceInterface( GUID , HDEVNOTIFY * );
/*************************************
* WinMain
**************************************/
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL fGotMessage;
if (!InitApplication(hinstance))
return 1;

if (!InitInstance(hinstance, nCmdShow))
return 1;

if(!DoRegisterDeviceInterface( GUID_DEVINTERFACE_DISK, &hDevNotify ))
// GUID_DEVINTERFACE_MEDIUMCHANGER
// GUID_DEVINTERFACE_VOLUME
// GUID_DEVINTERFACE_STORAGEPORT
// ……

{
return 1;
}

while ((fGotMessage = GetMessage(&msg, (HWND) NULL, 0, 0)) != 0 && fGotMessage != -1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
UNREFERENCED_PARAMETER(lpCmdLine);
}
/*************************************
* InitApplication
**************************************/
BOOL InitApplication(HINSTANCE hinstance)
{
WNDCLASSEX wcx;

wcx.cbSize = sizeof(wcx);
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.lpfnWndProc = MainWndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hinstance;
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = GetStockObject( WHITE_BRUSH);
wcx.lpszMenuName = "MainMenu";
wcx.lpszClassName = "MainWClass";
wcx.hIconSm = LoadImage(hinstance,
MAKEINTRESOURCE(5),
IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
LR_DEFAULTCOLOR);

return RegisterClassEx(&wcx);
}
/*************************************
* InitInstance
**************************************/
BOOL InitInstance(HINSTANCE hinstance, int nCmdShow)
{
HWND hwnd;
hinst = hinstance;

hwnd = CreateWindow(
"MainWClass",
"device monitor",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
(HWND) NULL, (HMENU) NULL, hinstance, (LPVOID) NULL);

if (!hwnd)
return FALSE;

hWnd = hwnd;

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
return TRUE;

}
/*************************************
* MainWndProc
**************************************/
LRESULT CALLBACK MainWndProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{

switch (uMsg)
{
case WM_DEVICECHANGE:
OnDeviceChange ( hwnd, wParam, lParam);
break;

case WM_DESTROY:
ExitProcess(0);
return 0;

default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}

/*************************************
* void OnDeviceChange (HWND , WPARAM , LPARAM )
* 功能 处理 WM_DEVICECHANGE 消息
* 参数为窗口消息
**************************************/
void OnDeviceChange (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
// 获取 PDEV_BROADCAST_HDR 参数
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
char szMsg[256];

HDC hdc = GetDC(hwnd);
DWORD dwStrLen;
SIZE sz;
TEXTMETRIC tm;

switch(wParam)
{
case DBT_DEVICEARRIVAL:
// 插入 CD 或者 DVD 到光驱中
if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
{
// 获取参数
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
// 判断标志
if (lpdbv -> dbcv_flags & DBTF_MEDIA)
{
wsprintf (szMsg, "Drive %c: Media has arrived.",
// 根据mask获取盘符,
// dbcv_unitmask的bit依次表示A:,B:...,如果为1,表示是该盘符,
FirstDriveFromMask(lpdbv ->dbcv_unitmask));
}
else
// 标志不配置,打印事件ID
wsprintf (szMsg, "Message: %u.", wParam);
}
else
// 设置类型不配置,打印事件ID
wsprintf (szMsg, "Message: %u.", wParam);
break;

case DBT_DEVICEREMOVECOMPLETE:
// 光驱弹出
if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
{
// 获取参数
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
// 检查标志
if (lpdbv -> dbcv_flags & DBTF_MEDIA)
{
wsprintf (szMsg, "Drive %c: Media was removed.",
FirstDriveFromMask(lpdbv ->dbcv_unitmask));
}
else
wsprintf (szMsg, "Message: %u.", wParam);
}
else
wsprintf (szMsg, "Message: %u.", wParam);
break;

default:
// 其他设备改变情况,打印设备ID
wsprintf (szMsg, "Message: %u.", wParam);

}
// 在界面上输出设备变更消息
dwStrLen = lstrlen(szMsg);
// 计算输出位置
GetTextExtentPoint32(hdc, szMsg, dwStrLen, &sz);
YStart += sz.cy;
GetTextMetrics(hdc, &tm);
YStart -= tm.tmOverhang;
// TODO 窗口滚动
TextOut(hdc, 10, YStart, szMsg, dwStrLen);
DeleteDC( hdc ); // 释放DC
}

/*************************************
* char FirstDriveFromMask (ULONG unitmask)
* 功能 将盘符信息mask转换为盘符
**************************************/
char FirstDriveFromMask (ULONG unitmask)
{
char i;

for (i = 0; i < 26; ++i)
{
if (unitmask & 0x1)
break;
unitmask = unitmask >> 1;
}

return (i + 'A');
}

/*************************************
* DoRegisterDeviceInterface
* 功能 调用RegisterDeviceNotification
* API 函数注册设备变更广播消息,
* 所注册类型的设置发生变更后,窗口会收到消息
**************************************/
BOOL DoRegisterDeviceInterface(
GUID InterfaceClassGuid,
HDEVNOTIFY *hDevNotify
)

{
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
char szMsg[80];
// 填充DEV_BROADCAST_DEVICEINTERFACE结构,作为参数
ZeroMemory( ¬ificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size =
sizeof(DEV_BROADCAST_DEVICEINTERFACE);
// 所需监视的设备类型
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
// 类型的GUID,可以是GUID_DEVINTERFACE_DISK等。
NotificationFilter.dbcc_classguid = InterfaceClassGuid;
// 调用RegisterDeviceNotification API
*hDevNotify = RegisterDeviceNotification( hWnd,
¬ificationFilter,
DEVICE_NOTIFY_WINDOW_HANDLE
);
// 判断调用结果,返回。
if(!*hDevNotify)
{
wsprintf(szMsg, "RegisterDeviceNotification failed: %d\n",
GetLastError());
MessageBox(hWnd, szMsg, "Registration", MB_OK);
return FALSE;
}
return TRUE;
}
这个是我在书上找的例子,但是和qt融合起来就不起作用了
zhaoyinfei 2011-06-29
  • 打赏
  • 举报
回复
自己顶起来
Proteas 2011-06-28
  • 打赏
  • 举报
回复
没有这方面的经验,
自己看看驱动相关的资料吧。

16,818

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧