📄 hidgetdlg.cpp
字号:
// HIDGetDlg.cpp : implementation file
//
#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[5];
HANDLE hReadFinished;
}ThreadData;
LRESULT CALLBACK ReadThreadWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
ResetEvent(ThreadData.hReadFinished);
OVERLAPPED ol;
ol.hEvent = ThreadData.hReadFinished;
ol.Offset = 0;
ol.OffsetHigh = 0;
DWORD wResult;
DWORD 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, 5,
&wByteRead, &ol);
wResult = WaitForSingleObject(ThreadData.hReadFinished, 1000);
if(wResult==WAIT_OBJECT_0)
::PostMessage(ThreadData.hWnd, WM_THREADDATA, 0, 0);
else if(wResult==WAIT_TIMEOUT)
::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
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();
for(DWORD w=0; w<20; w++)
{
if((ThreadData.hDev = GetDeviceHandle(guid, hDeviceInfo, 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==2290 &&
att.ProductID==69 &&
att.VersionNumber==1 &&
cap.Usage==5 &&
cap.UsagePage==13)
{
HidD_FreePreparsedData(pPreData);
break;
}
}
HidD_FreePreparsedData(pPreData);
}
}
CloseHandle(ThreadData.hDev);
ThreadData.hDev = INVALID_HANDLE_VALUE;
}
}
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("%d %d %d %d %d %d", nCount++, ThreadData.cBuf[0],
ThreadData.cBuf[1],
ThreadData.cBuf[2],
ThreadData.cBuf[3],
ThreadData.cBuf[4]);
Show("Data", str);
if(nCount>500)
{
Clear();
nCount = 0;
}
::PostMessage(m_hReadThread, WM_READDATA, 0, 0);
}
return CDialog::DefWindowProc(message, wParam, lParam);
}
void CHIDGetDlg::CreateReadThread()
{
ThreadData.hWnd = m_hWnd;
m_hReadThreadCreated = CreateEvent(NULL, TRUE, FALSE, NULL);
if(m_hReadThreadCreated)
{
DWORD threadID;
if(0 != _beginthreadex(NULL, 0, (unsigned int (__stdcall *)(void *))ReadThread,
this, 0, (unsigned int*)&threadID))
WaitForSingleObject(m_hReadThreadCreated, INFINITE);
CloseHandle(m_hReadThreadCreated);
}
}
void CHIDGetDlg::SetReadThreadHWND(HWND hWnd)
{
m_hReadThread = hWnd;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -