MFC框架中视图窗口全屏显示

 

在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;
};
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;
}

作者:苏林
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值