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

📄 lane_newdlg.cpp

📁 高速公路收费系统车道软件. 功能: 1 检测公路过往车辆 2 收费过程控制和数据采集 3 车辆信息和图片上传服务器.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -