📄 mouse.cpp
字号:
#include "StdAfx.h"
#include "Mouse.h"
// 构造函数,初始化时调用
CMouse::CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,
LPCUSB_INTERFACE lpInterface)
{
m_fClosing = FALSE;
m_fReadyForMouseEvents = FALSE;
m_hEvent = NULL;
m_hThread = NULL;
m_hDevice = hDevice;
m_hInterruptPipe = NULL;
m_hInterruptTransfer = NULL;
m_lpUsbFuncs = lpUsbFuncs;
m_pInterface = lpInterface;
m_fPrevButton1 = FALSE;
m_fPrevButton2 = FALSE;
m_fPrevButton3 = FALSE;
memset(m_pbDataBuffer, 0, sizeof(m_pbDataBuffer));
}
// 析构函数,用于清除申请的资源。
CMouse::~CMouse()
{
// 通知系统去关闭相关的函数接口。
m_fClosing = TRUE;
// Wake up the connection thread again and give it time to die.
if (m_hEvent != NULL)
{
// 通知关闭数据接受线程。
SetEvent(m_hEvent);
if (m_hThread != NULL)
{
DWORD dwWaitReturn;
dwWaitReturn = WaitForSingleObject(m_hThread, 1000);
if (dwWaitReturn != WAIT_OBJECT_0)
{
TerminateThread(m_hThread, DWORD(-1));
}
CloseHandle(m_hThread);
m_hThread = NULL;
}
CloseHandle(m_hEvent);
m_hEvent = NULL;
}
//关闭传送
if(m_hInterruptTransfer)
(*m_lpUsbFuncs->lpCloseTransfer)(m_hInterruptTransfer);
//关闭管道
if(m_hInterruptPipe)
(*m_lpUsbFuncs->lpClosePipe)(m_hInterruptPipe);
}
// 初始化USB鼠标驱动程序
BOOL CMouse::Initialize()
{
LPCUSB_DEVICE lpDeviceInfo = (*m_lpUsbFuncs->lpGetDeviceInfo)(m_hDevice);
// 检测配置:USB鼠标应该只有一个中断管道
if ((m_pInterface->lpEndpoints[0].Descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) != USB_ENDPOINT_TYPE_INTERRUPT)
{
RETAILMSG(1,(TEXT("!USBMouse: EP 0 wrong type (%u)!\r\n"),
m_pInterface->lpEndpoints[0].Descriptor.bmAttributes));
return FALSE;
}
DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: EP 0:MaxPacket: %u, Interval: %u\r\n"),
m_pInterface->lpEndpoints[0].Descriptor.wMaxPacketSize, /*数据包大小*/
m_pInterface->lpEndpoints[0].Descriptor.bInterval)); /*中断延时*/
//配置中断管道
m_hInterruptPipe = (*m_lpUsbFuncs->lpOpenPipe)(m_hDevice,
&m_pInterface->lpEndpoints[0].Descriptor);
//打开中断管道出错
if (m_hInterruptPipe == NULL) {
RETAILMSG(1,(TEXT("Mouse: Error opening interrupt pipe\r\n")));
return (FALSE);
}
//创建事件
m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hEvent == NULL)
{
RETAILMSG(1,(TEXT("USBMouse: Error on CreateEvent for connect event\r\n")));
return(FALSE);
}
// 创建数据接受线程
m_hThread = CreateThread(0, 0, MouseThreadStub, this, 0, NULL);
if (m_hThread == NULL)
{
RETAILMSG(1,(TEXT("USBMouse: Error on CreateThread\r\n")));
return(FALSE);
}
return(TRUE);
}
// 从USB鼠标设备中读出数据,产生相应的鼠标事件。
BOOL CMouse::SubmitInterrupt()
{
//判断m_hInterruptTranser是否为空如果不为空关闭transfer
if(m_hInterruptTransfer)
(*m_lpUsbFuncs->lpCloseTransfer)(m_hInterruptTransfer);
// 从USB鼠标PIPE中读数据
/*
lpIssueInterruptTransfer 中断传送
lpIssueContrilTransfer 控制传送
lpIssueIsochTransfer 同步传送
lpIssueVendorTransfer ?块传送?
*/
//启动一个中断传送
/*
*/
m_hInterruptTransfer = (*m_lpUsbFuncs->lpIssueInterruptTransfer)
(m_hInterruptPipe, MouseTransferCompleteStub, this,
USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK, // 表示输入数据 /数据桢短
min(m_pInterface->lpEndpoints[0].Descriptor.wMaxPacketSize,
sizeof(m_pbDataBuffer)),
m_pbDataBuffer,
NULL);
if (m_hInterruptTransfer == NULL)
{
DEBUGMSG(ZONE_ERROR,L("!USBMouse: Error in IssueInterruptTransfer\r\n"));
return FALSE;
}
else
{
DEBUGMSG(ZONE_TRANSFER,(L"USBMouse::SubmitInterrupt,Transfer:0x%X\r\n",
m_hInterruptTransfer));
}
return TRUE;
}
// 处理鼠标中断传输的数据
BOOL CMouse::HandleInterrupt()
{
//USB传送过来的信息8位
// 1 2 3 4 5 6 7 8
// 鼠标状态 dx dy
DWORD dwError;
DWORD dwBytes;
DWORD dwFlags = 0;
INT dx = (signed char)m_pbDataBuffer[1];
INT dy = (signed char)m_pbDataBuffer[2];
BOOL fButton1 = m_pbDataBuffer[0] & 0x01 ? TRUE : FALSE;
BOOL fButton2 = m_pbDataBuffer[0] & 0x02 ? TRUE : FALSE;
BOOL fButton3 = m_pbDataBuffer[0] & 0x04 ? TRUE : FALSE;
if (!(*m_lpUsbFuncs->lpGetTransferStatus)(m_hInterruptTransfer, &dwBytes,&dwError))
{
DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error in GetTransferStatus(0x%X)\r\n"),
m_hInterruptTransfer));
return FALSE;
}
else
{
DEBUGMSG(ZONE_TRANSFER,(TEXT("USBMouse::HandleInterrupt, hTransfer 0x%X complete (%u bytes, Error:%X)\r\n"),
m_hInterruptTransfer,dwBytes,dwError));
}
//再次开始接收鼠标消息
if (!SubmitInterrupt())
return FALSE;
if(dwError != USB_NO_ERROR)
{
DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error 0x%X in interrupt transfer\r\n"),dwError));
return TRUE;
}
if(dwBytes < 3)
{
DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Invalid byte cnt %u from interrupt transfer\r\n"),dwBytes));
return TRUE;
}
//处理鼠标动作
if(dx || dy)
dwFlags |= MOUSEEVENTF_MOVE;
if(fButton1 != m_fPrevButton1)
{
if(fButton1)
dwFlags |= MOUSEEVENTF_LEFTDOWN;
else
dwFlags |= MOUSEEVENTF_LEFTUP;
}
if(fButton2 != m_fPrevButton2)
{
if(fButton2)
dwFlags |= MOUSEEVENTF_RIGHTDOWN;
else
dwFlags |= MOUSEEVENTF_RIGHTUP;
}
if(fButton3 != m_fPrevButton3)
{
if(fButton3)
dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
else
dwFlags |= MOUSEEVENTF_MIDDLEUP;
}
m_fPrevButton1 = fButton1;
m_fPrevButton2 = fButton2;
m_fPrevButton3 = fButton3;
DEBUGMSG(ZONE_EVENTS,
(TEXT("USBMouse event: dx:%d, dy:%d, dwFlags:0x%X (B1:%u, B2:%u, B3:%u)\r\n"),
dx,dy,dwFlags,fButton1,fButton2,fButton3));
// 通知系统产生鼠标事件
if (m_fReadyForMouseEvents)
{
mouse_event(dwFlags, dx, dy, 0, 0);
}
else
{
//判断当前鼠标的API是否可用
m_fReadyForMouseEvents = IsAPIReady(SH_WMGR);
}
return TRUE;
}
DWORD CALLBACK CMouse::MouseTransferCompleteStub(LPVOID lpvNotifyParameter)
{
CMouse * pMouse = (CMouse *)lpvNotifyParameter;
return(pMouse->MouseTransferComplete());
}
// 数据传输完毕回调函数
DWORD CMouse::MouseTransferComplete()
{
if (m_hEvent)
SetEvent(m_hEvent);
return 0;
}
//启动线程函数
ULONG CALLBACK CMouse::MouseThreadStub(PVOID context)
{
//返回
CMouse * pMouse = (CMouse *)context;
return(pMouse->MouseThread());
}
// USB鼠标线程
DWORD CMouse::MouseThread()
{
DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: Worker thread started\r\n")));
//设置线程属性
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
//初始化中断传输
if (SubmitInterrupt())
{
while (!m_fClosing)
{
WaitForSingleObject(m_hEvent, INFINITE);
if (m_fClosing)
break;
if ((*m_lpUsbFuncs->lpIsTransferComplete)(m_hInterruptTransfer))
{
if (!HandleInterrupt())
break;
}
else
{
RETAILMSG(1,(TEXT("!USBMouse: Event signalled, but transfer not complete\r\n")));
// The only time this should happen is if we get an error on the transfer
ASSERT(m_fClosing || (m_hInterruptTransfer == NULL));
break;
}
}
}
RETAILMSG(1,(TEXT("USBMouse: Worker thread exiting\r\n")));
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -