Lesson 03MFC应用程序的生与死.docx

上传人:b****1 文档编号:13369808 上传时间:2023-06-13 格式:DOCX 页数:18 大小:68.58KB
下载 相关 举报
Lesson 03MFC应用程序的生与死.docx_第1页
第1页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第2页
第2页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第3页
第3页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第4页
第4页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第5页
第5页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第6页
第6页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第7页
第7页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第8页
第8页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第9页
第9页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第10页
第10页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第11页
第11页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第12页
第12页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第13页
第13页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第14页
第14页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第15页
第15页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第16页
第16页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第17页
第17页 / 共18页
Lesson 03MFC应用程序的生与死.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Lesson 03MFC应用程序的生与死.docx

《Lesson 03MFC应用程序的生与死.docx》由会员分享,可在线阅读,更多相关《Lesson 03MFC应用程序的生与死.docx(18页珍藏版)》请在冰点文库上搜索。

Lesson 03MFC应用程序的生与死.docx

Lesson03MFC应用程序的生与死

Lesson03MFC应用程序的生与死

一、如何学习MFC

1.使用WindowsAPI开发程序

以rawWindowsAPI开发程序,学习的路径是单纯的,条理分明的,你一定先从程序进入点开始,然后产生窗口类,然后产生窗口,然后取得消息,然后分辨消息,然后决定如何处理消息。

虽然动作繁琐,学习却容易。

 

图1学习WindowsAPI编程

2.使用MFC编程

(1)开始容易,学习困难,如图2

 

图2学习MFC编程

以MFC开发程序,一开始很快速,因为开发工具会为你产生一个骨干程序,一般该有的各种界面一应俱全。

但是MFC的学习曲线十分陡峭,程序员从骨干程序出发一直到有能力修改程序代码以符合个人的需要,是一段不易攀登的峭壁。

(2)理解MFC的根本,学习变得容易,如图3

如果我们了解Windows程序的基本运行原理,并了解MFC如何把这些基础动作整合起来,我们就能够使MFC学习曲线的陡峭程度缓和下来。

因此能够迅速接受MFC,进而使用MFC。

一条似远实近的道路!

图3理解MFC的根本

3.熟悉MFC的类层次结构

MSDNMFC最主要的几个类及其继承关系。

二、MFC程序的来龙去脉

MFC程序也是Windwos程序,有且只有一个全局对象theApp,当操作系统将程序加载并激活时,这个全局对象获得配置,其构造函数会先执行,比WinMain更早。

MFC实际上把WinMain内部操作封装在CWinApp中,把WndProc内部操作封装在CFrameWnd中:

●CWinApp代表程序本体

●CFrameWnd代表一个主窗口

(1)CWinApp取代WinMain的地位

MFC中CWinApp的声明:

(文件:

AFXWIN.H)

ClassCWinApp:

publicCWinThread

{

//Attributes

//Startupargs(donotchange)

HINSTANCEm_hInstance;

HINSTANCEm_hPrevInstance;

LPTSTRm_lpCmdLine;

intm_nCmdShow;

……

public:

//Overridables

//hooksforyourinitializationcode

virtualBOOLInitApplication();

……

//overridesforimplementation

virtualBOOLInitInstance();

virtualintExitInstance();//returnappexitcode

virtualintRun();

virtualBOOLOnIdle(LONGlCount);//returnTRUEifmoreidleprocessing

……

};

其中记录主窗口句柄的变量在CWinApp的父类CWinThread中。

(文件:

AFXWIN.H)

classCWinThread:

publicCCmdTarget

{

public:

//Attributes

CWnd*m_pMainWnd;//mainwindow(usuallysameAfxGetApp()->m_pMainWnd)

CWnd*m_pActiveWnd;//activemainwindow(maynotbem_pMainWnd)

BOOLm_bAutoDelete;//enables'deletethis'afterthreadtermination

//onlyvalidwhilerunning

HANDLEm_hThread;//thisthread'sHANDLE

……

//Overridables

//threadinitialization

virtualBOOLInitInstance();

//runningandidleprocessing

virtualintRun();

virtualBOOLPreTranslateMessage(MSG*pMsg);

virtualBOOLPumpMessage();//lowlevelmessagepump

virtualBOOLOnIdle(LONGlCount);//returnTRUEifmoreidleprocessing

……

};

(2)CFrameWnd取代WndProc的地位

CFrameWnd主要掌管窗口,MFC内建了一个MessageMap机制,会把消息自动送到与消息对应的特定函数中去;消息与处理函数之间的对应关系由程序员指定。

下面的宏把消息与其处理函数关联在一起:

BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)

ON_WM_PAINT()

……

END_MESSAGE_MAP

与DECLARE_MESSAGE_MAP对应

(3)应用程序对象theApp

每个MFC应用程序都有且只有一个应用程序对象:

theApp,当程序运行时,这个全局对象产生,于是其构造函数执行。

CWinApp类的构造函数内容如下:

(文件:

APPCORE.CPP)

CWinApp:

:

CWinApp(LPCTSTRlpszAppName)

{

if(lpszAppName!

=NULL)

m_pszAppName=_tcsdup(lpszAppName);

else

m_pszAppName=NULL;

//initializeCWinThreadstate

AFX_MODULE_STATE*pModuleState=_AFX_CMDTARGET_GETSTATE();

AFX_MODULE_THREAD_STATE*pThreadState=pModuleState->m_thread;

ASSERT(AfxGetThread()==NULL);

pThreadState->m_pCurrentWinThread=this;

ASSERT(AfxGetThread()==this);

m_hThread=:

:

GetCurrentThread();

m_nThreadID=:

:

GetCurrentThreadId();

//initializeCWinAppstate

ASSERT(afxCurrentWinApp==NULL);//onlyoneCWinAppobjectplease

pModuleState->m_pCurrentWinApp=this;

ASSERT(AfxGetApp()==this);

//innon-runningstateuntilWinMain

m_hInstance=NULL;

m_pszHelpFilePath=NULL;

m_pszProfileName=NULL;

m_pszRegistryKey=NULL;

m_pszExeName=NULL;

m_pRecentFileList=NULL;

m_pDocManager=NULL;

m_atomApp=m_atomSystemTopic=NULL;

m_lpCmdLine=NULL;

m_pCmdInfo=NULL;

//initializewaitcursorstate

m_nWaitCursorCount=0;

m_hcurWaitCursorRestore=NULL;

//initializecurrentprinterstate

m_hDevMode=NULL;

m_hDevNames=NULL;

m_nNumPreviewPages=0;//notspecified(defaultsto1)

//initializeDAOstate

m_lpfnDaoTerm=NULL;//willbesetifAfxDaoInitcalled

//otherinitialization

m_bHelpMode=FALSE;

m_nSafetyPoolSize=512;//defaultsize

}

CWinApp之中的成员变量因为theApp全局对象的产生而获得配置与初值。

(4)隐含的WinMain

theApp配置完成后,WinMain开始,其代码是MFC早已准备好并由链接器直接加到应用程序的代码中,代码如下,_tWinMain函数的“_t”是为了支持Unicode而准备的一个宏:

(文件:

APPMODUL.CPP)

extern"C"intWINAPI

_tWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,

LPTSTRlpCmdLine,intnCmdShow)

{

//callshared/exportedWinMain

returnAfxWinMain(hInstance,hPrevInstance,lpCmdLine,nCmdShow);

}

MFC程序的入口点:

AfxWinMain:

(文件:

WINMAIN.CPP)

//StandardWinMainimplementation

//Canbereplacedaslongas'AfxWinInit'iscalledfirst

intAFXAPIAfxWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,

LPTSTRlpCmdLine,intnCmdShow)

{

ASSERT(hPrevInstance==NULL);

intnReturnCode=-1;

CWinThread*pThread=AfxGetThread();

CWinApp*pApp=AfxGetApp();

//AFXinternalinitialization

if(!

AfxWinInit(hInstance,hPrevInstance,lpCmdLine,nCmdShow))

gotoInitFailure;

//Appglobalinitializations(rare)

if(pApp!

=NULL&&!

pApp->InitApplication())

gotoInitFailure;

//Performspecificinitializations

if(!

pThread->InitInstance())

{

if(pThread->m_pMainWnd!

=NULL)

{

TRACE0("Warning:

Destroyingnon-NULLm_pMainWnd\n");

pThread->m_pMainWnd->DestroyWindow();

}

nReturnCode=pThread->ExitInstance();

gotoInitFailure;

}

nReturnCode=pThread->Run();

InitFailure:

#ifdef_DEBUG

//CheckformissingAfxLockTempMapcalls

if(AfxGetModuleThreadState()->m_nTempMapLock!

=0)

{

TRACE1("Warning:

Tempmaplockcountnon-zero(%ld).\n",

AfxGetModuleThreadState()->m_nTempMapLock);

}

AfxLockTempMaps();

AfxUnlockTempMaps(-1);

#endif

AfxWinTerm();

returnnReturnCode;

}

(5)AfxWinMain的四个主要操作以及引发的行为:

①AfxWinInit:

内部初始化操作

AfxWinInit是继CWinApp构造函数之后的第一个操作,以下为源代码:

(文件:

APPINIT.CPP)

BOOLAFXAPIAfxWinInit(HINSTANCEhInstance,HINSTANCEhPrevInstance,

LPTSTRlpCmdLine,intnCmdShow)

{

ASSERT(hPrevInstance==NULL);

//handlecriticalerrorsandavoidWindowsmessageboxes

SetErrorMode(SetErrorMode(0)|

SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);

//setresourcehandles

AFX_MODULE_STATE*pModuleState=AfxGetModuleState();

pModuleState->m_hCurrentInstanceHandle=hInstance;

pModuleState->m_hCurrentResourceHandle=hInstance;

//fillintheinitialstatefortheapplication

CWinApp*pApp=AfxGetApp();

if(pApp!

=NULL)

{

//Windowsspecificinitialization(notdoneifnoCWinApp)

pApp->m_hInstance=hInstance;

pApp->m_hPrevInstance=hPrevInstance;

pApp->m_lpCmdLine=lpCmdLine;

pApp->m_nCmdShow=nCmdShow;

pApp->SetCurrentHandles();

}

//initializethreadspecificdata(formainthread)

if(!

afxContextIsDLL)

AfxInitThread();

returnTRUE;

}

②CWinApp:

:

InitApplication

AfxWinInit之后的操作是pApp->InitApplication。

实际的pApp指向CMyWinApp的对象,也就是theApp,CMyWinApp的父类是CWinApp,而InitApplication是CWinApp的一个虚函数,在CMyWinApp中没有重写它(大多数情况不需要重写它),因而最终实质调用的是:

CWinApp:

:

InitApplication();

此函数的程序原代码:

(文件:

APPCORE.CPP)

BOOLCWinApp:

:

InitApplication()

{

if(CDocManager:

:

pStaticDocManager!

=NULL)

{

if(m_pDocManager==NULL)

m_pDocManager=CDocManager:

:

pStaticDocManager;

CDocManager:

:

pStaticDocManager=NULL;

}

if(m_pDocManager!

=NULL)

m_pDocManager->AddDocTemplate(NULL);

else

CDocManager:

:

bStaticInit=FALSE;

returnTRUE;

}

这些操作都是MFC的内部管理

③CMyWinApp:

:

InitInstance

InitApplication之后,AfxWinMain调用了pThread->InitInstance(),CWinApp的父类是CWinThread,CWinApp是CMyWinApp的父类,而CMyWinApp实现了虚拟函数InitInstance(),所以实际调用的是CMyWinApp:

:

InitInstance()。

●CFrameWnd:

:

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

CMyWinApp:

:

InitInstance()会引发CMyFrameWnd构造函数的调用(New了窗口对象),接着会执行LoadFrame(),再执行Create()函数,从而产生窗口,在产生窗口之前,会引发窗口类的注册操作。

(实际还有很多动作执行,由MFC内部机制完成)

CFrameWnd:

:

Create(winfrm.cpp)->CreateEx(wincore.cpp)->PreCreateWindow(winfrm.cpp)

->AfxDeferRegisterClass(AFXIMPL.H,宏)

->AfxEndDeferRegisterClass(wincore.cpp)->DefWindowProc

->AfxRegisterClass->RegisterClass或

->RegisterWithIcon->AfxRegisterClass->RegisterClass

->CreateWindowEx

●窗口的显示与更新

CMyFrameWnd:

:

CMyFrameWnd结束之后,窗口已经产生,又回到CMyWinApp:

:

InitInstance(),于是调用ShowWindow和UpdateWindow显示和更新窗口。

④CWinThread:

:

Run()

接下来调用Run(),在CWinApp:

:

Run()中(文件:

APPCORE.CPP),最后是调用CWinThread:

:

Run(),(文件:

THRDCORE.CPP)

intCWinThread:

:

Run()

{

ASSERT_VALID(this);

//fortrackingtheidletimestate

BOOLbIdle=TRUE;

LONGlIdleCount=0;

//acquireanddispatchmessagesuntilaWM_QUITmessageisreceived.

for(;;)

{

//phase1:

checktoseeifwecandoidlework

while(bIdle&&

!

:

:

PeekMessage(&m_msgCur,NULL,NULL,NULL,PM_NOREMOVE))

{

//callOnIdlewhileinbIdlestate

if(!

OnIdle(lIdleCount++))

bIdle=FALSE;//assume"noidle"state

}

//phase2:

pumpmessageswhileavailable

do

{

//pumpmessage,butquitonWM_QUIT

if(!

PumpMessage())

returnExitInstance();

//reset"noidle"stateafterpumping"normal"message

if(IsIdleMessage(&m_msgCur))

{

bIdle=TRUE;

lIdleCount=0;

}

}while(:

:

PeekMessage(&m_msgCur,NULL,NULL,NULL,PM_NOREMOVE));

}

ASSERT(FALSE);//notreachable

}

……

BOOLCWinThread:

:

PumpMessage()

{

ASSERT_VALID(this);

if(!

:

:

GetMessage(&m_msgCur,NULL,NULL,NULL))

{

#ifdef_DEBUG

if(afxTraceFlags&traceAppMsg)

TRACE0("CWinThread:

:

PumpMessage-ReceivedWM_QUIT.\n");

m_nDisablePumpCount++;//applicationmustdie

//Note:

preventscallingmessageloopthingsin'ExitInstance'

//willneverbedecremented

#endif

returnFALSE;

}

#ifdef_DEBUG

if(m_nDisablePumpCount!

=0)

{

TRACE0("Error:

CWinThread:

:

PumpMessagecalledwhennotpermitted.\n");

ASSERT(FALSE);

}

#endif

#ifdef_DEBUG

if(afxTraceFlags&traceAppMsg)

_AfxTraceMsg(_T("PumpMessage"),&m_msgCur);

#endif

//processthismessage

if(m_msgCur.message!

=WM_KICKIDLE&&!

PreTranslateMessage(&m_msgCur))

{

:

:

TranslateMessage(&m_msgCur);

:

:

DispatchMessage(&m_msgCur);

}

returnTRUE;

}

注意:

上面消息循环,MFC采用消息映射机制(MessageMap):

窗口函数由MFC提供,采用消息映射宏把消息与处理函数相联系。

MFC把消息主要分为三类,MessageMap机制中对于消息与函数之间的对应关系也基本为三种:

1标准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_

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 生产经营管理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2