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

📄 childfrm.cpp

📁 实时视频捕获
💻 CPP
字号:
// ChildFrm.cpp : implementation of the CChildFrame class
//

#include "stdafx.h"
#include "ChildFrm.h"
#include "resource.h"
#include "imageobject.h"
#include "ImageObjectDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

typedef struct tagSTREAMNOTIFYPARAME
{
	bool IsSetStatu;
	int iDetectNum;
	CRect rtDetectRegion[6];
	
	
} STREAMNOTIFYPARAME;

//数据流回调函数
void __stdcall VideoStreamCallbak(const BYTE* pDIBHead, const BYTE* pDIBits, LPVOID pParam)
{
	static char counter;
	counter++;
//	if(counter>12)
	{
		counter=0;
		if( !pDIBHead || !pDIBits)
			return;

//		CImageObjectDlg* lpDlg = ::afxg;
//		lpDlg->lpcallbakdata=(void *)pDIBits;
/*		for(long i=0;i<((BITMAPINFOHEADER*)pDIBHead)->biSizeImage;i++)
		{
			lpDlg->m_bufferVideo[i]=pDIBits[i];
		}
*/
//		long k=lpDlg->m_bmpMain.SetBitmapBits(((BITMAPINFOHEADER*)pDIBHead)->biSizeImage,(void*)pDIBits);
//		memcpy((lpDlg->m_bufferVideo),pDIBits,((BITMAPINFOHEADER*)pDIBHead)->biSizeImage);

/*		FILE *lpfile=fopen("d:\\callbak.bin", "w");
		fwrite(pDIBits,1,((BITMAPINFOHEADER*)pDIBHead)->biSizeImage,lpfile);
		fclose(lpfile);
 */
/*
		HDC hdc=::GetDC(lpDlg->m_hWnd);//(this);
		HBITMAP hnewbmp=CreateDIBSection(
								hdc ,                 // handle to DC
								(BITMAPINFO*)pDIBHead,  // bitmap data
								 DIB_RGB_COLORS,             // data type indicator
								(void**)&pDIBits,          // bit values
								NULL,         // handle to file mapping object
								0           // offset to bitmap bit values
								);
		lpDlg->m_bmpMain.DeleteObject();
		lpDlg->m_bmpMain.Attach(hnewbmp);
			::ReleaseDC(lpDlg->m_hWnd,hdc);
		::DeleteObject(hnewbmp);
*/
		PostMessageW((HWND)pParam,UM_PROCESS_IMAGE_DATA,(WPARAM)pDIBHead,(LPARAM)pDIBits);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CChildFrame

IMPLEMENT_DYNCREATE(CChildFrame, CWnd)

BEGIN_MESSAGE_MAP(CChildFrame, CWnd)
	//{{AFX_MSG_MAP(CChildFrame)
		ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
		ON_WM_CREATE()
	ON_WM_SIZE()
	ON_COMMAND(ID_NORMALSIZE, OnNormalSize)
/*	ON_COMMAND(ID_PROPERTYDIALOG, OnPropertyDialog)
	ON_COMMAND(ID_CONFIGDIALOG, OnConfigDialog)
	ON_COMMAND(ID_LISTALLFILTER, OnListAllFilter)
	ON_COMMAND(ID_LOGODIALOG, OnLogoDialog)
	ON_COMMAND(ID_SAVEBMP, OnSaveBmp)
	ON_COMMAND(ID_SAVEJPG, OnSaveJpg)
	ON_COMMAND(ID_STARTCAPTURE, OnStartCapture)
	ON_COMMAND(ID_STOPCAPTURE, OnStopCapture)
	ON_UPDATE_COMMAND_UI(ID_STARTCAPTURE, OnUpdateStartCapture)
	ON_UPDATE_COMMAND_UI(ID_STOPCAPTURE, OnUpdateStopCapture)
	ON_COMMAND(ID_CAPTUREAUDIO, OnCaptureAudio)
	ON_UPDATE_COMMAND_UI(ID_CAPTUREAUDIO, OnUpdateCaptureAudio)
	ON_COMMAND(ID_STATE_RUN, OnStateRun)
	ON_UPDATE_COMMAND_UI(ID_STATE_RUN, OnUpdateStateRun)
	ON_COMMAND(ID_STATE_STOP, OnStateStop)
	ON_UPDATE_COMMAND_UI(ID_STATE_STOP, OnUpdateStateStop)
	ON_COMMAND(ID_STATE_PAUSE, OnStatePause)
	ON_UPDATE_COMMAND_UI(ID_STATE_PAUSE, OnUpdateStatePause)
	ON_COMMAND(ID_STARTSHOWSTREAM, OnStartShowStream)
	ON_UPDATE_COMMAND_UI(ID_STARTSHOWSTREAM, OnUpdateStartShowStream)
	ON_COMMAND(ID_STOPSHOWSTREAM, OnStopShowStream)
	ON_UPDATE_COMMAND_UI(ID_STOPSHOWSTREAM, OnUpdateStopShowStream)
	ON_COMMAND(ID_OVERLAY, OnOverlay)
	ON_UPDATE_COMMAND_UI(ID_OVERLAY, OnUpdateOverlay)
	ON_COMMAND(ID_FOURWAYDLG, OnFourwayDlg)
*/	
	ON_MESSAGE(UM_VIDEO_ERROR_NOTIFY, OnVideoErrorNotify)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChildFrame construction/destruction

CChildFrame::CChildFrame()
{
	// TODO: add member initialization code here
	m_iCardID = -1;
	m_bOverlay = FALSE;
}

CChildFrame::~CChildFrame()
{
//======== Add for ver5.2, begin =================
//extern 	bool SaveParame(int);
	//保存卡的当前属性,以备下次连接时重新设回
//	SaveParame(m_iCardID);
//======== Add for ver5.2, end ===================

	//释放对卡的连接
	DSStream_DisconnectDevice(m_iCardID);
}

BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	if( !CWnd::PreCreateWindow(cs) )
		return FALSE;

	cs.style &= ~FWS_ADDTOTITLE;
	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
	cs.lpszClass = AfxRegisterWndClass(0);

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CChildFrame diagnostics

#ifdef _DEBUG
void CChildFrame::AssertValid() const
{
	CWnd::AssertValid();
}

void CChildFrame::Dump(CDumpContext& dc) const
{
	CWnd::Dump(dc);
}

#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CChildFrame message handlers
void CChildFrame::OnFileClose() 
{
	// To close the frame, just send a WM_CLOSE, which is the equivalent
	// choosing close from the system menu.

	SendMessage(WM_CLOSE);
}

int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	return 0;
}

void CChildFrame::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);
	
	//设置视频窗口的位置
	RECT rc;
	GetClientRect(&rc);
	DSStream_SetWindowPos(m_iCardID, rc);
}

//将视频窗口调整为标准大小
void CChildFrame::OnNormalSize() 
{
	VIDEOSTREAMINFO vsi;
	HRESULT hr;
	RECT rcFrame, rcView;
	long w, h;
	long width, height;

	//如果窗口是最大化的,先还原它
	DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);
	if(style & WS_MAXIMIZE)
		ShowWindow(SW_RESTORE);

	hr = DSStream_GetVideoInfo(m_iCardID, &vsi, PREVIEW);
	if(FAILED(hr))
		return;

	GetWindowRect(&rcFrame);
	GetClientRect(&rcView);

	w = (rcFrame.right-rcFrame.left) - (rcView.right-rcView.left);
	h = (rcFrame.bottom-rcFrame.top) - (rcView.bottom-rcView.top);

	width = vsi.bmiHeader.biWidth + w;
	height = vsi.bmiHeader.biHeight + h;

	SetWindowPos(NULL, -1, -1, width, height, SWP_NOZORDER|SWP_NOMOVE);
}
//视频发生错误时的回调消息
HRESULT CChildFrame::OnVideoErrorNotify(WPARAM wparam, LPARAM lparam)
{
/*	DSStreamError errorCode = (DSStreamError) (lparam & 0x0000FFFFL);
	int iCardID = (lparam>>16) & 0x0000FFFFL;
	char szErrorInfo[300];
	CString str;
	switch(errorCode)
	{
		case Error_FirstNotifyMsg: //收到这个错误,必须调用 DSStream_ManageNotifyMessage()
			DSStream_ManageNotifyMessage(iCardID);
			break;
		case Error_DiskFull:
			//sprintf(szErrorInfo, , iCardID);
			
			str.Format(_T("%d号卡"), iCardID);
			MessageBoxW(_T("磁盘已满,按“确定”停止录像"), str);
//			SendMessage(WM_COMMAND, ID_STOPCAPTURE);
			break;
		case Error_VideoSizeChange:
			str.Format(_T("%d号卡:%d x %d"),iCardID, LOWORD(wparam), HIWORD(wparam));
//			sprintf(szErrorInfo, , iCardID, LOWORD(wparam), HIWORD(wparam));
//			SetWindowText(szErrorInfo);
			SetWindowText(str);
			break;
		case Error_StreamStatusChange:
			//视频流状态改变。不过,无法获得“停止”状态 ^_^
			break;
		case Error_CaptureError:
			str.Format(_T("%d号卡录像异常:0x%08X \n 按“确定”停止录像"),iCardID, wparam);
//			sprintf(szErrorInfo, "%d号卡录像异常:0x%08X \n 按“确定”停止录像",	iCardID, wparam);
//			MessageBox(szErrorInfo);
//			SendMessage(WM_COMMAND, ID_STOPCAPTURE);
			SetWindowText(str);
			break;
		default:
			break;
	}
*/
	return 0;
}

/*
//显示对话框,枚举各项属性
void CChildFrame::OnPropertyDialog() 
{
	CPropertyDlg dlg(m_iCardID);
	dlg.DoModal();

//======== Add for ver5.2, begin =================
	if( ::IsWindowVisible(m_ShowStreamDlg[0].m_hWnd) )
	{
		SendMessage(WM_COMMAND, ID_STOPSHOWSTREAM, NULL);
		SendMessage(WM_COMMAND, ID_STARTSHOWSTREAM, NULL);
	}
//======== Add for ver5.2, end ===================
}

//显示对话框,配置视频参数
void CChildFrame::OnConfigDialog() 
{
	CConfigDlg dlg(m_iCardID, this);
	dlg.DoModal();

//======== Add for ver5.2, begin =================
	if( ::IsWindowVisible(m_ShowStreamDlg[0].m_hWnd) )
	{
		SendMessage(WM_COMMAND, ID_STOPSHOWSTREAM, NULL);
		SendMessage(WM_COMMAND, ID_STARTSHOWSTREAM, NULL);
	}
//======== Add for ver5.2, end ===================
}

//显示对话框,配置Logo、Time、Date
void CChildFrame::OnLogoDialog() 
{
	CLogoDlg dlg(m_iCardID);
	dlg.DoModal();
}

//得到Filter信息,输出到文件C:\Filter1.log、Filter2.log... ...
void CChildFrame::OnListAllFilter() 
{
	char szFileName[20];
	sprintf(szFileName, "C:\\Filter%d.log", m_iCardID);
	DSStream_ListAllFilter(m_iCardID, szFileName);
}

//快照:存为bmp格式
void CChildFrame::OnSaveBmp() 
{
	char szFile[20];
	HRESULT hr;

	sprintf(szFile, "C:\\Test_No%d.bmp", m_iCardID);
	hr = DSStream_SaveToBmpFile(m_iCardID, szFile);
	if(FAILED(hr))
		MessageBox("快照失败!");
}

//快照:存为jpg格式
void CChildFrame::OnSaveJpg() 
{
	char szFile[20];
	HRESULT hr;

	sprintf(szFile, "C:\\Test_No%d.jpg", m_iCardID);
	hr = DSStream_SaveToJpgFile(m_iCardID, szFile, 65);//图像质量 0-100
	if(FAILED(hr))
		MessageBox("快照失败!");
}

//开始录像
void CChildFrame::OnStartCapture() 
{
	CMenu *pMainMenu = NULL, *pMenu = NULL;
	char szFile[20];
	BOOL ok;

	sprintf(szFile, "C:\\Test_No%d.avi", m_iCardID);
	DSStream_SetCaptureFile(m_iCardID, szFile);
	DSStream_StartCapture(m_iCardID);
	DSStream_IsCapturing(m_iCardID, &ok);
	if(!ok)
	{
		MessageBox("录像失败!");
		return;
	}
}

//停止录像
void CChildFrame::OnStopCapture() 
{
	BOOL bCapturing;

	DSStream_StopCapture(m_iCardID);
	DSStream_IsCapturing(m_iCardID, &bCapturing);
	if(bCapturing)
	{
		MessageBox("无法停止录像!");
		return;
	}
}

//是否捕捉音频
void CChildFrame::OnCaptureAudio() 
{
	int iAudioState;
	BOOL bCaptureAudio;

	DSStream_WhoIsCapturingAudio(&iAudioState);

	if(iAudioState == AUDIO_DEVICE_NO_EXIST)
		return;
	
	bCaptureAudio = (iAudioState!=m_iCardID);
	DSStream_SetCaptureAudio(m_iCardID, &bCaptureAudio);
}

//RUN
void CChildFrame::OnStateRun() 
{
	DSStream_SetStreamStatus(m_iCardID, RUN);
}

//PAUSE
void CChildFrame::OnStatePause() 
{
	DSStream_SetStreamStatus(m_iCardID, PAUSE);
}

//STOP
void CChildFrame::OnStateStop() 
{
	DSStream_SetStreamStatus(m_iCardID, STOP);
}


//开始数据流回调
void CChildFrame::OnStartShowStream() 
{
	static STREAMNOTIFYPARAME snp;
	snp.pDlgArray = m_ShowStreamDlg;

	if( !IsWindow(m_ShowStreamDlg[0].m_hWnd) )
		return;

	if(Is4WayCard())
	{
		snp.iDlgCount = 4;
		for(int i=0; i<4; i++)
		{
			m_ShowStreamDlg[i].ShowWindow(SW_SHOW);
			m_ShowStreamDlg[i].SetShowWay(m_iCardID, true, i);
		}
	}
	else
	{
		snp.iDlgCount = 1;
		m_ShowStreamDlg[0].ShowWindow(SW_SHOW);
		m_ShowStreamDlg[0].SetShowWay(m_iCardID, false, 0);
	}

	HRESULT hr = DSStream_GetVideoStream(m_iCardID, StreamNotify, &snp);
	if(FAILED(hr))
	{
		MessageBox("开始数据流回调失败!");
		return;
	}
}

//停止数据流回调
void CChildFrame::OnStopShowStream() 
{
	if( !IsWindow(m_ShowStreamDlg[0].m_hWnd) )
		return;

	HRESULT hr = DSStream_GetVideoStream(m_iCardID, NULL, NULL);
	if(FAILED(hr))
	{
		MessageBox("无法停止数据流回调!");
		return;
	}

	for(int i=0; i<4; i++)
		m_ShowStreamDlg[i].ShowWindow(SW_HIDE);
}

//Overlay <===> Preview
void CChildFrame::OnOverlay() 
{
	m_bOverlay = !m_bOverlay;

	RECT rc;
	GetClientRect(&rc);

	//先断开,再连接
	DSStream_DisconnectDevice(m_iCardID);
	HRESULT hr = DSStream_ConnectDevice(m_iCardID, m_bOverlay, m_hWnd);
	if(FAILED(hr))
	{
		MessageBox("连接设备失败!");
		return;
	}

	DSStream_SetWindowPos(m_iCardID, rc);
	DSStream_SetMessageDrain(m_iCardID, m_hWnd);
	DSStream_SetNotifyWindow(m_iCardID, m_hWnd, UM_VIDEO_ERROR_NOTIFY);

	SendMessage(WM_COMMAND, ID_NORMALSIZE);
}

//四路卡特性
void CChildFrame::OnFourwayDlg() 
{
	CFourwayDlg dlg(m_iCardID);
	dlg.DoModal();
}

void CChildFrame::OnUpdateStartCapture(CCmdUI* pCmdUI) 
{
	BOOL bCapturing;
	DSStream_IsCapturing(m_iCardID, &bCapturing);

	pCmdUI->Enable(!bCapturing);
}

void CChildFrame::OnUpdateStopCapture(CCmdUI* pCmdUI) 
{
	BOOL bCapturing;
	DSStream_IsCapturing(m_iCardID, &bCapturing);

	pCmdUI->Enable(bCapturing);
}

void CChildFrame::OnUpdateCaptureAudio(CCmdUI* pCmdUI) 
{
	int iAudioState;
	DSStream_WhoIsCapturingAudio(&iAudioState);

	if(iAudioState == AUDIO_DEVICE_NO_EXIST)
		pCmdUI->Enable(FALSE);
	else if(iAudioState == m_iCardID)
		pCmdUI->SetCheck(1);
	else
		pCmdUI->SetCheck(0);
}

void CChildFrame::OnUpdateStateRun(CCmdUI* pCmdUI) 
{
	int iState;
	HRESULT hr;

	hr = DSStream_GetStreamStatus(m_iCardID, &iState);
	if(SUCCEEDED(hr))
	{
		pCmdUI->SetRadio( iState==RUN );
	}
}

void CChildFrame::OnUpdateStatePause(CCmdUI* pCmdUI) 
{
	int iState;
	HRESULT hr;

	hr = DSStream_GetStreamStatus(m_iCardID, &iState);
	if(SUCCEEDED(hr))
	{
		pCmdUI->SetRadio( iState==PAUSE );
	}
}

void CChildFrame::OnUpdateStateStop(CCmdUI* pCmdUI) 
{
	int iState;
	HRESULT hr;

	hr = DSStream_GetStreamStatus(m_iCardID, &iState);
	if(SUCCEEDED(hr))
	{
		pCmdUI->SetRadio( iState==STOP );
	}
}

void CChildFrame::OnUpdateStartShowStream(CCmdUI* pCmdUI) 
{
	if( !IsWindow(m_ShowStreamDlg[0].m_hWnd) )
		pCmdUI->Enable(FALSE);

	BOOL bShow = m_ShowStreamDlg[0].IsWindowVisible();
	pCmdUI->Enable(!bShow);
}

void CChildFrame::OnUpdateStopShowStream(CCmdUI* pCmdUI) 
{
	if( !IsWindow(m_ShowStreamDlg[0].m_hWnd) )
		pCmdUI->Enable(FALSE);

	BOOL bShow = m_ShowStreamDlg[0].IsWindowVisible();
	pCmdUI->Enable(bShow);
}

void CChildFrame::OnUpdateOverlay(CCmdUI* pCmdUI) 
{
	if(m_bOverlay)
		pCmdUI->SetText("切换到 Preview 模式");
	else
		pCmdUI->SetText("切换到 Overlay 模式");
}

//当前是否处于四路同屏模式
bool CChildFrame::Is4WayCard()
{
	long source = 0;
	DSStream_WhatInPinRouteToOutPin(m_iCardID, 0, &source);
	return (source==4);
}
*/

bool CChildFrame::GetDIBImage(void* lpbuffer)
{
	long size;
//	BYTE *buffer=new BYTE[1244200];
	HRESULT hr = DSStream_GetCurrentDib(m_iCardID,NULL,&size);
	if(SUCCEEDED(hr)&&(size=1244200))
	{
		hr =DSStream_GetCurrentDib(m_iCardID,(BYTE*)lpbuffer,&size);
		if(SUCCEEDED(hr)&&(size=1244200))
		{
			return TRUE;
		}else
		{
			return FALSE;
		}
	}
	
//	CWnd *lpWnd=this->GetOwner();

//	memcpy(lpbuffer,buffer,size);
//	delete []buffer;
//	::PostMessageW(this->m_hWndOwner,UM_PROCESS_IMAGE_DATA,0,0);
	return FALSE;
}

⌨️ 快捷键说明

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