📄 childview.cpp
字号:
// ChildView.cpp : implementation of the CChildView class
//
#include "stdafx.h"
#include "VideoNet2.h"
#include "ChildView.h"
#include "Mainfrm.h"
#include "DialogConnect.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static long reccount = 0l;
/////////////////////////////////////////////////////////////////////////////
// CChildView
unsigned char rgbdata[IMAGE_WIDTH*IMAGE_HEIGHT*3];
int buffersize=IMAGE_WIDTH*IMAGE_HEIGHT*3;
CChildView::CChildView()
{
_bStart = false; //会议启动标志
m_bFull = false; //全屏标志
InitH263Decoder(); // c初始化视频解码器
_bmpinfo=(BITMAPINFO*)(new char[sizeof(BITMAPINFOHEADER)]);
_bmpinfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
_bmpinfo->bmiHeader.biWidth=vertical_size;
_bmpinfo->bmiHeader.biHeight=vertical_size;
_bmpinfo->bmiHeader.biPlanes=1;
_bmpinfo->bmiHeader.biBitCount=24;
_bmpinfo->bmiHeader.biCompression=BI_RGB;
_bmpinfo->bmiHeader.biSizeImage=0;
_bmpinfo->bmiHeader.biClrUsed=0;
}
CChildView::~CChildView()
{
}
// zmzhu 20070830
IMPLEMENT_DYNAMIC(CChildView, CWnd)
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_COMMAND(ID_CON_CONNECT, OnConConnect)
ON_COMMAND(ID_CON_DISCONNECT, OnConDisconnect)
ON_COMMAND(ID_CON_FULLSCREEN, OnConFullscreen)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChildView message handlers
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
NULL, HBRUSH(COLOR_WINDOW+1), NULL);
return TRUE;
}
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
if (!_bStart)
{
CDC* pDisplayMemDC ;
CBitmap* pBitmap ;
CBitmap* pOldBitmap ;
pDisplayMemDC = new CDC ;
pBitmap = new CBitmap ;
_pDrawDC = GetDC(); //GetDC(hwnd)--获取所指窗口的Device Context句柄,
//若hwnd==NULL时,则取得整个屏幕的Device Context句柄。
pBitmap->LoadBitmap(IDB_BITMAP2); //装入一副位图
pDisplayMemDC->CreateCompatibleDC(_pDrawDC);
pOldBitmap = (CBitmap*)pDisplayMemDC->SelectObject(pBitmap) ;
_pDrawDC->BitBlt(0,0,240,320,pDisplayMemDC,0,0,SRCCOPY) ;
pDisplayMemDC->SelectObject(pOldBitmap) ;
delete pBitmap;
delete pDisplayMemDC ;
}
// Do not call CWnd::OnPaint() for painting messages
}
// 会议连接
void CChildView::OnConConnect()
{
if (_bStart) //如果会议启动了则断开
OnConDisconnect();
CDialogConnect dlg;
dlg.m_strIp = _T("10.27.0.81");
if (dlg.DoModal() == IDOK) //弹出连接对话框
{
if (_sVideo != NULL) //如果视频Socket不指向空,则关闭之。
closesocket(_sVideo);
_sVideo = socket(AF_INET, SOCK_DGRAM, 0);
/**** 注:sockaddr_in 的定义如下:
struct socket_in{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8]; }
*/
sockaddr_in addr; //定义socket地址变量 addr 并清空它。
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET; //必须是 AF_INET
addr.sin_port = htons(PORT_VIDEO); //IP端口号
addr.sin_addr.s_addr = INADDR_ANY; //
if (bind(_sVideo, (sockaddr*)&addr, sizeof(addr)) != 0)
{
::MessageBox(NULL,_T("不能产生视频socket!"),_T("Message"),MB_OK);
return;
}
_hVideo = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadVideo, (void*)this, 0, &_threadId);
if (_hVideo == NULL)
{
::MessageBox(NULL,_T("不能产生接收线程!"),_T("Message"),MB_OK);
return;
}
_skSend.remoteaddress = dlg.m_strIp; //
_skSend.CreateSocket(PORT_CONTROL,TYPE_CONTROL);
if (dlg.n_type == 0) //176x144 //为什么要发三次?
{
_skSend.SendControlMessage(MESG1_CONNECT,NULL);
// _skSend.SendControlMessage(MESG1_CONNECT,NULL);
// _skSend.SendControlMessage(MESG1_CONNECT,NULL);
}else if (dlg.n_type == 1) //320x240 //为什么要发三次?
{
_skSend.SendControlMessage(MESG2_CONNECT,NULL);
// _skSend.SendControlMessage(MESG2_CONNECT,NULL);
// _skSend.SendControlMessage(MESG2_CONNECT,NULL);
}
_bStart = true;
Invalidate();
UpdateWindow();
}
}
// 会议断开
void CChildView::OnConDisconnect()
{
if (!_bStart) //会议启动了吗?未启动则直接返回!
return;
_bStart = false; //
TerminateThread(_hVideo, 0);
_hVideo = NULL;
_skSend.CloseSocket();
closesocket(_sVideo);
// Invalidate window so entire client area
// is redrawn when UpdateWindow is called.
Invalidate();
// Update Window to cause View to redraw.
UpdateWindow();
}
// 接收视频线程
DWORD WINAPI CChildView::threadVideo(void* param)
{
CChildView* parent = (CChildView*)param;
SOCKET s = parent->_sVideo;
unsigned char* vdata = new unsigned char[20000];
unsigned int vlength = 20000;
sockaddr address;
int addlen = sizeof(address);
while (1)
{
int retvalue = recvfrom(s, (char*)vdata, vlength,0, &address, &addlen);
Sleep(100);
continue;
if(retvalue==SOCKET_ERROR)
{
::MessageBox(NULL,_T("SOCKET_ERROR"),NULL,MB_OK);
return 1;
}
if(retvalue==0)
{
::MessageBox(NULL,_T("Server cann't be connected"),_T("Message"),MB_OK);
return 1;
}
parent->DisplayRemoteFrame(vdata,retvalue);
}
// 记录接受到的帧计数
reccount++;
printf("\n reccount = %d ",reccount);
delete[] vdata;
return 0;
}
// 显示视频函数
void CChildView::DisplayRemoteFrame(unsigned char *data,int size)
{
int retvalue;
if(!_bStart)
return;
retvalue=DecompressFrame(m_bFull, data,size,rgbdata,buffersize); //视频解码
if(!retvalue)
return;
DisplayBt(rgbdata); //显示
}
void CChildView::DisplayBt(unsigned char *data)
{
CDC* pDisplayMemDC ;
CBitmap* pBitmap ;
CBitmap* pOldBitmap ;
pDisplayMemDC = new CDC ;
pBitmap = new CBitmap ;
PVOID pBits;
static int old_size = 0;
if (old_size != vertical_size)
{
old_size = vertical_size;
Invalidate();
UpdateWindow();
}
if (m_bFull)
{
_bmpinfo->bmiHeader.biWidth=vertical_size;
_bmpinfo->bmiHeader.biHeight=horizontal_size;
}
else
{
_bmpinfo->bmiHeader.biWidth=horizontal_size;
_bmpinfo->bmiHeader.biHeight=vertical_size;
}
HBITMAP hBitmap=CreateDIBSection(_pDrawDC->GetSafeHdc(),
_bmpinfo,DIB_RGB_COLORS, (void**)&pBits,NULL,0);
memcpy(pBits, rgbdata, horizontal_size*vertical_size*3);
pBitmap->Attach(hBitmap);
//_pDrawDC = AfxGetMainWnd()->GetWindowDC();
_pDrawDC = GetWindowDC();
pDisplayMemDC->CreateCompatibleDC(_pDrawDC);
pOldBitmap = (CBitmap*)pDisplayMemDC->SelectObject(pBitmap) ;
if (!m_bFull)
{
if ((horizontal_size ==176)&&(vertical_size ==144))
{
_pDrawDC->BitBlt(30, 40,176,144,pDisplayMemDC,0,0,SRCCOPY);
}
else if ((horizontal_size ==320)&&(vertical_size ==240))
{
_pDrawDC->StretchBlt(20,40,200,240,pDisplayMemDC,0,0,vertical_size,horizontal_size,SRCCOPY);
}
}
else
{
_pDrawDC->StretchBlt(0,0,240,320,pDisplayMemDC,0,0,vertical_size,horizontal_size,SRCCOPY);
}
pBitmap = pDisplayMemDC->SelectObject(pOldBitmap) ;
pBitmap->DeleteObject();
pDisplayMemDC->DeleteDC();
_pDrawDC->DeleteDC();
delete pBitmap;
delete pDisplayMemDC;
}
//20080904 zmzhu
///////////////////////////////////////////////////
// 在WINCE 下如何得到屏幕大小?
// GetDeviceCaps
//
// GetDeviceCaps HORZRES/VERTRES
// or
// GetSystemMetrics SM_CXSCREEN, SM_CYSCREEN
//
// 宽
// int nWidth = GetSystemMetrics(SM_CXSCREEN);
// 高
// int nHeight = GetSystemMetrics(SM_CYSCREEN);
////////////////////////////////////////////////////
// mike 20070827
#pragma comment(lib, "Aygshell.lib")
// 全屏显示
void CChildView::OnConFullscreen()
{
// TODO: Add your command handler code here
RECT rc;
GetWindowRect(&rc);
HWND hWnd = AfxGetMainWnd()->GetSafeHwnd();
#ifdef WINCE
SHFullScreen(hWnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);
// ::MoveWindow(hWnd, 0, 0, 240, 320, TRUE); //zmzhu 20080831
::MoveWindow(hWnd, 0, 0, rc.right, rc.bottom, TRUE);
((CMainFrame*)AfxGetMainWnd())->m_wndCommandBar.ShowWindow(FALSE);
#endif
m_bFull = true;
Invalidate();
UpdateWindow();
}
// 全屏显示切换回原状
void CChildView::RestoreWindow()
{
// TODO: Add your command handler code here
m_bFull = false;
RECT rc;
GetWindowRect(&rc);
HWND hWnd = AfxGetMainWnd()->GetSafeHwnd();
#ifdef WINCE
SHFullScreen(hWnd, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON);
// ::MoveWindow(hWnd, 0, 20, 240, 300, TRUE); //zmzhu 20080831
::MoveWindow(hWnd, 0, 20, rc.right, rc.bottom-20, TRUE);
((CMainFrame*)AfxGetMainWnd())->m_wndCommandBar.ShowWindow(TRUE);
#endif
Invalidate();
UpdateWindow();
}
BOOL CChildView::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message == WM_LBUTTONDOWN && m_bFull)
{
RestoreWindow();
}
return CWnd ::PreTranslateMessage(pMsg);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -