1. 程式人生 > >ActiveX 網頁播放控制元件

ActiveX 網頁播放控制元件

        最近在搞視訊監控專案,需要在網頁上顯示實時視訊,於是網上找了很多資料研究如何在網頁上播放視訊,一種實現方式就是開發activex控制元件嵌入到網頁中。如下我將介紹如何開發一個可以分屏播放視訊的activex控制元件 (部分內容也是從網上抄的,感謝各位勞動人民:))

建立ActiveX工程(使用VS2008)

1.選擇“檔案”選單,然後選擇“新建”->“專案”。

2.在“新建專案”對話方塊中,如下圖1所示,選擇“Visual C++”分類下的“MFC”。然後選擇“MFC ActiveX控制元件”作為專案模板。  

3.將新專案命名 為“TVWallAX”,然後選擇專案的儲存目錄,最後點選“確定”按鈕,關閉“新專案”對話方塊,進入“MFC ActiveX控制元件”嚮導。

4.在“MFC ActiveX控制元件”嚮導中,如下圖2所示,選擇左側的“控制元件設定”,進入控制元件引數設定頁面。

5.在“Create control based on”下拉列表中選擇“STATIC”。這表示我們使用的是一個靜態控制元件,因為我們僅僅是顯示輸出而不接收輸入。

6.在下面的“Additional features”的所有選項中,我們確認選中“Activates when visible”和“Flicker-free activation”這兩個選項,同時確認“Has an About box dialog”選項沒有被選中。

7.點選“Finish”按鈕關閉整個“MFC ActiveX控制元件嚮導”對話方塊,然後嚮導就會為我們建立整個專案的原始碼。預設情況下,嚮導建立的專案是使用共享MFC DLL的,這裡我們需要改變這一設定。因為如果目標機器上沒有安裝MFC DLL,那麼ActiveX控制元件就不會執行。我們常常看到一些網頁上的ActiveX控制元件被顯示為紅色的叉叉,很多都是這個原因造成的。為了解決這個問題,我們使用靜態的MFC DLL。從Visual Studio的選單中選擇“專案”->“屬性”,然後切換到“配置屬性”->“普通”,在配置頁面中的“Use of MFC ”下拉列表中,將“use MFC in a shared DLL”切換成“Use MFC in a Static Library”就可以了。

以上步驟就完成了控制元件的基本框架。

設計分屏控制元件

接下來我們需要編寫一個可以16分屏的控制元件,使用者可以選擇1分屏、4分屏、6分屏、9分屏、16分屏。如下:

設計3個類CPlayerItem、CPlayer、CPlayerGroup

CPlayerItem放在CPlayer上面,主要用來顯示視訊。CPlayerItem是CPlayer的子控制元件,比CPlayer尺寸小4個畫素。CPlayer放在CPlayerGroup上面,主要用來顯示滑鼠選中播放視訊視窗(CPlayer)後的矩形框。

CPlayerGroup主要用來管理16個CPlayer即CPlayerGroup是CPlayer的父視窗。CPlayerGroup放在建立好的CTVWallAXCtrl上面。

CPlayerGroup分屏實現

CPlayerGroup中定義16個CPlayer,需要實現如下功能:

  1. 按使用者選擇的畫面數顯示對應個數的CPlayer。
  2. 正確佈局當前所有CPlayer。
  3. 當視窗尺寸變化是調整CPlayer位置及尺寸。
  4. 把使用者當前滑鼠操作反饋給主介面,如使用者點選視訊播放視窗、使用者最大化視訊播放視窗等。

使用者選擇對應的畫面數目就需要對各個CPlayer重新佈局即重新計算在CPlayerGroup中對應的座標位置。

void CPlayerGroup::RecalWndPos()
{
	CRect rcWindow;
	GetClientRect(rcWindow);
	int nWidth;
	int nHeight;
	int nPos;
	// 清空所有CRect
	for(nPos=0;nPos<PlayWinow;nPos++)
	{
		m_rcWnd[nPos]=CRect(0,0,0,0);
		m_player[nPos].rcWnd=CRect(0,0,0,0);
	}
	
	// 得到最大化CRect
	m_rcWndMax=rcWindow;

	// 計算各個顯示數量時的CRect
	if(m_nCount==PlayCount1)
	{
		rcWindow.InflateRect(0,0,0,0);
		m_rcWnd[0]=rcWindow;
		
	}
	else if(m_nCount==PlayCount4)
	{
		nWidth	=rcWindow.Width()/2;
		nHeight	=rcWindow.Height()/2;
		m_rcWnd[0]=CRect(0,0,nWidth,nHeight);
		m_rcWnd[1]=CRect(nWidth,0,rcWindow.Width(),nHeight);
		m_rcWnd[2]=CRect(0,nHeight,nWidth,rcWindow.Height());
		m_rcWnd[3]=CRect(nWidth,nHeight,rcWindow.Width(),rcWindow.Height());
	}
	else if(m_nCount==PlayCount6)
	{
		nWidth	=rcWindow.Width()	/3;
		nHeight	=rcWindow.Height()	/3;
		m_rcWnd[0]=CRect(0,0,nWidth*2,nHeight*2);
		m_rcWnd[1]=CRect(nWidth*2,0,rcWindow.Width(),nHeight);
		m_rcWnd[2]=CRect(nWidth*2,nHeight,rcWindow.Width(),nHeight*2);
		m_rcWnd[3]=CRect(nWidth*2,nHeight*2,rcWindow.Width(),rcWindow.Height());
		m_rcWnd[4]=CRect(0,nHeight*2,nWidth,rcWindow.Height());
		m_rcWnd[5]=CRect(nWidth,nHeight*2,nWidth*2,rcWindow.Height());
		
	}
	else if(m_nCount==PlayCount8)
	{
		nWidth	=rcWindow.Width()	/4;
		nHeight	=rcWindow.Height()	/4;
		m_rcWnd[0]=CRect(0,0,nWidth*3,nHeight*3);
		m_rcWnd[1]=CRect(nWidth*3,0,rcWindow.Width(),nHeight);
		m_rcWnd[2]=CRect(nWidth*3,nHeight,rcWindow.Width(),nHeight*2);
		m_rcWnd[3]=CRect(nWidth*3,nHeight*2,rcWindow.Width(),nHeight*3);
		m_rcWnd[4]=CRect(nWidth*3,nHeight*3,rcWindow.Width(),rcWindow.Height());
		m_rcWnd[5]=CRect(0,nHeight*3,nWidth,rcWindow.Height());
		m_rcWnd[6]=CRect(nWidth,nHeight*3,nWidth*2,rcWindow.Height());
		m_rcWnd[7]=CRect(nWidth*2,nHeight*3,nWidth*3,rcWindow.Height());
	}
	else if(m_nCount==PlayCount9)
	{
		nWidth	=rcWindow.Width()	/3;
		nHeight	=rcWindow.Height()	/3;
		int x,y;
		for(y=0;y<3;y++)
		{
			for(x=0;x<3;x++)
			{
				if(y==2)
				{
					if(x==2)
					{
						m_rcWnd[x+3*y]=CRect(x*nWidth,y*nHeight,rcWindow.Width(),rcWindow.Height());
					}
					else
					{
						m_rcWnd[x+3*y]=CRect(x*nWidth,y*nHeight,(x+1)*nWidth,rcWindow.Height());
					}
				}
				else
				{
					if(x==2)
					{
						m_rcWnd[x+3*y]=CRect(x*nWidth,y*nHeight,rcWindow.Width(),(y+1)*nHeight);
					}
					else
					{
						m_rcWnd[x+3*y]=CRect(x*nWidth,y*nHeight,(x+1)*nWidth,(y+1)*nHeight);
					}
				}
			}
		}
	}
	else if(m_nCount==PlayCount16)
	{
		nWidth	=rcWindow.Width()	/4;
		nHeight	=rcWindow.Height()	/4;
		int x,y;
		for(y=0;y<4;y++)
		{
			for(x=0;x<4;x++)
			{
				if(y==3)
				{
					if(x==3)
					{
						m_rcWnd[x+4*y]=CRect(x*nWidth,y*nHeight,rcWindow.Width(),rcWindow.Height());
					}
					else
					{
						m_rcWnd[x+4*y]=CRect(x*nWidth,y*nHeight,(x+1)*nWidth,rcWindow.Height());
					}
				}
				else
				{
					if(x==3)
					{
						m_rcWnd[x+4*y]=CRect(x*nWidth,y*nHeight,rcWindow.Width(),(y+1)*nHeight);
					}
					else
					{
						m_rcWnd[x+4*y]=CRect(x*nWidth,y*nHeight,(x+1)*nWidth,(y+1)*nHeight);
					}
				}
			}
		}
		
	}

	// 設定CRect
	int nCurCount=0;
	for(nPos=0;nPos<PlayWinow;nPos++)
	{
		if(m_player[nPos].bIsUsed==TRUE)
		{
			m_player[nPos].rcWnd=m_rcWnd[nCurCount];
			nCurCount++;	
			if(nCurCount>=m_nCount)
			{	
				return;
			}
		}
	}

	for(nPos=0;nPos<PlayWinow;nPos++)
	{
		if(m_player[nPos].bIsUsed==FALSE)
		{
			m_player[nPos].rcWnd=m_rcWnd[nCurCount];
			nCurCount++;	
			if(nCurCount>=m_nCount)
			{
				return;
			}
		}
	}
}

我們還需要重寫CPlayerGroup 對應的OnSize(UINT nType, int cx, int cy)訊息處理函式,當視窗尺寸改變後需要重新對CPlayer佈局。

最後效果