ActiveX控制元件全屏顯示
(一) 第一種方式,轉載
思路:
雙擊窗體
1。把嵌入在ActiveX裡有窗體“跳”出來
2。隱藏工作列
再次雙擊和上面相反,又回到了這個ActiveX裡去了
bool m_bFullScreen=false; HWND m_hWndParent; void CFfDlg::OnLButtonDblClk(UINT nFlags, CPoint point) { CDialog::OnLButtonDblClk(nFlags, point); m_bFullScreen=!m_bFullScreen; // 設定全屏顯示標誌 //一種更好的全屏顯示 LONG style = ::GetWindowLong(this->m_hWnd,GWL_STYLE); if(m_bFullScreen)//全屏顯示 { //用MFC隱藏系統工作列 CWnd * wnd = FindWindow("Shell_TrayWnd",NULL); wnd->SetWindowPos(NULL,0,0,0,0,SWP_HIDEWINDOW); m_hWndParent=::GetParent(m_hWnd); ::ShowWindow(m_hWndParent,SW_HIDE); ::SetParent(m_hWnd,NULL); style &= ~(WS_DLGFRAME | WS_THICKFRAME); SetWindowLong(this->m_hWnd,GWL_STYLE, style); this->ShowWindow(SW_SHOWMAXIMIZED); //CRect rect; //this->GetWindowRect(&rect); //::SetWindowPos((this->m_hWnd,HWND_NOTOPMOST,rect.left-1, rect.top-1, rect.right-rect.left + 3, rect.bottom-rect.top + 3, SWP_FRAMECHANGED); int nScreenWidth=GetSystemMetrics(SM_CXSCREEN); int nScreenHeight=GetSystemMetrics(SM_CYSCREEN); ::SetWindowPos(this->m_hWnd,HWND_NOTOPMOST,0,0, nScreenWidth,nScreenHeight, SWP_FRAMECHANGED); } else { //用MFC顯示系統工作列 CWnd * wnd = FindWindow("Shell_TrayWnd",NULL); wnd->SetWindowPos(NULL,0,0,0,0,SWP_SHOWWINDOW); style |= WS_DLGFRAME | WS_THICKFRAME; SetWindowLong(this->m_hWnd, GWL_STYLE, style); ::SetParent(m_hWnd,m_hWndParent); ::ShowWindow(m_hWndParent,SW_SHOW); } }
(二)第二種方式,轉載
複合視窗的ActiveX控制元件全屏及鍵盤訊息處理問題 [轉
最近在開發一個ActiveX視訊控制元件,需要有全屏功能,因為用到好幾層視窗,在全屏的時候費了很多周折,最後瞎湊總算湊好了,寫下來與大家共享。
讓應用程式全屏顯示其實思路很簡單:
1.先儲存要全屏的視窗的父視窗
2.如果要全屏的視窗不是子視窗,設定其風格為WS_CHILD
3.設定視窗的父視窗為桌面(::GetDesktopWindow())
4.移動視窗至全屏,並將視窗設為總在最上HWND_TOPMOST
m_videoMgr是我控制元件裡建立的視訊視窗,它的父視窗是控制元件視窗(CameraControl)控制元件本身的視窗不直接顯示,被這個m_videoMgr視窗完全覆蓋。在全屏的時候,如果直接更改CameraControl的父視窗,它的子視窗m_videoMgr視窗總是不能正確的設定為全屏,可能在控制元件測試容器里正常,但是到了IE裡就不正常了。於是我改為更改m_videoMgr視窗的父視窗,保留控制元件本身視窗,但是改變視窗大小的時候,改變父視窗的大小,也許m_videoMgr視窗可能和控制元件本身視窗的大小有關聯,這樣成功的進行了全屏,而且不管是在IE和控制元件測試容器裡都可以正常的全屏和恢復。
if(bFullScreen)
{
//獲取控制元件視窗的絕對位置
GetWindowRect(m_rcCtrlRect);
::SetParent(m_videoMgr.GetSafeHwnd(),::GetDesktopWindow());
int cx = ::GetSystemMetrics(SM_CXSCREEN);
int cy = ::GetSystemMetrics(SM_CYSCREEN);
MoveWindow(0, 0, cx, cy);
::SetWindowPos(m_videoMgr.GetSafeHwnd(),HWND_TOPMOST,0,0,cx,cy,SWP_FRAMECHANGED|SWP_DEFERERASE);
m_bFullScreen = TRUE;
}
else
{
::SetParent(m_videoMgr.GetSafeHwnd(),m_hWnd);
//MoveWindow使用相對視窗座標,所以必須先轉化為相對座標
CPoint LeftTop(m_rcCtrlRect.TopLeft());
CPoint BottomRight(m_rcCtrlRect.BottomRight());
::ScreenToClient(m_hWnd,&LeftTop);
::ScreenToClient(m_hWnd,&BottomRight);
::MoveWindow(m_hWnd,LeftTop.x,LeftTop.y,m_rcCtrlRect.Width(),m_rcCtrlRect.Height(),TRUE);
::SetWindowPos(m_videoMgr.GetSafeHwnd(),HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
m_bFullScreen = FALSE;
}
解決了上面的問題之後,又發現了一個新的問題,就是全屏以後想使用Esc鍵退出全屏時,根本不響應鍵盤訊息,後來發現MFC也有控制元件不處理鍵盤訊息的問題,想想可能跟控制元件的焦點有關係,於是在FullScreen的之前,加一個SetFocus()
if(FullScreen&&!IsFullScreen())
{
SetFocus();
OnFullScreen(TRUE);
}
然後發現鍵盤訊息處理正常了,問題解決。
(三)根據上述程式碼修改
環境 VC++2008,ATL專案(新增MFC支援)
1、先生成兩個控制元件,一個是static控制元件,一個是複合控制元件,將static控制元件放置在複合控制元件
在// AtlComFull2.h : CAtlComFull2 的宣告新增變數宣告
private:
HWND m_hWndParent;
BOOL bFullScreen;//全屏標識
int m_nTotalWnd;//視訊視窗個數
int m_nCurIndex;//當前活動的視窗
CAxWindow m_videoWnd[16];
int MAXWNDNUM;//最大視窗數
void ArrayWindow(WORD iNumber);//矩陣化視訊視窗
bool m_bFullScreen ;
WINDOWPLACEMENT m_struOldWndpl;
public:
CAtlComFull2()
{
m_bWindowOnly = TRUE;
CalcExtent(m_sizeExtent);
MAXWNDNUM=16;
m_bFullScreen=false;
}
矩陣排列子控制元件在複合控制元件上:
void CAtlComFull2::ArrayWindow(WORD iNumber)
{
m_nTotalWnd = iNumber;
int i = 0;
CRect Rect;//此處需要MFC支援,可以改用ATL的形式,Rect即可RECT rect = { 0, 0, 100, 100 };
GetClientRect(&Rect);
WORD iWidth,iHeight;
int nFullWidth=Rect.Width();
int nFullHeight=Rect.Height();
/* iWidth = (int) nFullWidth*0.75515625;
iHeight = (int)nFullHeight*0.91*/;
iWidth = nFullWidth;
iHeight = nFullHeight;
for (i = 0;i < MAXWNDNUM;i++)
{
m_videoWnd[i].ShowWindow(SW_HIDE);
}
int nNull = 3;
switch(iNumber)
{
case 1:
m_videoWnd[0].MoveWindow(3 + 0, 0, iWidth, iHeight);
m_videoWnd[0].ShowWindow(SW_SHOW);
break;
case 4:
for(i = 0; i < 2; i++)
{
m_videoWnd[i].MoveWindow( 3 + i * (iWidth / 2) + i * nNull , 0, (iWidth / 2), iHeight / 2);
m_videoWnd[i].ShowWindow(SW_SHOW);
}
for(i = 2; i < 4; i++)
{
m_videoWnd[i].MoveWindow(3 + (i - 2) * (iWidth / 2) + (i - 2) * nNull, iHeight / 2 + nNull, (iWidth / 2), iHeight / 2);
m_videoWnd[i].ShowWindow(SW_SHOW);
}
break;
case 9:
for (i=0;i<3;i++)
{
m_videoWnd[i].MoveWindow(3 + i * (iWidth / 3) + i * nNull, 0, (iWidth / 3), iHeight / 3);
m_videoWnd[i].ShowWindow(SW_SHOW);
}
for (i=3;i<6;i++)
{
m_videoWnd[i].MoveWindow(3 +(i - 3) * (iWidth / 3) + (i - 3) * nNull, iHeight / 3 + nNull, (iWidth / 3), iHeight / 3);
m_videoWnd[i].ShowWindow(SW_SHOW);
}
for (i=6;i<9;i++)
{
m_videoWnd[i].MoveWindow(3 + (i - 6) * (iWidth / 3) + (i - 6) * nNull, 2 * iHeight / 3 + 2 * nNull ,(iWidth / 3), iHeight / 3);
m_videoWnd[i].ShowWindow(SW_SHOW);
}
break;
case 16:
for(i = 0; i < 4; i++)
{
m_videoWnd[i].MoveWindow(3 + i * (iWidth / 4) + (i) * nNull, 0, (iWidth / 4), iHeight / 4);
m_videoWnd[i].ShowWindow(SW_SHOW);
}
for(i = 4; i < 8; i++)
{
m_videoWnd[i].MoveWindow(3 +(i - 4) * (iWidth / 4) + (i - 4) * nNull, iHeight / 4 + nNull, (iWidth / 4), iHeight / 4);
m_videoWnd[i].ShowWindow(SW_SHOW);
}
for(i = 8; i < 12; i++)
{
m_videoWnd[i].MoveWindow(3 +(i - 8) * (iWidth / 4) + (i - 8) * nNull, iHeight / 2 + 2 * nNull, (iWidth / 4), iHeight / 4);
m_videoWnd[i].ShowWindow(SW_SHOW);
}
for(i = 12; i < 16; i++)
{
m_videoWnd[i].MoveWindow(3 +(i - 12) * (iWidth / 4) + (i - 12) * nNull, 3 * iHeight / 4 + 3 * nNull, (iWidth / 4), iHeight / 4);
m_videoWnd[i].ShowWindow(SW_SHOW);
}
break;
default:
break;
}
}
初始化子控制元件,使之顯示在複合控制元件上
LRESULT CAtlComFull2::OnBnClickedButton1(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
AtlAxWinInit();
RECT rect = { 0, 0, 100, 100 };
for(int i=0;i<MAXWNDNUM;i++)
{
if(!m_videoWnd[i].m_hWnd)
{
m_videoWnd[i].Create(m_hWnd,rect,_T("{9AA126CB-19CA-47B8-AE76-3598E0227C1A}"),WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
}
}
ArrayWindow(4);
return 0;
}
全屏與退出全屏
LRESULT CAtlComFull2::OnBnClickedButton2(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// 全屏
//if(!bFullScreen){
GetWindowPlacement(&m_struOldWndpl);
m_hWndParent=::GetParent(m_hWnd);
::SetParent(m_hWnd,::GetDesktopWindow());
int cx = ::GetSystemMetrics(SM_CXSCREEN);
int cy = ::GetSystemMetrics(SM_CYSCREEN);
MoveWindow(0, 0, cx, cy);
::SetWindowPos(m_hWnd,HWND_TOPMOST,0,0,cx,cy,SWP_FRAMECHANGED|SWP_DEFERERASE);
m_bFullScreen = TRUE;
//最大化之後重新佈局播放視窗
ArrayWindow(9);
bFullScreen=true;
//}else{ }
return 0;
}
//退出全屏
LRESULT CAtlComFull2::OnBnClickedButton3(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// TODO: 在此新增控制元件通知處理程式程式碼
if(bFullScreen){
::SetParent(m_hWnd,m_hWndParent);
SetWindowPlacement(&m_struOldWndpl);
ArrayWindow(9);
bFullScreen=false;
}
return 0;
}