?? childfrm.cpp
字號:
// ChildFrm.cpp : implementation of the CChildFrame class
//
#include "stdafx.h"
#include "Multicard.h"
#include "ChildFrm.h"
#include "PropertyDlg.h"
#include "ConfigDlg.h"
#include "LogoDlg.h"
#include "ShowStreamDlg.h"
#include "FourwayDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
typedef struct tagSTREAMNOTIFYPARAME
{
int iDlgCount;
CShowStreamDlg * pDlgArray;
} STREAMNOTIFYPARAME;
//數據流回調函數
void __stdcall StreamNotify(const BYTE* pDIBHead, const BYTE* pDIBits, LPVOID pParam)
{
STREAMNOTIFYPARAME * pSNP = (STREAMNOTIFYPARAME *) pParam;
if(!pSNP || !pDIBHead || !pDIBits)
return;
BITMAPINFO *curHead=(BITMAPINFO*)pDIBHead;
int wth=curHead->bmiHeader.biWidth;
int hgt=curHead->bmiHeader.biHeight;
int fmsz=curHead->bmiHeader.biSizeImage;
//BYTE *pLastFrame=new BYTE[wth*hgt*bts/8];
// memcpy(plastFrame,pDIBits,wth*hgt*bts/8);
//HGLOBAL HNDL=GlobalHandle(pDIBits);
//只有當前已經處理過了,才能將上一覆蓋
//pLastFrame 應為全局變量,有待完成
///for(int i=0;i)
pSNP->pDlgArray[0].DisplayGrayImage((BITMAPINFO*)pDIBHead,pDIBits);
/* for(int i=0;i<4;i++)
pSNP->pDlgArray[i].GrayShow((BITMAPINFO*)pDIBHead,pDIBits);//,fmsz,pSNP);
*/
//memcpy(pLastFrame,pDIBits,wth*hgt*bts/8);
//不在這里進行兩幀的轉換,應該在ProcessImage中,為Cshowstreamdlg的全局兩
// pSNP->pDlgArray[0].ShowStream((BITMAPINFO*)pDIBHead,pFrame2Dsp);
// delete [] pLastFrame;
}
/////////////////////////////////////////////////////////////////////////////
// CChildFrame
IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)
BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
//{{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)
//}}AFX_MSG_MAP
ON_MESSAGE(UM_VIDEO_ERROR_NOTIFY, OnVideoErrorNotify)
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( !CMDIChildWnd::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
{
CMDIChildWnd::AssertValid();
}
void CChildFrame::Dump(CDumpContext& dc) const
{
CMDIChildWnd::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 (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
return -1;
for(int i=0; i<4; i++)
m_ShowStreamDlg[i].Create(IDD_SHOWSTREAM, this);
return 0;
}
void CChildFrame::OnSize(UINT nType, int cx, int cy)
{
CMDIChildWnd::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);
}
//顯示對話框,枚舉各項屬性
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::OnVideoErrorNotify(WPARAM wparam, LPARAM lparam)
{
DSStreamError errorCode = (DSStreamError) (lparam & 0x0000FFFFL);
int iCardID = (lparam>>16) & 0x0000FFFFL;
char szErrorInfo[300];
switch(errorCode)
{
case Error_FirstNotifyMsg: //收到這個錯誤,必須調用 DSStream_ManageNotifyMessage()
DSStream_ManageNotifyMessage(iCardID);
break;
case Error_DiskFull:
sprintf(szErrorInfo, "%d號卡", iCardID);
MessageBox("磁盤已滿,按“確定”停止錄像", szErrorInfo);
SendMessage(WM_COMMAND, ID_STOPCAPTURE);
break;
case Error_VideoSizeChange:
sprintf(szErrorInfo, "%d號卡:%d x %d", iCardID, LOWORD(wparam), HIWORD(wparam));
SetWindowText(szErrorInfo);
break;
case Error_StreamStatusChange:
//視頻流狀態改變。不過,無法獲得“停止”狀態 ^_^
break;
case Error_CaptureError:
sprintf(szErrorInfo, "%d號卡錄像異常:0x%08X \n 按“確定”停止錄像",
iCardID, wparam);
MessageBox(szErrorInfo);
SendMessage(WM_COMMAND, ID_STOPCAPTURE);
break;
default:
break;
}
}
//開始數據流回調
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);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -