zoukankan      html  css  js  c++  java
  • MFC 框架技术简单研讨

    引用:http://www.cnblogs.com/chinazhangjie/archive/2011/09/20/2181986.html

    正文:

    第一讲 Win32 App  和  MFC Framework

    Win32 App 程序生与死:
    (1)注册窗口
    (2)创建窗口
    (3)显示并更新窗口
    (4)消息循环( WM_QUIT 结束循环)
    (5)退出

    实例代码:

    复制代码
    #include <windows.h>

    ATOM RegisterWndClass( HINSTANCE hInstance , LPCWSTR className);
    LRESULT CALLBACK WindowProc(HWND ,UINT, WPARAM, LPARAM);

    /* WinMain parameters:
    * hInstance : A handle to the current instance of the application.
    * hPrevInstance : A handle to the previous instance of the application.
    * This parameter is always NULL. ...
    * lpCmdLine : The command line for the application, excluding(不包括) the program name.
    * To retrieve(获取) the entire(全部) command line, use the GetCommandLine function.
    * nCmdShow : Controls how the window is to be shown. eg. SW_HIDE, SW_MAXIMIZE
    *
    * return value: If the function succeeds, terminating when it receives a WM_QUIT message,
    * it should return the exit value contained in that message's wParam parameter.
    * If the function terminates before entering the message loop,
    * it should return zero.
    */
    int CALLBACK WinMain(
    __in HINSTANCE hInstance,
    __in HINSTANCE hPrevInstance,
    __in LPSTR lpCmdLine,
    __in
    int nCmdShow )
    {
    // (1)注册窗口
    LPCWSTR className = TEXT("FirstWnd");
    if (!RegisterWndClass(hInstance, className)) {
    ::MessageBox(NULL, TEXT(
    "Register class failed"),
    TEXT(
    "Error"), MB_OK | MB_ICONEXCLAMATION);
    return0;
    }

    // (2)创建窗口
    HWND hWnd; // 窗口句柄
    hWnd = CreateWindow(
    className,
    // 窗口类名称
    TEXT("A simple Win32 Application"), // 窗口标题
    WS_OVERLAPPEDWINDOW, // 窗口风格
    100, // 窗口位置的 x 坐标 , CW_USEDEFAULT
    100, // 窗口位置的 y 坐标 , CW_USEDEFAULT
    400, // 窗口的宽度 , CW_USEDEFAULT
    300, // 窗口的高度 , CW_USEDEFAULT
    NULL, // 父窗口句柄
    NULL, // 菜单句柄
    hInstance, // 应用程序句柄
    NULL); // 窗口创建数据指针, WM_CREATE lParam
    if (!hWnd) {
    ::MessageBox(NULL, TEXT(
    "Register class failed"),
    TEXT(
    "Error"), MB_OK | MB_ICONEXCLAMATION);
    return0;
    }

    // (3)显示并更新窗口
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    // (4)进入消息循环
    MSG msg;
    // 如果 msg 消息为 WM_QUIT , GetMessage 返回为 0 ,退出循环
    while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(
    &msg);
    DispatchMessage(
    &msg);
    }

    // 程序结束
    return msg.wParam;
    }

    // 注册窗口
    ATOM RegisterWndClass( HINSTANCE hInstance , LPCWSTR className)
    {
    WNDCLASS wc;
    wc.style
    = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; //
    wc.lpfnWndProc = (WNDPROC)WindowProc; // A pointer to the window procedure.
    wc.cbClsExtra =0; //
    wc.cbWndExtra =0; //
    wc.hInstance = hInstance; //
    wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION ); // A handle to the class icon.
    wc.hCursor = LoadCursor( NULL, IDC_ARROW ); // A handle to the class cursor.
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // A handle to the class background brush.
    wc.lpszMenuName = NULL; // The resource name of the class menu,
    wc.lpszClassName = className; // A pointer to a null-terminated string or is an atom.
    return RegisterClass( &wc );
    }

    // 窗口过程
    LRESULT CALLBACK WindowProc(
    __in HWND hWnd,
    // A handle to the window.
    __in UINT uMsg, // The message.
    __in WPARAM wParam, // Additional message information
    __in LPARAM lParam // Additional message information
    )
    {
    HDC hDC;
    PAINTSTRUCT ps;

    switch (uMsg)
    {
    case WM_PAINT:
    hDC
    = BeginPaint(hWnd, &ps);
    RECT rc;
    rc.bottom
    =100;
    rc.left
    =100;
    rc.right
    =300;
    rc.top
    =400;
    ::SetTextColor(hDC, RGB(
    255, 0, 0));
    SetBkMode(hDC, TRANSPARENT);
    ::TextOut(hDC,
    30, 30, TEXT("This is my first Win32 App !"),
    strlen(
    "This is my first Win32 App !"));
    EndPaint(hWnd,
    &ps);
    break;
    case WM_DESTROY:
    MessageBox(NULL, TEXT(
    "Window will be closed"), TEXT("Message"), MB_OK);
    PostQuitMessage(
    0);
    break;
    case WM_LBUTTONDOWN:
    MessageBox(NULL, TEXT(
    "left button down"), TEXT("Message"), MB_OK);
    break;
    default:
    break;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    复制代码

    思考:

    1. Console App 入口点 是  main  ; Win32 App 入口点是 WinMain ;那么 MFC 入口点在哪里 ?
    2.  相对简洁的 Win32 App ,复杂的  MFC Framework  强大在哪里 ?  
    3. 大量的虚函数、复杂的宏,或者说 MFC Framework 背着我们用户做了哪些事情 ?


    第二讲 MFC 六大关键技术

     2.1 MFC 程序的初始化过程
     2.2 RTTI(运行时类型识别)
     2.3 Dynamic Creation(动态创建)

            C++动态创建对象的困难在于,无法在程序执行期间,根据动态获得的一个类名称,要求程序产生一个对象。
            在 RTTI 中,CRuntimeClass 对象记录了类的 CreateObject  函数,在程序执行期间获得类名称,遍历链表找到名称匹配项,调用 CreateObject ,产生新对象。

      C++ 动态类型相关
      (1) typeid  运算子
      (2)宏  [ RTTI ]
      (3)模板实参演绎  [STL iterator_traits]
           C++在动态对象创建上一直是一个缺陷,据我说知,C# 有一项技术支持(反射)。
     2.4 Persistence(永久保存)机制

      Persistence:将对象永久保留下来(写入文件),Persistence 机制,也就是Serialize(数据读写)。

      Persistence 简介

      (1) MFC 提供 CObList 、CDWordArray 等类来支持 Persistence 。
      (2) MFC 利用 
          DECLARE_SERIAL/IMPLIMENT_SERIAL 
              两个宏来实现  Persistence  机制。
      (3)个人觉得,Persistence 只不过限定了一种文件格式来存储。普通程序员也可以很快设定一种文件格式来存储,不用受框架的限制,灵活性高且调试方便。
     2.5 Message Mapping(消息映射)与Command Routing(命令传递)

            Windows 程序本质系事借着消息来维持脉动(消息驱动),并以 WM_ 开头的常量开表示。
            消息循着 Application Framework 规定的路线,游走于各个对象之间,直到找到它的归宿(消息处理函数)。找不到的话,Framework 最终把它交给 :DefWindowProc 函数处理。

    MFC 消息分类

            命令消息(WM_COMMAND):“使用者命令程序做些操作”。凡是 UI 对象产生的消息都是这种命令消息,可能来自菜单或者加速键或工具栏按钮,并且都以 WM_COMMAND 呈现。SDK 程序主要靠 wParam 识别之,MFC 程序则主要靠菜单项的识别码( menu ID)识别——其实两者是一样的。
            凡是派生自 CCmdTarget 的类,都由资格接受命令消息。

        标准消息:除 WM_COMMAND 之外,任何以 WM_ 开头的都算这一类,均可接受此消息。
        Control Notification:由控件产生,为的是向父类窗口通知某种情况。例如当你在 ListBox 上选择其中一个项目,ListBox 就会产生 LBN_SELCHANGE 传送给父窗口。这类消息是以 WM_COMMAND 形式呈现。

    第三讲 MFC 多线程技术简介

    MFC 线程分类:Work Thread,UI Thread
    区别:Work Thread 没有消息循环
                UI Thread   有自己的消息和队列循环
    Work Thread:通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等
    UI  Thread:一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等。

    4.1 Work Thread的创建

    CWinThread*
    AfxBeginThread(AFX_THREADPROC       pfnThreadProc,
                          LPVOID  pParam,
                          nPriority=THREAD_PRIORITY_NORMAL,
                          UINT nStackSize=0,
                          DWORD dwCreateFlags=0,
                          LPSECURITY_ATTRIBUTES   lpSecurityAttrs=NULL);
    线程函数类型:
    UINT ExecutingFunction(LPVOID pParam);

    4.2 UI Thread的创建

    CWinThread* AfxBeginThread(CRuntimeClass* pThreadClass,
                          int nPriority=THREAD_PRIORITY_NORMAL,
                          UINT nStackSize=0,
                          DWORD dwCreateFlags=0,
                          LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);

    具体请看:多线程编程之二——MFC中的多线程开发

    第五讲 MFC 常用技术

      略(幻灯片中讲了一些,但是比较杂碎,就不在这里列出来了……)

  • 相关阅读:
    EXTI—外部中断/事件控制器
    启动文件讲解
    SysTick—系统定时器
    USART—串口通讯
    关于引脚复用,不得不提的GPIO_Pin_sources 和GPIO_Pin
    DMA—直接存储区访问
    【LightOJ1282】Leading and Trailing(数论)
    【LightOJ1336】Sigma Function(数论)
    【LightOJ1370】Bi-shoe and Phi-shoe(欧拉函数)
    【BZOJ2440】完全平方数(二分答案,莫比乌斯反演)
  • 原文地址:https://www.cnblogs.com/sode/p/3156919.html
Copyright © 2011-2022 走看看