|          
文/刘涛
 前言:
 
 在Visual C++编程中,有时需要采用尽量大的区域来作为显示区域,那么实现程序的全屏幕显示就不失为一种很好的选择了,所谓全屏幕显示,就是程序界面上没有菜单条、工具条等附加项,整个显示屏幕作为一个显示窗口来显示数据或图像,Windows的很多应用程序都提供了全屏幕显示功能,如Word、Excel和IE等。本例通过响应鼠标单击在全屏幕上画数字曲线来说明如何实现程序的全屏幕显示。
 
 一、实现方法
 
 实现程序的全屏幕其实很容易,它的实现思路就是:首先要自定义一个窗口类,重载该窗口类的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,使窗口能够顺利的最大、最小化。可以看出,与本文的实现方法比起来,这种方法实现起来十分繁琐,不太适合初级编程爱好者。
 
 |