MFC USB HID
时间:2011-01-19 来源:yangzd
建立个Project;
执行Visual C++ Project|Settings,打开Link选项卡,在Category中选择Input,在Object/library modules中输入hid.lib setupapi.lib;
在应用程序一个文档内引用头文件,如:
extern "C" { |
// Declare the C libraries used |
#include "hidsdi.h" // Must link in hid.lib |
#include <setupapi.h> // Must link in setupapi.lib |
} |
为方便起见,a_nothing直接拷贝hidpi.h, hidsdi.h, hidusagee.h, hidsdi.lib, setupapi.lib进工程文件夹。
接下来调用API函数,完成需求。
说几个遇到的问题:
应用程序调用ReadFile()函数时,缓冲区是空的,应用程序的执行进程会停止。直到有报表,或Ctrl+Alt+Del关闭应用程序,或是从总线上移除设备。
有仨方法解决:
1. 设备继续发数据;
2. 使用重叠(overlapped)选项ReadFile读取;
3. 使用多线程执行ReadFile读取。
在此采用创建个线程读取。引出的问题是不能UpdateData(), 在界面显示信息等不给力。
说俩方法:
1. 不用UpdateData();
例如,添加个CListBox m_ctrlList;
然后m_ctrlList.AddString(str); m_ctrlList.SetCurSel(m_ctrlList.GetCount()-1);等等。
不太给力。
2. 定义个用户消息。
多说下创建线程和消息:
HANDLE ThreadHandle; |
DWORD ThreadID; |
ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&StaticIO_Thread, |
this, 0, &ThreadID); |
CxxxDlg *godKnowsPt; |
DWORD CxxxDlg::StaticIO_Thread(LPVOID Param) |
{ |
if(Param != NULL) |
{ |
godKnowsPt = (CxxxDlg*)CWnd::FromHandle(((CxxxDlg*)Param)->m_hWnd); // UpdateData()用 |
return ((CxxxDlg*)Param)->ReadReport(); |
} |
else |
return -1; |
} |
// CxxxDlg.cpp中加入: |
#define WM_GODKNOWS_MESSAGE WM_USER+47 |
BEGIN_MESSAGE_MAP(CSCOM6816Dlg, CDialog) |
//{{AFX_MSG_MAP(CSCOM6816Dlg) |
... |
ON_MESSAGE(WM_GODKNOWS_MESSAGE, OnUpdateMessage) // insert in |
... |
//}}AFX_MSG_MAP |
END_MESSAGE_MAP() |
// CxxxDlg.h中加入: |
// Generated message map functions |
//{{AFX_MSG(CSCOM6816Dlg) |
... |
afx_msg LRESULT OnUpdateMessage(WPARAM wParam, LPARAM lParam); // added here |
... |
DECLARE_EVENTSINK_MAP() |
//}}AFX_MSG |
// 程序中调用 |
godKnowsPt->PostMessage(WM_GODKNOWS_MESSAGE,0,0); |
// UpdateData() |
LRESULT CxxxDlg::OnUpdateMessage(WPARAM wParam, LPARAM lParam) |
{ |
UpdateData(FALSE); |
return 0; |
} |
再说下重叠ReadFile读取,放这里:
// 声明一个重叠结构 |
OVERLAPPED HIDOverlapped; |
// 建立一个事件对象,来指示ReadFile的完成 |
hEventObject = CreateEvent(NULL, TRUE, TRUE, ""); |
// 指定重叠结构的成员 |
HIDOverlapped.hEvent = hEventObject; |
HIDOverlapped.Offset = 0; |
HIDOverlapped.Offset = 0; |
// 取得一个代号 |
ReadHandle = CreateFile( |
detaileData->DevicePath, |
GENERIC_READ|FILE_SHARE_WRITE, |
FILE_SHARE_READ|FILE_SHARE_WRITE, |
NULL, |
OPEN_EXISTING, |
FILE_FLAG_OVERLAPPED, |
NULL); |
// 读取一个报表,传递一个指针给重叠结构 |
Result = ReadFile( |
ReadHandle, |
InputReport, |
Capabilities.InputRepoortByteLength, |
&BytesRead, |
(LPOVERLAPPED)&HIDOverlapped); |
// 等待ReadFile完成或是时间到期 |
Result = WaitForSingleObject(hEventObject, 5000); |
参考书籍:USB2.0硬件设计(第2版) 萧世文 宋延清 编著