WinMain和MFC的区别

API(Application Programming Interface):开放给应用程序调用的系统功能。

一个Windows Application(SDK):

WinMain

ReristerClass

CreateWindow

GetMessage/DispatchMessage

/Window Procedure

various Windows APIs

一个MFC Application:

WinMain由MFC提供

RegisterClass包装于AfxWinInit中

CreateWindow在CWinApp::InitInstance中调用

GetMessage/DispatchMessage包装在CWinApp::Run中

Window Procedure由MFC提供

Windows APIs包装在MFC各类中

Massage Mapping, Message Routing.

Dynamic Creation, Serialization.

CWinApp代表程序本体——取代WndProc

传统上SDK程序的WinMain所完成的工作现在由CWinAoo的三个函数完成:

virtual BOOL InitApplication();

virtual BOOL InitInstance();

virtual int Run();

WinMain只是扮演驾驶它们的角色。

传统的SDK窗口函数写法是:

long FAR PASCAL WndProc(HWND hWnd, UINT msg, WORD wParam, LONG lParam)
{
	switch(msg) {
		case WM_COMMAND :
			swtich(wParam) {
				case IDM_ABOUT :
					OnAbout(hWnd, wParam, lParam);
					break;
			}
			break;
		case WM_PAINT :
			OnPaint(hWnd, wParam, lParam);
			break;
		default :
			DefWindowProc(hWnd, msg, wParam, lParam);
	}
}

MFC中使用两个函数OnPaint(),OnAbout()与其对应,MFC中的声明如下:

class CMyFrameWnd : public CFrameWnd
{
public :
	CMyFrameWnd();
	afx_msg void OnPaint();
	afx_msg void OnAbout();
	DECLARE_MESSAGE_MAP()
}

OnPaint处理WM_PAINT

OnAbout处理WM_COMMAND和IDM_ABOUT

MFC内建的一个Message机制,会把消息自动送到“与消息对应的特定函数”中去,消息与对应函数之间的对应关系由程序员指定。DECLARE_MESSAGE_MAP另搭配其它宏,就可以很便利的将消息与其处理函数关联在一起:

BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)

ON_WM_PAINT()

ON_COMMAND(IDM_ABOUT, OnAbout)

END_MESSAGE_MAP()

/***********************************************************/
/*                 WINMAIN.CPP                             */
/***********************************************************/
/*  int AFXAPI AfxWinMain (...)                            */
/*  {                                                      */
/*  	CWinApp* pApp = AfxGetApp();                       */
/*  	                                                   */
/*  	AfxWinInit(...);                                   */
/*  	                                                   */
/*  	pApp->InitApplication();                           */
/*  	pApp->InitInstance();                              */
/*  	nReturnCode = pApp->Run();                         */
/*  	                                                   */
/*  	AfxWinTerm();                                      */
/*  }                                                      */
/***********************************************************/
/*                 HELLO.CPP                               */
/***********************************************************/
/*  CMyWinApp theApp;	//application object               */
/*                                                         */
/*  BOOL CMyWinApp::initInstance()                         */
/*  {                                                      */
/*  	m_pMainWnd = new CMyFrameWnd();                    */
/*  	m_pMainWnd->ShowWindow(m_nCmdShow);                */
/*  	m_pMainWnd->UpdateWindow();                        */
/*  	return TRUE;                                       */
/*  }                                                      */
/*                                                         */
/*  CMyFrameWnd::CMyFrameWnd()                             */
/*  {                                                      */
/*  	Create(NULL, "Hello MFC", ..., "MainMenu");        */
/*  }                                                      */
/*                                                         */
/*  void CMyFrameWnd::OnPaint() {...}                      */
/*  void CMyFrameWnd::OnAbout() {...}                      */
/*                                                         */
/*  BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)              */
/*  	ON_COMMAND(IDM_ABOUT, OnAbout)                     */
/*  	ON_WM_PAINT()                                      */
/*  END_MESSAGE_MAP()                                      */
/***********************************************************/

Application object:每一个MFC应用程序都有一个,而且只有一个。

WINMAIN.CPP中,AfxGetApp其实就是取得CMyWinApp对象指针。所以,AfxWinMain中这样的操作:

CWinApp* pApp = AfxGetApp();

pApp->InitApplication();

pApp->InitInstance();

nReturnCode = pApp->Run();

其实就相当于调用:

CMyWinApp::InitApplication();

CMyWinApp::InitInstance();

CMyWinApp::Run();

因而导致调用:

CWinApp::InitApplication(); //因为CMyWinApp并没有改写InitApplication

CMyWinAPP::InitInstance(); //因为CMyWinApp改写了InitInstance

CWinApp::Run(); //因为CMyWinApp并没有改写Run

AfxWinInit——AFX内部初始化操作

WinMain一开始即调用AfxWinInit,注册四个窗口类。

MFC中也会为我们注册窗口类,但不再是在AfxWinInit中完成。

pApp指向CMyWinApp对象(theApp),所以,当程序调用:

pApp->InitApplication();

CMyWinApp继承自CWinApp,而InitApplication又是CWinApp的一个虚拟函数;若我们并没有改写它(大部分情况下不需改写它),上述操作相当于调用:

CWinApp::InitApplication();

与此类似,当程序调用

pApp->InitInstance();

相当于调用:

CMyWinApp::InitInstance();。

CFrameWnd::Create 产生主窗口(并先注册窗口类)

CMyWinApp::InitInstance 一开始new了一个CMyFrameWnd对象,准备用作主框窗口的C++对象。new会引发构造函数:

CMyFrameWnd::CMyFrameWnd()

{

Create(NULL, "Hello MFC", WS_OVERLAPPEDWINDOW, rectDefault, NULL, "MainMenu");

}

其中,Create是CFrameWnd的成员函数,他将产生一个窗口。

CFrame::Create的规格:

BOOL Create(LPCTSTR lpszClassName, //指定WNDCLASS窗口类

LPCTSTR lpszWindowName,
//指定窗口标题

DWORD dwStyle = WS_OVERLAPPEDWINDOW,
//指定窗口风格

const RECT& rect = rectDefault,
//指定窗口的位置与大小

CWnd* pParentWnd = NULL,
//指定父窗口

LPCTSTR lpszMenuName = NULL,
//指定菜单

DWORD dwExStyle = 0,

CCreateContext* pContext = NULL );
//指向CCreateContext结构的指针,framework利用它,在具备Document/View结构的程序中初始化外框窗口.

pApp指向CMyWinApp对象(theApp),所以,当程序调用:

pApp->Run();

相当于调用:

CMyWinApp::Run();

把消息与处理函数连接在一起:Message Map机制

MFC提供给应用程序使用的“很方便的接口”是两组宏。以Hello的主窗口为例,第一个操作是在HELLO.H的CMyFrameWnd加上DECLARE_MESSAGE_MAP:

class CMyFrameWnd : public CFrameWnd

{

public :

CMyFrameWnd();

afx_msg void OnPaint();

afx_msg void OnAbout();

DECLARE_MESSAGE_MAP();

}

第二个操作是在HELLO.CPP的任何位置(当然不能在函数之内)使用宏如下:

BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)

ON_WM_PAINT()

ON_COMMAND(IDM_ABOUT, OnAbout)

END_MESSAGE_MAP()

MFC把消息主要分为三大类,Message Map机制中对于消息与函数间的对应关系也明确以下三种:

标准Windows消息(WM_xxx)的对应规则:

    |-----------------------------------------------------------------------------|
    |    宏名称         |     对应消息      |   消息处理函数(名称已由系统默认)    |
    |-------------------|-------------------|-------------------------------------|
    | ON_WM_CHAR        |    WM_CHAR        |          OnChar                     |
    |-------------------|-------------------|-------------------------------------|
    | ON_WM_CLOSE       |    WM_CLOSE       |          OnClose                    |
    |-------------------|-------------------|-------------------------------------|
    | ON_WM_CREATE      |    WM_CREATE      |          OnCreate                   |
    |-------------------|-------------------|-------------------------------------|
    | ON_WM_DESTROY     |    WM_DESTROY     |          OnDestroy                  |
    |-------------------|-------------------|-------------------------------------|
    | ON_WM_LBUTTONDOWN |    WM_LBUTTONDOWN |          OnLButtonDown              |
    |-------------------|-------------------|-------------------------------------|
    | ON_WM_LBUTTONUP   |    WM_LBUTTONUP   |          OnLButtonUp                |
    |-------------------|-------------------|-------------------------------------|
    | ON_WM_MOUSEMOVE   |    WM_MOUSEMOVE   |          OnMouseMove                |
    |-------------------|-------------------|-------------------------------------|
    | ON_WM_PAINT       |    WM_PAINT       |          OnPaint                    |
    |-----------------------------------------------------------------------------|

命令消息(WM_COMMAND)的一般对应规则是:

ON_COMMAND(<id>, <memberFxn>)

例如:

ON_COMMAND(IDM_ABOUT,
OnAbout)

ON_COMMAND(IDM_FILENEW,
OnFileNew)

ON_COMMAND(IDM_FILEOPEN,OnFileOpen)

ON_COMMAND(IDM_FILESAVE,OnFileSave)

"Notification消息"(由控件产生,例如 BN_xxx)的对应机制的宏分为好几种(因为控件分为好几种),例:

    |-----------------------------------------------------------|
	|   控件   |              宏名称               |消息处理函数|
	|----------|-----------------------------------|------------|
	|  Button  |  ON_BN_CLICKED(<id>,<memberFxn>)  | memberFxn  |
	|----------|-----------------------------------|------------|
	| ComboBox |  ON_CBN_DBLCLK(<id>,<memberFxn>)  | memberFxn  |
	|----------|-----------------------------------|------------|
	|   Edit   |  ON_EN_SETFOCUS(<id>,<memberFxn>) | memberFxn  |
	|----------|-----------------------------------|------------|
	| ListBox  |  ON_LBN_DBLCLK(<id>,<memberFxn>)  | memberFxn  |
	|-----------------------------------------------------------|

各个消息处理函数均以afx_msg void 为函数类型。

时间: 2024-11-08 19:30:59

WinMain和MFC的区别的相关文章

QT 与 MFC 的区别 .

MFC(微软基础类库)是专门为windows设计的一个用于开发图形用户界面的类库.MFC或多或少使用了面向对象的方法包装了Win32的API,正因如此,这些API有时是C++,有时是C,甚至是C和C++的混合体. Qt这个C++的图形库由Trolltech在1994年左右开发.它可以运行在Windows,Mac OS X, Unix,还有像Sharp Zaurus这类嵌入式系统中.Qt是完全面向对象的. Document/View model:MFC编程需要使用Document/View模式以及

WinMain和MFC的差别

API(Application Programming Interface):开放给应用程序调用的系统功能. 一个Windows Application(SDK): WinMain ReristerClass CreateWindow GetMessage/DispatchMessage /Window Procedure various Windows APIs 一个MFC Application: WinMain由MFC提供 RegisterClass包装于AfxWinInit中 Creat

Visual Studio C++ Win32控制台应用程序,Win32项目,MFC的区别

背景 Visual Studio C++ 创建新项目蹦出来如下选项: Win32控制台应用程序,Win32项目,MFC有什么区别? 正文: Win32控制台,没有界面,命令行执行生成的文件则直接在后台运行,运行效果如下:生成的".exe"文件相当于Linux系统下用gcc编译出来一个".out"文件,直接运行操作即可,只有命令符,没有界面. Win32项目这个就有界面了,但是界面里面的控件,基本上要自己去实现. MFC项目这个也有界面,可是界面里面的控件就不需要自己

在共享DLL中使用MFC 和在静态库中使用MFC的区别

使用VS2008,在项目属性中有一项MFC的使用,有三种设置: 1.使用标准Windows库 2.在共享DLL中使用MFC 3.在静态库中使用MFC 第一种顾名思义. 第二种指的是打包时一些MFC的DLL的内容没有被包含在EXE文件中,所以EXE文件较小,但是运行时要求系统中要有相关的DLL文件. 第三种是将DLL中的相关代码写进EXE文件中,文件较大,但是可以在没有相关DLL的机器上运行. 同时,如果程序本来是第二种方式,发给同事,在同事机器上运行时,可能会出现错误: “无法启动程序……,由于

VS2008中 ATL CLR MFC Win32 区别

ATL用于编写COM程序,CLR是.NET的公共语言运行库,MFC是指MFC类库,MFC程序是用这些类库做出的程序,WIN32常规就是不用MFC,使用API函数编的程序.MFC.ATL和CLR是VC2005内置的3大库,涵盖了windows的各种开发方法和开发应用.当然关于C++开发的库不止这3个,不过这3个是微软推荐.从编程所处层次而言,WIN32为最底层,其次是MFC.然后是CLR.WIN32 winAPI MFC MFC类库 CLR .net库 1. WIN32常规就是不用MFC,使用AP

Visual Studio中 ATL CLR MFC Win32 区别

ATL用于编写COM程序, CLR是.NET的公共语言运行库, MFC是指MFC类库,MFC程序是用这些类库做出的程序, WIN32常规就是不用MFC,使用API函数编的程序. MFC.ATL和CLR是VC2005内置的3大库,涵盖了windows的各种开发方法和开发应用.当然关于C++开发的库不止这3个,不过这3个是微软推荐.从编程所处层次而言,WIN32为最底层,其次是MFC.然后是CLR. WIN32 winAPI MFC MFC类库 CLR .net库 1. WIN32常规就是不用MFC

API、Win32 SDK、Win32项目、MFC、Windows窗体应用程序的区别

[原]API.Win32 SDK.Win32项目.MFC.Windows窗体应用程序的区别 首先来看一下每一个术语的定义: API:Application Programming Interface.Windows操作系统提供给应用程序编程的接口, 简称 为API函数. Win32 SDK:SDK(Software Development Kit)中文是软件开发包.则Win32 SDK是Windows 32位平台下的软件开发包,包括了API函数.帮助文档.微软 提供的一些辅助开发工具. Win3

MFC中如何改装SDK的WinMain函数

1.在TCHAR.H文件中定义了一个宏:#define _tWinMain WinMain这样MFC源代码在编译的时候,_tWinMain就会被替换为WinMain(),这样操作系统就可以调用了. 2.在APPMODUL.CPP文件中,定义了_tWinMain(),在_tWinMain()中 return AfxWinMain(); 1 extern "C" int WINAPI 2 _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInsta

MFC学习之路

一.接触MFC  day01 1. 使用资源: ①insert resource,对话框资源 ②resource view下面,右键对话框,修改properties,重要的是资源ID,一般为IDD_Dialogxx ③对资源的操作一般都是通过类来完成,因此要操作资源需要为资源添加类,基类一般都是CDialog 注意:添加类后,在class view中没有该类的浏览信息 方法一:可以删除 .ncb文件(no compile browse 无编译浏览文件),重新编译一遍 方法二:在文件视图,右键工程