📄 sermouse.cpp
字号:
// SerMouse.cpp : Defines the entry point for the DLL application.
//
#include <windows.h>
#include <devload.h>
#include <nkintr.h>
#include <pkfuncs.h>// 驱动中自动生成的Include
#include <diskio.h>
#include <winnt.h>
#include <CEDDK.h>
#include <Windev.h>
#include "stdafx.h"
#include "SerMouse.h"
HANDLE hPort;
HANDLE hReadThread;
bool m_fPrevButton1=false;
bool m_fPrevButton2=false;
bool m_fPrevButton3=false;
bool m_fReadyForMouseEvents=false;
bool InitDCB()
{
DCB PortDCB;
// DWORD dwError;
PortDCB.DCBlength = sizeof (DCB);//得到端口的默认设置信息
GetCommState (hPort, &PortDCB);
//改变DCB结构设置
PortDCB.BaudRate = 1200; //波特率
PortDCB.fBinary = TRUE; //Win32不支持非二进制串行传输模式,必须为TRUE
PortDCB.fParity = TRUE; //启用奇偶校验
PortDCB.fOutxCtsFlow = TRUE; //串行端口的输出由CTS线控制
PortDCB.fOutxDsrFlow = FALSE; //关闭串行端口的DSR流控制
PortDCB.fDtrControl = DTR_CONTROL_ENABLE; //启用DTR线
PortDCB.fDsrSensitivity = FALSE; //如果设为TRUE将忽略任何输入的字节,除非DSR线被启用
//PortDCB.fTXContinueOnXoff = TRUE; //当为TRUE时,如果接收缓冲区已满且驱动程序已传送XOFF字符,将使驱动程序停止传输字符
PortDCB.fTXContinueOnXoff = FALSE;
PortDCB.fOutX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输出
PortDCB.fInX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输入
PortDCB.fErrorChar = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
PortDCB.fNull = FALSE; //设为TRUE将使串行驱动程序忽略收到的空字节
PortDCB.fRtsControl = RTS_CONTROL_ENABLE; //启用RTS线
PortDCB.fAbortOnError = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
PortDCB.ByteSize = 7; //每字节的位数
PortDCB.Parity = NOPARITY; //无奇偶校验
PortDCB.StopBits = ONESTOPBIT; //每字节一位停止位
//(1200,N,7,1)
//根据DCB结构配置端口
if (!SetCommState (hPort, &PortDCB))
{
//不能配置串行端口
DEBUGMSG(1, (_T("Unable to configure the serial port\r\n")) );
return FALSE;
}
return TRUE;
}
bool InitCommTimeouts()
{
COMMTIMEOUTS CommTimeouts;
// DWORD dwError;
//得到超时参数
GetCommTimeouts (hPort, &CommTimeouts);
//改变COMMTIMEOUTS结构设置
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
//设置端口超时值
if (!SetCommTimeouts (hPort, &CommTimeouts))
{
//不能设置超时值Unable to set the time-out parameters
DEBUGMSG(1, (_T("Unable to set the time-out parameters\r\n")) );
return FALSE;
}
return TRUE;
}
bool MouseDataHandler(BYTE *m_pbDataBuffer)
{
DWORD dwFlags=0;
INT dx=(m_pbDataBuffer[0] & 0x03) * 64 + (m_pbDataBuffer[1] & 0x3F);
if (dx > 127)dx=dx-256;
INT dy=(m_pbDataBuffer[0] & 0x0C) * 16 + (m_pbDataBuffer[2] & 0x3F);
if (dy > 127)dy=dy-256;
bool fButton1 = m_pbDataBuffer[0] & 0x20 ? TRUE:FALSE;
bool fButton2 = m_pbDataBuffer[0] & 0x10 ? TRUE:FALSE;
bool fButton3 = m_pbDataBuffer[3] & 0x10 ? TRUE:FALSE;
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(1,
(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
m_fReadyForMouseEvents=true;//IsAPIReady(SH_WMGR);
return true;
}
DWORD WINAPI portThread(LPVOID lpvoid)
{
while (1)
{
RETAILMSG(1,(TEXT("DATA \r\n")));
}
}
DWORD WINAPI ReadPortThread(LPVOID lpvoid)
{
BOOL fReadState;
DWORD dwCommModemStatus;
DWORD dwLength,offset=0;
COMSTAT ComStat;
DWORD dwErrorFlags;
BYTE buf[512];
while (hPort != INVALID_HANDLE_VALUE)
{
//等待串口的事件发生
WaitCommEvent (hPort, &dwCommModemStatus, 0);
// RETAILMSG(1, (_T("sermouse data !!!\r\n")) );
if (dwCommModemStatus & EV_RXCHAR)
{
ClearCommError(hPort,&dwErrorFlags,&ComStat);
//cbInQue返回在串行驱动程序输入队列中的字符数
dwLength=ComStat.cbInQue;
if(dwLength>0)
{
//从串口读取数据
fReadState=ReadFile(hPort,buf,dwLength,&dwLength,NULL);
if(!fReadState)
{
//不能从串口读取数据
MessageBox(NULL,TEXT("Error in read from serial port"),TEXT("Read Error"),MB_OK);
}
else
{
offset=0;
//查找数据包的头
while(!(buf[offset]&0x40))
{
if((dwLength-offset)<4)break;
//没有找到数据包
offset++;
}
while((dwLength-offset)>=4)
{
//还存在一个以上的完整数据包
MouseDataHandler(buf+offset);
offset+=4;
}
}
}
}
GetCommModemStatus (hPort, &dwCommModemStatus);
}
return 0;
}
BOOL OpenPort(LPTSTR lpszPortName)
{
//DWORD dwError;
DWORD dwThreadID;
//打开串口
hPort = CreateFile (lpszPortName, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING,0, NULL);
//如果打开端口出错, 返回FALSE
if ( hPort == INVALID_HANDLE_VALUE )
{
RETAILMSG(1, (_T("Open Port File ERROR\r\n")) );
return FALSE;
}
RETAILMSG(1, (_T("Open COM2 port successfully\r\n")) );
//指定端口监测的事件集
SetCommMask (hPort, EV_RXCHAR);
//分配设备缓冲区
SetupComm(hPort,512,512);
//初始化缓冲区中的信息
PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
//配置串行端口
if(!InitDCB())return FALSE;
//设置端口超时值
if(!InitCommTimeouts())
return FALSE;
//设置端口上指定信号的状态
// SETDTR: 发送DTR (data-terminal-ready)信号
// SETRTS: 发送RTS (request-to-send)信号
EscapeCommFunction (hPort, SETDTR);
EscapeCommFunction (hPort, SETRTS);
//创建一个从串口读取数据的线程
if (hReadThread = CreateThread(NULL, 0, ReadPortThread, 0, 0,&dwThreadID))
{
;
}
else
{
DEBUGMSG(1, (_T("Unable to Create Mouse Thread\r\n")) );
return FALSE;
}
// CreateThread(NULL, 0, portThread, 0, 0,&dwThreadID);
return TRUE;
}
BOOL ClosePort(HANDLE hCommPort)
{
if (hCommPort != INVALID_HANDLE_VALUE)
{
//设置连接属性为FALSE
//m_bConnected=FALSE;
//结束线程中WaitCommEvent的等待
SetCommMask(hPort,0);
//阻塞至线程停止
if(hReadThread)
{
TerminateThread(hReadThread,0);
CloseHandle(hReadThread);
}
//清除端口上指定信号的状态
EscapeCommFunction(hPort,CLRDTR);
EscapeCommFunction(hPort,CLRRTS);
//清除驱动程序内部的发送和接收队列
PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
//关闭串口
CloseHandle (hCommPort);
hCommPort = INVALID_HANDLE_VALUE;
return TRUE;
}
else
{
return TRUE;
}
}
BOOL APIENTRY DllEntry( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
UNREFERENCED_PARAMETER(hModule);
UNREFERENCED_PARAMETER(ul_reason_for_call);
UNREFERENCED_PARAMETER(lpReserved);
RETAILMSG(0,(_T("Enter DLL\r\n")));
return TRUE;
}
// This is an example of an exported variable
//SERMOUSE_API int nSerMouse=0;
// This is an example of an exported function.
//SERMOUSE_API int fnSerMouse(void)
//{
// return 42;
//}
// This is the constructor of a class that has been exported.
// see SerMouse.h for the class definition
DWORD
SMS_Init(
PVOID Context
)
{
UNREFERENCED_PARAMETER(Context);
RETAILMSG(1,(_T("Enter Sermouse INIT\r\n")));
OpenPort(L"COM2:");
return TRUE;
}
BOOL
SMS_Deinit(
DWORD dwContext
)
{
UNREFERENCED_PARAMETER(dwContext);
return TRUE;
}
BOOL
SMS_IOControl(
DWORD dwContext,
DWORD Ioctl,
LPTSTR pInBuf,
DWORD InBufLen,
PUCHAR pOutBuf,
DWORD OutBufLen,
PDWORD pdwBytesTransferred
)
{
UNREFERENCED_PARAMETER(dwContext);
UNREFERENCED_PARAMETER(Ioctl);
UNREFERENCED_PARAMETER(pInBuf);
UNREFERENCED_PARAMETER(InBufLen);
UNREFERENCED_PARAMETER(pOutBuf);
UNREFERENCED_PARAMETER(OutBufLen);
UNREFERENCED_PARAMETER(pdwBytesTransferred);
return 1;
}
VOID
SMS_PowerDown(
DWORD dwContext
)
{
UNREFERENCED_PARAMETER(dwContext);
}
VOID
SMS_PowerUp(
DWORD dwContext
)
{
UNREFERENCED_PARAMETER(dwContext);
}
DWORD
SMS_Open(
DWORD Context,
DWORD Access,
DWORD ShareMode)
{
UNREFERENCED_PARAMETER(Access);
UNREFERENCED_PARAMETER(ShareMode);
return Context; // 0 indicates failure
}
BOOL
SMS_Close(
DWORD Context
)
{
DEBUGMSG(1,(_T("SMS_Close(%x)\r\n"), Context));
return TRUE;
}
DWORD
SMS_Read(
DWORD dwContext,
LPVOID pBuf,
DWORD Len
)
{
UNREFERENCED_PARAMETER(dwContext);
UNREFERENCED_PARAMETER(pBuf);
UNREFERENCED_PARAMETER(Len);
return 0;
}
DWORD
SMS_Write(
DWORD dwContext,
LPVOID pBuf,
DWORD Len
)
{
UNREFERENCED_PARAMETER(dwContext);
UNREFERENCED_PARAMETER(Len);
DEBUGMSG(1,(_T("##SMS_Write:%s\r\n"),(LPTSTR)pBuf));
return 1;
}
ULONG
SMS_Seek(
PVOID Context,
LONG Position,
DWORD Type
)
{
UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(Position);
UNREFERENCED_PARAMETER(Type);
return (DWORD)-1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -