Files
SimpleRemoter/server/2015Remote/VideoDlg.cpp
yuanyuanxiang 79903cbdff 彻底修复多次打开文件管理窗口崩溃的缺陷
1、在主对话框清理子窗口的资源(原先在各自的OnClose函数),通过CLOSE_DELETE_DLG控制。

2、修正CFileManagerDlg的构造函数调用SHGetFileInfo和FromHandle方法,解决多次打开崩溃。

3、更新服务端zlib版本为V1.2.11。(与客户端不同,因inflate_fast 崩溃,没有采用汇编)
2019-01-13 13:13:59 +08:00

247 lines
5.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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
);
}