⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mouse.cpp

📁 WinCE下实现USB的驱动源代码
💻 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 + -