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版) 萧世文 宋延清 编著










