📄 lane_newdlg.cpp
字号:
// lane_newDlg.cpp : implementation file
//
#include "stdafx.h"
#include "lane_new.h"
#include "lane_newDlg.h"
#include "vfw.h"
#include "MulThread.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CLane_newApp theApp;
extern struct TimerStruct TimerOut[MAX_TIMER_COUNT];
extern BOOL bKill1,bKill2,bKill3,bKill4;
extern BOOL bCxpFreeFlag,bSavePictureFlag,bStartCaptureFlag;
extern char strPictureName[PICTURE_NAME_LEN];
BYTE * pData;
long pSize;
static BOOL bCaptureSuccessFlag=FALSE; //捕获成功标志
// 为了防止车道软件误存相同的图像,只有当捕获成功标志置位后
// 才允许将剪贴板中的数据存储为图片
/////////////////////////////////////////////////////////////////////////////
// CLane_newDlg dialog
CLane_newDlg::CLane_newDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLane_newDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CLane_newDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
bKill1=bKill2=bKill3=FALSE;
bCxpFreeFlag=TRUE;
memset(strPictureName,0,PICTURE_NAME_LEN);
bSavePictureFlag=FALSE;
for(int i=0;i<MAX_TIMER_COUNT;i++)
TimerOut[i].Active=0;
}
void CLane_newDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLane_newDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLane_newDlg, CDialog)
//{{AFX_MSG_MAP(CLane_newDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_NORMAL_QUIT,ProcessQuit)
ON_MESSAGE(WM_ABNORMAL_QUIT,ProcessAbnormalQuit)
ON_MESSAGE(WM_ABNORMAL,ProcessAbnormal)
ON_MESSAGE(WM_OPTION_FINISH,ProcessOptionFinish)
ON_MESSAGE(WM_CAPTURE_WINDOW,ProcessCaptureWindow)
ON_MESSAGE(WM_CAPTURE,ProcessCapture)
ON_MESSAGE(WM_STARTUP_TIMER,ProcessStartupTimer)
ON_MESSAGE(WM_TIMER_OUT,ProcessTimerOut)
ON_MESSAGE(WM_CLOSE_TIMER,ProcessCloseTimer)
ON_MESSAGE(WM_CXP,ProcessCXP)
ON_MESSAGE(WM_CXP_STATUS,ProcessCxpStatus)
ON_MESSAGE(WM_SEND_PICTURE,ProcessSendPicture)
ON_MESSAGE(WM_FINISH_CAPTURE,ProcessFinishCapture)
ON_MESSAGE(WM_SAVE_PICTURE,ProcessSavePicture)
ON_MESSAGE(WM_UPDATE_OK,ProcessUpdate)
ON_MESSAGE(WM_STATUS_INFO,ProcessStatusInfo)
//ON_MESSAGE(WM_OVERLAY,ProcessOverlay)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLane_newDlg message handlers
BOOL CLane_newDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
nScreenX=theApp.nScreenX; //获取屏幕分辨率
nScreenY=theApp.nScreenY;
SetWindowPos(NULL,0,0,nScreenX,nScreenY,SWP_SHOWWINDOW);
// SetWindowPos(&wndTopMost,0,0,ScreenX,ScreenY,SWP_SHOWWINDOW);
//对话框大小为全屏且总在最顶上
CClientDC dc(this); //获取客户区DC(内存DC必须与客户DC兼容)
theApp.memDC.CreateCompatibleDC(&dc);
//产生兼容的内存DC
newMemDCBitmap=new CBitmap; //创建与内存DC相联系的客户DC
newMemDCBitmap->CreateCompatibleBitmap(&dc,nScreenX,nScreenY);
//产生兼容位图
oldMemDCBitmap=theApp.memDC.SelectObject(newMemDCBitmap);
theApp.memDC.PatBlt(0,0,nScreenX,nScreenY,BLACKNESS);
//用黑色覆盖整个屏幕
theApp.Font1=new CFont; //产生文本字体
theApp.Font1->CreatePointFont(nScreenX/6,"宋体",NULL);
ASSERT(theApp.Font1);
theApp.Font2=new CFont;
theApp.Font2->CreatePointFont(nScreenX/4,"宋体",NULL);
ASSERT(theApp.Font2);
theApp.Pen1.CreatePen(PS_SOLID,nScreenX/400,RGB(255,255,255));
theApp.memDC.SelectObject(&theApp.Pen1);
theApp.Brush1.CreateSolidBrush(RGB(0,0,0));
theApp.memDC.SelectObject(&theApp.Brush1);
SetFocus();
CheckFileDirectory();
AfxBeginThread(CheckTimer,NULL);
AfxBeginThread(MulportComm,NULL);
AfxBeginThread(PrintThread,NULL);
CTimeInfo m_clsTime;
m_clsTime.SetTime(); //设置当前时间
m_clsStatus.Initial();
m_clsDevice.Initial();
// 网络初始化时要读取车道配置参数,因此下面两行不能前移
m_clsMessage.NetworkInitial();
m_clsPicture.NetworkInitial();
// 启动图像抓拍线程时需要读取收费站名称,因此该行不可前移
AfxBeginThread(SavePicture,NULL);
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CLane_newDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CPaintDC dc(this);
dc.BitBlt(0,0,nScreenX,nScreenY,&theApp.memDC,0,0,SRCCOPY);
SetFocus(); //获取焦点
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CLane_newDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
// 检查车道软件存储数据的文件路径是否存在,若不存在,产生该些目录
// 车道软件调用该函数时对话框尚未完成初始化,因此不能用CNoteError
// 类来提示用户错误,故采用提示框提示错误
void CLane_newDlg::CheckFileDirectory()
{
struct _finddata_t FileInfo;
long hFile;
if((hFile=_findfirst(PARAM_PATH,&FileInfo))==-1L){
if(_mkdir(PARAM_PATH)!=0){
AfxMessageBox("产生目录D:\\PARAM失败",0,0);
PostMessage(WM_ABNORMAL_QUIT,ERROR_CREATE_DIR_FAILURE,0);
return;
}
} else {
_findclose(hFile);
}
if((hFile=_findfirst(INFO_PATH,&FileInfo))==-1L){
if(_mkdir(INFO_PATH)!=0){
AfxMessageBox("产生目录D:\\INFO失败",0,0);
PostMessage(WM_ABNORMAL_QUIT,ERROR_CREATE_DIR_FAILURE,0);
return;
}
} else {
_findclose(hFile);
}
if((hFile=_findfirst(PICTURE_PATH,&FileInfo))==-1L){
if(_mkdir(PICTURE_PATH)!=0){
AfxMessageBox("产生目录D:\\PICTURE失败",0,0);
PostMessage(WM_ABNORMAL_QUIT,ERROR_CREATE_DIR_FAILURE,0);
return;
}
} else {
_findclose(hFile);
}
if((hFile=_findfirst(LOG_PATH,&FileInfo))==-1L){
if(_mkdir(LOG_PATH)!=0){
AfxMessageBox("产生目录D:\\LOG失败",0,0);
PostMessage(WM_ABNORMAL_QUIT,ERROR_CREATE_DIR_FAILURE,0);
return;
}
} else {
_findclose(hFile);
}
CLaneInfo m_clsLane;
if(m_clsLane.RAM_Disk()){
if((hFile=_findfirst(TEMP_PATH,&FileInfo))==-1L){
// 假如在RAM盘产生路径失败,自动禁止使用RAM盘
if(_mkdir(TEMP_PATH)!=0){
m_clsLane.RAM_Disk(FALSE);
}
} else {
_findclose(hFile);
}
}
}
/*
const UCHAR START_KEY ='A'; //上班键 /7/
const UCHAR END_KEY ='B'; //下班键 /0/
const UCHAR MONTH_KEY ='E'; //月票键 /f4/
const UCHAR FREE_KEY ='F'; //免征键 /F5/
const UCHAR ARMY_POLICE_KEY ='U'; //军车键 /F6/
const UCHAR GROUP_KEY ='D'; //车队键 /8/
const UCHAR FIND_KEY ='L'; //查询键 /9/
const UCHAR REPEAT_PRINT_KEY='I'; //重打票键 /F2/
const UCHAR TICKET_KEY ='J'; //定额票键 /F1/
const UCHAR HAS_GO_KEY ='K'; //车已走键 /F3/
const UCHAR CODING_KEY ='M'; //编码切换键 /./
const UCHAR MODIFY_KEY =0x20; //修改键 /clear/
*/
// 截取窗口消息,对按键消息,如果操作员按键为非系统键,将该消息
// 转发给状态控制类CStatusControl;若操作员按F10,车道软件退出
BOOL CLane_newDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
// 若按键不是系统键,将该消息转发给状态控制类CStatusControl
if(pMsg->message==WM_KEYDOWN){
// 以下修改是因为专用键盘与通用键盘不同,键盘定义需要重新影射。
if((pMsg->wParam>=96)&&(pMsg->wParam<=105))
pMsg->wParam=pMsg->wParam-48; // 键盘中数字键定义重新影射
if(pMsg->wParam==8)
pMsg->wParam=MODIFY_KEY;// 键盘中更正键定义重新影射
if(pMsg->wParam==110)
pMsg->wParam=CODING_KEY;// 键盘中‘.’键定义重新影射
switch(pMsg->wParam){
case VK_UP:
// 若按键为向上的箭头键,转换为UP_KEY键
m_clsStatus.ProcessKeyboard(UP_KEY);
break;
case VK_F1:
pMsg->wParam=TICKET_KEY;
m_clsStatus.ProcessKeyboard(pMsg->wParam);
break;
case VK_F2:
pMsg->wParam=REPEAT_PRINT_KEY;
m_clsStatus.ProcessKeyboard(pMsg->wParam);
break;
case VK_F3:
pMsg->wParam=HAS_GO_KEY;
m_clsStatus.ProcessKeyboard(pMsg->wParam);
break;
case VK_F4:
pMsg->wParam=MONTH_KEY;
m_clsStatus.ProcessKeyboard(pMsg->wParam);
break;
case VK_F5:
pMsg->wParam=FREE_KEY;
m_clsStatus.ProcessKeyboard(pMsg->wParam);
break;
case VK_F6:
pMsg->wParam=ARMY_POLICE_KEY;
m_clsStatus.ProcessKeyboard(pMsg->wParam);
break;
case VK_CLEAR:
pMsg->wParam=MODIFY_KEY;
m_clsStatus.ProcessKeyboard(pMsg->wParam);
break;
case VK_DECIMAL:
pMsg->wParam=CODING_KEY;
m_clsStatus.ProcessKeyboard(pMsg->wParam);
break;
case VK_DOWN:
// 若按键为向下的箭头键,转换为DOWN_KEY键
m_clsStatus.ProcessKeyboard(DOWN_KEY);
break;
case COME_KEY:
// O键模拟车压上线圈
SendMessage(WM_CXP,7,(LPARAM)"E100000");
break;
case GO_KEY:
// p键模拟车离开线圈
SendMessage(WM_CXP,7,(LPARAM)"E001000");
break;
case 'W':
SendMessage(WM_CXP,7,(LPARAM)"E011000");
break;
default:
m_clsStatus.ProcessKeyboard(pMsg->wParam);
break;
}
}
// 若按键为系统键F10,车道软件退出
if((pMsg->message==WM_SYSKEYDOWN)&&(pMsg->wParam==VK_F10)){
SetTimer(2,500,NULL);
}
return CDialog::PreTranslateMessage(pMsg);
}
// 车道软件退出。本函数负责在程序退出前回收系统资源
// 1、通知其他后台线程结束运行;
// 2、释放字体、画刷等系统资源;
// 3、释放不再使用的内存资源
void CLane_newDlg::ProcessQuit(WPARAM wParam,LPARAM lParam)
{
m_clsMessage.NetworkClose(); //关闭网络连接
m_clsPicture.NetworkClose();
m_clsDevice.ReleaseDevice();
m_clsStatus.ReleaseMemory();
CLaneInfo m_clsLane;
m_clsLane.FreeMemory(); //释放统计信息所占内存
CScreen m_clsScreen;
m_clsScreen.ReleaseMemory(); //释放显示位图文件时申请的内存
theApp.muxKill1.Lock();
bKill1=TRUE;
theApp.muxKill1.Unlock();
theApp.muxKill2.Lock();
bKill2=TRUE;
theApp.muxKill2.Unlock();
theApp.muxKill3.Lock();
bKill3=TRUE;
theApp.muxKill3.Unlock();
theApp.muxKill4.Lock();
bKill4=TRUE;
theApp.muxKill4.Unlock();
Sleep(500);
int nCount=0;
BOOL bExitFlag1,bExitFlag2,bExitFlag3,bExitFlag4;
do{
Sleep(50);
theApp.muxKill1.Lock();
bExitFlag1=bKill1;
theApp.muxKill1.Unlock();
theApp.muxKill2.Lock();
bExitFlag2=bKill2;
theApp.muxKill2.Unlock();
theApp.muxKill3.Lock();
bExitFlag3=bKill3;
theApp.muxKill3.Unlock();
theApp.muxKill4.Lock();
bExitFlag4=bKill4;
theApp.muxKill4.Unlock();
if(nCount>=40) break;
nCount++;
} while((bExitFlag1)||(bExitFlag2)||(bExitFlag3)||(bExitFlag4));
if(theApp.Font1!=0) delete theApp.Font1;
if(theApp.Font2!=0) delete theApp.Font2;
theApp.Pen1.DeleteObject();
theApp.Brush1.DeleteObject();
if(newMemDCBitmap!=0) delete newMemDCBitmap;
EndDialog(0);
}
// 车道软件出现异常而必须退出时调用本程序:首先记录异常原因,
// 然后调用正常退出函数退出车道软件
void CLane_newDlg::ProcessAbnormalQuit(WPARAM wParam,LPARAM lParam)
{
FILE *fp1;
char FileName[30];
memset(FileName,0,30);
CTimeInfo m_clsTime;
sprintf(FileName,"%s\\Log%.2d%.3d.txt",LOG_PATH,
m_clsTime.GetYear()%100,m_clsTime.GetDayCount());
if((fp1=fopen(FileName,"a"))!=NULL){
CLaneInfo m_clsLane;
fprintf(fp1,"%.4d/%.2d/%.2d %.2d:%.2d:%.2d ",
m_clsTime.GetYear(),m_clsTime.GetMonth(),
m_clsTime.GetDay(),m_clsTime.GetHour(),
m_clsTime.GetMinute(),m_clsTime.GetSecond());
if(wParam==ERROR_NO_ENOUGH_MEMORY){
fprintf(fp1,"No enough memory! %s\n",(char *)lParam);
m_clsLane.SetErrorInfo("内存不足!");
SendMessage(WM_OPTION_FINISH,MUST_EXIT,0);
}
if(wParam==ERROR_MULPORT_FAILURE){
fputs("Mulport initial failure!\n",fp1);
m_clsLane.SetErrorInfo("串口初始化失败!");
SendMessage(WM_OPTION_FINISH,MUST_EXIT,0);
}
if(wParam==ERROR_NETWORK_FAILURE){
fputs("Network setup failure!\n",fp1);
m_clsLane.SetErrorInfo("网络初始化失败!");
SendMessage(WM_OPTION_FINISH,MUST_EXIT,0);
}
if(wParam==ERROR_CREATE_DIR_FAILURE){
fputs("Can't create directory!\n",fp1);
m_clsLane.SetErrorInfo("无法产生数据目录!");
SendMessage(WM_OPTION_FINISH,MUST_EXIT,0);
}
if(wParam==ERROR_NO_LPT){
fputs("No LPT!\n",fp1);
m_clsLane.SetErrorInfo("无法打开并行口!");
SendMessage(WM_OPTION_FINISH,MUST_EXIT,0);
}
fclose(fp1);
} else {
AfxMessageBox("无法在D:盘记录数据",0,0);
SendMessage(WM_OPTION_FINISH,MUST_EXIT,0);
}
}
// 车道软件出现不太严重的错误时调用该函数记录错误原因
void CLane_newDlg::ProcessAbnormal(WPARAM wParam,LPARAM lParam)
{
FILE *fp1;
char strFileName[30];
memset(strFileName,0,30);
CTimeInfo m_clsTime;
sprintf(strFileName,"%s\\Log%.2d%.3d.txt",LOG_PATH,
m_clsTime.GetYear()%100,m_clsTime.GetDayCount());
if((fp1=fopen(strFileName,"a"))!=NULL){
fprintf(fp1,"%.4d/%.2d/%.2d %.2d:%.2d:%.2d ",
m_clsTime.GetYear(),m_clsTime.GetMonth(),
m_clsTime.GetDay(),m_clsTime.GetHour(),
m_clsTime.GetMinute(),m_clsTime.GetSecond());
fputs((char *)lParam,fp1);
fclose(fp1);
}
}
// 一次人机交互完成,将人机交互事件转发给CStatusControl对象
void CLane_newDlg::ProcessOptionFinish(WPARAM wParam,LPARAM lParam)
{
m_clsStatus.ProcessOptionFinish(wParam,lParam);
}
// 视频捕获回调函数,若视频捕获过程中发生错误则调用这个函数:
// 记录发生错误的原因
LRESULT CALLBACK CaptureErrorCallBack(HWND hWnd,int nID,LPCSTR lpsz)
{
if(nID!=0){
char tmpStr[120];
memset(tmpStr,0,120);
sprintf(tmpStr,"Capture Error=%d %s\n",nID,lpsz);
SendMessage(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)tmpStr);
bStartCaptureFlag=FALSE;
}
return 0;
}
// 初始化视频捕获窗口。为了保证视频捕获卡可靠地工作,每天零点对捕获
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -