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

📄 lane_newdlg.cpp

📁 高速公路收费系统车道软件. 功能: 1 检测公路过往车辆 2 收费过程控制和数据采集 3 车辆信息和图片上传服务器.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//	卡重新初始化
void CLane_newDlg::ProcessCaptureWindow(WPARAM wParam,LPARAM lParam)
{
	HRESULT hr;
	int id;
	BOOL bIsConnected = TRUE;

	int iCardNumber;
	char szDeviceName[MAX_DEVICE_NUM][MAX_DEVICE_NAME_LEN];
	const char sz10Moons[] = {"10Moons"};
	switch(wParam){
		case RESET_CAPTURE:		//交班时复位捕获设备
		case OVERLAY_CAPTURE:	//捕获窗口进入Overlay模式,
//			DSStream_DisconnectDevice(0);
//			capDriverDisconnect(hWndc);
			break;
		case POWER_ON_CAPTURE:
			//寻找可用的卡,剔除非10Moons卡
	hr = DSStream_EnumVideoCaptureDev(szDeviceName, &iCardNumber);
	if(FAILED(hr))
	{
		//AfxMessageBox("枚举失败", MB_OK, 0);
		SendMessage(WM_ABNORMAL,0,(LPARAM)"枚举视频卡失败");
		return;
	}
	for(id=0; id<iCardNumber; id++)
	{
		szDeviceName[id][7] = '\0';
		hr = DSStream_IsConnected(id, &bIsConnected);
		if(FAILED(hr))
		{
			bIsConnected = TRUE;
			break;
		}
		if(_stricmp(szDeviceName[id], sz10Moons) != 0)
		{
			bIsConnected = TRUE;
			continue;
		}
		if(!bIsConnected)
			break;
	}

	int nLineWidth=nScreenX/320;
	int nLeft=nScreenX*125/192-nLineWidth;
	int nRight=nScreenX*63/64;
	int nTop=nScreenY*25/48-2*nLineWidth;
	int nButtom=nScreenY*41/48-nLineWidth;
	theApp.memDC.Rectangle(nLeft,nTop,nRight,nButtom);
	
	//无可用的卡
	if(bIsConnected || id>=iCardNumber)
	{
		SendMessage(WM_ABNORMAL,0,(LPARAM)"没有可用的视频卡失败");
		return;
	}

	VIDEOSTREAMINFO vsi;
	RECT rc;

	const BOOL bOverlay2=FALSE;//现在把它设置为捕获方式
	hr = DSStream_ConnectDevice(id, bOverlay2);
	if(FAILED(hr))
	{
		SendMessage(WM_ABNORMAL,0,(LPARAM)"连接视频卡失败");
		return;
	}

	hr = DSStream_GetVideoInfo(id, &vsi, PREVIEW);
	if(FAILED(hr))
		return;
	//设置视频制式
	DSStream_SetVideoStandard(id,VideoStandard_PAL_D);

	//设置视频源
	DSStream_RouteInPinToOutPin(id,1, 0);

	vsi.subtype = VideoSubType_RGB24;
	vsi.bmiHeader.biWidth=352;
	vsi.bmiHeader.biHeight=288;
	DSStream_SetVideoInfo(id, vsi, PREVIEW);
	
	int width = vsi.bmiHeader.biWidth;
	int height = vsi.bmiHeader.biHeight;
	hWndc2=capCreateCaptureWindow("",WS_POPUP|WS_VISIBLE,
//		0,0,640,480,m_hWnd,0);
		nLeft+2*nLineWidth,nTop+2*nLineWidth,nScreenX/3-nLineWidth,
		nScreenY/3-nLineWidth,m_hWnd,0);
	DSStream_SetOwnerWnd(id,hWndc2);
	rc.left=rc.top=0;
	rc.right=width;
	rc.bottom=height;
	DSStream_SetWindowPos(id, rc);
		break;
	}

	
	/*int LineWidth,Left,Right,Buttom,Top;
	switch(wParam){
	case RESET_CAPTURE:		//交班时复位捕获设备
	case OVERLAY_CAPTURE:	//捕获窗口进入Overlay模式,
		capDriverDisconnect(hWndc);
		break;
	case POWER_ON_CAPTURE:
		LineWidth=nScreenX/320;
		Left=nScreenX*125/192-LineWidth;
		Right=nScreenX*63/64;
		Top=nScreenY*25/48-2*LineWidth;
		Buttom=nScreenY*41/48-LineWidth;
		theApp.memDC.Rectangle(Left,Top,Right,Buttom);
		hWndc=capCreateCaptureWindow("",WS_POPUP|WS_VISIBLE,
			Left+2*LineWidth,Top+2*LineWidth,nScreenX/3-LineWidth,
			nScreenY/3-LineWidth,m_hWnd,0);
							//在对话框右下脚产生捕获窗口
		break;
	}
	if(hWndc==NULL)	return;
	capSetCallbackOnError(hWndc,CaptureErrorCallBack);	
										//设置捕获图象错误回调函数
	capDriverConnect(hWndc,0);			//连接到捕获卡驱动程序
	if(wParam==OVERLAY_CAPTURE){
//	若进入Overlay模式,将捕获设备设置为Overlay工作模式
		capOverlay(hWndc,TRUE);
		bOverlayMode=TRUE;				//视频卡工作在非捕获模式
		return;
	}
//	否则,需要设置捕获设备的参数
	struct {
		BITMAPINFOHEADER BmpHead;
		RGBQUAD			 QuadColor[256];
	} BitmapInfo;
	for(int i=0;i<256;i++){
		BitmapInfo.QuadColor[i].rgbBlue=i;
		BitmapInfo.QuadColor[i].rgbGreen=i;
		BitmapInfo.QuadColor[i].rgbRed=i;
		BitmapInfo.QuadColor[i].rgbReserved=i;
	}
//	估计因为设备驱动程序或硬件不兼容,本部分设置在WINDOW 2000下无
//	法配置视频卡,视频卡使用了缺省配置:16位彩色、高度288、宽度352
//	现象:启动计算机后必须先调用圆刚公司的演示程序,然后再运行车道
//	软件,否则显示的图象不正确
//	解决办法:1、配置为16位彩色,但尚未找到压缩16位彩色的方法;
//	2、改用NT操作系统;3、用圆刚的二次开发包函数代替标准WINDOWS的
//	视频捕获函数;4、换一台WINDOWS 2000的机子实验一下是否和本机的
//	硬件有关
	BitmapInfo.BmpHead.biBitCount=24;
	BitmapInfo.BmpHead.biClrImportant=0;
	BitmapInfo.BmpHead.biClrUsed=0;
	BitmapInfo.BmpHead.biCompression=BI_RGB;
	BitmapInfo.BmpHead.biHeight=nScreenY/2;
	BitmapInfo.BmpHead.biPlanes=1;
	BitmapInfo.BmpHead.biSize=sizeof(BitmapInfo.BmpHead);
	BitmapInfo.BmpHead.biSizeImage=0;		//对BI_RGB格式,此项可为0
	BitmapInfo.BmpHead.biWidth=nScreenX/2;
	BitmapInfo.BmpHead.biXPelsPerMeter=0;
	BitmapInfo.BmpHead.biYPelsPerMeter=0;
	capSetVideoFormat(hWndc,&BitmapInfo,sizeof(BitmapInfo));
	CAPTUREPARMS CaptureParms;
	capCaptureGetSetup(hWndc,&CaptureParms,sizeof(CAPTUREPARMS));
										//获取当前捕获流参数
	CaptureParms.dwRequestMicroSecPerFrame=66667;
										//15帧/秒 帧速率(帧数/微秒)
	CaptureParms.fCaptureAudio=FALSE;	//不捕捉音频信号
	capCaptureSetSetup(hWndc,&CaptureParms,sizeof (CAPTUREPARMS));
										//设置捕获参数
										//Preview模式可以捕获图片
	capPreviewScale(hWndc,TRUE);		//按捕获窗口的大小显示图象
	capPreviewRate(hWndc,67);			//每秒15帧
	capPreview(hWndc,TRUE);				//进入预览模式
	bOverlayMode=FALSE;					//视频卡工作在捕获模式*/
	bStartCaptureFlag=FALSE;			//捕获标志复位*/
}

//	操作系统将视频图象捕获到内存后自动调用该函数,本函数负责通知车道
//	软件视频图象已经成功地放入内存
void CALLBACK FinishCaptureImage(
  HWND hwnd,        // handle of destination window
  UINT uMsg,        // message
  DWORD dwData,     // application-defined value
  LRESULT lResult   // result of message processing
  ){
	if((uMsg==WM_CAP_GRAB_FRAME_NOSTOP)&&(lResult!=0)){
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_FINISH_CAPTURE,dwData,0);
	}
}

//	抓拍视频图形进内存。如果上一幅图片尚未处理完成,本次不捕获图片;
//	若上幅图片已经处理完成,向操作系统发送视频捕获命令并指定捕获行为
//	完成后应调用的回调函数
void CLane_newDlg::ProcessCapture(WPARAM wParam,LPARAM lParam)
{
	DWORD RetValue=1;
	//if(bOverlayMode) return;		//工作在非捕获模式时不抓拍图像
	if(bStartCaptureFlag) return;	//上幅图片未捕获完,不再捕获
	theApp.muxPicture.Lock();
	if(bSavePictureFlag){		//上幅图片未压缩完,不再捕获
		theApp.muxPicture.Unlock();
		return;
	}
	theApp.muxPicture.Unlock();
	bStartCaptureFlag=TRUE;
/*在这里处理图像抓拍*/
	pSize=0;
	pData=NULL;
	theApp.muxPicture.Lock();
	bStartCaptureFlag=TRUE;
	theApp.muxPicture.Unlock();
	DSStream_GetCurrentDib(0,pData,&pSize);
	if(pSize!=0){
		pData=new BYTE[pSize];
		DSStream_GetCurrentDib(0,pData,&pSize);
		if(pData==NULL){
			SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"捕捉图像进内存失败\n",SMTO_BLOCK,200,&RetValue);
			return;
		}
		
	}else{
//		pData=new BYTE[160000];
//		memset(pData,0,160000);
//		DSStream_GetCurrentDib(0,pData,&pSize);
//		if(pData==NULL){
			SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"捕捉图像进内存失败\n",SMTO_BLOCK,200,&RetValue);
			return;
//		}
	}
	theApp.muxPicture.Lock();
	bStartCaptureFlag=FALSE;
	theApp.muxPicture.Unlock();
	//SendMessageCallback(hWndc,WM_CAP_GRAB_FRAME_NOSTOP,0,0,FinishCaptureImage,wParam);
}

//	将内存中的视频图象拷贝到剪切板成功后调用该回调函数。本函数负责
//	通知车道软件图象已经在剪切板上
/*void CALLBACK FinishSaveImage(
  HWND hwnd,        // handle of destination window
  UINT uMsg,        // message
  DWORD dwData,     // application-defined value
  LRESULT lResult   // result of message processing
  ){
	if((uMsg==WM_CAP_EDIT_COPY)&&(lResult!=0)){
//	数据已经拷贝到剪贴板上,允许压缩图片
		bCaptureSuccessFlag=TRUE;
	}
}*/

//	命令操作系统将内存中的视频图象拷贝到剪切板上
void CLane_newDlg::ProcessFinishCapture(WPARAM wParam,LPARAM lParam)
{
	//SendMessageCallback(hWndc,WM_CAP_EDIT_COPY,(WPARAM)0,0,FinishSaveImage,wParam);
}

//	需要存储抓拍到的图像文件时调用本函数。本函数根据图像类型设定
//	文件名并将该名称传到图像压缩线程。为了防止两个线程同时调用文
//	件名字符串,使用互斥量保护资源。图像存储类型由wParam指定
void CLane_newDlg::ProcessSavePicture(WPARAM wParam,LPARAM lParam)
{
//	假如剪贴板上无新数据,不存储该帧图片
	//if(!bCaptureSuccessFlag) return;
	//bCaptureSuccessFlag=FALSE;
	char strFileName[PICTURE_NAME_LEN];
	memset(strFileName,0,PICTURE_NAME_LEN);
	sprintf(strFileName,"%s\\",PICTURE_PATH);
	int nLen=strlen(strFileName);
	CRecord m_clsRecord;
	m_clsRecord.GetPictureName(strFileName+nLen);
	theApp.muxPicture.Lock();
	bSavePictureFlag=TRUE;
	memmove(strPictureName,strFileName,PICTURE_NAME_LEN);
	theApp.muxPicture.Unlock();
	bStartCaptureFlag=FALSE;
}

//	启动定时器函数。将当前时间和要定时的时长赋给定时器结构,并置定时
//	器激活标志。为了防止冲突,使用互斥量保护资源
void CLane_newDlg::ProcessStartupTimer(WPARAM wParam,LPARAM lParam)
{
	struct timeb loc1;
	theApp.muxTime.Lock();
	ftime(&loc1);
	theApp.muxTime.Unlock();
	theApp.muxTimerOut.Lock();
	if(wParam==ALL_TIMER){
		for(int i=0;i<MAX_TIMER_COUNT;i++)
			TimerOut[i].StartTime=loc1;
	} else {
		TimerOut[wParam].Active=1;
		TimerOut[wParam].StartTime=loc1;
		CLaneInfo m_clsLane;
		switch(wParam){
		case LEAVE_LOOP_TIMER:
			TimerOut[wParam].TimerValue=m_clsLane.LeaveLoopDelays()*1000;
			break;
		case PICTURE_LOOP_TIMER:
			TimerOut[wParam].TimerValue=m_clsLane.PictureLoopDelays()*1000;
			break;
		case AMBER_LIGHT_TIMER:
			TimerOut[wParam].TimerValue=m_clsLane.AmberDelays()*1000;
			break;
		case ASK_IO_STATUS_TIMER:
			TimerOut[wParam].TimerValue=5000;
			break;
		case SECOND_TIMER:
			TimerOut[wParam].TimerValue=1000;
			break;
		case WORK_WINDOW_TIMER:
			TimerOut[wParam].TimerValue=lParam;
			break;
		case PICTURE_QUERY_TIMER:
//	为了缩短生成图像到图像上传的时间,将30秒查询时间改为12秒
			TimerOut[wParam].TimerValue=12000;
			break;
		case PICTURE_SEND_TIMER:
			TimerOut[wParam].TimerValue=2000;
			break;
		case PICTURE_RESET_TIMER:
			TimerOut[wParam].TimerValue=60000;
			break;
		case TFI_TIMER:
			TimerOut[wParam].TimerValue=1500;
			break;
		case SOUND_TIMER:
			TimerOut[wParam].TimerValue=lParam;
			break;
		case OVERLAY_TIMER:
			TimerOut[wParam].TimerValue=lParam;
			break;
		case INITIAL_TIMER:
			TimerOut[wParam].TimerValue=500;
			break;
		case ALARM_INFO_TIMER:
			TimerOut[wParam].TimerValue=lParam;
			break;
		}
	}
	theApp.muxTimerOut.Unlock();
}

//	定时器超时后调用本程序,负责将超时消息传送到指定的类
//	根据“多型”的概念,本函数只负责将超时消息送到指定的
//	控制类,至于每个控制类对此消息如何处理和该函数无关
void CLane_newDlg::ProcessTimerOut(WPARAM wParam,LPARAM lParam)
{
	m_clsDevice.ProcessTimerOut(wParam);
	m_clsStatus.ProcessTimerOut(wParam);
	m_clsPicture.ProcessTimerOut(wParam);
}

//	关闭定时器函数,将指定的定时器置为非激活状态
void CLane_newDlg::ProcessCloseTimer(WPARAM wParam,LPARAM lParam)
{
	theApp.muxTimerOut.Lock();
	if(wParam==ALL_TIMER){
		for(int i=0;i<MAX_TIMER_COUNT;i++)
			TimerOut[i].Active=0;
	} else {
		TimerOut[wParam].Active=0;
	}
	theApp.muxTimerOut.Unlock();
}

//	处理来自输入/输出外设的数据并将该数据传送到指定的类。为了防止
//	冲突,使用互斥量保护资源
void CLane_newDlg::ProcessCXP(WPARAM wParam,LPARAM lParam)
{
	char tmpStr[8];
	memset(tmpStr,0,8);
//	如果收到的数据长度不合法,说明通讯过程中出现错误,丢弃收到
//	的数据(设备边界类中处理这个错误)
//	上传的输入外设状态共7个字节,请求下传输出外设状态共1个字节
	if((wParam==7)||(wParam==1)){
		memmove(tmpStr,(char *)lParam,wParam);
	} else {
//	指明正在接收数据,但所接收到的数据被丢弃
		tmpStr[0]='E';		
	}
	theApp.muxCxpFree.Lock();
	bCxpFreeFlag=TRUE;
	theApp.muxCxpFree.Unlock();
	m_clsDevice.ProcessCxpInput(tmpStr);
}

//	处理来自打印机的数据并将该数据传送到指定的类
void CLane_newDlg::ProcessPrinter(WPARAM wParam,LPARAM lParam)
{
	m_clsDevice.ProcessPrinter((char)wParam);
}

//	输入外设的状态发生变化调用该函数,将该消息转发到控制类
//	CStatusControl进行处理
void CLane_newDlg::ProcessCxpStatus(WPARAM wParam,LPARAM lParam)
{
	m_clsStatus.ProcessCxpStatus(wParam,(char)lParam);
}

//	有图象需要上传时调用本函数,负责通知图象传送类有图象需要传送
void CLane_newDlg::ProcessSendPicture(WPARAM wParam,LPARAM lParam)
{
	CLaneInfo m_clsLane;
	CRecord m_clsRecord;
	char strFileName[PICTURE_NAME_LEN];
	memset(strFileName,0,PICTURE_NAME_LEN);
	memmove(strFileName,(char *)lParam,strlen((char *)lParam));
	if(m_clsLane.RAM_Disk()){
		m_clsRecord.RecordP(IMG_INDEX,IMG_TRANS,strFileName);
	} else {
		m_clsRecord.RecordP(IMG_INDEX_1,IMG_TRANS_1,strFileName);
	}
}

//	车道软件收到收费站的下传文件并完成更新时调用本函数,负责将该
//	消息转发给控制类CStatusControl处理
void CLane_newDlg::ProcessUpdate(WPARAM wParam,LPARAM lParam)
{
	switch(wParam){
	case UPDATE_FILE:				//正在更新运行参数文件
		m_clsStatus.ProcessUpdate(wParam,"");
		break;
	case UPDATE_INVOICE:			//正在更新发票起、止号
		char tmpStr[72];			//7种发票号码
		memset(tmpStr,0,72);
		memmove(tmpStr,(char *)lParam,70);
		m_clsStatus.ProcessUpdate(wParam,tmpStr);
		break;
	}
}

//	外设有数据输入时调用本函数,负责将该消息转发给控制类
//	CStatusControl处理
void CLane_newDlg::ProcessStatusInfo(WPARAM wParam,LPARAM lParam)
{
	m_clsStatus.ProcessStatusInfo((char *)lParam);
}

//处理字符叠加消息
/*
void CLane_newDlg::ProcessOverlay(WPARAM wParam,LPARAM lParam)
{
	m_clsDevice.ProcessOverlayData((unsigned char)wParam);
}
*/

void CLane_newDlg::OnOK()		//重载OnOK()使按回车键程序不退出
{
}

void CLane_newDlg::OnCancel()	//重载OnCancel()使按Esc键程序不退出
{
}

//	本定时器只用于程序退出时
void CLane_newDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	PostMessage(WM_NORMAL_QUIT,NORMAL,0);
	CDialog::OnTimer(nIDEvent);
}

void CLane_newDlg::WinHelp(DWORD dwData, UINT nCmd) 
{
	// TODO: Add your specialized code here and/or call the base class
	
//	CDialog::WinHelp(dwData, nCmd);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -