📄 initialize.cpp
字号:
#include <windows.h>
#include <stdio.h>
#include <shlwapi.h> // include strTrim should include shlwapi.lib
#include "initialize.h"
#include "accelerator.h"
/***************************************
函数功能:对串口读写的初始化.包括:
(1) 获取串口句柄
(2) 设置COM口的基本参数
(3) 和加速器建立连接
***************************************/
HANDLE Initialize(HANDLE hAccelerator, OVERLAPPED *pOverlappedRead, OVERLAPPED *pOverlappedWrite)
{
hAccelerator = CreateFile(COMPORT,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL );
if (hAccelerator == INVALID_HANDLE_VALUE)
{
com_error = CANNOT_OPEN_COM;
return NULL;
}
memset( pOverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( pOverlappedWrite, 0, sizeof( OVERLAPPED ) );
pOverlappedRead->hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
pOverlappedWrite->hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if (!pOverlappedRead->hEvent || !pOverlappedWrite->hEvent)
{
CloseHandle(pOverlappedRead->hEvent);
CloseHandle(pOverlappedWrite->hEvent);
CloseHandle(hAccelerator);
com_error = CANNOT_GET_EVENT_RESOURCE;
return NULL;
}
if (!InitializeCOM(hAccelerator))
{
CloseHandle(hAccelerator);
com_error = CANNOT_INITIALIZE_COM;
return NULL;
}
//设置串口的MASK,当没有数据读入系统缓存时,WaitCommEvent处将阻塞
SetCommMask(hAccelerator, EV_RXCHAR);
if(!SetupCommunication(hAccelerator, pOverlappedWrite,pOverlappedRead))
{
CloseHandle(hAccelerator);
return NULL;
}
return hAccelerator;
}
/***************************************
函数功能:设置COM口的基本参数
***************************************/
bool InitializeCOM(HANDLE hAccelerator)
{
COMMTIMEOUTS CommTimeOuts;
DCB dcb;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
if(!SetCommTimeouts( hAccelerator, &CommTimeOuts))
{
return false;
}
dcb.DCBlength = sizeof(DCB);
if (!GetCommState(hAccelerator, &dcb))
{
return false;
}
dcb.BaudRate = BAUDRATE;
dcb.ByteSize = BYTESIZE;
dcb.StopBits = STOPBITS;
dcb.Parity = PARITY;
if( !SetCommState(hAccelerator, &dcb ) || !SetupComm(hAccelerator, 10000, 10000))
{
return false;
}
return true;
}
/***************************************
函数功能: 和加速器建立连接. 包括:
(1) 向加速器发送请求建立控制符"R"
(2) 获得加速器响应"N"
如果握手成功,表示可以和加速器进行通信
***************************************/
bool SetupCommunication(HANDLE hAccelerator, OVERLAPPED *pOverlappedWrite,OVERLAPPED *pOverlappedRead)
{
DWORD dwByteRead = 1;
char szCommand[20];
Sleep(50);
if(!HandShakeToAccelerator(hAccelerator, pOverlappedWrite,'R', 1))
{
com_error = CANNOT_SEND_SIGNAL;
return false;
}
Sleep(50); //从串口读数据有延时.不加Sleep在开始启动加速器的时候经常需要多次重启
if(!HandShakeFromAccelerator(hAccelerator,pOverlappedRead, szCommand, dwByteRead))
{
return false;
}
return true;
}
/***************************************
函数功能: 向加速器发送控制命令.
发送"R"表示请求和加速器进行通信,期望获得
返回值"N";
发送"V"表示请求获得加速器当前数据,期望获
得返回值"X X-value Y Y-value Z Z-value"
***************************************/
bool HandShakeToAccelerator(HANDLE hAccelerator, OVERLAPPED *pOverlappedWrite , char cCommand,int nLength)
{
BOOL bWriteStat;
DWORD dwByteWritten;
bWriteStat = WriteFile(hAccelerator, (LPSTR) &cCommand, nLength, &dwByteWritten, pOverlappedWrite);
if (!bWriteStat && (GetLastError() == ERROR_IO_PENDING))
{
switch(WaitForSingleObject(pOverlappedWrite->hEvent, 1000))
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
case WAIT_ABANDONED:
return false;
}
}
else
{
return false;
}
return true;
}
/***************************************
函数功能: 从加速器获得返回值.
若发送的值为"R",则期望获得的返回值为"N";
若发送的值为"V",则期望获得返回值为
"X X-value Y Y-value Z Z-value"
***************************************/
bool HandShakeFromAccelerator(HANDLE hAcclerator, OVERLAPPED *pOverlappedRead, char *szBuffer, DWORD dwByteRead)
{
BOOL bReadStat, bSetup;
DWORD dwEvtMask;
static OVERLAPPED OverlappedRecv;
//用于判断超时
static int iTimeOut = 0;
int cTotalLength;
int cCount = 0;
//判断是否为发送"R"期望获得的输出
bSetup = (dwByteRead == 1) ? true : false;
if (bSetup)
{
cTotalLength = 1;
}
else
{
cTotalLength = 6;
}
OverlappedRecv.hEvent = CreateEvent(NULL,false, false, NULL);
bool bResult = WaitCommEvent(hAcclerator, &dwEvtMask ,&OverlappedRecv);
if (bResult != true && GetLastError() == ERROR_IO_PENDING)
{
switch(WaitForSingleObject(OverlappedRecv.hEvent, 200))
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
case WAIT_ABANDONED:
com_error = CANNOT_SETUP_ACCELERATOR;
return false;
}
}
else if (bResult != true)
{
com_error = CANNOT_RECV_DATA;
return false;
}
if (dwEvtMask & EV_RXCHAR)
{
DWORD dwErrorFlags;
COMSTAT ComStat;
do
{
ClearCommError(hAcclerator, &dwErrorFlags, &ComStat );
if (ComStat.cbInQue > 0)
{
dwByteRead = ComStat.cbInQue;
}
bReadStat = ReadFile( hAcclerator, (char*)szBuffer, dwByteRead, &dwByteRead, pOverlappedRead);
if (!bReadStat && (GetLastError() == ERROR_IO_PENDING))
{
switch(WaitForSingleObject(pOverlappedRead->hEvent, 1000))
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
case WAIT_ABANDONED:
com_error = CANNOT_RECV_DATA;
return false;
}
}
cCount += dwByteRead;
++iTimeOut;
if (iTimeOut >= 5000)
{
break;
}
}while(cCount < cTotalLength);
if (iTimeOut >= 5000)
{
iTimeOut = 0;
com_error = TIME_OUT;
return false;
}
iTimeOut = 0;
if ((*szBuffer != 'N') && bSetup)
{
com_error = CANNOT_SETUP_ACCELERATOR;
return false;
}
return true;
} // end of if (dwEvtMask & EV_RXCHAR)
com_error = CANNOT_RECV_DATA;
return false;
}
/***************************************
函数功能: 显示读串口数据时的错误信息
***************************************/
void DisplayCOMError()
{
char szErrorString[30];
switch(com_error)
{
case CANNOT_OPEN_COM:
strcpy(szErrorString,"无法打开串口!");
break;
case CANNOT_GET_EVENT_RESOURCE:
strcpy(szErrorString,"系统资源event无法得到分配!");
break;
case CANNOT_INITIALIZE_COM:
strcpy(szErrorString,"无法初始化串口!");
break;
case CANNOT_SEND_SIGNAL:
strcpy(szErrorString,"无法发送数据!");
break;
case CANNOT_RECV_DATA:
strcpy(szErrorString,"无法接收数据!");
break;
case TIME_OUT:
strcpy(szErrorString,"超时!");
break;
case CANNOT_SETUP_ACCELERATOR:
strcpy(szErrorString,"请重启加速器!");
break;
default:
strcpy(szErrorString,"未知错误!");
break;
}
MessageBox(NULL,szErrorString, "警告",MB_OK);
}
/***************************************
函数功能: 关闭程序.
***************************************/
bool EndProgram()
{
char szComdLine[1024];
strcpy(szComdLine,GetCommandLine());
int iLength = strlen(szComdLine);
if (szComdLine[iLength-1] == 'e' && szComdLine[iLength - 2] == '-')
{
return true;
}
else
{
return false;
}
}
/***************************************
函数功能: 设置注册表键值,用与关闭程序.
***************************************/
void SetRegedit()
{
HKEY keyHandle;
DWORD dwDisposition;
char szBuf[] = "关闭加速器";
char szcmd[1024];
if (RegCreateKeyEx(HKEY_CLASSES_ROOT,
SUBKEY,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&keyHandle,
&dwDisposition
) != ERROR_SUCCESS)
{
MessageBox(NULL,"无法写注册表!","警告",MB_OK);
return;
}
if (RegSetValueEx(keyHandle,
NULL,
0,
REG_SZ,
(LPBYTE)szBuf,
strlen(szBuf) + 1) != ERROR_SUCCESS)
{
MessageBox(NULL,"无法写注册表!","警告",MB_OK);
return;
}
RegCloseKey(keyHandle);
if (RegCreateKeyEx(HKEY_CLASSES_ROOT,
ACCELERATOR_SUBKEY,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&keyHandle,
&dwDisposition
) != ERROR_SUCCESS)
{
MessageBox(NULL,"无法写注册表!","警告",MB_OK);
return;
}
strcpy(szcmd, GetCommandLine());
char szTrim[] = TEXT("\"\0");
StrTrim(szcmd, szTrim);
StrCpyN(szcmd,szcmd,strlen(szcmd) - 1);
strcat(szcmd, " -e");
if (RegSetValueEx(keyHandle,
NULL,
0,
REG_SZ,
(LPBYTE)szcmd,
strlen(szcmd) + 1) != ERROR_SUCCESS)
{
MessageBox(NULL,"无法写注册表!","警告",MB_OK);
return;
}
}
/***************************************
函数功能: 程序结束,删除相关注册表键值
***************************************/
void DeleteReg()
{
HKEY hkey;
RegOpenKeyEx(HKEY_CLASSES_ROOT,
SUBKEY,
0,
KEY_ALL_ACCESS,
&hkey);
RegDeleteKey(hkey,"command");
RegOpenKeyEx(HKEY_CLASSES_ROOT,
SHELL_SUBKEY,
0,
KEY_ALL_ACCESS,
&hkey);
RegDeleteKey(hkey,"accelerator");
RegCloseKey(hkey);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -