关于全屏显示与退出的搜集整理

第一种 CMainFrame类

全屏显示是一些应用软件程序必不可少的功能。比如在用VC++编辑工程源文件或编辑对话框等资源时,选择菜单“View\Full Screen”,即可进入全屏显示状态,按“Esc”键后会退出全屏显示状态。
  在VC++6.0中我们用AppWizard按默认方式生成单文档界面的应用程序框架。下面将先讨论点击菜单项“View\Full Screen”实现全屏显示的方法,再讲述按“Esc”键后如何退出全屏显示状态。
  1) 在CMainFrame类中,增加如下三个成员变量。
  class CMainFrame : public CFrameWnd
  { private: //自己添加的三个成员变量
  WINDOWPLACEMENT m_OldWndPlacement; //用来保存原窗口位置
  BOOL m_bFullScreen; //全屏显示标志
  CRect m_FullScreenRect; //表示全屏显示时的窗口位置
  protected: CMainFrame();
  DECLARE_DYNCREATE(CMainFrame)}
  2)在资源编辑器中编辑菜单IDR_MAINFRAME。在“View”菜单栏下添加菜单项“Full Screen”。在其属性框中,ID设置为ID_FULL_SCREEN,Caption为“Full Screen”。还可以在工具栏中添加新的工具图标,并使之与菜单项“Full Screen”相关联,即将其ID值也设置为ID_FULL_SCREEN。
  3)设计全屏显示处理函数,在CMainFrame类增加上述菜单项ID_FULL_SCREEN消息的响应函数。响应函数如下:
  void CMainFrame::OnFullScreen()
  {GetWindowPlacement(&m_OldWndPlacement);
  CRect WindowRect;
  GetWindowRect(&WindowRect);
  CRect ClientRect;
  RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery, &ClientRect);
  ClientToScreen(&ClientRect);
  // 获取屏幕的分辨率
  int nFullWidth=GetSystemMetrics(SM_CXSCREEN);
  int nFullHeight=GetSystemMetrics(SM_CYSCREEN);
  // 将除控制条外的客户区全屏显示到从(0,0)到(nFullWidth, nFullHeight)区域, 将(0,0)和(nFullWidth, nFullHeight)两个点外扩充原窗口和除控制条之外的 客户区位置间的差值, 就得到全屏显示的窗口位置
  m_FullScreenRect.left=WindowRect.left-ClientRect.left;
  m_FullScreenRect.top=WindowRect.top-ClientRect.top;
  m_FullScreenRect.right=WindowRect.right-ClientRect.right+nFullWidth;
  m_FullScreenRect.bottom=WindowRect.bottom-ClientRect.bottom+nFullHeight;
  m_bFullScreen=TRUE; // 设置全屏显示标志为 TRUE
  // 进入全屏显示状态
  WINDOWPLACEMENT wndpl;
  wndpl.length=sizeof(WINDOWPLACEMENT);
  wndpl.flags=0;
  wndpl.showCmd=SW_SHOWNORMAL;
  wndpl.rcNormalPosition=m_FullScreenRect;
  SetWindowPlacement(&wndpl);}
  4)重载CMainFrame类的OnGetMinMaxInfo函数,在全屏显示时提供全屏显示的位置信息。
  void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
  {if(m_bFullScreen)
  {lpMMI->ptMaxSize.x=m_FullScreenRect.Width();
  lpMMI->ptMaxSize.y=m_FullScreenRect.Height();
  lpMMI->ptMaxPosition.x=m_FullScreenRect.Width();
  lpMMI->ptMaxPosition.y=m_FullScreenRect.Height();
  // 最大的Track尺寸也要改变
  lpMMI->ptMaxTrackSize.x=m_FullScreenRect.Width();
  lpMMI->ptMaxTrackSize.y=m_FullScreenRect.Height();
  }CFrameWnd::OnGetMinMaxInfo(lpMMI) ;
  }完成上面的编程后,可以联编执行FullScreen.exe,选择菜单“View\Full Screen”或点击与之关联的工具栏按钮即可进入全屏显示状态。但现在还需要增加用户退出全屏显示状态的操作接口,下面讲述如何编程实现按“Esc”键退出全屏显示状态。
  1)在ClassView中选中CMainFrame并单击鼠标右键,选择“Add Member Function...”,添加public类型的成员函数EndFullScreen,该函数将完成退出全屏显示的操作。
  void CMainFrame::EndFullScreen()
  {if(m_bFullScreen)
  {// 退出全屏显示, 恢复原窗口显示
  ShowWindow(SW_HIDE);
  SetWindowPlacement(&m_OldWndPlace
ment);}}
  2)函数EndFullScreen可以退出全屏显示状态,问题是如何在“Esc”键被按下之后调用执行此函数。由于视图类可以处理键盘输入的有关消息(如WM_KEYDOWN表示用户按下了某一个键),我们将在视图类CFullScreenView中添加处理按键消息WM_KEYDOWN的响应函数OnKeyDown。判断如果按的键为“Esc”键,则调用CMainFrame类的函数EndFullScreen,便可退出全屏显示状态。
  void CFullScreenView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  {if(nChar==VK_ESCAPE) // 如果按的键为Esc键
  {// 获取主框架窗口的指针
  CMainFrame *pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  // 调用主窗口类的自定义函数 EndFullScreen ,便可退出全屏显示状态
  pFrame->EndFullScreen();}
  CView::OnKeyDown(nChar, nRepCnt, nFlags);}
  这样我们就实现了比较专业的全屏显示的功能,相信肯定会令你设计的软件程序增色不少。

第二种 


一、实现方法

实现程序的全屏幕其实很容易,它的实现思路就是:首先要自定义一个窗口类,重载该窗口类的OnPaint()或OnDraw()函数,实现具体的窗口显示功能,然后调用API函数GetDeviceCaps(int nIndex )函数来获取当前显示屏幕的尺寸,如nIndex取LOGPIXELSX值可以得到屏幕的宽度(以像素为单位),取LOGPIXELSY值可以得到屏幕的高度。有了屏幕的尺寸还不够,还必须调用一个API函数MoveWindow()用来定位当前窗口到整个屏幕。需要读者注意的是,为了实现窗口与用户的交互,要在窗口中装载一个光标,另外,为了重全屏幕显示恢复到正常状态,需要在该窗口类中处理WM_KEYDOWN消息,在该消息处理函数中识别是否用户按下了ESC(退出)键,如是,程序恢复到正常显示状态。下面的代码实现了上面所有的功能,并且能够响应鼠标操作,在屏幕上数字曲线。编程步骤如下:

1、定义一个窗口类CGribbleWnd,它包含两个整形变量m_pixelsX、m_pixelsY,分别用来存储窗口的尺寸;
2、使用CLASSWIZARD重载窗口类的OnPain()函数,实现具体的显示功能;
3、使用CLASSWIZARD为窗口类添加WM_CREATE、WM_ERASEBKGND、WM_KEYDOWN、WM_LBUTTONDOWN等消息处理函数,以实现全屏幕窗口和响应用户操作;

二、程序代码:

CGribbleWnd类的头文件
#if !defined(AFX_GRIBBLEWND_H__6E1D4ED1_D9A6_11D4_9B9F_525400DAE6A0__INCLUDED_)
#define AFX_GRIBBLEWND_H__6E1D4ED1_D9A6_11D4_9B9F_525400DAE6A0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CGribbleWnd : public CWnd
{
// Construction
public:
CGribbleWnd();
// Attributes
public:
// screen stuff
int m_pixelsX;//存放屏幕的宽度;
int m_pixelsY;//存放屏幕的高度;
CDC* m_pDC;//设备上下文对象;
HCURSOR m_hCursor; //光标句柄;
COLORREF m_backColor; //颜色对象,用来存放用户自定义的颜色;
// Operations
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CGribbleWnd)
//}}AFX_VIRTUAL
// Implementation
virtual ~CGribbleWnd();
// Generated message map functions
protected:
//{{AFX_MSG(CGribbleWnd)
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnPaint();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
#endif // !defined(AFX_GRIBBLEWND_H__6E1D4ED1_D9A6_11D4_9B9F_525400DAE6A0__INCLUDED_)
/// CGribleWnd类的实现文件;
#include "stdafx.h"
#include "GribbleWnd.h"
#include
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CGribbleWnd::CGribbleWnd()//构造函数;
{
}
CGribbleWnd::~CGribbleWnd()//析构函数;
{
}
BEGIN_MESSAGE_MAP(CGribbleWnd, CWnd)
//{{AFX_MSG_MAP(CGribbleWnd)
ON_WM_ERASEBKGND()
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_PAINT()
ON_WM_KEYDOWN()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CGribbleWnd::OnEraseBkgnd(CDC* pDC) //重画背景窗口的背景;
{
m_backColor = RGB(125,200,125);//自定义颜色;
//生成一个新的画刷,用自定义的颜色刷新显示区域;
CBrush cb(m_backColor);
HBRUSH hOldBrush = (HBRUSH)pDC->SelectObject(cb);
RECT rect = {0,0,m_pixelsX,m_pixelsY};
pDC->FillRect(&rect,&cb);
pDC->SelectObject(hOldBrush);
cb.DeleteObject();
return TRUE;
}
int CGribbleWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) //创建窗口;
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
m_hCursor =LoadCursor(NULL,IDC_ARROW); //装载鼠标,用来与用户交互;
SetCursor(m_hCursor);//将装载的鼠标附给生成的窗体;
ShowCursor(true);//显示鼠标;
m_pDC = GetDC();//得到当前窗体的设备上下文对象;
m_pixelsX = m_pDC->GetDeviceCaps(HORZRES);//获取屏幕的宽度;
m_pixelsY = m_pDC->GetDeviceCaps(VERTRES);//获取屏幕的高度;
MoveWindow(0,0,m_pixelsX, m_pixelsY);//将当前窗口全屏幕显示;
return 0;
}
void CGribbleWnd::OnLButtonDown(UINT nFlags, CPoint point) //响应用户的鼠标单击操作;
{
Invalidate();//重画窗口;
}
void CGribbleWnd::OnPaint() //实现具体的显示效果,本例用来显示数学曲线;
{
CPaintDC dc(this); //得到设备上下文对象;
//下面的代码用来实现显示数学曲线;
static int s_nLisXCoef = 1;
static int s_nLisYCoef = 3;
static int s_nLisYOffset = 44;
++s_nLisXCoef;
++s_nLisYCoef;
int x,y;
for (float t = 0; t < 32767; t+=0.2) {
x = sin(s_nLisXCoef*t) * m_pixelsX/2 + m_pixelsX/2;
y = sin(s_nLisYCoef*t+s_nLisYOffset) * m_pixelsY/2 + m_pixelsY/2;
dc.SetPixel(x, y, RGB(255,80,255));
}
}
//响应用户的按键操作,当用户按下ESC(退出)键后,程序恢复正常显示;
void CGribbleWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if(VK_ESCAPE == nChar)//判断当前按下的键是否为"ESC"
DestroyWindow();//销毁当前窗体;
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

三、小结

实现程序全屏幕显示的思路有很多种,例如另外一种可行的思路是:

1)利用Windows API提供的一个结构体WINDOWPLACEMENT来存储全屏显示前视图和主框架窗口在屏幕上的位置和显示信息、非客户区窗口的显隐信息,以便全屏幕显示时恢复窗口原状;
2)通过API函数::GetDesktopWindow()得到桌面窗口,由::GetWindowRect()得到显示器的尺寸;
3)通过::AdjustWindowRect()来计算当客户区大小为屏幕大小时相应的窗口大小;
4)通过::SetWindowPlacement()来设置视图窗口和主窗口为客户区大小和屏幕大小的窗口;
5)处理窗口消息WM_GETMINMAXINFO,使窗口能够顺利的最大、最小化。可以看出,与本文的实现方法比起来,这种方法实现起来十分繁琐,不太适合


and:






void CXXXDlg::SetFullScreen()
{
int frameWidth =  GetSystemMetrics(SM_CXFRAME);
int frameHeight = GetSystemMetrics(SM_CYFRAME);
int captionHeight = GetSystemMetrics(SM_CYCAPTION);
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
CRect rect;
GetClientRect(&rect);
rect.left = rect.left - frameWidth;
rect.top = rect.top - frameHeight - captionHeight ;
rect.bottom = rect.top + screenHeight + 2 * frameHeight + captionHeight;
rect.right = rect.left + screenWidth + 2 * frameWidth;
ShowWindow(SW_HIDE);
SetWindowPos(&wndTopMost, rect.left, rect.top, rect.Width(), rect.Height(), SWP_SHOWWINDOW);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值