实验5 输入/输出管理
5.1  Windows鼠标处理 
背景知识
一台计算机拥有大量的输入设备,而鼠标和键盘是其中最常用的输入设备。实际上,基本的鼠标和键盘处理就像使用Visual C++ 的Class Wizard在MFC程序中添加一两个消息响应函数一样简单。
鼠标和键盘各自生成自己类型的消息。例如,鼠标生成类似WM_MOUSEMOVE、WM_LBUTTON和WM_RBUTTONCLK的Windows消息。
1. 客户区的鼠标消息
客户区就是应用程序可在其中绘图的窗口部分。当鼠标指针滑过应用程序所拥有的窗口客户区时,Windows将就把客户区鼠标消息传送给应用程序。使用诸如WM_MOUSEMOVE这类鼠标事件消息,鼠标就可以与应用程序通信。例如,在用户移动鼠标经过应用程序窗口的客
户区时,应用程序接收WM_MOUSEMOVE消息流,不仅通知用户正在移动鼠标,而且通知Windows生成WM_MOUSEMOVE消息时鼠标的位置。
在鼠标移出应用程序窗口的客户区时,应用程序停止接收客户区鼠标消息。Windows改为把鼠标消息传送给鼠标碰巧经过的窗口 (包含桌面) 。当鼠标返回窗口的客户区时,Windows重新将鼠标消息传送给应用程序。
表5-1描述了应用程序可以接收的18种客户区鼠标消息。
 
5-1  客户区鼠标消息
消息
描述
WM_CAPTURECHANGED
窗口失去鼠标捕获
WM_LBUTTONDBLCLK
双击鼠标左键
WM_LBUTTONDOWN
单击鼠标左键
WM_LBUTTONUP
释放鼠标左键
WM_MBUTTONDBLCLK
双击鼠标中键
WM_MBUTTONDOWN
单击鼠标中键
WM_MBUTTONUP
释放鼠标中键
WM_MOUSEACTIVATE
在用户点击鼠标按钮时,鼠标光标位于非活动窗口中mousemove是什么键
WM_MOUSEHOVER
鼠标光标掠过窗口的客户区,停留时间通过调用TrackMouseEvent() 进行设置
WM_MOUSELEAVE
鼠标离开TrackMouseEvent() 调用指定的窗口客户区
WM_MOUSEMOVE
鼠标移到客户区之上
WM_MOUSEWHEEL
滚动鼠标滚轮
WM_RBUTTONDBLCLK
双击鼠标右键
WM_RBUTTONDOWN
单击鼠标右键
WM_RBUTTONUP
释放鼠标右键
WM_XBUT’TONDBLCLK
双击鼠标X
WM_XBUTTONDOWN
单击鼠标X
WM_XBUTTONUP
释放鼠标X
 
2. 非客户区鼠标消息
Windows也会把非客户区鼠标消息传送给应用程序。当鼠标经过应用程序窗口客户区之外的区域时,就会产生这类鼠标消息。例如,当鼠标经过窗口的标题栏或者控制按钮时,应用程序就会接收非客户区鼠标消息。因为非客户区的鼠标消息最好由Windows自己来处理,所以大部分应用程序忽略这些消息。例如,用户双击窗口标题栏,Windows恢复上一次设置的窗口尺寸。
通常不希望干涉Windows对非客户区鼠标消息的缺省处理,因为这样做会导致应用程序的窗口停止对用户期待的响应。
实验目的
通过学习如何在Windows应用程序中添加对鼠标的支持:
1) 讨论Windows的鼠标编程技巧;
2) 了解Windows 2000输入/输出处理技术。
工具/准备工作
在开始本实验之前,请回顾教科书的相关内容。
您需要做以下准备:
1) 一台运行Windows 2000 Professional操作系统的计算机。
2) 计算机中需安装Visual C++ 6.0专业版或企业版。
实验内容与步骤
在本实验中,我们通过一个应用程序示例来讨论鼠标编程技巧,了解如何响应鼠标消息和如何在应用程序中捕获鼠标。 (该程序的完整实例保存在本书所附光盘的“程序代码”文件夹中“5-1”子文件夹)
步骤1:登录进入Windows 2000 Professional。
步骤2:在“开始”菜单中单击“程序”-“Microsoft Visual Studio 6.0”-“Microsoft Visual C++ 6.0”命令,进入Visual C++ 窗口。
步骤3在File菜单单击命令,在“Open Workspace”对话框中到“5-1”文件夹并打开实验文件Mouse.dsw。
 
提示项目工作区Workspace是一个包含用户的所有相关项目和配置的实体。工程定义为一个配置和一组文件,用以生成最终的程序或二进制文件。一个项目工作区可以包含多个工程,这些工程既可以是同一类型的工程,也可以是由不同类型的工程 (Visual C++ Visual J++工程) 。工作区文件以 .dsw为后缀名 (以前为.mdp) ,项目文件以 .dsp (以前为.mak) 为后缀名。
 
步骤4单击Build菜单中的命令,系统对程序进行编译并建立可执行文件。
操作能否正常进行?如果不行,则可能的原因是什么?
    _______可以正常运行_________________________________________________
________________________________________________________________________
步骤5在工具栏单击“Execute Program”按钮,执行程序,响应鼠标消息。
Mouse示例程序演示了如何截取和响应鼠标消息。运行这个程序,就会显示一个主窗口。最初窗口是空白的,但是直接在窗口中移动鼠标,WM_MOUSEMOVE消息就会出现在窗口上,同时显示鼠标的坐标。在鼠标经过窗口时单击鼠标左键,窗口中不仅出现WM_LBUTTONDOWN和WM_LBUTTONUP消息,而且显示事件发生的坐标。单击鼠标右键,再次出现上述情况。
请记录:
      WM_MOUSEMOVE            X: ____178______    Y: ____114______
      WM_LBUTTONDOWN        X: ____230______    Y: ____115______
      WM_LBUTTONUP            X: ____230______    Y: ____115______
 
      WM_RBUTTONDOWN        X: ____201______    Y: ____204______
      WM_RBUTTONUP            X: ____201______    Y: ____204______
观察演示情况,请说明,显示的各消息反映了什么鼠标事件?
      WM_MOUSEMOVE        :_______显示鼠标移动到的位置的坐标_________
      WM_LBUTTONDOWN    :_______显示点击鼠标左键位置的下坐标______
      WM_LBUTTONUP        :_______显示点击鼠标左键位置的上坐标_______
      WM_RBUTTONDOWN    :_______显示点击鼠标右键位置的下坐标________
      WM_RBUTTONUP        :_______显示点击鼠标右键位置的上坐标________
步骤6:捕获鼠标消息。
Mouse应用程序也举例说明了鼠标捕获的技巧。有些时候需要应用程序接收鼠标消息,甚至鼠标不在应用程序客户区时,也有这个要求。例如在一个画图程序中,用户在窗口中画线时一直接住鼠标左键。如果一个用户碰巧把鼠标指针移到画图应用程序的窗口之外,应用程序必须继续接收鼠标消息。否则用户在窗口之外释放鼠标按钮,应用程序将无法知道用户是否仍旧在画图。
为了解鼠标捕获的工作情况,可把指针移动到Mouse应用程序的客户区,然后一直按住鼠标右键,在屏幕上任意移动鼠标。即使鼠标移动到窗口外,窗口继续接收鼠标消息。
在不按住鼠标右键移动鼠标时,鼠标指针离开了应用程序的客户区的情况下,应用程序停止接收鼠标消息。
注意到,在按住鼠标右键移动到客户区外面左侧时,WM_MOUSEMOVE的坐标值现在为负的。这是因为什么?
 答:因为客户区窗口左侧和上边为坐标轴,边际值为0,鼠标超出客户区时还要继续捕捉鼠标信息,此时坐标只能用负数表示。
5.2  Windows打印
背景知识
1. 在MFC应用程序中打印文本
进一步地,如果使用MFC AppWizard来组装应用程序,可以十分容易地获得基本的打印和打印预览功能。
为了获得这种功能,要确保在AppWizard的“Step 4 of 6”对话框中选择“Printing and print preview (打印和打印预览) ”选项,使AppWizard应用程序可获得打印机的名称和获取打印机DC的所有细节。读者只需要改进所生成的源代码就能够为应用程序产生适当的打印输出。
使用MFC的缺省打印功能时,应用程序的文档都在OnDraw() 函数中屏幕显示和发送到打
印机。所不同的是,在屏幕显示的情况下,发送到OnDraw() 的DC对象是客户窗口;在打印的情况下,DC用于当前打印机。DC切换的灵活运用使某一函数既能向屏幕输出,也能向打印机输出,使产生WYSIWYG (What You See Is What You Get,所见即所得) 更加容易。
除了以正确的尺寸缩放打印机输出外,还可能要处理页码、页眉和页脚、字体以及Windows应用程序为打印具有专业外观的文档而必须完成的其他任务。MFC不仅通过创建打印机描述环境,而且通过在CView类中提供在各阶段都能够使视图窗口访问打印过程的各种成员函数,从而进行大量的打印文档的作业。
当编写带有打印功能的MFC程序时,通常需要为指定的应用程序改进缺省的MFC打印功能。CView类 (可从中派生自己的应用程序视图窗口) 定义了五个用于打印的MFC成员函数:OnPreparePrinting() 、OnBeginPrinting() 、OnPrepareDC() 、OnPrint() 和OnEndPrinting() ,能够用来对打印过程的不同阶段实施控制。
(1) OnPreparePrinting() 函数
必须在视图窗口类中重载这个函数并调用DoPreparePrinting()函数。DoPreparePrinting() 函数显示Print对话框,并创建打印机DC。在OnPreparePrinting()函数中可以改变Print对话框中显示的一些值。
当使用MFC AppWizard来创建自己的应用程序,并为此应用程序选择Printing and print preview选项时,AppWizard自动重载了OnPreparePrinting() 函数,如下所示:
      BOOL CPrintAppView :: OnPreparePrinting(CPrintInfo * pInfo)
      {
          // 缺省的准备过程
          return DoPreparePrinting(pInfo) ;
      }
OnPreparePrinting() 重载了DoPreparePrinting() 函数,后者用来显示Print对话框。通过初始化作为惟一参数传递给该函数的CPrintInfo对象成员,可以控制在此对话框中显示的选项。
例如,如果已知文档有三页,就可以按如下方式对CPrintInfo对象的SetMinPage() 和SetMaxPageo成员函数加以调用:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。