VC++技术内幕(第四版)笔记(第4章)[1]

[入库:2006年2月23日] [更新:2007年3月24日]

本文简介:

/******************************************/
第四章:基本事件处理、映射模式和滚动视图


1,消息映射:如在视窗中按下鼠标做键,会自动发送WM_LBUTTONDOWN消息,如果要对这消息有所反应的话,需

//{{AFX_MSG(CEx04aView)
 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);//头文件声明消息响应函数原型。
//}}AFX_MSG
DECLARE_MESSAGE_MAP()//头文件

BEGIN_MESSAGE_MAP(CDrawView, CView)//代码文件
 //{{AFX_MSG_MAP(CEx04aView)
 ON_WM_LBUTTONDOWN()//该消息映射宏将OnLButtonDown函数和应用程序框架联系在一起
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) //代码文件
{
 //event processing code here
}
说明:
为了方便ClassWizard,AppWizard生成了一些注释行。它把消息映射函数原型放在两个AFX_MSG“刮弧对”之间,在AFX_MSG_MAP“刮弧对”之间添加消息映射入口,并在代码文件中给出完整的OnLButtonDown成员函数框架。

2,视图中的OnDraw()是根据视图当前状态来绘制图象的,用户的操作可以改变这中状态。在完整的MFC库应用程序中,文档的对象掌握在应用程序(视图)的状态。

3,如果用全程变量来保存视图状态,这将在多视图情况下会遇到麻烦;(待体会)

4,CWnd::InvalidateRect函数能够触发WM_PAINT消息,该消息被窗口类如CView映射后,引起对OnDraw函数调用,从而重绘无效矩形区域。
优化窗口的绘制过程:
1)设置的无效区域越小,重画的速度就越快;
2)执行无效区域外的绘制纯属于浪费时间,OnDraw函数可以调用CDC的成员函数GetClipBox得到无效区域大小。
注意:
OnDraw函数不仅仅响应InValidate*之类的调用,它也会在窗口改变大小和窗口显露时被调用。

5,本章重要介绍函数
PtInRect(..);//测试一个点是否落在某个矩形内。
PtInRegion(..);//判断一个点是否落在椭圆(CRgn对象)内//A region is an elliptical or polygonal area within a window.
GetClientRect(..);//获得客户矩形坐标并保持在CRect对象中
SelectStockObject(..);//选择the predefined stock pens, brushes, or fonts到DC中,函数返回先前的CGdiObject 对象指针。

6,在构造函数中对类数据成员初始化。
CEx04aView::CEx04aView() : m_rectEllipse(0, 0, 200, 200)//注意这种初试化方式,m_rectEllipse是CEx04aView类数据成员CRect类对象
{
 m_nColor = GRAY_BRUSH;
}

7,[致WIN32程序员]:
 标准的基于WINDOWS应用程序会首先登记一个窗口类(不同于C++类[补:实际是个_WNDCLASS结构体]),同时在处理过程中,还需要对每个类指定窗口过程(WINDOWS PROCEDURE)。每次应用程序调用CreateWindow建立一个窗口时候,都要指定一个窗口类做为参数,这样就把新建立的窗口和窗口过程函数连接起来了。每次Windows给窗口发送消息时候,这个函数就会被调用(补:消息循环中DispatchMessage(&msg)分派消息到窗口的回调函数处理,OS调用窗口回调函数进行处理),以检查用参数传送进来的消息码,并执行适当的代码来处理该消息。
 MFC库应用程序框架有一个适用于大多数窗口类型的简单窗口类和窗口过程函数。该窗口过程函数会根据参数传进来的窗口句柄,在MFC的句柄映射表(handle map)中查找,从而得到对应的C++窗口对象指针。然后,该窗口过程函数用MFC运行时类(runtime class)系统来决定窗口对象的C++类。下一步,它从由消息分发映射函数生成的静态表中找到消息处理函数,最后用正确的窗口对象调用消息处理函数。

8,映射模式:
1)MM_TEXT映射模式:坐标被映射到象素,X值向右递增,Y值向下递增。可用它来表示[设备坐标]。
CDC::SetMapMode(..)//设置映射模式
CDC::GetMapMode(..)
CDC::SetViewportOrg(..)//设置视口原点
CDC::GetViewportOrg(..)
CDC::SetWindowOrg (..)//设置屏幕原点
CDC::GetWindowOrg(..)
2)固定比例映射模式(MM_HIENGLISH,MM_HIMETRIC ,MM_LOMETRIC ,MM_LOENGLISH,MM_TWIPS )
固定比例映射模式均X值向右递增,Y值向下递增,它们之间唯一差别是 实际的比例因子。如下:
MM_HIENGLISH   Each logical unit is converted to 0.001 inch.
MM_HIMETRIC   Each logical unit is converted to 0.01 millimeter.
MM_LOENGLISH   Each logical unit is converted to 0.01 inch.
MM_LOMETRIC   Each logical unit is converted to 0.1 millimeter.
MM_TWIPS   Each logical unit is converted to 1/20 of a point(磅). (Because a point is 1/72 inch, a twip is 1/1440 inch.)
//MM_TWIPS常常用于打印机。        
3)可变比例映射模式:(MM_ISOTROPIC ,MM_ANISOTROPIC )
这两种模式用许我们改变它们的比例因子和坐标原点。
应用这两中模式,如用户改变窗口的尺寸,绘制的图形大小也会发生响应的变化
具体如下:
The MM_HIENGLISH, MM_HIMETRIC, MM_LOENGLISH, MM_LOMETRIC, and MM_TWIPS modes are useful for applications that must draw in physically meaningful units (such as inches or millimeters). The MM_ISOTROPIC mode ensures a 1:1 aspect ratio, which is useful when it is important to preserve the exact shape of an image. The MM_ANISOTROPIC mode allows the x- and y-coordinates to be adjusted independently
常一起使用的函数:
SetWindowExt(..)//Sets the x- and y-extents of the window associated with the device context.
SetViewportExt(..)//Sets the x- and y-extents of the viewport of the device context. 

注意:
When the following mapping modes are set, calls to SetWindowExt and SetViewportExt functions are ignored:
 MM_HIENGLISH,MM_HIMETRIC,MM_LOENGLISH,MM_LOMETRIC,MM_TEXT,MM_TWIPS
When MM_ISOTROPIC mode is set, an application must call the SetWindowExt member function before calling SetViewportExt.

9,坐标变换:(具体参见P54)
许多MFC库函数只能在设备坐标下工作(尤其CRect类成员函数)。可以认为CDC的所有成员函数都一逻辑坐标作参数。可以认为CWnd的成员函数都以设备坐标做参数。(所有在实际窗口上点击获得的坐标都是逻辑坐标)。在设置了设备环境的映射模式及相应的参数以后,CDC的LPtoDP和DPtoLP函数可以用来在逻辑坐标系和设备做表系之间进行转换。
在CView的虚函数OnPrepareDC中设置映射模式要比在OnDraw函数中要好。
//*注意:
CView::OnPrepareDC
virtual void OnPrepareDC( CDC* pDC, CPrintInfo* pInfo = NULL );
应用程序将在调用OnDraw之前调用OnPrepareDC函数。
(OnPrepareDC在为屏幕显示而调用OnDraw函数之前,或在为打印或打印预览每一页而调用OnPrint成员函数之前。)

10,CScrollView支持滚动条的滚动,但不支持键盘的滚动。通过使用CWnd的ScrollWindow和SetViewportOrg函数,CScrollView类允许将视口原点移到窗口中的任何一个位置,甚至包括窗口区域的上部或窗口的原点的左边。

键盘输入是分两步处理的。OS向窗口发送类如WM_KEYDOWN和WM_KEYUP消息时用的是虚拟键盘码,在消息到达窗口之前,被翻译成WM_CHAR消息,该消息带着正常的键码。

本文关键:VC++技术内幕(第四版)笔记(第4章)
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top