标签:20px 方法 app oid library format 需要 ext rod
原地址http://213style.blogspot.com/2013/09/usb-human-interface-device.html
恩,發本文的原因是看到了以前畢業的朋友在旁邊的對話框問了一些問題,我想這些問題
| Report Size (8) | 75 08 | 
| Report Count (8) | 95 08 | 
| Logical Maximum (255) | 26 FF 00 | 
| Report ID (50) | 85 32 | 
| Usage (Vendor-Defined 195) | 09 C3 | 
| Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Buf) | B2 02 01 | 
#include "stdafx.h"
#include "HIDGet.h"
#include "HIDGetDlg.h"
#include "Process.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WM_THREADDATA   WM_USER + 1
#define WM_READDATA     WM_USER + 2
/////////////////////////////////////////////////////////////////////////////
// CHIDGetDlg dialog
struct _ThreadData
{
    HWND   hWnd;
    HANDLE hDev;
    char   cBuf[9];
    HANDLE hReadFinished;
}ThreadData;
LRESULT CALLBACK ReadThreadWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    BOOL bRet;
    ResetEvent(ThreadData.hReadFinished);
    OVERLAPPED ol;
    ol.hEvent = ThreadData.hReadFinished;
    ol.Offset = 0;
    ol.OffsetHigh = 0;
    DWORD wResult, wByteRead;
    switch(msg)
    {
    case WM_CLOSE:
        CancelIo(ThreadData.hDev);
        CloseHandle(ThreadData.hReadFinished);
        DestroyWindow(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_READDATA:
        //ReadFile(ThreadData.hDev, ThreadData.cBuf, 9, &wByteRead, &ol);
        ThreadData.cBuf[0] = 50;
        bRet = HidD_GetFeature(ThreadData.hDev, ThreadData.cBuf, 9);
        //wResult = WaitForSingleObject(ThreadData.hReadFinished, 1000);
        if(/*wResult == WAIT_OBJECT_0*/ bRet == TRUE)
            ::PostMessage(ThreadData.hWnd, WM_THREADDATA, 0, 0);
        else if(/*wResult == WAIT_TIMEOUT*/ bRet == FALSE)
            ::PostMessage(hWnd, WM_READDATA, 0, 0);
        break;
    default:
        return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}
void ReadThread(CHIDGetDlg* pDlg)
{
    WNDCLASSEX wndclass;
    wndclass.cbSize        = sizeof(WNDCLASSEX);
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0 ;
    wndclass.hbrBackground = NULL;
    wndclass.hCursor       = NULL;
    wndclass.hIcon         = NULL;
    wndclass.hIconSm       = NULL;
    wndclass.hInstance     = GetModuleHandle(NULL);
    wndclass.lpfnWndProc   = ReadThreadWindowProc;
    wndclass.lpszClassName = "ReadThread";
    wndclass.lpszMenuName  = NULL;
    wndclass.style         = 0 ;
    RegisterClassEx(&wndclass);
    HWND hReadThreadWindow = ::CreateWindow("ReadThread", "", WS_POPUP, 
                                            0, 0, 0, 0, NULL, NULL,
                                            GetModuleHandle(NULL), NULL);
    pDlg->SetReadThreadHWND(hReadThreadWindow);
    ThreadData.hReadFinished = CreateEvent(NULL, TRUE, FALSE, NULL);
    SetEvent(pDlg->m_hReadThreadCreated);
    // Start the message loop 
    MSG msg;
    while(GetMessage(&msg, NULL, NULL, NULL))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
CHIDGetDlg::CHIDGetDlg(CWnd* pParent /*=NULL*/) : CDialog(CHIDGetDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CHIDGetDlg)
    // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CHIDGetDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CHIDGetDlg)
    DDX_Control(pDX, IDC_DATA_ED, m_edData);
    //}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CHIDGetDlg, CDialog)
    //{{AFX_MSG_MAP(CHIDGetDlg)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_CLOSE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHIDGetDlg message handlers
void CHIDGetDlg::SetReadThreadHWND(HWND hWnd)
{
    m_hReadThread = hWnd;
}
void CHIDGetDlg::CreateReadThread()
{
    ThreadData.hWnd = m_hWnd;
    m_hReadThreadCreated = CreateEvent(NULL, TRUE, FALSE, NULL);
    if(m_hReadThreadCreated)
    {
        DWORD threadID;
        if(_beginthreadex(NULL, 0, (unsigned int (WINAPI*)(PVOID))ReadThread, 
            this, 0, (unsigned int*)&threadID) != 0)
            WaitForSingleObject(m_hReadThreadCreated, INFINITE);
        CloseHandle(m_hReadThreadCreated);
    }
}
BOOL CHIDGetDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    // Set the icon for this dialog.  The framework does this automatically
    //  when the application‘s main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
    // TODO: Add extra initialization here
    GetDeviceHandle();
    CreateReadThread();
    ::PostMessage(m_hReadThread, WM_READDATA, 0, 0);
    return TRUE;  // return TRUE  unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.
void CHIDGetDlg::OnPaint() 
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting
        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}
// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CHIDGetDlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}
HANDLE CHIDGetDlg::GetDeviceHandle(GUID guid, HANDLE hDev, DWORD wDevice)
{
    SP_DEVICE_INTERFACE_DATA interfaceDev;
    interfaceDev.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    //Get interface
    DWORD wSize = 0;
    if(!SetupDiEnumDeviceInterfaces(hDev, NULL, &guid, wDevice, &interfaceDev) 
        || SetupDiGetDeviceInterfaceDetail(hDev, &interfaceDev, NULL, 0, &wSize, NULL))
        return INVALID_HANDLE_VALUE;
    //Create buffer
    SP_INTERFACE_DEVICE_DETAIL_DATA *pDeviceDetail;
    pDeviceDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA*)malloc(wSize);
    pDeviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
    if(!SetupDiGetDeviceInterfaceDetail(hDev, &interfaceDev, pDeviceDetail, wSize, &wSize, NULL))
    {
        free(pDeviceDetail);
        return INVALID_HANDLE_VALUE;
    }
    //Get device handle
    HANDLE hDevice = CreateFile(pDeviceDetail->DevicePath, GENERIC_READ,
        FILE_SHARE_READ, NULL, OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED, NULL);
    free(pDeviceDetail);
    return hDevice;
}
void CHIDGetDlg::Show(CString str,long n)
{
    CString strN;
    strN.Format("%d", n);
    m_edData.ReplaceSel(str + ":" + strN + "\r\n");
}
void CHIDGetDlg::Show(CString str, CString s)
{
    m_edData.ReplaceSel(str + ": " + s + "\r\n");
}
void CHIDGetDlg::Clear()
{
    int nStart, nStop;
    m_edData.GetSel(nStart, nStop);
    m_edData.SetSel(0, nStop);
    m_edData.Clear();
}
void CHIDGetDlg::GetDeviceHandle()
{
    //Get HID GUID
    GUID guid;
    HidD_GetHidGuid(&guid);
    //Get all present HID interface
    HDEVINFO hDeviceInfo = SetupDiGetClassDevs(&guid, NULL, NULL,
                                               DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
    if(hDeviceInfo == INVALID_HANDLE_VALUE) return;
    Clear();
    DWORD w = 0;
    while(1) /*for(DWORD w=0; w<20; w++)*/
    {
        if((ThreadData.hDev = GetDeviceHandle(guid, hDeviceInfo, /*w*/w++))!=INVALID_HANDLE_VALUE)
        {
            HIDD_ATTRIBUTES att;
            if(HidD_GetAttributes(ThreadData.hDev, &att))
            {
                PHIDP_PREPARSED_DATA pPreData;
                if(HidD_GetPreparsedData(ThreadData.hDev, &pPreData))
                {
                    HIDP_CAPS cap;
                    if(HidP_GetCaps(pPreData, &cap)==HIDP_STATUS_SUCCESS)
                    {
                        if(att.VendorID==0x056D && att.ProductID==0x0002 && att.VersionNumber==0x7530)
                        {
                            if(cap.Usage==0x01 && cap.UsagePage==0x80)
                            {
                                HidD_FreePreparsedData(pPreData);
                                break;
                            }
                        }
                    }
                    HidD_FreePreparsedData(pPreData);
                }
            }
            CloseHandle(ThreadData.hDev);
            ThreadData.hDev = INVALID_HANDLE_VALUE;
        }
        if(w > 65536)
        {
            CloseHandle(ThreadData.hDev);
            ThreadData.hDev = INVALID_HANDLE_VALUE;
            break;
        }
    }
    SetupDiDestroyDeviceInfoList(hDeviceInfo);
}
void CHIDGetDlg::OnClose() 
{
    // TODO: Add your message handler code here and/or call default
    ::SendMessage(m_hReadThread, WM_CLOSE, 0, 0);
    if(ThreadData.hDev!=INVALID_HANDLE_VALUE)
        CloseHandle(ThreadData.hDev);
    CDialog::OnClose();
}
LRESULT CHIDGetDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
    // TODO: Add your specialized code here and/or call the base class
    static long nCount = 0;
    if(message == WM_THREADDATA)
    {           
        CString str;
        str.Format("# of packet = %d, report id =%d, LCD = %c %c %c %c %c %c %c %c",
            nCount++, 
            ThreadData.cBuf[0], // report id = 50
            ThreadData.cBuf[1],
            ThreadData.cBuf[2],
            ThreadData.cBuf[3],
            ThreadData.cBuf[4],
            ThreadData.cBuf[5],
            ThreadData.cBuf[6],
            ThreadData.cBuf[7],
            ThreadData.cBuf[8]);
        Show("Data", str);
        if(nCount > 500)
        {
            Clear();
            nCount = 0;
        }
        ::PostMessage(m_hReadThread, WM_READDATA, 0, 0);
    }
    return CDialog::DefWindowProc(message, wParam, lParam);
}
    case WM_READDATA:
        //ReadFile(ThreadData.hDev, ThreadData.cBuf, 9, &wByteRead, &ol);
        ThreadData.cBuf[0] = 50;
        bRet = HidD_GetFeature(ThreadData.hDev, ThreadData.cBuf, 9);
        //wResult = WaitForSingleObject(ThreadData.hReadFinished, 1000);
        if(/*wResult == WAIT_OBJECT_0*/ bRet == TRUE)
            ::PostMessage(ThreadData.hWnd, WM_THREADDATA, 0, 0);
        else if(/*wResult == WAIT_TIMEOUT*/ bRet == FALSE)
            ::PostMessage(hWnd, WM_READDATA, 0, 0);
        break;
【转】簡單講講 USB Human Interface Device
标签:20px 方法 app oid library format 需要 ext rod
原文地址:http://www.cnblogs.com/libra13179/p/7259007.html