程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> MFC框架程序中全屏顯示特性的實現

MFC框架程序中全屏顯示特性的實現

編輯:關於VC++

在開發圖像顯示程序以及視頻應用程序時,常常需要全屏顯示特性,比如ACD See和豪傑解霸等應用都有全屏顯示功能。本文將介紹如何在MFC框架程序中實現視圖的全屏顯示,也就是說將標題、菜單、工具欄、狀態欄以及窗口的所有邊框全部被隱藏,視圖充滿整個屏幕。並提供全屏顯示與框架窗口之間的快捷切換操作。

大家知道,在MFC框架中並沒有提供現成的類或者函數來實現全屏顯示特性,至少我到目前為止是沒有發現。但是要實現這個特性也並不難。其基本思路是調整主窗口的大小和位置,使視圖的顯示充滿屏幕。它需要以屏幕左上角為原點,處理x,y方向上的負坐標。本文擬用“使用GDI+進行圖像處理”一文中的例子代碼作為基礎,實現視圖的全屏顯示。我在原來代碼中增加了一個可重用的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象素,比屏幕自身的水平值和垂直值稍大。至於要大多少,我認為只要一個比屏幕大的模糊值即可。如果你硬要知道屏幕的精確尺寸,自己可以計算一下。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved