⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 revplaymdichildwnd.cpp

📁 在vc下实现远程视频监控的基本功能的代码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	
	m_FirstRead=FALSE;
	return 0;
}




LRESULT CRevPlayWnd::OnDelegatedCmdMsg(WPARAM, LPARAM lParam)
{
	COnCmdMsg* pOnCmdMsg = (COnCmdMsg*)lParam;
	return CWnd::OnCmdMsg(pOnCmdMsg->m_nID, pOnCmdMsg->m_nCode, pOnCmdMsg->m_pExtra,
		pOnCmdMsg->m_pHandlerInfo);
}

LRESULT CRevPlayWnd::OnPrepareToClose(WPARAM, LPARAM)
{
	
    StopReceive();
	if( stWSABuf.buf)
	{
		delete  stWSABuf.buf;
		stWSABuf.buf=NULL;
	}
	if(achInBuf)
	{
		delete achInBuf;
		achInBuf=NULL;
	}
	DestroyWindow();
	return 0;
}

BOOL CRevPlayWnd::Create(LPCTSTR szTitle, LONG style, const RECT& rect, CWnd* parent)
{
	// Register a custom WndClass and create a window.
	// This must be done because CBounceWnd has a custom cursor, and
	//  no icon.
	LPCTSTR lpszRevPlayClass =
		AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
		LoadCursor(NULL, IDC_UPARROW),
		(HBRUSH)(COLOR_WINDOW+1),
		NULL);
	
	return CWnd::Create(lpszRevPlayClass, szTitle, style, rect, parent,
		IDC_REVPLAY_WND);
}


int CRevPlayWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	int status;
	int sock;
	CConnectDlg ConnectDlg;
	
	stWSABuf.buf = new char[BUFSIZE];
	stWSABuf.len = BUFSIZE;
	achInBuf = new BYTE [BUFSIZE*2];
	
	if(ConnectDlg.DoModal()==IDOK)
	{
		status=Connect(m_hWnd,AddressIp,LISTEN_PORT,sock);
		if(status<0)
			return -1;
	}
	
	return 0;
}

int CRevPlayWnd::Connect(HWND hwnd, const char *Addr, short Port, int &sock)
{
	SOCKADDR_IN send_sin;
	int status;
	//创建一个socket
	sock = socket(AF_INET,SOCK_STREAM,0);
	if (sock == INVALID_SOCKET)
	{
       	MessageBox("Socket Error");
        closesocket(sock);   
		return -1;
	} 
	else
	{
		send_sin.sin_family=AF_INET;
		send_sin.sin_addr.s_addr=inet_addr(Addr);
		send_sin.sin_port=htons(Port);
		//设置响应的网络事件为FD_CONNECT,即建立连接
		//发送WSA_CONNECT消息给窗口
		status=WSAAsyncSelect(sock,hwnd,WSA_CONNECT,FD_CONNECT); 
		if(status<0)	
		{//连接建立失败,关闭socket
			MessageBox("Error on WSAAsyncSelect()");
			WSAAsyncSelect(sock, hwnd, 0, 0);
			closesocket(sock);
			return -1;
		} 
	}
	//连接发送端
	connect(sock,(struct sockaddr FAR *)&send_sin, sizeof(send_sin));
	int error=WSAGetLastError();
	//有阻塞,弹出等待对话框
	if (error==WSAEWOULDBLOCK)
		WaitDlg.DoModal(); 
	return 0;
}



void CRevPlayWnd::InitMultiSock()
{
    int RevBuf;
    int status;
    BOOL  bFlag;
	CString ErrMsg;
	SOCKADDR_IN stLocalAddr;
	SOCKADDR_IN stDestAddr;
	SOCKET hNewSock;
    int RevLen=sizeof(RevBuf);
	//创建一个IP组播套接字
    MultiSock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
		  (LPWSAPROTOCOL_INFO)NULL, 0, 
		  WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF);
	if (MultiSock == INVALID_SOCKET) 
	{
		MessageBox("WSASocket() failed");
		return;
    } 
	
    //允许对同一地址bind多次
	bFlag = TRUE;
	status = setsockopt(
		MultiSock,					/* socket */
    	SOL_SOCKET,				/* socket level */
		SO_REUSEADDR,			/* socket option */
	    (char *)&bFlag,			/* option value */
	 	sizeof (bFlag));	/* size of value */

	if (status == SOCKET_ERROR) 
	{
	  ErrMsg.Format ("set SO_REUSEADDR failed, Err: %d",WSAGetLastError());
      MessageBox(ErrMsg);
	  return;
	}
	// 将套接字绑定到用户指定端口
	stLocalAddr.sin_family = AF_INET;
  //  stLocalAddr.sin_port = htons (DestPort);
    stLocalAddr.sin_port = htons (201);
	stLocalAddr.sin_addr.s_addr = INADDR_ANY;
    status = bind (
        MultiSock, 
        (struct sockaddr FAR *)&stLocalAddr, 
        sizeof(struct sockaddr));

    if (status == SOCKET_ERROR) 
	{
		ErrMsg.Format ("Bind(socket: %d, port: %d) failed, Err: %d",
			MultiSock, DestPort, WSAGetLastError());
		MessageBox(ErrMsg);
			
    }
	//设定接收缓冲区为64k
 	RevBuf=65536;
	status = setsockopt(
		MultiSock,					/* socket */
    	SOL_SOCKET,				/* socket level */
	    SO_RCVBUF,			/* socket option */
	    (char *)&RevBuf,			/* option value */
	    sizeof(RevBuf));	/* size of value */
	if (status == SOCKET_ERROR) 
	{
		MessageBox("set SO_REVBUF error");
		return;
	}
    
	//加入组播组
	stDestAddr.sin_family = PF_INET;
	stDestAddr.sin_port = htons (201);
    stDestAddr.sin_addr.s_addr = inet_addr("234.5.6.7");
    hNewSock = WSAJoinLeaf (MultiSock, /* socket */
        (PSOCKADDR)&stDestAddr, /* multicast address */
        sizeof (stDestAddr),    /* length of addr struct */	
        NULL,                   /* caller data buffer */
        NULL,                   /* callee data buffer */
        NULL,                   /* socket QOS setting */
        NULL,                   /* socket group QOS */
        JL_RECEIVER_ONLY);               /* do both: send *and* receive */

    if (hNewSock == INVALID_SOCKET) 
	{
	  ErrMsg.Format ("WSAJoinLeaf() failed, Err: %d",WSAGetLastError());
      MessageBox(ErrMsg);
	} 	
}


int CRevPlayWnd::ReceiveData()
{//接收组播数据
    CString msg;
    int status;
    DWORD cbRet;
    DWORD dFlag;
	int iLen;
	SOCKADDR_IN stSrcAddr;
	cbRet = 0;
	iLen = sizeof (stSrcAddr);
	dFlag = 0;
	//接收组播数据,存放到缓冲区stWSABuf中
	status = WSARecvFrom (MultiSock, /* socket */
		&stWSABuf,               /* input buffer structure */
		1,                       /* buffer count */
		&cbRet,                  /* number of bytes recv'd */
		&dFlag,                 /* flags */
		(struct sockaddr *)&stSrcAddr,/* source address */
		&iLen,                   /* size of addr structure */
		NULL,                    /* overlapped structure */
		NULL);                   /* overlapped callback function */
	
	if (status == SOCKET_ERROR) 
	{
		//数据丢失,丢失的块数计数加1
		m_LostBlock++;
		msg.Format ("WSARecvFrom() failed, Err:%d", WSAGetLastError());
		MessageBox (msg);
		return -1;
	} 
	return cbRet;
}



void CRevPlayWnd::OnSave() 
{
	// TODO: Add your command handler code here
	m_Save=!m_Save;
	DWORD dwFlags;
	CString SaveFileName;
	CString strSave;
	TCHAR Driver;
    CFileDialog dlg(TRUE,NULL,"temp.mpg",NULL,"mpeg文件(*.mpg)|*.mpg|AVI文件(*.avi)|*.avi");
    dlg.m_ofn.lpstrTitle="保存到...";
    if(dlg.DoModal()==IDOK)
	{
		
		SaveFileName=dlg.GetPathName();
        Driver=SaveFileName.GetAt(0);
       	CWnd* pParent = GetOwner();
		strSave.Format("保存到:%s",SaveFileName);
		CMainFrame* pFrame=(CMainFrame*)pParent->GetOwner();
		//   pFrame->m_wndStatusBar.SetPaneText(1,strSave);
		
	}
    dwFlags = MMIO_CREATE | MMIO_WRITE;
    hmmioSave = mmioOpen(SaveFileName.GetBuffer(_MAX_PATH), (LPMMIOINFO)NULL, dwFlags);
    SaveFileName.ReleaseBuffer();
}

void CRevPlayWnd::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	// TODO: Add your message handler code here
	CMenu menu;
	menu.LoadMenu(IDR_POP_MENU);
	menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this);
}

void CRevPlayWnd::OnStopReceive() 
{
	// TODO: Add your command handler code here
	StopReceive();
	m_Save=FALSE;
    m_FirstRead=TRUE;
    m_RenderOk=FALSE;
    m_Stop=FALSE;
    rIndex=0;
}

int  CRevPlayWnd::InitGraph()
{//构建Filter Graph
    HRESULT hr;
	hr = S_OK;
	//设置媒体类型,为MPEG1数据流
    mt.majortype = MEDIATYPE_Stream;
    mt.subtype = MEDIASUBTYPE_MPEG1System;
	//创建Source Filter
	m_pStream = new CMemStream(achInBuf, 0x80000000, INFINITE);
    m_pStream->pWnd=this;
    m_rdr = new CMemReader(m_pStream, &mt, &hr);
	
    if(FAILED(hr) || m_rdr == NULL)
	{
		MessageBox("CMemReader Error");
		return -1;
	}
    
	m_rdr -> AddRef();
	//创建Filter Graph
	CHECK_ERROR(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IFilterGraph, (void**)&m_pifg),"CoCreateInstance Error") ;
	//将Source Filter加入到Filter Graph中    
	CHECK_ERROR(m_pifg -> AddFilter(m_rdr, NULL), "AddFilter Error");
	//查询IGraphBuilder接口
	CHECK_ERROR(m_pifg -> QueryInterface(IID_IGraphBuilder, (void **)&m_pigb),"QueryInterface(IGraphBuilder) Error");
    m_pigb->AddRef ();
	//查询IMediaControl接口
	CHECK_ERROR(m_pigb -> QueryInterface(IID_IMediaControl, (void **)&m_pimc),"QueryInterface(IMediaControl) Error");
    m_pimc->AddRef ();
	//查询IVideoWindow接口
    CHECK_ERROR(m_pigb -> QueryInterface(IID_IVideoWindow, (void **)&m_pivw),"QueryInterface(IVideoWindow) Error");
    m_pivw->AddRef ();
    //查询IMediaPosition接口
    CHECK_ERROR(m_pigb -> QueryInterface(IID_IMediaPosition, (void **)&m_ppos),"QueryInterface(IMediaPosition) Error");
    m_ppos->AddRef ();
	return 0;
}

void CRevPlayWnd::OnRevPlay() 
{
	// TODO: Add your command handler code here
	int status;
	//建立组播socket,加入组播组
  	InitMultiSock();
	//设置响应的网络事件为FD_READ,即读数据
	//发送WSA_READ消息给窗口
	status=WSAAsyncSelect(MultiSock,m_hWnd,WSA_READ,FD_READ);
	if(status<0)	
	{
       MessageBox("Error on WSAAsyncSelect()");
       closesocket(MultiSock);
	   return;
	}
	//初始化存放接收数据的缓冲区
	for (int i = 0; i< 100; i++ )
		pRevMem[i] =new BYTE[BUFSIZE]; //32k
	m_Receive=TRUE;
	
}

BOOL CMemStream::PeekAndPump()
{
	static MSG msg;
	
	while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {
		if (!AfxGetApp()->PumpMessage()) {
			::PostQuitMessage(0);
			return FALSE;
		}	
	}
	
	return TRUE;
}

void CRevPlayWnd::RenderFrom(PBYTE Buf, LPCTSTR File)
{
    CFile f;
	CString MyPath;
	char path[MAX_PATH];
	
	GetModuleFileName (AfxGetInstanceHandle(), path, _MAX_PATH);
	MyPath = path;
	int index = MyPath.ReverseFind ('\\');
	MyPath = MyPath.Left (index+1);
	MyPath += File;
	
	int r = f.Open (MyPath, CFile::modeRead);
    if(r>0)	   
		r = f.Read (Buf, BUFSIZE*2);
    else
		return;
	f.Close ();
}

DWORD CRevPlayWnd::Parse(PBYTE Ptr, DWORD dwSize, LONGLONG *llTime)
{
	DWORD	RetV;
	DWORD LeftBytes = dwSize;
	while ((LONGLONG)LeftBytes >= 4 ) {
		if (!NextStartCode ((const BYTE **)&Ptr, &LeftBytes))
			break;
		DWORD Code = DWORD_SWAP(*(UNALIGNED DWORD *)Ptr);
		
		if (VALID_PACKET(Code)) {
			PBYTE PcktPtr;
			DWORD  Remain;
			DWORD PtsPos;
			RetV = ParseMPEG1Packet(Ptr, LeftBytes, &PacketData, &PtsPos);
			
			PcktPtr = Ptr+4;
			Remain = RetV;
			while ((LONG)Remain > 4) {
				if (!NextStartCode ((const BYTE **)&PcktPtr, &Remain))
					break;
				DWORD PcktCode = DWORD_SWAP(*(UNALIGNED DWORD *)PcktPtr);
				switch (PcktCode) {
				case SEQUENCE_HEADER_CODE:
					ParseSequenceHeader(PcktPtr, 0, &SeqInfo);
					return (SeqInfo.dwBitRate);
				}
				PcktPtr += 4;
				Remain -=4 ;
			}
			
		} else {
			switch (Code) {
			case PACK_START_CODE:
				GetClock (Ptr+4, llTime);
				RetV = PACK_HEADER_LENGTH;
				break;
			case SYSTEM_HEADER_START_CODE:
				RetV = ParseSystemHeader(Ptr, LeftBytes);
				break;
			default:
				RetV = 4;
				break;
			}
		}
		
		Ptr += RetV;
		LeftBytes -= RetV;
		if (RetV <=0)
			break;
	} 
	return 0;
}

void CRevPlayWnd::OnUpdateSave(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable (!m_Stop);
	pCmdUI->SetCheck (m_Save);
}

void CRevPlayWnd::OnUpdateStopReceive(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable (m_Stop);
}

void CRevPlayWnd::StopReceive()
{
    WSAAsyncSelect(MultiSock,m_hWnd,WSA_READ,0);
	closesocket(MultiSock);
	if (hmmioSave)
	{
		mmioClose(hmmioSave, NULL);
		hmmioSave = NULL;
	}
	if(m_pimc)
	{
		m_pimc -> Pause ();
		m_pimc ->StopWhenReady();
		m_pimc -> Stop();
	}
	if(m_pivw)
	{
		m_pivw -> put_Visible(OAFALSE);
		m_pivw -> put_Owner(NULL);
	}
	HELPER_RELEASE(m_pifg);
	HELPER_RELEASE(m_pigb);
	HELPER_RELEASE(m_pimc);
	HELPER_RELEASE(m_pivw);
	HELPER_RELEASE(m_ppos);
	
	if(m_pStream)
	{
		delete m_pStream;
		m_pStream = NULL;
	}
	
	if(m_rdr)
	{
		delete m_rdr;
		m_rdr = NULL;
	}
	for (int i = 0; i< 100; i++) 
	{
		
		if (m_Receive) //表示按了Receive菜单
			if(pRevMem[i])
				delete pRevMem[i];
			pRevMem[i] = NULL;
	}
}

void CRevPlayWnd::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	CRect rect;
	GetClientRect(&rect);
	if(m_pivw)
		m_pivw -> SetWindowPosition(rect.left, rect.top, rect.right, rect.bottom);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -