MFC应用程序框架分析

SDK应用程序

程序运行都要有入口函数,在之前的C++教程中都是main函数,而Windows应用程序的入口函数是WinMain函数,MFC程序也是从WinMain函数开始的。

下面就给出用Windows SDK写的"HelloWorld"程序,与应用程序框架进行对比,这样能更好的了解框架是怎样运行的。Windows SDK开发程序就是不使用MFC类库,直接用Windows API函数进行软件开发。

#include <windows.h>    
  
LRESULT CALLBACK myWndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam);   
     
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)      
{      
  const static TCHAR appName[] = TEXT("Hello world");      
  WNDCLASSEX myWin;      
  myWin.cbSize = sizeof(myWin);      
  myWin.style = CS_HREDRAW | CS_VREDRAW;      
  myWin.lpfnWndProc = myWndProc;      
  myWin.cbClsExtra = 0;      
  myWin.cbWndExtra = 0;      
  myWin.hInstance = hInstance;      
  myWin.hIcon = 0;      
  myWin.hIconSm  = 0;      
  myWin.hCursor = 0;      
  myWin.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);      
  myWin.lpszMenuName = 0;      
  myWin.lpszClassName = appName;      
  //Register      
  if (!RegisterClassEx(&myWin)) return 0;      
  const HWND hWindow = CreateWindow(      
    appName,      
    appName,      
    WS_OVERLAPPEDWINDOW,      
    CW_USEDEFAULT,      
    CW_USEDEFAULT,      
    CW_USEDEFAULT,      
    CW_USEDEFAULT,      
    0,      
    0,      
    hInstance,      
    0);      
  ShowWindow(hWindow,iCmdShow);      
  UpdateWindow(hWindow);      
  {      
    MSG msg;      
    while(GetMessage(&msg,0,0,0))      
    {      
      TranslateMessage(&msg);      
      DispatchMessage(&msg);      
    }      
    return (int)msg.wParam;      
  }      
}      
     
LRESULT CALLBACK myWndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam)      
{      
  if (msg==WM_PAINT)      
  {      
    PAINTSTRUCT ps;      
    const HDC hDC = BeginPaint(hWindow,&ps);      
    RECT rect;      
    GetClientRect(hWindow,&rect);      
    DrawText(hDC,TEXT("HELLO WORLD"),-1,&rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);      
    EndPaint(hWindow,&ps);      
    return 0;      
  }      
  else if (msg==WM_DESTROY)      
  {      
    PostQuitMessage(0);      
    return 0;      
  }      
  return DefWindowProc(hWindow,msg,wParam,lParam);      
}  

上面的程序运行的流程是
进入WinMain函数->初始化WNDCLASSEX,调用RegisterClassEx函数注册窗口类->调用ShowWindow和UpdateWindow函数显示并更新窗口->进入消息循环。

关于消息循环再简单说下,Windows应用程序是消息驱动的,系统或用户让应用程序进行某项操作或完成某个任务时会发送消息,进入程序的消息队列,然后消息循环会将消息队列中的消息取出,交予相应的窗口过程处理,此程序的窗口过程函数就是 myWndProc 函数,窗口过程函数处理完消息就完成了某项操作或任务。本例是要显示"HELLO WORLD"字符串,UpdateWindow函数会发送WM_PAINT消息,但是此消息不经过消息队列而是直接送到窗口过程处理,在窗口过程函数中最终绘制了"HELLO WORLD"字符串。

MFC应用程序

首先在 HelloWorld.cpp 中定义全局对象 theApp:CHelloWorldApp theApp;。调用 CWinApp和CHelloWorldApp 的构造函数后,进入 WinMain 函数(位于appmodul.cpp中)。

InitInstance 中的 ProcessShellCommand 函数又调用了CMainFrame 的 LoadFrame 函数注册并创建了窗口,执行完ProcessShellCommand 函数以后,调用了 m_pMainWnd 的ShowWindow和UpdateWindow 函数显示并更新框架窗口。

接下来该是消息循环了,上面的 AfxWinMain 函数中调用了 pThread 的 Run 函数(位于THRDCORE.cpp中),在 Run 中包含了消息循环。

我们看到 PumpMessage 中通过调用 GetMessage、TranslateMessage、DispatchMessage 等建立了消息循环并投递消息。

CHelloWorldApp 类处理消息,将收到的消息分发给相应的对象。CMainFrame 是视图 CHelloWorldView 的父窗口,视图CHelloWorldView 就显示在 CMainFrame 的客户区中。视图类 CHelloWorldView 用来显示文档类 CHelloWorldDoc 中的数据,并根据对视图类的操作修改文档类的数据。一个视图类只能跟一个文档类相联系,而一个文档类可以跟多个视图类相联系。

二者比较

到此,通过对比可以发现,MFC 应用程序的运行流程与 SDK 程序是类似的,都是先进行一些初始化过程,再注册并创建窗口,然后显示、更新窗口,最后进入消息循环,消息都由窗口过程函数处理。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光开朗男孩

你的鼓励是我最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值