Chinaunix首页 | 论坛 | 博客
  • 博客访问: 455389
  • 博文数量: 724
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5010
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:47
文章分类

全部博文(724)

文章存档

2011年(1)

2008年(723)

我的朋友

分类:

2008-10-13 17:21:59

MFC框架程序中全屏显示特性的实现


编译/




    在开发图像显示程序以及视频应用程序时,常常需要全屏显示特性,比如ACD See和豪杰解霸等应用都有全屏显示功能。本文将介绍如何在MFC框架程序中实现视图的全屏显示,也就是说将标题、菜单、工具栏、状态栏以及窗口的所有边框全部被隐藏,视图充满整个屏幕。并提供全屏显示与框架窗口之间的快捷切换操作。
    大家知道,在MFC框架中并没有提供现成的类或者函数来实现全屏显示特性,至少我到目前为止是没有发现。但是要实现这个特性也并不难。其基本思路是调整主窗口的大小和位置,使视图的显示充满屏幕。它需要以屏幕左上角为原点,处理x,y方向上的负坐标。本文拟用“”一文中的例子代码作为基础,实现视图的全屏显示。我在原来代码中增加了一个可重用的C++类CFullScreenHandler,顾名思义,这个类的作用就是专门用来实现全屏显示特性的,它封装了所有的实现细节,只要你把它加到自己的工程代码中,不用怎么修改就能是程序具备全屏显示功能。这个类中有两个重要的方法调用:第一、Maximize进入全屏显示模式,注意了,这里的全屏显示模式并不是平常我们说的窗口最大化按钮哦。第二、Restore方法用来恢复原来的窗口框架。CFullScreenHandler还提供了一个InFullScreenMode方法,用它来检查程序是否处于全屏显示状态,这些方法都通过一个CFullScreenHandler全程对象实例来调用。下面是程序的主窗口处理命令,全屏显示特性由“查看”菜单中的“全屏显示(&U)”触发执行,关键代码如下:
void CMainFrame::OnViewFullScreen() 
{
    if (FullScreenHandler.InFullScreenMode())
       FullScreenHandler.Restore(this);
    else
       FullScreenHandler.Maximize(this);
}  
一旦进入全屏显示方式,那么标题栏、菜单栏和工具栏都会消失。千万别忘了告诉用户如何恢复原样,在OnDraw函数中加上几句即可:
void CPictureView::OnDraw(CDC* pDC)
{
     ......

	if (*ppic) {
        ......
        
		pDC->DrawText(FullScreenHandler.InFullScreenMode() ?
			_T("恢复窗口按 Ctrl-U 或者在客户区双击鼠标") : _T(""), &rc, 0);
	}
} 
如图一所示:

图一 给用户的恢复提示

    之所以一定要给用户这种提示,是因为Windows程序的一个重要的GUI特点就是界面操作的自解释。否则,当用户进入全屏显示模式后(有意或无意),如果找不到恢复的方法便会令用户感到不知所措。 
    下面我们就来看看CFullScreenHandler::Maximize和Restore的工作原理:其实这些代码没有什么高深的东西,只是一些象素计算而已。Maximize首先在m_rcRestore数据成员中保存当前框架的位置,然后计算期望的屏幕尺寸。如图二所示:

 
图二 计算期望的屏幕尺寸

    获得屏幕尺寸的方法是调用GetSystemMetrics函数。 Restore函数比Maximize更简单,它用m_rcRestore成员变量中保存的值将框架恢复到原来的样子,然后调用m_rcRestore.SetRectEmpty来表示框架不再处于全屏显示状态。就这么简单。
    程序中有一个地方要说明一下,那就是OnGetMinMaxInfo函数的作用。你可以试一下,如果把这个函数去掉,则当你按下工具栏中的全屏显示按钮时,框架视图确实变大了,但没有想象的那样实现全屏显示,底边留下一个状态栏——一个有些发育不良的全屏显示窗口。为什么会这样呢?经过调试后,发现问题出在WM_GETMINMAXINFO消息的处理上。在Windows中,无论什么时候以何种方式改变窗口的尺寸或大小,是拖拽窗口边缘也好,或是在代码中调用改变窗口尺寸的函数也好,总之不管你用什么方法,Windows都会首先发送WM_GETMINMAXINFO消息。这个消息的意思是说:“嘿,如果你要强迫我的尺寸变大或变小,就附上详细的MINMAXINFO结构信息,否则我用默认值处理。”大多数应用程序都不用显式处理这个WM_GETMINMAXINFO消息(也就是说让DefWindowProc窗口过程进行缺省处理),而Windows在进行缺省处理时是不会让一个窗口视图比屏幕还大的,所以我们会碰上前面讲的那个问题。解决的方法是:不要让Windows对WM_GETMINMAXINFO消息进行缺省处理,而是由我们自己处理,方法如下:
void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpmmi)
{
  CSize sz = FullScreenHandler.GetMaxSize();
  lpmmi->ptMaxSize = CPoint(sz);
  lpmmi->ptMaxTrackSize = CPoint(sz);
}     
这里CFullScreenHandler.GetMaxSize 返回的最大尺寸要比整个屏幕稍微大一点。
CSize CFullScreenHandler::GetMaxSize()
{
  CRect rc(0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
  rc.InflateRect(10,50);
  return rc.Size();
}
    GetMaxSize 返回的值分别是2×10=20和2×50=100象素,比屏幕自身的水平值和垂直值稍大。至于要大多少,我认为只要一个比屏幕大的模糊值即可。如果你硬要知道屏幕的精确尺寸,自己可以计算一下。
--------------------next---------------------

没什么价值,使用windows sdk可以很容易实现 ( jieer 发表于 2004-1-19 13:24:00)
 
我费了很大劲才调通了,其实还有点价值
首先到
中下载GdiPlus.zip
解压后分开放到VC目录下面
编译时有三个错误,一个是gdiplus某个头文件中没有定义ULONG_PTR谁都知道自己定义它,保存后重新编译就没有这个错误了,另外一个是找不到文件
C:\CQA0212\fullscreen\Myimgapp.cpp或什么的
我在该目录所有类型文件中搜索\CQA0212并把它去掉,问题就没了.最后一个错误是
CStaticLink::OnSetCursor(...)中有什么函数没有定义,
将该函数的所有语句屏蔽掉就好了
对了我是放在C:\fullscreen下面编译的,如果放在
C:\CQA0212\fullscreen下面可能就没有第二个错误了 ( dragonzht 发表于 2003-5-1 11:18:00)
 
是的,为什么不能运行啊,这个不负责啊, ( dyj057 发表于 2003-3-30 22:10:00)
 
那连接库哪里有啊! ( luoyou 发表于 2002-11-28 13:43:00)
 
好象少了一个连接库 ( raoyunfei 发表于 2002-11-28 12:58:00)
 
fsd ( iamsoHappy 发表于 2002-11-25 20:02:00)
 
.......................................................

--------------------next---------------------

阅读(225) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~