海康威视车牌识别调试

海康威视SDK车牌号识别调试

使用海康官方SDK调试门禁车牌号识别,MFC开发

一、WEB登录设备

首次使用设备需激活,输入说明书写的默认ip地址,用户名admin,修改密码。

进入设备的配置界面,我这里车牌识别方式改为视频识别。

进入预览界面就可以查看视频是否打开成功。

二、环境配置

新建自己的MFC项目,基于对话框项目,运行。
将SDK中库文件中的所有文件和文件夹统一放到你项目中输出有exe的地方。

新建include放头文件。

pApIOFf.png

配置项目的属性,

pApoIhT.jpg
pApo5NV.jpg
pApoT9U.jpg
pApo4A0.jpg

项目的目录结构

pApT3bn.jpg

在HKMFCcard.h中加入
#include "HCNetSDK.h"

三、开发

1.界面设计

pApRMPH.jpg

两个PictureControl分别显示场景图和车牌小图,两个本文框显示状态信息,中间本文框显示车牌号,两个按钮远程开关道闸暂时未开发

2.流程

设备注册 -->> 打开布防 -->> 检测到车牌 -->> 进入回调函数 -->> 抓拍识别 -->> 保存数据 -->> 界面显示

全局变量:

int iNum = 0;
NET_DVR_SETUPALARM_PARAM struSetupParam = { 0 };

3.设备注册

在HKMFcard.cpp中初始化

NET_DVR_Init(); // init DVR

打开软件进行设备注册,将此过程放在了OnInitDialog()中。

//---------------------------------------
	//注册设备

	//登录参数,包括设备地址、登录用户、密码等
	LONG lUserID = -1;
	NET_DVR_USER_LOGIN_INFO struLoginInfo = { 0 };
	struLoginInfo.bUseAsynLogin = 0; //同步登录方式
	strcpy(struLoginInfo.sDeviceAddress, "192.168.11.111"); //设备IP地址
	struLoginInfo.wPort = 8000; //设备服务端口
	strcpy(struLoginInfo.sUserName, "admin"); //设备登录用户名
	strcpy(struLoginInfo.sPassword, "11111111"); //设备登录密码

	//设备信息, 输出参数
	NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = { 0 };

	lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
	if (lUserID < 0)
	{
		/*printf("Login failed, error code: %d\n", NET_DVR_GetLastError());*/
		m_textLogin.SetWindowTextA("登录失败");
		NET_DVR_Cleanup();
		return 0;  
	}
		m_textLogin.SetWindowTextA("登录成功");

4.报警布防

//---------------------------------------
	//报警布防

	//设置报警回调函数
	/*注:多台设备对接时也只需要调用一次设置一个回调函数,不支持不同设备的事件在不同的回调函数里面返回*/
	NET_DVR_SetDVRMessageCallBack_V50(0, cbMessageCallback, NULL);

	//启用布防
	
	struSetupParam.dwSize = sizeof(NET_DVR_SETUPALARM_PARAM);
	struSetupParam.byLevel = 1; //布防优先级:0- 一等级(高),1- 二等级(中)   
	struSetupParam.byAlarmInfoType = 1; //上传报警信息类型: 0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)

	LONG lHandle = NET_DVR_SetupAlarmChan_V41(lUserID, &struSetupParam);
	if (lHandle < 0)
	{
		//printf("NET_DVR_SetupAlarmChan_V41 failed, error code: %d\n", NET_DVR_GetLastError());
		m_textBufang.SetWindowTextA("布防失败");
		NET_DVR_Logout(lUserID);
		NET_DVR_Cleanup();
		return 0;
	}
	m_textBufang.SetWindowTextA("布防成功");

cbMessageCallback 回调函数,当检测到有车牌号时调用此函数。

5.回调函数

void CALLBACK cbMessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
{	
	HWND hWnd = FindWindow(NULL, _T("车牌号识别系统"));
	//以下代码仅供参考,实际应用中不建议在该回调函数中直接处理数据保存文件,
	//例如可以使用消息的方式(PostMessage)在消息响应函数里进行处理。

	switch (lCommand)
	{
	case COMM_UPLOAD_PLATE_RESULT:
	{
		
		NET_DVR_PLATE_RESULT struPlateResult = { 0 };
		memcpy(&struPlateResult, pAlarmInfo, sizeof(struPlateResult));
	
		if (hWnd != NULL)
		{
			SendMessage(hWnd, WM_SAVE_DATA, (WPARAM)((void *)struPlateResult), 0);
		}
		
		break;
	}
	case COMM_ITS_PLATE_RESULT:
	{
		NET_ITS_PLATE_RESULT struITSPlateResult = { 0 };
		memcpy(&struITSPlateResult, pAlarmInfo, sizeof(struITSPlateResult));

		
		if (/*AfxGetMainWnd()->m_hWnd*/hWnd != NULL)
		{
			SendMessage(hWnd, WM_SAVE_DATA, (WPARAM)(&struITSPlateResult), 0);
		}
		break;
	}
	default:
		break;
	}

	return;
}

使用SendMessage传出消息。

1)宏定义

自定义消息
#define WM_SAVE_DATA (WM_USER + 100) //自定义消息

2)创建映射
BEGIN_MESSAGE_MAP(CHKMFCcardDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_MESSAGE(WM_SAVE_DATA, &CHKMFCcardDlg::OnSaveData)
	ON_BN_CLICKED(IDC_BUTTON1, &CHKMFCcardDlg::OnBnClickedButton1)
END_MESSAGE_MAP()

3)数据处理OnSaveData及显示
//数据的存储与显示
LRESULT CHKMFCcardDlg::OnSaveData(WPARAM wParam, LPARAM lParam)
{
	// 在这里处理数据保存操作
	// 例如,将 lParam 解释为指向数据的指针
	char filename[100];
	FILE *fSnapPic = NULL;
	FILE *fSnapPicPlate = NULL;

	//NET_ITS_PLATE_RESULT* struITSPlateResult = reinterpret_cast<NET_ITS_PLATE_RESULT*>(lParam);
	NET_ITS_PLATE_RESULT* struITSPlateResult = (NET_ITS_PLATE_RESULT*)(wParam);
	//NET_ITS_PLATE_RESULT struITSPlateResult = wParam;
	// 进行数据保存操作
	if (struSetupParam.byAlarmInfoType == 1)
	{
		int i = 0;
		for (i = 0; i < struITSPlateResult->dwPicNum; i++)
		{
			if (i >= sizeof(struITSPlateResult->struPicInfo) / sizeof(struITSPlateResult->struPicInfo[0])) {
				break;
			}
			//printf("车牌号: %s\n", struITSPlateResult->struPlateInfo.sLicense);//车牌号
			m_card.SetWindowTextA(struITSPlateResult->struPlateInfo.sLicense);

			switch (struITSPlateResult->struPlateInfo.byColor)//车牌颜色
			{
			case VCA_BLUE_PLATE:
				printf("车辆颜色: 蓝色\n");
				break;
			case VCA_YELLOW_PLATE:
				printf("车辆颜色: 黄色\n");
				break;
			case VCA_WHITE_PLATE:
				printf("车辆颜色: 白色\n");
				break;
			case VCA_BLACK_PLATE:
				printf("车辆颜色: 黑色\n");
				break;
			default:
				break;
			}

			//保存场景图
			if ((struITSPlateResult->struPicInfo[i].dwDataLen != 0) && (struITSPlateResult->struPicInfo[i].byType == 1) || (struITSPlateResult->struPicInfo[i].byType == 2))
			{
				if (struITSPlateResult->struPicInfo[i].pBuffer != NULL) {
					sprintf(filename, "testITSpic%d_%d.jpg", iNum, i);
					fSnapPic = fopen(filename, "wb");

					fwrite(struITSPlateResult->struPicInfo[i].pBuffer, struITSPlateResult->struPicInfo[i].dwDataLen, 1, fSnapPic);
					
					iNum++;

					fclose(fSnapPic);

					ShowImage(filename, 1);
				}			

			}
			//车牌小图片
			if ((struITSPlateResult->struPicInfo[i].dwDataLen != 0) && (struITSPlateResult->struPicInfo[i].byType == 0))
			{

				if (struITSPlateResult->struPicInfo[i].pBuffer != NULL)
				{
					sprintf(filename, "testPicPlate%d_%d.jpg", iNum, i);
					fSnapPicPlate = fopen(filename, "wb");
					fwrite(struITSPlateResult->struPicInfo[i].pBuffer, struITSPlateResult->struPicInfo[i].dwDataLen, 1, fSnapPicPlate);
					iNum++;
					fclose(fSnapPicPlate);
					ShowImage(filename, 0);
				}

			}
			//其他信息处理......
		}
		// 释放内存
		//delete[] struITSPlateResult;

	}
	return 0;
}
void CHKMFCcardDlg::ShowImage(const CString& filename, int type)
{

	float cx, cy, dx, dy, k, t;//跟控件的宽和高以及图片宽和高有关的参数
	CRect   rect;//用于获取图片控件的宽和高
	CImage q;//为cimage图片类创建一个对象
	q.Load(filename);//构造函数的形参是所加载图片的路径 
	cx = q.GetWidth();
	cy = q.GetHeight();//获取图片的宽 高
	k = cy / cx;//获得图片的宽高比

	CWnd *pWnd = NULL;
	if (type == 1)
	{
		pWnd = GetDlgItem(IDC_BigPic);//获取控件句柄
	}
	else
	{
		pWnd = GetDlgItem(IDC_SmallPic);//获取控件句柄
	}
	
	pWnd->GetClientRect(&rect);//获取Picture Control控件的客户区
	dx = rect.Width();
	dy = rect.Height();//获得控件的宽高比
	t = dy / dx;//获得控件的宽高比
	if (k >= t)
	{

		rect.right = floor(rect.bottom / k);
		rect.left = (dx - rect.right) / 2;
		rect.right = floor(rect.bottom / k) + (dx - rect.right) / 2;
	}
	else
	{
		rect.bottom = floor(k*rect.right);
		rect.top = (dy - rect.bottom) / 2;
		rect.bottom = floor(k*rect.right) + (dy - rect.bottom) / 2;
	}

	CDC *pDc = NULL;
	pDc = pWnd->GetDC();//获取picture control的DC
	int ModeOld = SetStretchBltMode(pDc->m_hDC, STRETCH_HALFTONE);//设置指定设备环境中的位图拉伸模式

	//GetDlgItem(IDC_BigPic)->ShowWindow(FALSE);
	//GetDlgItem(IDC_BigPic)->ShowWindow(TRUE);
	GetDlgItem(IDC_SmallPic)->ShowWindow(FALSE);
	GetDlgItem(IDC_SmallPic)->ShowWindow(TRUE);
	q.StretchBlt(pDc->m_hDC, rect, SRCCOPY);//显示函数
	SetStretchBltMode(pDc->m_hDC, ModeOld);
	ReleaseDC(pDc);//释放指针空间
}

四、源代码

HKMCcard.h


// HKMFCcard.h : PROJECT_NAME 应用程序的主头文件
//

#pragma once

#ifndef __AFXWIN_H__
	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif

#include "resource.h"		// 主符号
#include "HCNetSDK.h"

#define WM_SAVE_DATA (WM_USER + 100)   //自定义消息


// CHKMFCcardApp: 
// 有关此类的实现,请参阅 HKMFCcard.cpp
//

class CHKMFCcardApp : public CWinApp
{
public:
	CHKMFCcardApp();

// 重写
public:
	virtual BOOL InitInstance();

// 实现

	DECLARE_MESSAGE_MAP()
};

extern CHKMFCcardApp theApp;

HKMCcard.cpp


// HKMFCcard.cpp : 定义应用程序的类行为。
//

#include "stdafx.h"
#include "HKMFCcard.h"
#include "HKMFCcardDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CHKMFCcardApp

BEGIN_MESSAGE_MAP(CHKMFCcardApp, CWinApp)
	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()


// CHKMFCcardApp 构造

CHKMFCcardApp::CHKMFCcardApp()
{
	// 支持重新启动管理器
	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;

	// TODO:  在此处添加构造代码,
	// 将所有重要的初始化放置在 InitInstance 中
}


// 唯一的一个 CHKMFCcardApp 对象

CHKMFCcardApp theApp;


// CHKMFCcardApp 初始化

BOOL CHKMFCcardApp::InitInstance()
{
	// 如果一个运行在 Windows XP 上的应用程序清单指定要
	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
	//则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// 将它设置为包括所有要在应用程序中使用的
	// 公共控件类。
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();


	AfxEnableControlContainer();

	// 创建 shell 管理器,以防对话框包含
	// 任何 shell 树视图控件或 shell 列表视图控件。
	CShellManager *pShellManager = new CShellManager;

	// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

	// 标准初始化
	// 如果未使用这些功能并希望减小
	// 最终可执行文件的大小,则应移除下列
	// 不需要的特定初始化例程
	// 更改用于存储设置的注册表项
	// TODO:  应适当修改该字符串,
	// 例如修改为公司或组织名
	SetRegistryKey(_T("山东力山特智能科技股份有限公司"));

	NET_DVR_Init();  // init DVR
	CHKMFCcardDlg dlg;
	m_pMainWnd = &dlg;
	INT_PTR nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO:  在此放置处理何时用
		//  “确定”来关闭对话框的代码
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO:  在此放置处理何时用
		//  “取消”来关闭对话框的代码
	}
	else if (nResponse == -1)
	{
		TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
		TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
	}

	// 删除上面创建的 shell 管理器。
	if (pShellManager != NULL)
	{
		delete pShellManager;
	}

	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
	//  而不是启动应用程序的消息泵。
	return FALSE;
}


HKMFCcardDlg.h


// HKMFCcardDlg.h : 头文件
//

#pragma once
#include "afxwin.h"
#include "afxcmn.h"

// CHKMFCcardDlg 对话框
class CHKMFCcardDlg : public CDialogEx
{
// 构造
public:
	CHKMFCcardDlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum { IDD = IDD_HKMFCCARD_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;
	void ShowImage(const CString& filename, int type);

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg LRESULT OnSaveData(WPARAM wParam, LPARAM lParam);

	DECLARE_MESSAGE_MAP()
public:

	afx_msg void OnBnClickedButton1();

	CStatic m_textLogin;
	CStatic m_textBufang;
	CStatic m_bigPic;
	CStatic m_smallPic;
	CStatic m_card;
};

HMFCcardDlg.cpp


// HKMFCcardDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "HKMFCcard.h"
#include "HKMFCcardDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

int iNum = 0;
NET_DVR_SETUPALARM_PARAM struSetupParam = { 0 };
void CALLBACK cbMessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
{
	
#if 1	
	HWND hWnd = FindWindow(NULL, _T("车牌号识别系统"));
	//以下代码仅供参考,实际应用中不建议在该回调函数中直接处理数据保存文件,
	//例如可以使用消息的方式(PostMessage)在消息响应函数里进行处理。

	switch (lCommand)
	{
	case COMM_UPLOAD_PLATE_RESULT:
	{
		//NET_DVR_PLATE_RESULT struPlateResult = { 0 };
		//memcpy(&struPlateResult, pAlarmInfo, sizeof(struPlateResult));
		NET_DVR_PLATE_RESULT *struPlateResult = { 0 };
		memcpy(struPlateResult, pAlarmInfo, sizeof(*struPlateResult));

	
		if (hWnd != NULL)
		{
			SendMessage(hWnd, WM_SAVE_DATA, (WPARAM)((void *)struPlateResult), 0);
		}
		
		break;
	}
	case COMM_ITS_PLATE_RESULT:
	{
		NET_ITS_PLATE_RESULT struITSPlateResult = { 0 };
		memcpy(&struITSPlateResult, pAlarmInfo, sizeof(struITSPlateResult));


		if (/*AfxGetMainWnd()->m_hWnd*/hWnd != NULL)
		{
			SendMessage(hWnd, WM_SAVE_DATA, (WPARAM)(&struITSPlateResult), 0);
		}
		break;
	}
	default:
		break;
	}
#else
int i = 0;
char filename[100];
FILE *fSnapPic = NULL;
FILE *fSnapPicPlate = NULL;

//以下代码仅供参考,实际应用中不建议在该回调函数中直接处理数据保存文件,
//例如可以使用消息的方式(PostMessage)在消息响应函数里进行处理。

switch (lCommand)
{
case COMM_UPLOAD_PLATE_RESULT:
{
	NET_DVR_PLATE_RESULT struPlateResult = { 0 };
	memcpy(&struPlateResult, pAlarmInfo, sizeof(struPlateResult));
	printf("车牌号: %s\n", struPlateResult.struPlateInfo.sLicense);//车牌号

	switch (struPlateResult.struPlateInfo.byColor)//车牌颜色
	{
	case VCA_BLUE_PLATE:
		printf("车辆颜色: 蓝色\n");
		break;
	case VCA_YELLOW_PLATE:
		printf("车辆颜色: 黄色\n");
		break;
	case VCA_WHITE_PLATE:
		printf("车辆颜色: 白色\n");
		break;
	case VCA_BLACK_PLATE:
		printf("车辆颜色: 黑色\n");
		break;
	default:
		break;
	}

	//场景图
	if (struPlateResult.dwPicLen != 0 && struPlateResult.byResultType == 1)
	{
		sprintf(filename, "testpic_%d.jpg", iNum);
		fSnapPic = fopen(filename, "wb");
		fwrite(struPlateResult.pBuffer1, struPlateResult.dwPicLen, 1, fSnapPic);
		iNum++;
		fclose(fSnapPic);
	}
	//车牌图
	if (struPlateResult.dwPicPlateLen != 0 && struPlateResult.byResultType == 1)
	{
		sprintf(filename, "testPicPlate_%d.jpg", iNum);
		fSnapPicPlate = fopen(filename, "wb");
		fwrite(struPlateResult.pBuffer1, struPlateResult.dwPicLen, 1, fSnapPicPlate);
		iNum++;
		fclose(fSnapPicPlate);
	}

	//其他信息处理......
	break;
}
case COMM_ITS_PLATE_RESULT:
{
	NET_ITS_PLATE_RESULT struITSPlateResult = { 0 };
	memcpy(&struITSPlateResult, pAlarmInfo, sizeof(struITSPlateResult));

	for (i = 0; i < struITSPlateResult.dwPicNum; i++)
	{
		printf("车牌号: %s\n", struITSPlateResult.struPlateInfo.sLicense);//车牌号

		switch (struITSPlateResult.struPlateInfo.byColor)//车牌颜色
		{
		case VCA_BLUE_PLATE:
			printf("车辆颜色: 蓝色\n");
			break;
		case VCA_YELLOW_PLATE:
			printf("车辆颜色: 黄色\n");
			break;
		case VCA_WHITE_PLATE:
			printf("车辆颜色: 白色\n");
			break;
		case VCA_BLACK_PLATE:
			printf("车辆颜色: 黑色\n");
			break;
		default:
			break;
		}

		//保存场景图
		if ((struITSPlateResult.struPicInfo[i].dwDataLen != 0) && (struITSPlateResult.struPicInfo[i].byType == 1) || (struITSPlateResult.struPicInfo[i].byType == 2))
		{
			sprintf(filename, "testITSpic%d_%d.jpg", iNum, i);
			fSnapPic = fopen(filename, "wb");
			fwrite(struITSPlateResult.struPicInfo[i].pBuffer, struITSPlateResult.struPicInfo[i].dwDataLen, 1, fSnapPic);
			iNum++;
			fclose(fSnapPic);
		}
		//车牌小图片
		if ((struITSPlateResult.struPicInfo[i].dwDataLen != 0) && (struITSPlateResult.struPicInfo[i].byType == 0))
		{
			sprintf(filename, "testPicPlate%d_%d.jpg", iNum, i);
			fSnapPicPlate = fopen(filename, "wb");
			fwrite(struITSPlateResult.struPicInfo[i].pBuffer, struITSPlateResult.struPicInfo[i].dwDataLen, 1, fSnapPicPlate);
			iNum++;
			fclose(fSnapPicPlate);
		}
		//其他信息处理......
	}
	break;
}
default:
	break;
}

return;

#endif
	return;
}

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
	
END_MESSAGE_MAP()


// CHKMFCcardDlg 对话框


CHKMFCcardDlg::CHKMFCcardDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CHKMFCcardDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	
}

void CHKMFCcardDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LOGIN, m_textLogin);
	DDX_Control(pDX, IDC_BUFANG, m_textBufang);
	DDX_Control(pDX, IDC_BigPic, m_bigPic);
	DDX_Control(pDX, IDC_SmallPic, m_smallPic);
	DDX_Control(pDX, IDC_CARD, m_card);
}

BEGIN_MESSAGE_MAP(CHKMFCcardDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_MESSAGE(WM_SAVE_DATA, &CHKMFCcardDlg::OnSaveData)
	ON_BN_CLICKED(IDC_BUTTON1, &CHKMFCcardDlg::OnBnClickedButton1)
END_MESSAGE_MAP()


// CHKMFCcardDlg 消息处理程序

BOOL CHKMFCcardDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO:  在此添加额外的初始化代码
	m_textLogin.SetWindowTextA("登录无状态");
	m_textBufang.SetWindowTextA("布防无状态");
	
	//---------------------------------------
	//注册设备

	//登录参数,包括设备地址、登录用户、密码等
	LONG lUserID = -1;
	NET_DVR_USER_LOGIN_INFO struLoginInfo = { 0 };
	struLoginInfo.bUseAsynLogin = 0; //同步登录方式
	strcpy(struLoginInfo.sDeviceAddress, "192.168.1.64"); //设备IP地址
	struLoginInfo.wPort = 8000; //设备服务端口
	strcpy(struLoginInfo.sUserName, "admin"); //设备登录用户名
	strcpy(struLoginInfo.sPassword, "lst686868"); //设备登录密码

	//设备信息, 输出参数
	NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = { 0 };

	lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
	if (lUserID < 0)
	{
		/*printf("Login failed, error code: %d\n", NET_DVR_GetLastError());*/
		m_textLogin.SetWindowTextA("登录失败");
		NET_DVR_Cleanup();
		return 0;  
	}
		m_textLogin.SetWindowTextA("登录成功");

	//---------------------------------------
	//报警布防

	//设置报警回调函数
	/*注:多台设备对接时也只需要调用一次设置一个回调函数,不支持不同设备的事件在不同的回调函数里面返回*/
	NET_DVR_SetDVRMessageCallBack_V50(0, cbMessageCallback, NULL);

	//启用布防
	
	struSetupParam.dwSize = sizeof(NET_DVR_SETUPALARM_PARAM);
	struSetupParam.byLevel = 1; //布防优先级:0- 一等级(高),1- 二等级(中)   
	struSetupParam.byAlarmInfoType = 1; //上传报警信息类型: 0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)

	LONG lHandle = NET_DVR_SetupAlarmChan_V41(lUserID, &struSetupParam);
	if (lHandle < 0)
	{
		//printf("NET_DVR_SetupAlarmChan_V41 failed, error code: %d\n", NET_DVR_GetLastError());
		m_textBufang.SetWindowTextA("布防失败");
		NET_DVR_Logout(lUserID);
		NET_DVR_Cleanup();
		return 0;
	}
	m_textBufang.SetWindowTextA("布防成功");
	

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CHKMFCcardDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CHKMFCcardDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		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;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}

}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CHKMFCcardDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CHKMFCcardDlg::OnBnClickedButton1()
{

}



//数据的存储与显示
LRESULT CHKMFCcardDlg::OnSaveData(WPARAM wParam, LPARAM lParam)
{
	// 在这里处理数据保存操作
	// 例如,将 lParam 解释为指向数据的指针
	char filename[100];
	FILE *fSnapPic = NULL;
	FILE *fSnapPicPlate = NULL;

	//NET_ITS_PLATE_RESULT* struITSPlateResult = reinterpret_cast<NET_ITS_PLATE_RESULT*>(lParam);
	NET_ITS_PLATE_RESULT* struITSPlateResult = (NET_ITS_PLATE_RESULT*)(wParam);
	//NET_ITS_PLATE_RESULT struITSPlateResult = wParam;
	// 进行数据保存操作
	if (struSetupParam.byAlarmInfoType == 1)
	{
		int i = 0;
		for (i = 0; i < struITSPlateResult->dwPicNum; i++)
		{
			if (i >= sizeof(struITSPlateResult->struPicInfo) / sizeof(struITSPlateResult->struPicInfo[0])) {
				break;
			}
			//printf("车牌号: %s\n", struITSPlateResult->struPlateInfo.sLicense);//车牌号
			m_card.SetWindowTextA(struITSPlateResult->struPlateInfo.sLicense);

			switch (struITSPlateResult->struPlateInfo.byColor)//车牌颜色
			{
			case VCA_BLUE_PLATE:
				printf("车辆颜色: 蓝色\n");
				break;
			case VCA_YELLOW_PLATE:
				printf("车辆颜色: 黄色\n");
				break;
			case VCA_WHITE_PLATE:
				printf("车辆颜色: 白色\n");
				break;
			case VCA_BLACK_PLATE:
				printf("车辆颜色: 黑色\n");
				break;
			default:
				break;
			}

			//保存场景图
			if ((struITSPlateResult->struPicInfo[i].dwDataLen != 0) && (struITSPlateResult->struPicInfo[i].byType == 1) || (struITSPlateResult->struPicInfo[i].byType == 2))
			{
				if (struITSPlateResult->struPicInfo[i].pBuffer != NULL) {
					sprintf(filename, "testITSpic%d_%d.jpg", iNum, i);
					fSnapPic = fopen(filename, "wb");

					fwrite(struITSPlateResult->struPicInfo[i].pBuffer, struITSPlateResult->struPicInfo[i].dwDataLen, 1, fSnapPic);
					
					iNum++;

					fclose(fSnapPic);

					ShowImage(filename, 1);
				}			

			}
			//车牌小图片
			if ((struITSPlateResult->struPicInfo[i].dwDataLen != 0) && (struITSPlateResult->struPicInfo[i].byType == 0))
			{

				if (struITSPlateResult->struPicInfo[i].pBuffer != NULL)
				{
					sprintf(filename, "testPicPlate%d_%d.jpg", iNum, i);
					fSnapPicPlate = fopen(filename, "wb");
					fwrite(struITSPlateResult->struPicInfo[i].pBuffer, struITSPlateResult->struPicInfo[i].dwDataLen, 1, fSnapPicPlate);
					iNum++;
					fclose(fSnapPicPlate);
					ShowImage(filename, 0);
				}

			}
			//其他信息处理......
		}
		// 释放内存
		//delete[] struITSPlateResult;

	}
	return 0;
}


void CHKMFCcardDlg::ShowImage(const CString& filename, int type)
{

	float cx, cy, dx, dy, k, t;//跟控件的宽和高以及图片宽和高有关的参数
	CRect   rect;//用于获取图片控件的宽和高
	CImage q;//为cimage图片类创建一个对象
	q.Load(filename);//构造函数的形参是所加载图片的路径 
	cx = q.GetWidth();
	cy = q.GetHeight();//获取图片的宽 高
	k = cy / cx;//获得图片的宽高比

	CWnd *pWnd = NULL;
	if (type == 1)
	{
		pWnd = GetDlgItem(IDC_BigPic);//获取控件句柄
	}
	else
	{
		pWnd = GetDlgItem(IDC_SmallPic);//获取控件句柄
	}
	
	pWnd->GetClientRect(&rect);//获取Picture Control控件的客户区
	dx = rect.Width();
	dy = rect.Height();//获得控件的宽高比
	t = dy / dx;//获得控件的宽高比
	if (k >= t)
	{

		rect.right = floor(rect.bottom / k);
		rect.left = (dx - rect.right) / 2;
		rect.right = floor(rect.bottom / k) + (dx - rect.right) / 2;
	}
	else
	{
		rect.bottom = floor(k*rect.right);
		rect.top = (dy - rect.bottom) / 2;
		rect.bottom = floor(k*rect.right) + (dy - rect.bottom) / 2;
	}

	CDC *pDc = NULL;
	pDc = pWnd->GetDC();//获取picture control的DC
	int ModeOld = SetStretchBltMode(pDc->m_hDC, STRETCH_HALFTONE);//设置指定设备环境中的位图拉伸模式

	//GetDlgItem(IDC_BigPic)->ShowWindow(FALSE);
	//GetDlgItem(IDC_BigPic)->ShowWindow(TRUE);
	GetDlgItem(IDC_SmallPic)->ShowWindow(FALSE);
	GetDlgItem(IDC_SmallPic)->ShowWindow(TRUE);
	q.StretchBlt(pDc->m_hDC, rect, SRCCOPY);//显示函数
	SetStretchBltMode(pDc->m_hDC, ModeOld);
	ReleaseDC(pDc);//释放指针空间
}

五、改进

1.添加用户管理
2.历史记录,数据库中添加图片字段,点击查看
3.实时记录
4.用户的操作记录
5.图片备份,时间久了存到备份盘中
6.添加录入数据库中没有的车牌号
7.添加车牌号对比之后自动开关门
8.接受库管传来的车辆信息
9.将车牌信息传递给库管

posted on 2024-10-15 16:08  ZanderChan  阅读(2247)  评论(1)    收藏  举报

导航