The CmyFrame class
An object of class CmyFrame represents the application’s main frame window. When the constructor class the Create member function of the base class CframeWnd, Windows creates the actual window structure and the application framework links it to the C++ object. You must call the SbowWindow and UpdateWindow functions, also member functions of the base class, in order to display the window.
CmyFrame类
在你的应用程序中声明一个名为CmyFrame的主窗口类.当调用基类的成员函数Create是,Windows才真正的去建立窗口结构和连接到应用框架的C++对象.你必须调用ShowWindow和UpdateWindow函数,它们也是基类的成员函数,顺序的显示窗口.
The CmyFrame::OnLButtonDown function
This function is a sneak preview of the MFC library’s message-handling capability. I’ve elected to “map” the left mouse button down event to a CmyFrame member function. You’ll learn the details of the MFC library’s message mapping in Chapter 5. For the time being, accept that this function gets called when the user presses the left mouse button. The function invokes the MFC library TRACE macro to display a message in the debugging window.
CmyFrame::OnLButtonDown函数
这个函数事先在背后查看MFC消息处理的能力.我将用”map”映射这个词来代替在CmyFrame 成员函数引发的鼠标左键单击事件.你将在第5章学习更详细的MFC消息映射的内容.事实上,当用户按鼠标左键是这个函数被调用来接收此信息.这个函数调用MFC中的TRACE宏在调试窗口中显示消息.
The CmyFrame::OnPaint function
The application framework calls this important mapped member class CmyFrame every time it’s necessary to repaint the window: at the start of the program, when the user resizes the window, and when all or part of the window is newly exposed. The CpaintDC statement relates to the classic Graphics Device Interface(GDI) and is explained in later chapters. The TextOut function displays “Hello, world!”(We’ll look at GDI+ when we discuss .NET).
CmyFrame::OnPaint函数
应用程序框架每次调用CmyFrame类中重要的映射成员时都必须重绘窗口:
在程序的开始,当用户重绘窗口,并且当全部或部分的窗口是重新显示的.在本
章后面将介绍CpaintDC在图象设备接口中的关系.TextOut函数显示”Hello,World!”(我门讨论.NET时来考虑GDI+)
Application shutdown
The user shuts down the application by closing the main frame window. This action initiates a sequence of events, which ends with the destruction of the CmyFrame object, the exit from Run, the exit from WinMain, and the destruction of the CmyApp object.
应用程序的关闭
当用户通过主框架窗口来关闭应用程序是,事情是这样进行的,先销毁CmyFrame对象,退出运行,退出WinMain,最后销毁CmyApp对象.
Look at the code example again. This time try to get the big picture.
Most of the application’s functionality is in the MFC library base
classes CwinApp and CframeWnd. In writing MYAPP, I’ve followed a few
simple structure rules and have written key functions in my derived
classes. C++ lets you “borrow” a lot of code without copying it. Think
of it as a partnership between you and the application framework. The
application framework provides the structure, and you provide the code
that makes the application unique.
在一次考虑例子中的代码,此时试着得到一个大的轮廓.许多应用程序的功能
都在MFC基类CwinApp和CframeWnd中.在MYAPP中,我们跟踪一些简单的结构
类中关键的函数.C++允许你”借用”许多它之外的代码,复制给它.感谢应用
架跟你之间的伙伴关系.应用框的结构和你提供的代码在应用程序中是唯一的.
Now you’re beginning to see why the application framework is more
than just a class library. Not only does the application framework define
the application structure, but it also encompasses more than C++ base
classes. You’ve already seen the hidden WinMain function at work. Other
elements support message processing, diagnostics, DLLs, and so forth.
现在刚刚好开始看应用框架中更多的类库.应用程序框架不仅仅是定义应
程序结构,它还包含很多C++的基础类.你已经看到了隐藏的WinMain函数的工作
了.以后你将看到其它元素,支持消息处理,诊断,动态连接库等等.
MFC Library Message Mapping
Take a look at the OnLButtonDown member function in the previous
example. You might think that it would be an ideal candidate for a virtual
function. A window base class would define virtual functions for mouse
event messages and other standard messages, and derived window classes
could override the functions as necessary. Some Windows class libraries
do work this way.
MFC消息映射
注意例子中的OnLButtonDown成员函数.你可能在想它是虚函数的完美代表
窗口基类将定义鼠标事件消息和其他标准消息的虚函数,同时你必须重载来自窗
口类的函数.少数Windows类库是这样工作的.
However, the MFC library application framework doesn’t use virtual
functions for Windows messages. Instead, it uses macros to “map”
specified messages to derived class member functions. Why the rejection
of virtual functions? Suppose the MFC library used virtual functions for
messages. The CWnd class would declare virtual functions for more than
100 messages. C++ requires a virtual function dispatch table, called a
vtable, for each derived class used in a program. Each vtable needs one
4-byte entry for each virtual function, regardless of whether the
functions are actually overridden in the derived class. Thus, for each
distinct type of window or control, the application would need a table
consisting of over 400 bytes to support virtual message handlers.
然而,MFC应用框架不会为Windows消息使用虚函数.改成,它用宏来实
给”map”指定消息到类成员函数.为什么拒绝使用虚函数呢?设想一下MFC库为消息使用虚函数.CWnd类将定义多达100条消息的虚函数.C++请求虚函数分配表,调用vtable,在程序中每个类都这么做. 每个vtable都需要为每个虚函数分配一个4字节的入口空间.不管有没有超过类的实际需要.因而,对于每个不同类型的窗口和类,应用程序将需要一个由400字节组成的支持虚消息管理器.
What about message handlers for menu command messages and messages
from button clicks? You couldn’t define these as virtual functions in
a window base class because each application might have a different set
of menu commands and buttons. The MFC library message map system avoids
large vtables, and it accommodates application-specific command messages
in parallel with ordinary Windows messages. It also allows selected
nonwindow classes, such as document classes and the application class,
to handle command messages. The MFC library uses macros to connect(or
map) Windows messages to C++ member functions. No extensions to the C++ language are necessary.
菜单命令消息和按钮单击消息的消息管理器是怎样呢? 你不能在窗口基类
中定义这些虚函数因为每个应用程序可能有不同的菜单名称和按钮.MFC的消息
映射系统消除了巨大的虚表,它与普通的Windows消息相比,提供给应用程序更
详细的命令消息.它也允许选择非窗口的类,如文档类和应用程序类来处理命令
消息.MFC用宏连接(或映射)到Windows的消息到C++成员函数.C++语言的非扩展
是必须的.
An MFC message handler requires a function prototype, a function body,
and an entry (macro invocation) in the message map. The Properties window
helps you add message handlers to your classes. You select a Windows
message ID from a list box, and the wizard generates the code with the
correct function parameters and return values.
MFC的消息管理器请求函数原型,函数主体和进入(宏命令)消息映射.通过
属性窗口的帮助你可以在你类里增加消息管理器.你可以从列表框中选择
Windows消息ID,并且向导会生成代码,正确的函数参数和返回值.
Documents and Views
The previous example used an application object and a frame window
object. Most of your MFC library applications will be more complex .
Typically, they’ll contain application and frame classes plus two other
classes that represent the “document” and the “view”.
This document-view architecture is the core of the application framework
And is loosely based on the Model/View/Controller classes from the
Smalltalk world.
文档和视图
前面的例子使用了一个应用程序对象和一个框架窗口对象.大部分你的MFC
应用程序将是很复杂的.典型的,它们在包含应用程序和框架类的基础上又增加
了倆个新类,表示为”文档”和”视图”.文档和视图架构是应用程序框架的核
心,它门是Smalltalk世界的类,并分散在模块/视图/控制器等类里.
In simple terms, the document-view architecture separates data from
the user’s view of the data. One obvious benefit is multiple views of
the same data. Consider a document that consists of a month’s worth of
stock quotes stored on disk. Suppose a table view and a chart view of the
data are both available. The user updates values through the table view
window, and the chart view window changes because both windows display
the same information(but in different views).
在一些简单的条件下,文档视图架构分离的数据是来自与用户自己视图的
据.一些有用的多文档视图的数据是一样的.考虑到一个文档是在磁盘上存放
一个多月的成果.假设有两种有用的视图,一个是表格视图和一个图表视图.用
要通过表格视图窗口和图表视图窗口来更新数据,因为两个窗口显示的是相同
信息.(但是是不同的视图)
In an MFC library application, documents and views are represented
by instances of C++ classes. Figure 2-1 shows three objects of class
CstockDoc cor-responding to three companies: AT&T, IBM, and GM. All three
documents have a table view attached, and one document also has a chart
view. As you can see, there are four view objects—three objects of class
CstockTableView and one of class CstockChartView.
在MFC的应用程序中,文档和视图是申明为C++类的实例的.图2-1显示了
三个类对象CstockDoc同三个公司之间的响应:AT&T,IBM,和GM.有三个文档是
表格视图的,一个是图表视图的.如你所看到的,这四个视图对象--- 三个
CstockTableView类对象和一个CstockChartView类对象.
The document base class code interacts with the File Open and File Save commands; the derived document class does the actual reading and writing of the document object’s data. (The application framework does most of the work of displaying the File Open and File Save dialog boxes and opening, closing, reading, and writing files.) The view base class represents a window contained inside a frame window; the derived view class interacts with its associated document class and does the application’s display and printer I/O. The derived view class and its base classes handle Windows messages. The MFC library orchestrates all interactions among documents, views, frame windows, and the application object; mostly through virtual functions.
文档基类的作用是使用文件打开和文件保存命令.源文档类实际是读取和写入文档对象
资料.(应用程序框架大部分的工作就是显示文件打开和文件保存对话框和打开,关闭,读取
和写文件).视图基类表现为窗口里的框架窗口. 源视图类的作用是联合文档类和应用程序
的显示和打印I/O.源视图类和它的基类句柄Windows消息.MFC库主要通过虚函数来编排文
档,视图,框架窗口和应用程序对象这支管弦乐队使其起作用的.
Don’t think that a document object must be associated with a disk file that is read entirely into memory. If a “document” were really a database, for example, you could override selected document class member functions and the File Open command would bring up a list of databases instead of a list of files.
不要以为文档对象必须是跟磁盘文件关联的,它完全可以从内存中读取.如果一个”文档”是一个真正的数据库,例如,你能重新选择文档类成员函数和文件打开命令将提出数据库列表来代替文件列表.