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

📄 play.cpp

📁 <VC++视频音频开发>一书的光盘资料。
💻 CPP
字号:
// play.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "play.h"

#include "playDoc.h"
#include "playView.h"
#include <dos.h>
#include <direct.h>
#include "SetPwd.h"
#include "InputPwd.h"
#include "ModifyPwd.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define LISTEN_PORT 1500
#define WSA_ACCPET WM_USER+300;


BOOL fail;
HKEY PasswdKey;
char dw_Passwd[100];
BOOL	m_Modify;
SOCKET Lsock;          //监听套接字
SOCKADDR_IN  DestAddr; //发送地址
SOCKET MultiSock ;     //组播套接字

/////////////////////////////////////////////////////////////////////////////
// CPlayApp

BEGIN_MESSAGE_MAP(CPlayApp, CWinApp)
	//{{AFX_MSG_MAP(CPlayApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard file based document commands
	ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPlayApp construction

UINT CPlayApp::m_nImages[12] =
{
	IDI_ICON1,
	IDI_ICON2,
	IDI_ICON3,
	IDI_ICON4,
	IDI_ICON5,
	IDI_ICON6,
	IDI_ICON7,
	IDI_ICON8,
	IDI_ICON9,
	IDI_ICON10,
	IDI_ICON11,
	IDI_ICON12,
};

CPlayApp::CPlayApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CPlayApp object

CPlayApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CPlayApp initialization

BOOL CPlayApp::InitInstance()
{
	AfxEnableControlContainer();
	
	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.
	
#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif
	
	// Change the registry key under which our settings are stored.
	// TODO: You should modify this string to be something appropriate
	// such as the name of your company or organization.
/*	SetRegistryKey(_T("Monitor"));
    DWORD IsExist;
	DWORD dwDataType;
	DWORD dwLength;
	dwDataType=REG_SZ;
    dwLength=sizeof(dw_Passwd);
    
	if((RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Monitor\\Sender",0,
		NULL,REG_OPTION_NON_VOLATILE,NULL,
		NULL,&PasswdKey,&IsExist))!=ERROR_SUCCESS)
		return FALSE;
	
	if(IsExist==REG_CREATED_NEW_KEY)
	{  
		CSetPwd SetPwd;
		SetPwd.DoModal();
	}
	if(IsExist==REG_OPENED_EXISTING_KEY)
	{
		if((RegQueryValueEx(PasswdKey,"Passwd",
			NULL,&dwDataType,(LPBYTE)dw_Passwd,&dwLength))!=ERROR_SUCCESS)
			return FALSE;
		//	RegCloseKey(PasswdKey);
		CInputPwd InputPwd;
		InputPwd.DoModal();
		if(m_Modify)
		{
			CModifyPwd ModifyPwd;
			ModifyPwd.DoModal();
		}
	}
	if(fail)
		return FALSE;	
	
	LoadStdProfileSettings();  // Load standard INI file options (including MRU)
*/	
	// Register the application's document templates.  Document templates
	//  serve as the connection between documents, frame windows and views.
	
	CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(CPlayDoc),
		RUNTIME_CLASS(CMainFrame),       // main SDI frame window
		RUNTIME_CLASS(CPlayView));
	AddDocTemplate(pDocTemplate);
    CoInitialize(NULL); 
	// Parse command line for standard shell commands, DDE, file open
	CCommandLineInfo cmdInfo;
	ParseCommandLine(cmdInfo);
	
	// Dispatch commands specified on the command line
	if (!ProcessShellCommand(cmdInfo))
		return FALSE;
	
    int status;
	WSADATA WSAData;
	if (!(status = WSAStartup(MAKEWORD(2,2), &WSAData)) == 0) 
	{
		AfxMessageBox("error StartUp");
		return FALSE;
	}
	
	InitSocket();           //建立监听socket
	InitMultiSocket();      //建立组播socket
	AddDevToMenu();
	::SetWindowText(m_pMainWnd->m_hWnd,"远程监控系统");
	return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
		// No message handlers
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CPlayApp::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// CPlayApp message handlers




int CPlayApp::ExitInstance() 
{
	// TODO: Add your specialized code here and/or call the base class
    WSACleanup();
	CoUninitialize();
	return CWinApp::ExitInstance();
}

void CPlayApp::AddDevToMenu()
{
    CVideoPlay vPlay;
	CStringList DevList;
	int i;
	CString DevName;
	vPlay.FindDevice(DevList);
	for(i=0;i<DevList.GetCount();i++)
	{
		DevName=DevList.GetHead();
		CMenu* Pmenu=m_pMainWnd->GetMenu();
		CMenu* Smenu=Pmenu->GetSubMenu(0);		
		Smenu->AppendMenu(MF_STRING,MENU_VDEVICE0 + i,DevName);
		Smenu->DeleteMenu(0,MF_BYPOSITION);
		Smenu->EnableMenuItem(MENU_VDEVICE0 + i,MF_ENABLED||MF_BYCOMMAND);   
    }
/*	HRESULT hr;
	int uIndex=0;
	ICreateDevEnum *pCreateDevEnum;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
			  IID_ICreateDevEnum, (void**)&pCreateDevEnum);
    IEnumMoniker *pEm;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
								&pEm, 0);
    HELPER_RELEASE(pCreateDevEnum);
    pEm->Reset();
    ULONG cFetched;
    IMoniker *pM;
    while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
    {
	  IPropertyBag *pBag;
	  hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
	  if(SUCCEEDED(hr)) 
	  {
	    VARIANT var;
	    var.vt = VT_BSTR;
	    hr = pBag->Read(L"FriendlyName", &var, NULL);
	    if (hr == NOERROR)
		{
		char achName[80];
		WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, achName, 80,NULL, NULL);
	    CMenu* Pmenu=m_pMainWnd->GetMenu();
	    CMenu* Smenu=Pmenu->GetSubMenu(0);		
	    Smenu->AppendMenu(MF_STRING,MENU_VDEVICE0 + uIndex,achName);
	    Smenu->DeleteMenu(0,MF_BYPOSITION);
	    Smenu->EnableMenuItem(MENU_VDEVICE0 + uIndex,MF_ENABLED||MF_BYCOMMAND);   
	    SysFreeString(var.bstrVal);
	    }
	  	HELPER_RELEASE(pBag);
	  }
	  
	}
/*	CMainFrame* pFrame=(CMainFrame*)m_pMainWnd;
	hr = pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&(pFrame->pVCap));
	if(pFrame->pVCap== NULL) 
	{
	    
		return;
	} */
/*	HELPER_RELEASE(pM);
	uIndex++;
    }
   	HELPER_RELEASE(pEm);*/
}

//建立监听socket
DWORD CPlayApp::InitSocket()
{
  
	SOCKADDR_IN send_sin;
	int status;
	CMainFrame* pFrame;
	pFrame=(CMainFrame*)m_pMainWnd;
	HWND m_hwndRec=pFrame->m_hWnd;
	pFrame->m_bAutoMenuEnable=FALSE;
	
	//创建一个socket
	Lsock = socket(AF_INET,SOCK_STREAM,0);
	if (Lsock == INVALID_SOCKET)
	{
		ErrMsg(m_hwndRec,"Socket failed");
		return -1;
	}
	send_sin.sin_port=htons(1500); 
	send_sin.sin_family=AF_INET;
	send_sin.sin_addr.s_addr=INADDR_ANY;
	//绑定服务器主机地址与端口
	if (bind(Lsock, (struct sockaddr FAR *) &send_sin, sizeof(send_sin))==SOCKET_ERROR) 
	{
		ErrMsg(m_hwndRec,"bind failed");
	    closesocket(Lsock );
		return -1;
	}
	//设置端口状态为监听
	if (listen(Lsock, 10) < 0) 
	{
		ErrMsg(m_hwndRec,"Listen failed");
		closesocket(Lsock );
		return -1;
	}
  
	//设定服务器响应的网络事件为FD_ACCEPT,即程序想要接收数据 
	//产生相应传递给窗口的消息为WSA_ACCEPT
	if ((status = WSAAsyncSelect(Lsock,m_hwndRec,WSA_ACCEPT,FD_ACCEPT))>0) 
	{
 		ErrMsg(m_hwndRec,"Error on WSAAsyncSelect()");
        closesocket(Lsock );
		return -1;
	}
	return 0;
}

void CPlayApp::ErrMsg(HWND hwnd, const char *ErrMsg)
{
  char szBuff[80];
  sprintf(szBuff, "%d is the error", WSAGetLastError());
  MessageBox(hwnd,szBuff,ErrMsg,MB_OK);
}

//初始化IP组播套接字
int CPlayApp::InitMultiSocket()
{
    int SendBuf;
	DWORD cbRet;
    int status;
	BOOL bFlag;
    SOCKADDR_IN  SrcAddr;
    CMainFrame* pFrame=(CMainFrame*)m_pMainWnd;
    HWND m_hwnd=pFrame->m_hWnd;
	
   
	//创建一个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) 
	{
	    ErrMsg(m_hwnd,"WSASocket Error");
		return -1;
    } 
   	 
	//设置套接字为可重用端口地址
	bFlag = TRUE;
	status = setsockopt(
		MultiSock,				
		SOL_SOCKET,				
		SO_REUSEADDR,			
		(char *)&bFlag,			
		sizeof (bFlag));
	if (status == SOCKET_ERROR) 
	{
	    ErrMsg(m_hwnd,"setsockopt Error");
		return -1;
	}


   // 将套接字绑扎到用户指定端口及默认的接口
	SrcAddr.sin_family = AF_INET;
    SrcAddr.sin_port = htons (DESTPORT);
    SrcAddr.sin_addr.s_addr = INADDR_ANY;
    status = bind (
        MultiSock, 
        (struct sockaddr FAR *)&SrcAddr, 
        sizeof(struct sockaddr));

    if (status == SOCKET_ERROR) 
	{
		ErrMsg(m_hwnd,"bind Error");
	    return -1;
    }

	nIP_TTL = 2;   //允许跨网传播
	// 设置多址广播数据报传播范围,允许跨网传播
	status = WSAIoctl (MultiSock,     
		SIO_MULTICAST_SCOPE,   
		&nIP_TTL,              
		sizeof (nIP_TTL),      
		NULL,             
		0,         
		&cbRet,                
        NULL,                  
        NULL);                 
    if (status)
	{
     	ErrMsg(m_hwnd,"WSAIoctl Error");
		return -1;
    } 

  
    // 允许内部回送(LOOPBACK)
      bFlag = TRUE;
      status = WSAIoctl (MultiSock,              /* socket */
          SIO_MULTIPOINT_LOOPBACK,               /* LoopBack on or off */
          &bFlag,                                /* input */
          sizeof (bFlag),                        /* size */
          NULL,                                      /* output */ 
          0,                                         /* size */
          &cbRet,                                    /* bytes returned */
          NULL,                                      /* overlapped */
          NULL);                                     /* completion routine */
  	if (status)
  	{
       	ErrMsg(m_hwnd,"WSAIoctl Error");
  		return -1;
      } 
  
	

	//设定发送缓冲区为64k
	SendBuf=65536;
	status = setsockopt(
		MultiSock,					
    	SOL_SOCKET,				
	    SO_SNDBUF,			
	    (char *)&SendBuf,			
	    sizeof(SendBuf));	
	if (status == SOCKET_ERROR) 
	{
		ErrMsg(m_hwnd,"setsockopt Error");
		return -1;
	}
    //测试设定的发送缓冲区是否为64k
	int ASendBuf;
	int SLen=sizeof(ASendBuf);
	status=getsockopt(MultiSock,SOL_SOCKET,SO_SNDBUF,
		       (char * )&ASendBuf, &SLen);
    
	if (status == SOCKET_ERROR) 
	{
	    ErrMsg(m_hwnd,"setsockopt Error");
		return -1;
	}
    if(status==0)
	{ 
	 	if(ASendBuf!=65536)
			return -1;
	}

    DestAddr.sin_family = AF_INET; 
    DestAddr.sin_port = htons (DESTPORT);
    DestAddr.sin_addr.s_addr =inet_addr(MULTIDESTADDR);
	return 0;
}

⌨️ 快捷键说明

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