李国帅 2009年,用于实现播放控件全屏切换,并重新计算播放小窗口。一个大窗口有最多8×8个子窗口。
实现程序全屏幕显示的思路有很多种,最常见的一种就是:
1)存储全屏显示前视图和主框架窗口在屏幕上的位置和显示信息
利用Windows API提供的一个结构体WINDOWPLACEMENT来存储全屏显示前视图和主框架窗口在屏幕上的位置和显示信息、非客户区窗口的显隐信息,以便全屏幕显示时恢复窗口原状;
GetWindowRect(&m_NormalRect);//获取当前窗口的位置 POINT pt1,pt2; pt1.x = m_NormalRect.left; pt1.y = m_NormalRect.top; ::ScreenToClient(GetParent(), &pt1); pt2.x = m_NormalRect.right; pt2.y = m_NormalRect.bottom; ::ScreenToClient(GetParent(), &pt2); WidthRect = pt2.x - pt1.x; HeightRect = pt2.y - pt1.y; /* Change window style, no borders and no title bar Maximize window */ RECT rc;//获取父窗口的大小和位置 rc.left = rc.top = 0; rc.right = GetSystemMetrics(SM_CXSCREEN); rc.bottom = GetSystemMetrics( SM_CYSCREEN );
2)通过API函数GetDesktopWindow()得到桌面窗口,由GetWindowRect()得到显示器的尺寸;
HWND hDesktop=::GetDesktopWindow(); // if (hDesktop == NULL) { ATLTRACE2("Set Parent Window To Desktop Faild\n"); m_bFullScreen = !m_bFullScreen; return 0; } //改变窗口大小并置顶 SetParent(hDesktop);//atl
3)通过AdjustWindowRect()来计算当客户区大小为屏幕大小时相应的窗口大小;
4)通过SetWindowPlacement()来设置视图窗口和主窗口为客户区大小和屏幕大小的窗口;
//进入全屏显示状态 WINDOWPLACEMENT wndpl; wndpl.length=sizeof(WINDOWPLACEMENT); wndpl.flags=0; wndpl.showCmd=SW_SHOWNORMAL; wndpl.rcNormalPosition=rc; SetWindowPlacement(&wndpl);
或者
BOOL bChangeSize = FALSE; bChangeSize = SetWindowPos( HWND_TOPMOST, CtrlRect.left, CtrlRect.top, (CtrlRect.right - CtrlRect.left), (CtrlRect.bottom - CtrlRect.top), SWP_SHOWWINDOW | SWP_FRAMECHANGED);////SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED)) if (!bChangeSize) { bChangeSize = MoveWindow(CtrlRect.left, CtrlRect.top, CtrlRect.right - CtrlRect.left, CtrlRect.bottom - CtrlRect.top); }
5)处理窗口消息WM_GETMINMAXINFO,使窗口能够顺利的最大、最小化。
但是用这种方法并没有实现真正的全屏,好像VC6的全屏也是这样做的。如果有多屏显卡,这样实现的全屏是可以
从别的屏幕对其进行放大缩小的。
例程
LRESULT CALLBACK ScreenWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { return DefWindowProc(hWnd, message, wParam, lParam); } void CTopseePlayer::CreateScreenWnd(RECT rcWnd) { if(m_hWndScreen == NULL) { WNDCLASS wc; wc.style = 0; wc.lpfnWndProc = ScreenWndProc; wc.cbClsExtra = wc.cbWndExtra = 0; wc.hInstance = (HINSTANCE)NULL; wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);; wc.lpszMenuName = NULL; wc.lpszClassName = _T("ScreenWnd"); if (::FindWindow(_T("ScreenWnd"),NULL) == NULL) { RegisterClass(&wc); } TCHAR WindowName[100]; _tcscpy_s(WindowName,100,_T("")); srand((unsigned)time( NULL )); int ID = rand() & 0xfff; _stprintf_s(WindowName,_T("ScreenWnd%d"),ID); //HWND hw = ::FindWindow(_T("ScreenWnd"),WindowName); while (::FindWindow(_T("ScreenWnd"),WindowName) != NULL) { ID = rand() & 0xfff; _stprintf_s(WindowName,_T("ScreenWnd%d"),ID); } HWND hDesktop= NULL;//::GetDesktopWindow(); const DWORD nostyle=WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_POPUP|WS_MAXIMIZE; m_hWndScreen = ::CreateWindow(wc.lpszClassName, WindowName,nostyle, rcWnd.left, rcWnd.top,rcWnd.right, rcWnd.bottom, hDesktop,NULL,NULL,NULL); DWORD Errno = GetLastError(); ATLASSERT(m_hWndScreen != NULL); return; } } LRESULT CTopseePlayer::OnLButtonDblClk(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { // TODO://双击进行全屏处理 static BOOL m_bFullScreen = FALSE; static RECT m_NormalRect; static LONG WidthRect = 0; static LONG HeightRect = 0; if (m_hWnd == NULL) { ATLTRACE2("Impossible State Wnd is Null\n"); return 0; } CreateScreenWnd(m_rcScreen); BOOL bChangeSize = FALSE; m_bFullScreen = !m_bFullScreen;//标志切换 if( m_bFullScreen ) { RECT CtrlRect; GetWindowRect(&CtrlRect);//获取当前窗口的位置 POINT pt1,pt2; pt1.x = CtrlRect.left; pt1.y = CtrlRect.top; ::ScreenToClient(GetParent(), &pt1); pt2.x = CtrlRect.right; pt2.y = CtrlRect.bottom; ::ScreenToClient(GetParent(), &pt2); WidthRect = pt2.x - pt1.x; HeightRect = pt2.y - pt1.y; SetRect(&m_NormalRect,0,0,WidthRect,HeightRect); ::ShowWindow(m_hWndScreen,SW_HIDE); SetParent(m_hWndScreen);//atl //::MoveWindow(m_hWndScreen,m_rcScreen.left+1, m_rcScreen.top+1, m_rcScreen.right - m_rcScreen.left-2, m_rcScreen.bottom - m_rcScreen.top-2,FALSE); SetPlayWindowRect(m_rcScreen,&bChangeSize);//改变窗口大小并置顶 //::InvalidateRect(m_hWndScreen,&m_rcScreen,TRUE); if (!bChangeSize) { ATLTRACE2("SetWindowPos\n"); SetParent(m_hOldWndParent); m_bFullScreen = !m_bFullScreen; return 0; } ::ShowWindow(m_hWndScreen,SW_SHOW); } else { SetParent(m_hOldWndParent); //::MoveWindow(m_hOldWndParent,m_NormalRect.left+1, m_NormalRect.top+1, m_NormalRect.right - m_NormalRect.left-2, m_NormalRect.bottom - m_NormalRect.top-2,FALSE); SetPlayWindowRect(m_NormalRect,&bChangeSize); //::InvalidateRect(m_hOldWndParent,&m_NormalRect,TRUE); ::ShowWindow(m_hWndScreen,SW_HIDE); } RefreshSurface(); return 0; } STDMETHODIMP CTopseePlayer::SetPlayWindowRect(RECT CtrlRect, BOOL* retval) { ShowWindow(SW_HIDE); BOOL bChangeSize = FALSE; // RECT clientRect; // GetClientRect(&clientRect);//GetWindowRect(&clientRect);//获取当前窗口的位置 //bChangeSize = MoveWindow(CtrlRect.left+1, CtrlRect.top+1, CtrlRect.right - CtrlRect.left-2, CtrlRect.bottom - CtrlRect.top-2); RECT CtrlRectC; GetWindowRect(&CtrlRectC);//获取当前窗口的位置 POINT pt1,pt2; pt1.x = CtrlRect.left; pt1.y = CtrlRect.top; ::ClientToScreen(GetParent(), &pt1); pt2.x = CtrlRect.right; pt2.y = CtrlRect.bottom; ::ClientToScreen(GetParent(), &pt2); bChangeSize = SetWindowPos( HWND_TOPMOST, pt1.x, pt1.y, (pt2.x - pt1.x), (pt2.y - pt1.y), SWP_FRAMECHANGED); ////SWP_SHOWWINDOW | SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER)) ShowWindow(SW_SHOWMAXIMIZED); hash_map<int, Media*>::const_iterator iter; pLock->GetReadLock(); if( (iter = media_map.begin()) != media_map.end()) { Media* pMedia = iter->second; //CopyRect(&pMedia->rc, &CtrlRect); pMedia->left = 0;//Left;// pMedia->top = 0;//Top;// pMedia->right = 1;//Right;// pMedia->bottom = 1;//Bottom;// } pLock->ReleaseReadLock(); * retval = bChangeSize; return S_OK; } STDMETHODIMP CTopseePlayer::RefreshSurface() { RECT clientRect; GetClientRect(&clientRect);//GetWindowRect(&clientRect);//获取当前窗口的位置 InvalidateRect(&clientRect); // RECT RectParent; // ::GetClientRect(m_hOldWndParent,&RectParent); return S_OK; }