在MFC的视图文档结构中,视图永远在框架窗口的范围之内。本文介绍一种把视图全屏显示的方法,能使视图的大小占据整个显示器窗口。
方法要点1:扩大主框架窗口。因为视图的大小是随主框架窗口的大小自动调整的,所以首先要把主框比显示器窗口还大,以给视图留下足够占满显示器的空间。
方法要点2:把主框架窗口移到合适的位置,使视图的左上角正好在屏幕的左上角。
注意:对于不能自动按框架大小自动调整的视图,如被分割的视图,需要自己写程序,当主框架窗口的大小改变时,视图能跟随着改变大小,使视图窗口离主框架窗口的四周边距不变。
计算框架窗口在全屏时的大小可以使用下面的函数公式:
CRect FullScreenRect(CRect & rcFrame, CRect & rcView, CRect & rcScreen)
{
CRect rcMax;
rcMax.left = rcScreen.left + rcFrame.left - rcView.left;
rcMax.top = rcScreen.top + rcFrame.top - rcView.top;
rcMax.right= rcScreen.right + rcFrame.right - rcView.right;
rcMax.bottom= rcScreen.bottom+ rcFrame.bottom- rcView.bottom;
return rcMax;
}
rcFrame:当前框架窗口的矩形
rcView:视图窗口的矩形为
rcScreen:整个屏幕矩形为。
如果给出当前的框架窗口和视图窗口,我们就很容易计算出框架窗口在全屏时的大小和位置,如下面的函数。
CRect FullScreenRect(CWnd* pFrame, CWnd* pView)
{
CRect rcs(0,0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
if (pFrame==NULL || pView==NULL)
return rcs;
CRect rcv, rcf;
pView->GetWindowRect(rcv);
pFrame->GetWindowRect(rcf);
return FullScreenRect(rcf, rcv, rcs);
}
GetSystemMetrics(SM_CXSCREEN)
和GetSystemMetrics(SM_CYSCREEN)用来获得当前屏幕的宽度和高度。
在扩大主框架窗口时,需要注意一个消息
WM_GETMINMAXINFO
。MFC通过这个消息获取窗口的最大尺寸。默认窗口的最大尺寸是实际屏幕的大小。如果我们要使主框架窗口比屏幕大,那么必需响应这个消息,以返回一个足够的尺寸。
WM_GETMINMAXINFO
消息映射宏为ON_WM_GETMINMAXINFO()
响应函数声明为:afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
实现该消息的响应函数,可以参考下面的形式,假设框架窗口类为CXxxFrame(单文档框架):
void
CXxxFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
CWnd * pView = GetActiveView( ); //
单文档窗口,直接取VIEW
//
多文档窗口应该使用 m_hWndMDIClient
//
改为下面的样子:
// CWnd * pView = CWnd::FromeHandle(m_hWndMDIClient);
if (pView==NULL)
{
__super::OnGetMinMaxInfo(lpMMI);
return;
}
CPoint Point(FullScreenRect(this, pView).Size() );
lpMMI->ptMaxSize = Point;
lpMMI->ptMaxTrackSize = Point;
}
全屏显示时,我们使用
SetWindowPos
函数把框架窗口放大到应有的尺寸并移动到合适的位置。如下面的函数:
CRect FullScreenView(CWnd* pFrame, CWnd* pView)
{
CRect rcf;
pFrame->GetWindowRect(rcf);
pFrame->SetWindowPos(FullScreenRect(pFrame, pView) );
return rcf;
}
该函数返回框架窗口的原来大小,在从全屏状态恢复时,使用SetWindowPos函数把框架窗口移到原来的位置即可。
我们把这些函数包装成一个类,输入为框架和视图窗口的句柄(因为有时我们无法获得一个永久的指针,所以使用句柄)。该类提供全屏、恢复、获取状态、和获取全屏时尺寸四个接口。上面所述各函数被定义为静态函数,可以单独作用。
当主框架为单文档时,使用现在的语句设置参数(假设m_FullScreen为CFullScreen的实例):
m_FullScreen.(SetFrameView(GetSafeHwnd(),GetActiveView()->GetSafeHwnd());
多文档框架,使用下面的语句:
m_FullScreen..SetFrameView(GetSafeHwnd(),m_hWndMDIClient);
然后就可以调用FullScreen和Restore函数来操作窗口了。
头文件
FullScreen.h如下:
class
CFullScreen{
public :
CFullScreen();
~ CFullScreen();
void SetFrameView(HWND hwndFrame, HWND hwndView);
void FullScreen();
void Restore();
bool IsFullScreen();
CSize GetFullScreenSize();
static CRect FullScreenView(CWnd * pFrame, CWnd * pView);
static CRect FullScreenRect(CWnd * pFrame, CWnd * pView);
static CRect FullScreenRect(CRect & rcFrame, CRect & rcView, CRect & rcScreen);
protected :
CRect m_rcRestore, m_rcMax;
HWND m_hwndFrame, m_hwndView;
};
public :
CFullScreen();
~ CFullScreen();
void SetFrameView(HWND hwndFrame, HWND hwndView);
void FullScreen();
void Restore();
bool IsFullScreen();
CSize GetFullScreenSize();
static CRect FullScreenView(CWnd * pFrame, CWnd * pView);
static CRect FullScreenRect(CWnd * pFrame, CWnd * pView);
static CRect FullScreenRect(CRect & rcFrame, CRect & rcView, CRect & rcScreen);
protected :
CRect m_rcRestore, m_rcMax;
HWND m_hwndFrame, m_hwndView;
};
CPP
文件如下:
#include
"
StdAfx.h
"
#include " FullScreen.h "
CFullScreen::CFullScreen()
... {
m_rcRestore.SetRectEmpty();
m_hwndFrame = NULL;
m_hwndView = NULL;
m_rcMax.SetRect(0,0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
}
CFullScreen:: ~ CFullScreen()
... {
}
void CFullScreen::SetFrameView(HWND hwndFrame, HWND hwndView)
... {
m_hwndFrame = hwndFrame;
m_hwndView = hwndView;
}
void CFullScreen::FullScreen()
... {
if (IsFullScreen())
return;
m_rcMax = FullScreenRect(CWnd::FromHandle(m_hwndFrame), CWnd::FromHandle(m_hwndView));
m_rcRestore = FullScreenView(CWnd::FromHandle(m_hwndFrame), CWnd::FromHandle(m_hwndView));
}
void CFullScreen::Restore()
... {
if (!IsFullScreen())
return;
if (CWnd::FromHandle(m_hwndFrame)!=NULL)
CWnd::FromHandle(m_hwndFrame)->MoveWindow(m_rcRestore);
m_rcRestore.SetRectEmpty();
m_rcMax.SetRect(0,0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
}
bool CFullScreen::IsFullScreen()
... {
return !m_rcRestore.IsRectEmpty();
}
CSize CFullScreen::GetFullScreenSize()
... {
return m_rcMax.Size();
}
CRect CFullScreen::FullScreenView(CWnd * pFrame, CWnd * pView)
... {
CRect rcf(0,0,0,0);
if (pFrame==NULL)
return rcf;
pFrame->GetWindowRect(rcf);
pFrame->MoveWindow( FullScreenRect(pFrame, pView) );
return rcf;
}
CRect CFullScreen::FullScreenRect(CWnd * pFrame, CWnd * pView)
... {
CRect rcs(0,0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
if (pFrame==NULL || pView==NULL)
return rcs;
CRect rcv, rcf;
pView->GetWindowRect(rcv);
pFrame->GetWindowRect(rcf);
CRect rcMax = FullScreenRect(rcf, rcv, rcs);
if (rcMax.Width()<rcs.Width() || rcMax.Height() < rcs.Height())
return rcs;
return rcMax;
}
CRect CFullScreen::FullScreenRect(CRect & rcFrame, CRect & rcView, CRect & rcScreen)
... {
CRect rcMax;
rcMax.left = rcScreen.left + rcFrame.left - rcView.left;
rcMax.top = rcScreen.top + rcFrame.top - rcView.top;
rcMax.right= rcScreen.right + rcFrame.right - rcView.right;
rcMax.bottom = rcScreen.bottom+ rcFrame.bottom- rcView.bottom;
return rcMax;
}
#include " FullScreen.h "
CFullScreen::CFullScreen()
... {
m_rcRestore.SetRectEmpty();
m_hwndFrame = NULL;
m_hwndView = NULL;
m_rcMax.SetRect(0,0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
}
CFullScreen:: ~ CFullScreen()
... {
}
void CFullScreen::SetFrameView(HWND hwndFrame, HWND hwndView)
... {
m_hwndFrame = hwndFrame;
m_hwndView = hwndView;
}
void CFullScreen::FullScreen()
... {
if (IsFullScreen())
return;
m_rcMax = FullScreenRect(CWnd::FromHandle(m_hwndFrame), CWnd::FromHandle(m_hwndView));
m_rcRestore = FullScreenView(CWnd::FromHandle(m_hwndFrame), CWnd::FromHandle(m_hwndView));
}
void CFullScreen::Restore()
... {
if (!IsFullScreen())
return;
if (CWnd::FromHandle(m_hwndFrame)!=NULL)
CWnd::FromHandle(m_hwndFrame)->MoveWindow(m_rcRestore);
m_rcRestore.SetRectEmpty();
m_rcMax.SetRect(0,0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
}
bool CFullScreen::IsFullScreen()
... {
return !m_rcRestore.IsRectEmpty();
}
CSize CFullScreen::GetFullScreenSize()
... {
return m_rcMax.Size();
}
CRect CFullScreen::FullScreenView(CWnd * pFrame, CWnd * pView)
... {
CRect rcf(0,0,0,0);
if (pFrame==NULL)
return rcf;
pFrame->GetWindowRect(rcf);
pFrame->MoveWindow( FullScreenRect(pFrame, pView) );
return rcf;
}
CRect CFullScreen::FullScreenRect(CWnd * pFrame, CWnd * pView)
... {
CRect rcs(0,0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
if (pFrame==NULL || pView==NULL)
return rcs;
CRect rcv, rcf;
pView->GetWindowRect(rcv);
pFrame->GetWindowRect(rcf);
CRect rcMax = FullScreenRect(rcf, rcv, rcs);
if (rcMax.Width()<rcs.Width() || rcMax.Height() < rcs.Height())
return rcs;
return rcMax;
}
CRect CFullScreen::FullScreenRect(CRect & rcFrame, CRect & rcView, CRect & rcScreen)
... {
CRect rcMax;
rcMax.left = rcScreen.left + rcFrame.left - rcView.left;
rcMax.top = rcScreen.top + rcFrame.top - rcView.top;
rcMax.right= rcScreen.right + rcFrame.right - rcView.right;
rcMax.bottom = rcScreen.bottom+ rcFrame.bottom- rcView.bottom;
return rcMax;
}