Chinaunix首页 | 论坛 | 博客
  • 博客访问: 148835
  • 博文数量: 40
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 908
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-03 11:03
个人简介

学习linux

文章分类
文章存档

2014年(7)

2013年(33)

我的朋友

分类: C/C++

2013-09-05 14:25:46

1. MFC程序是在WIN32程序的基础上变化来的,都是Framework Application,所以理解win32程序的设计思想会有
    事半功倍的效果。
    WinMain是主函数,先注册类,产生并显示窗口后,就进入消息循环,不断从消息队列取出消息再处理。

点击(此处)折叠或打开

  1. WinMain
  2. {
  3.     RegisterClass;
  4.     CreateWindow;
  5.     ShowWindow;
  6.     UpdateWindow;
  7.     while(...)
  8.     {
  9.          WndProc;
  10.     }
  11. }

  12. //msg是取到的消息,在switch中先判断再处理。

  13. WndProc
  14. {    
  15.     switch(msg)
  16.     {
  17.        case: ....
  18.     }
  19. }
2. 从WIN32到MFC:
    MFC框架会自动注册窗口类,再调用它的显示函数,来显示窗口;然后我们点击菜单或者控件或者工具栏,会产生对应的
    消息放到消息队列中,而程序就while循环,不断从消息队列中取出消息并处理。(这里要说明,点击控件产生消息放到队列
    中的线程和while循环处理消息的线程不是同一个。)这就是整个大概过程。
    
    对于MFC的整个过程我们应该有几个问题:
    a. mfc程序中都是定义的类,并没有对象,它是如何根据我们的需要产生各种窗口,又如何显示窗口呢?
          答:每个类都用一个宏将自己的成员和函数信息包装并放到一个链表中,所以这么多类就组成了一个巨大的链表网,
                当要产生一个对象时,就会根据名称搜索这个网,调用它的构造函数。例如,创建新文档时就会根据CMultiDocTemplate
                的三个类名称生成三个对象,分别是子窗口,视图,文档。
    b. 当我们点击菜单或者控件或者工具栏,产生了什么消息呢?这些消息又是如何送到对应的处理函数呢?
          答:这只有两点,消息映射和消息路由。
                MFC把消息分为三类:一是命令消息(UI对象产生的消息都是这种,如工具栏和菜单,都是WM_COMMAND),
                只要派生CCmdTarget的类都可以接受这种消息,但一般将其处理函数放到CView或者CDocument,因为命令
                消息一般用来改变视图或文档。
                二是标准消息(除了WM_COMMAND,以WM_开头的都是这种消息),所有派生CWnd的类都可以接受这种消息,
                例如键盘或鼠标消息,WM_PAINT消息。
                三是Control Notification,即由控件产生的消息,(也是以WM_COMMAND呈现),一般直接发给父窗口,
                由父窗口的处理函数处理。
                
                每一个能够处理消息的类都用BEGIN_MESSAGE_MAP宏和END_MESSAGE_MAP宏组成了一个巨大的消息路由网,
                并且将控件ID映射到其处理函数。命令消息的路由方式有横向路由,类似与有优先级,先后顺序一般为CView,CDocument
                ,CFrame,当上一个没有对应处理函数就到下一个,比如对一个菜单项,如果CView和CDocument都有其处理函数,则
                只会调用CView中的处理函数;而标准消息的路由很简单,只有纵向路由,这一级没有就路由到上一级。
                比如当CView产生WM_PAINT消息时,就看自己有没有处理函数,如果没有就调用父类的对应处理函数。比较类似与
                虚函数重载,但要知道这不是虚函数重载,这是消息的路由。
                

3. MFC最重要的东西:

    CObject    (许多函数都用这个基类的指针作为参数)
        |___CCmdTarget    (可以接受命令消息的类)
                    |
                    |___CWinThread
                    |           |___CWinApp    
                    |                       |___CMyWinApp    (全局应用程序对象)
                    |
                    |___CWnd    (所有窗口的基类,可以接受标准消息的类)
                    |        |___CView    (窗口框架中的视图)
                    |        |          |___CMyView
                    |        |___CFrameWnd
                    |        |            |___CMDIFrameWnd---CMyMDIFrameWnd    (主框架,包含了菜单)
                    |        |            |___CMDIChildWnd-----CMyMDIChildWnd        (子框架,即视图的边框,多文档才有)

                    |        |___CControlBar
                    |        |            |___CStatusBar    (状态栏)
                    |        |            |___CToolBar        (工具栏)
                    |        |___CDialog
                    |                    |___CMyDialog    (可以继承许多种类的对话框)
                    |
                    |___CDocument
                    |            |___CMyDoc        (视图对应的文档,可以一个文档对应多个视图)
                    |
                    |___CDocTemplate
                                |___CMultiDocTemplate    (动态产生新文档用到的模板,包括子框架,视图,文档三个类)
                   
4. 可以用VC6.0创建一个MFC多文档应用程序,对照自动生成的代码看一下整个流程:
        a.     InitApplication中实现了注册窗口类;
        b.     InitInstance先注册所有的CMultiDocTemplate模板,再new CMainFrame生成主框架并LoadFrame加载菜单,
                这会产生WM_CREATE消息,调用OnCreate函数加载工具栏和状态栏,主框架的工作就完成了。再根据
                CMultiDocTemplate
选择一个模板,动态创建三个对象:子窗口,视图,文档(其实视图是后来子窗口产生的)。
                子窗口产生后调用OnCreateClient生成客户区(这里可自定义,例如拆分视图);再调用CreateView生成视图
               (可以有多个视图)。到这里,工作都完成了。
         c.    ShowWindow显示窗口;UpdateWindow发出WM_PAINT重绘消息,上面产生的视图的OnPaint被调用,继而
                调用OnDraw函数,进行绘制工作。
         d.    InitInstance结束,调用Run,进入消息循环处理。
             (注:c 中要补充的是,当CDocument发生变化CView要重绘时,pDoc->UpdateAllViews,会调用关联的每个
                    视图的OnUpdate,计算出重绘区后发送WM_PAINT,OnPaint就会被调用了,OnUpdate中默认的重绘区
                    是整个视图。而OnInitialUpdate是View产生后第一次关联到Document但还没有显示时,由子窗口调用的,
                    它会调用OnUpdate,所以要做一次的初始化操作且需要Document的数据,一般在这个函数完成。) 
    
阅读(1400) | 评论(0) | 转发(0) |
0

上一篇:linux与硬件通信

下一篇:ARM硬件基础之二

给主人留下些什么吧!~~