📄 statuscontrol.cpp
字号:
// StatusControl.cpp: implementation of the CStatusControl class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "lane_new.h"
#include "StatusControl.h"
#include "DeviceControl.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
extern CLane_newApp theApp;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CScreen * CStatusControl::pScreen;
UINT CStatusControl::nMainStatus;
UINT CStatusControl::nSlaveStatus;
CStatusControl::CStatusControl()
{
}
void CStatusControl::Initial()
{
CScreen m_clsScreen;
m_clsLane.Initial();
m_clsScreen.Initial(); //屏幕初始化
// 特别地:屏幕初始化不可移动到统计信息初始化之后,否则因为保护
// 现场文件中记录了退出前的车道状态,可能会导致车道框显示错误
CStatInfo m_clsStat;
m_clsStat.Initial(); //统计信息初始化
// 特别地:报表类初始化时需要访问统计信息类的保护现场文件,因此
// 报表类初始化必须位于统计信息类初始化之后
CRecord m_clsRecord;
m_clsRecord.Initial(); //报表边界类初始化
// 特别说明:因为报表边界类初始化过程中会访问统计信息数据及当前时间,
// 因此该行不能放到前两行前面
// 程序运行时价格表、延迟表、操作员表、收费站名称必须存在,
// 白名单、黑名单、新价格表文件可以存在也可以不存在
BOOL bFileFlag=TRUE;
if(!m_clsLane.FileReadyFlag(TFRMB_INDEX))
bFileFlag=FALSE;
if(!m_clsLane.FileReadyFlag(DELAYS_INDEX))
bFileFlag=FALSE;
if(!m_clsLane.FileReadyFlag(COLLECOD_INDEX))
bFileFlag=FALSE;
if(bFileFlag){ //车道信息初始化
nMainStatus=WAIT_BEGIN_SHIFT;
nSlaveStatus=SHOW_PRESS_BEGIN; //主状态转换后复位从状态
GetCurrentStatus()->DrawWorkInfo(nSlaveStatus);
} else {
// 若参数文件不存在,屏幕显示设置窗口以便设置IP地址、端口号等信
// 息。只有这些信息成功设置后才能和收费站建立连接,否则车道参数
// 文件无法下传
nMainStatus=WAIT_SET_PARAM;
nSlaveStatus=SHOW_PARAM; //主状态转换后复位从状态
GetCurrentStatus()->DrawWorkInfo(nSlaveStatus);
}
}
// 显示状态信息
void CStatusControl::ProcessStatusInfo(char *pStr)
{
GetCurrentStatus()->DrawStatusInfo(pStr);
}
// 用户边界类和用户完成一次交互后调用本函数。功能如下:
// 根据当前主状态询问对应界面类所完成的交互,并根据该交互内容
// 转换主状态或从状态
void CStatusControl::ProcessOptionFinish(UINT nEventType,UINT KeyValue)
{
switch(nEventType){
case MUST_EXIT:
ProcessMustExitEvent(); //通知用户程序将退出
break;
case SHOW_PRESS_BEGIN:
ProcessBeginKey(); //操作员按“开始”键
break;
case HAS_GO_KEY: //车已走
ProcessHasGoKey();
break;
case SHOW_INPUT_ID:
ProcessKeyOfInputID(KeyValue); //输入工号窗口的事件
break;
case SHOW_INPUT_PASSWORD:
ProcessKeyOfInputPassword(KeyValue);//密码输入窗口完毕
break;
case SHOW_SHIFT_NO:
ProcessKeyOfInputShiftNO(KeyValue); //选择班次或修改密码窗口
break;
case SHOW_START_INVOICE:
ProcessKeyOfStartInvoice(KeyValue); //发票起号被确认窗口
break;
case SHOW_CHANGE_PASSWORD:
ProcessKeyOfChangePassword(KeyValue);//输入修改密码
break;
case SHOW_PASSWORD_RESULT:
ProcessKeyOfPasswordResult(KeyValue);//输入修改密码结果
break;
case SHOW_END_INVOICE:
ProcessKeyOfEndInvoice(KeyValue); //交班显示发票窗口
break;
case SHOW_PRESS_VALID:
ProcessKeyOfEndShift(KeyValue); //确认交班窗口
break;
case SHOW_BUS_CLASS:
ProcessKeyOfInputBusClass(KeyValue);//输入车型窗口事件
break;
case SHOW_FARE:
ProcessKeyOfInputFare(KeyValue); //显示费额窗口
break;
case SHOW_BUS_NO:
ProcessKeyOfInputBusNO(KeyValue); //显示输入特殊车车牌窗口
break;
case SHOW_FREE_NOTE:
ProcessKeyOfNoteFree(KeyValue); //显示输入特殊车认证窗口
break;
case SHOW_VIOLATE:
ProcessKeyOfViolate(KeyValue); //显示违章车窗口
break;
case SHOW_GROUP_CLASS:
ProcessKeyOfInputGroupClass(KeyValue);//显示输入车队车型
break;
case SHOW_GROUP:
ProcessKeyOfGroup(KeyValue); //显示车队过车
break;
case SHOW_INPUT_BLACKCAR:
ProcessKeyOfInputBlackCar(KeyValue);//显示输入黑名单车车牌窗口
break;
case SHOW_IS_BLACK:
ProcessKeyOfIsBlackCar(KeyValue); //显示黑名单车认证窗口
break;
case END_SHIFT_PRESS: //编辑、设置、测试模式中下班
ProcessEndKey();
break;
case MODE_SELECT_CANCEL:
ProcessCancelOfMode(); //选择模式前按取消键
break;
case MODE_SELECT_OK:
ProcessModeOK(); //已经选择四种工作模式中一种
break;
case TEST_MENU_SELECT_OK:
ProcessTestMenuOK(); //已经选择测试菜单
break;
case CXP_TEST_MENU_CANCEL:
ProcessTestItemFinish(); //测试项目完成
break;
case CXP_TEST_MENU_OK:
ProcessCxpMenuOK(); //选择CXP菜单
break;
case CXP_INPUT_CANCEL:
ProcessCancelOfInputDevice(); //输入设备测试完毕
break;
case CXP_OUTPUT_CANCEL:
ProcessCancelOfOutputDevice(); //输出设备测试完毕
break;
case CXP_OUTPUT_CHANGE:
ProcessTestOutputDevice(); //改变输出设备状态
break;
case KEY_TEST_CANCEL:
ProcessTestItemFinish(); //键盘测试项目完成
break;
case TFI_TEST_CANCEL:
ProcessTestItemFinish(); //TFI测试项目完成
break;
case TFI_TEST_SELECT:
ProcessTestTFI(); //测试TFI
break;
case PRINTER_TEST_CANCEL:
ProcessTestItemFinish(); //测试项目完成
break;
case PRINTER_TEST_SELECT:
ProcessTestPrinter(); //测试票据打印机
break;
case OVERLAY_TEST_CANCEL:
ProcessTestItemFinish(); //测试项目完成
break;
case OVERLAY_TEST_SELECT:
ProcessTestOverlay(); //测试字符叠加器
break;
case SET_MENU_OK:
ProcessSetMenuOK(); //已经选择设置项目
break;
case SET_PARAM_OK:
ProcessSetParamOK(); //已经完成参数修改
break;
case SET_PARAM_CANCEL:
ProcessCancelOfSetParam(); //废弃已经进行的修改
break;
case UP_KEY_PRESS:
ProcessUpKey(); //处理上箭头键
break;
case DOWN_KEY_PRESS:
ProcessDownKey(); //处理下箭头键
break;
case EDIT_NUMBER_OK:
ProcessEditNumberOK(); //编辑发票号完成
break;
}
}
// 处理操作员的按键输入。由于收费专用键盘和标准101键盘具有相同
// 的接口,我们用处理标准101键盘的方法处理收费专用键盘
// 本函数负责将操作员输入的按键转发到相应的用户界面类并由用户界
// 面类检查按键的合法性。若按键合法,通知流程控制类CFlewControl
// 处理用户键入事件,否则驱动蜂鸣器报警
void CStatusControl::ProcessKeyboard(UINT nChar){
if(!GetCurrentStatus()->ProcessKeyboard(nChar)){
// 按键不合法,驱动蜂鸣器报警
// CDeviceControl m_clsDevice;
// m_clsDevice.Buzzer();
}
}
// 处理定时器超时消息。本函数只处理和本类有关的定时器消息,
// 和本类无关的定时器消息不做处理
void CStatusControl::ProcessTimerOut(UINT nIndex)
{
CTimeInfo m_clsTime;
switch(nIndex){
case LEAVE_LOOP_TIMER:
break;
case PICTURE_LOOP_TIMER:
break;
case AMBER_LIGHT_TIMER:
break;
case ASK_IO_STATUS_TIMER:
break;
case SECOND_TIMER:
m_clsTime.SetTime();
m_clsRecord.ProcessTime();
m_clsLane.ProcessTime();
break;
case WORK_WINDOW_TIMER:
GetCurrentStatus()->ProcessTimerOut();
break;
case PICTURE_QUERY_TIMER:
break;
case PICTURE_SEND_TIMER:
break;
case PICTURE_RESET_TIMER:
break;
case TFI_TIMER:
break;
case SOUND_TIMER:
break;
case OVERLAY_TIMER:
break;
case INITIAL_TIMER:
break;
case ALARM_INFO_TIMER:
CScreen m_clsScreen;
m_clsScreen.ProcessAlarmTimerOut();
break;
}
}
// 车道软件收到上位机的下传文件并完成更新后调用本函数
// 功能:通知CLaneInfo类更新文件就绪标志,如果主状态为
// WAIT_RECEIVE_FILE,更新显示
// 收费站下传的信息包括运行参数文件和发票起、止号
void CStatusControl::ProcessUpdate(UINT nType,char *pValue)
{
CStatInfo m_clsStatInfo;
BOOL bFileFlag=TRUE;
switch(nType){
case UPDATE_FILE:
// 若收费站更新了运行参数文件,运行参数文件立即生效
// 将所有运行参数文件重新读入内存
m_clsLane.RepeatReadFile();
// 程序运行时价格表、延迟表、操作员表、收费站名称必须存在,
// 月票表、黑名单、免征表、新价格表文件可以存在也可以不存在
if(!m_clsLane.FileReadyFlag(TFRMB_INDEX))
bFileFlag=FALSE;
if(!m_clsLane.FileReadyFlag(DELAYS_INDEX))
bFileFlag=FALSE;
if(!m_clsLane.FileReadyFlag(COLLECOD_INDEX))
bFileFlag=FALSE;
if(!m_clsLane.FileReadyFlag(PLAZANAM_INDEX))
bFileFlag=FALSE;
// 若人机界面正在等待下传运行参数文件,更新显示
if(nMainStatus==WAIT_RECEIVE_FILE){
if(bFileFlag){
nMainStatus=WAIT_BEGIN_SHIFT;
nSlaveStatus=SHOW_PRESS_BEGIN;
}
GetCurrentStatus()->DrawWorkInfo(nSlaveStatus);
}
break;
case UPDATE_INVOICE:
// 只有在等待更新发票号时才允许更新发票号码,否则若车道已经发出部
// 分票后收费站更新发票号码会导致发票号码出错
if (m_clsStatInfo.WorkMode()!=WORK_MODE_NORMAL)
{
for(int i=0;i<7;i++){ //取出7种票据的起号
char tmpInvoiceNO[12];
memset(tmpInvoiceNO,0,12);
memmove(tmpInvoiceNO,pValue+i*10,10);
CStatInfo m_clsStat;
m_clsStat.SetInvoiceStart(i,atol(tmpInvoiceNO));
}
if((nMainStatus==WAIT_SHIFT_INITIAL)&&(nSlaveStatus==SHOW_START_INVOICE)){
// 发票号码更改完成后更新屏幕显示
GetCurrentStatus()->DrawWorkInfo(nSlaveStatus);
}
}
break;
}
}
// 根据状态机的状态返回用户界面对象的指针
// 2002/10/29 程序被重新改写,原因是程序退出前定义的本地类已经被
// 被析构。虽然实践证明该方法也能使用,但可能存在隐患
// 修改办法: 用new 的方法定义一个对象并返回其对象指针,由于new
// 在堆上分配内存,函数返回时该内存并不释放
// 此外: 必须考虑分配的内存何时被释放
CScreen * CStatusControl::GetCurrentStatus()
{
if(pScreen!=NULL)
{
delete pScreen;
pScreen=NULL;
}
switch(nMainStatus)
{
case WAIT_QUIT_FOR_ERROR: //程序异常退出
pScreen=new CNoteError;
break;
case WAIT_BEGIN_SHIFT: //等待上班
pScreen=new CBeginShift;
break;
case WAIT_LOGIN:
pScreen=new CLogin;
break;
case WAIT_SHIFT_INITIAL:
pScreen=new CInformationBS;
break;
case WAIT_MODIFY_PASSWORD:
pScreen=new CPassword;
break;
case WAIT_END_SHIFT: //处理交班
pScreen=new CEndShift;
break;
case WAIT_BUS_NORMAL_INFO:
pScreen=new CBusNormal;
break;
case WAIT_AUTHENTICATION:
pScreen=new CAuthentication;
break;
case WAIT_CHECK_BLACK_CAR:
pScreen=new CCheckBlackCar;
break;
case WAIT_VIOLATE: //处理违章
pScreen=new CViolate;
break;
case WAIT_GROUP: //处理车队
pScreen=new CGroup;
break;
case WAIT_MODE_MENU: //处理工作模式选择
pScreen=new CModeMenu;
break;
case WAIT_TEST_MENU: //处理测试菜单
pScreen=new CTestMenu;
break;
case WAIT_TEST_CXP: //测试CXP
pScreen=new CTestCxp;
break;
case WAIT_TEST_KEY: //测试收费专用键盘
pScreen=new CTestKey;
break;
case WAIT_TEST_TFI: //测试TFI
pScreen=new CTestTfi;
break;
case WAIT_TEST_PRINTER: //测试票据打印机
pScreen=new CTestPrinter;
break;
case WAIT_TEST_OVERLAY: //测试字符叠加器
pScreen=new CTestOverlay;
break;
case WAIT_SET_MODE: //设置车道参数
pScreen=new CSetParam;
break;
case WAIT_EDIT_MODE: //工作于编辑模式
pScreen=new CEditMode;
break;
case WAIT_RECEIVE_FILE: //接收参数文件
pScreen=new CReceiveFile;
break;
case WAIT_SET_PARAM:
pScreen=new CSetIP;
break;
default:
pScreen=new CSendFile;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -