MFC学习笔记窗口创建.docx

上传人:b****5 文档编号:5151007 上传时间:2022-12-13 格式:DOCX 页数:21 大小:25.15KB
下载 相关 举报
MFC学习笔记窗口创建.docx_第1页
第1页 / 共21页
MFC学习笔记窗口创建.docx_第2页
第2页 / 共21页
MFC学习笔记窗口创建.docx_第3页
第3页 / 共21页
MFC学习笔记窗口创建.docx_第4页
第4页 / 共21页
MFC学习笔记窗口创建.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

MFC学习笔记窗口创建.docx

《MFC学习笔记窗口创建.docx》由会员分享,可在线阅读,更多相关《MFC学习笔记窗口创建.docx(21页珍藏版)》请在冰豆网上搜索。

MFC学习笔记窗口创建.docx

MFC学习笔记窗口创建

MFC

hierarchychart(类库列表)

 

MFC与Win32

1win32:

函数,使用API一步一步搭建应用程序。

(常使用FileView操作)

2MFC编程:

实现仍然调用API函数,但是是用类封装API函数,使用向导自动生成应

用程序框架。

(常使用ClassView操作)

2.1需要掌握的技能

2.1.1断点调试

2.1.2堆栈调用的查看

 

MFC课程内容

1MFC:

MFC的六大机制,文档式架构,常用的MFC类,(10--12)。

2COM(组件对象模型):

COM的原理和应用(6)。

3ADO/Socket:

MFC访问数据库以及一些简单的网络编程。

 

MFC应用程序编程

1MFC的历史:

92(VC1)98(VC6)……………………….

2MFC库基础:

2.1MFC库,微软基础类库。

封装了Windows应用程序编程的各种API以及相关机制

的C++类库

3类库的相关头文件件

★afx-applicationframework(应用程序框架x)

3.1-不是类库头文件,是项目的头文件,称为VC下编译的预编译头文件,

用来提高编译速度的。

(*.pch)(头文件是不参加编译的但是他参与生成*.pch)

3.2-几乎包含了各种常用的MFC有文件

3.3-提供扩展窗口类的支持(创建工具栏,状态栏等………)

 

MFC应用程序的类型

1支持MFC的控制台应用程序(控制台的第四个选项)

1.1多了一个CWinApp(应用程序类,封装类应用程序启动过沉重所涉及到得相

关信息)的全局对象(必须有,而且只能有一个)

1.2主函数中多了一个AfxWinInit函数,初始化MFC库中的相关信息

2MFC库程序

2.1MFC支持的静态库

2.2MFC支持的动态库

2.2.1MFC规则库(sharedMFCDLL)-可以被各种应用程序调用(非MFC程

序,没有MFC类也可以调用)

★还是有一个CWinApp派生的CMFC_DLLApp类对象

2.2.2MFC扩展库(usingsharedMFCDLL)-只能被MFC库所编写的应用程

序所调用(对原有的MFC类扩展)

★DllMain主函数只能被MFC程序调用

3MFC应用程序-----(注意看父类,子类名字可能不一样)

3.1单文档视图应用程序

★CWinApp应用程序类

★CAboutDlg(对话框-生成关于窗口-和框架没有任何关系)

★CMainFrame(父类是:

CFrameWnd)(应用程序主框架窗口类-生成应用程

序的主框架-负责各个对象的协调工作)

★CDocument(它是父类)(文档类-看不到的很重要-管理数据)

★CView(它是父类)(视图类-显示数据并和用户进行交互)

★CSingleDocApp(父类是CWinApp)-(使用前面的3个类来创建对象)

3.2多文档视图架构

★CWinApp应用程序类

★CAboutDlg(对话框-生成关于窗口-和框架没有任何关系)

★CView(它是父类)(视图类-显示数据并和用户进行交互)

★CDocument(它是父类)(文档类-看不到的很重要-管理数据)

★CMDIChildWnd(子框架窗口类,父类)

★CMDIFrameWnd(主框架窗口类,父类)

我们看到的子窗体其实是★CView和★CMDIChildWnd叠加的

3.3基于对话框的应用程序

★CWinApp应用程序类

★CDialog(对话框窗口类)

★★m_pMainWnd保存主窗口地址

DoModal显示对话框

 

MFC相关类的说明

1继承自CObject

1.1CObject类:

绝大多数MFC类的父类,提供了MFC库的一些机制

1new/delete操作符,定义了与构造函数相关的内存分配函数

2assert和dump调试,堆调试的支持

★3运行时类信息-属于哪个类,还有类的层次结构

★4动态创建

★5序列化

1.2CWinThread:

线程类。

1.2CwinAPP类:

封装了类应用程序,线程等的初始化信息,是应用程序开始创建

的第一个对象,并且也是结束前最后一个执行的对象,启动时应用程序类负责创建其余的对象。

1.3CDocTemplate类:

文档模板类,应用程序打开一个文档时,文档模板定义创

建什么的框架,文档和视图

两个子类CSingleDocTemplate(单文档)和CMultiDocTemplate(多文档)(注意:

InitInstance()函数)

1.4CFramWnd类:

框架窗口类

1.5CSplitterWnd类:

拆分窗口类

1.6CControlBar类:

工具栏类

1.7CPropertySheet类:

属性表单类-一个属性表单里面有很多属性页用

CPropertyPage类创建

1.8CDialog类:

对话框类

CCommonDialog通用对话框(各种颜色,字体,什么对话框)

COlePropertyPage-页对话框

1.9CView类:

视图类

1.10控件类:

CAnimateCtrl视频类

CButton按钮类

CComboBox组合框类

CLIstBox列表框

1.11CDucument类:

文档类

1.12CException类:

异常处理类

1.13CFile类:

文件处理类和序列化结合讲解

1.14画图类:

CDC:

绘图设备上下文类-(相当于纸)

CGdiObject-(相当于笔)

5.1.15集合类

CArray动态数组-查询快-查找都是从头找,如果数组很大,查找效率低

CLIst链表-底层双向链表-删除,插入块

Cmap映射-快速查找-(key,value)

CFileFind-文件查找类-同CFile一块用

2非CObject的子类

提供了各种数据结构的相关管理。

第一个MFC程序

1设置MFC开发环境

1.1修改头文件

1.2设置工程为使用MFC库(Seeting->UseMFCinashareDLL)

以下注意:

★加上:

:

的是调用的全局Win32函数,不加调用的是该类的成员函数

★窗口类对象和窗口(句柄,内存空间标识)有很大区别,窗口类对象是

用来操作窗口的,对象创建出来并不是创建出窗口了

VC6断点调试的操作:

F9(设断点),F5(跳到下一个断点),F10(执行下一条语句),

F11(当前语句如果有函数能进入就进入,不能进入执行一条语句)

(ALT+F9)(打开断点调试列表),ALT+F8(代码自动对齐)

F12(选中宏或者类,能看原型,类型能看原型)

★堆栈工具条里面:

下面的调用上边的(有时系统调用我写的,有时我写的函数调用系统的)

2程序的编写

★2.1定义CWinApp类的子类,并且定义该类的全局变量

例:

classCMyWinApp:

publicCWinApp

{

public:

virtualBOOLInitInstance();

};

CMyWinApptheApp;

★2.2定义CFrameWnd类的子类(主框架窗口类)

例:

classCMainFrame:

publicCFrameWnd

{

virtualLRESULTWindowProc(UINTmessage,WPARAMwParam,LPARAMlParam);

};

★2.3在CWinApp类的InitInstance函数中,创建CFrameWnd窗口,并显示

例:

BOOLCMyWinApp:

:

InitInstance()

{

//创建应用程序窗口

//创建框架窗口类对象

CMainFrame*pFrame=newCMainFrame();

//创建窗口

pFrame->Create(NULL,"MFC_Wnd");

//将窗口赋值成为当前用用程序的主窗口

m_pMainWnd=pFrame;

//显示主窗口

m_pMainWnd->ShowWindow(SW_SHOW);

m_pMainWnd->UpdateData();

returnTRUE;

}

★2.4实现CFrameWnd的WindowProc函数,处理消息

★例:

LRESULTCMainFrame:

:

WindowProc(UINTmessage,WPARAMwParam,LPARAMlParam){

switch(message){

caseWM_PAINT:

PAINTSTRUCTps={0};

CDC*hDc=BeginPaint(&ps);

hDC->TextOut(hDC,100,100,"HelloMFC",9);

EndPaint(&ps);

break;

}

returnCFrameWnd:

:

WindowProc(message,wParam,lParam);

}

MFC程序的启动-(入口函数机制)

1程序的入口在哪?

(MFC的第一个机制:

入口函数机制)

★第一步:

程序启动,调用CWinApp的构造,将CWinApp的对象theApp的地址保

存到模块状态信息中,将theApp的地址保存到线程状态信息中。

★第二步:

WinMain调用AfxWinMain(内核自动调用,不是说哪个函数调用,要不

是声明了一个全局变量,它才是第一步)

★第三步:

AfxWinMain函数的执行

3.1获取当前应用程序对象theApp(CFrameWnd类的子类的对象)的地址

使用AfxGetThread()函数从线程信息中获取

使用AFxGetApp()从模块信息中获取。

3.2使用AfxWinInit()初始化MFC库

3.3使用InitApplication()函数初始化应用程序数据

3.4调用CMyWinApp:

:

InitInstance()函数创建并显示窗口

3.5调用App的Run函数进行消息循环处理

3.6结束MFC库,退出程序。

2MFC的窗口创建过程和Win32创建过程一样

3CWinApp类

应用程序封装类,父类是CWinThread,封装程序的初始化,信息,消息循环等。

InitInstance-程序的初始化函数,完成窗口的创建等初始化工作

ExitInstance-程序突出时调用的函数,完成资源释放等善后工作

Run-消息循环

OnIdle-空闲处理函数

m_pMainWnd-当前程序的主窗口

一般先创建窗口然后设置为主窗口:

m_pMainWnd=pFrame;

 

窗口的创建-(窗口创建机制)

1窗口的消息处理函数是AfxWndProcBase,但是窗口类设计时不是他

是wndcls.lpfWndProc=DefWindowProc

2窗口的创建过程

2.1如果有的话加载菜单

2.2调用CWnd的CreateEx创建窗口

2.2.1PreCreateWindow设计并注册窗口类

此时是将DefWindowProc设置成为窗口的处理函数

2.2.2调用AfxHookWindowCreate()创建钩子函数,在函数内部调用

SetWindowsHookEx创建WH_CBT(窗口创建就创建钩子),钩子

的处理函数是_AfxCbtFilterHook(Ctrl+F能查找到在本文件定义

的函数的位置)

2.2.3调用CreateWindowEx()函数创建窗口立即调用钩子函数

2.2.4卸载钩子,并返回。

2.3在_AfxCbtFilterHook函数中

2.3.1调用AfxGetAfxWndProc获取MFC提供的窗口处理函数的地址

2.3.2使用SetWindowLong函数将该窗口处理函数设置成MFC提供的窗口处

理函数

为什么要替换?

消息处理-(消息映射机制)

不再是所有消息走一个函数而是一个消息对应一个消息处理函数

1消息映射的使用

1.1在CMainFrame类的定义中,添加消息映射声明DECLARE_MESSAGE_MAP()(宏可没有分号)

1.2在CMainFrame类的实现中,添加消息映射实现宏

BEGIN_MESSAGE_MAP(className(实现类),baseclassName(实现类的父类))

END_MESSAGE_MAP()

1.3在类中定义并且实现消息映射的处理函数。

1.4在消息映射的实现宏中,添加消息与消息处理函数的对应关系

ON_MESSAGE(WM_CREATE(消息),OnCreate(消息处理函数的函数名称))

例:

classCMainFrame:

publicCFrameWnd

{

DECLARE_MESSAGE_MAP()//消息映射声明宏

voidOnMyCreate();

voidOnMyPaint();

};

BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)//消息映射实现宏

ON_MESSAGE(WM_PAINT,OnMyPaint)//对应关系

ON_MESSAGE(WM_CREATE,OnMyCreate)

END_MESSAGE_MAP()

宏的具体实现

★DECLARE_MESSAGE_MAP()//消息映射声明宏

***************************替换消息映射声明宏代码**************************

private:

staticconstAFX_MSGMAP_ENTRY【1】_messageEntries[];

protected:

staticAFX_DATAconstAFX_MSGMAP【2】messageMap;

staticconstAFX_MSGMAP*PASCAL_GetBaseMessageMap();

virtualconstAFX_MSGMAP*GetMessageMap()const;

★BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)//消息映射实现宏

ON_MESSAGE(WM_PAINT,OnMyPaint)//对应关系

ON_MESSAGE(WM_CREATE,OnMyCreate)

END_MESSAGE_MAP()

********************************消息映射实现宏*********************************

constAFX_MSGMAP*PASCALCMainFrame:

:

_GetBaseMessageMap()

{

return&CFrameWnd:

:

messageMap;【5】

}

constAFX_MSGMAP*CMainFrame:

:

GetMessageMap()const

{

return&CMainFrame:

:

messageMap;【6】

}

AFX_COMDATAFX_DATADEFconstAFX_MSGMAPCMainFrame:

:

messageMap=

{

&CMainFrame:

:

_GetBaseMessageMap,【3】

&CMainFrame:

:

_messageEntries[0]【4】

};

AFX_COMDATconstAFX_MSGMAP_ENTRYCMainFrame:

:

_messageEntries[]=

{

{WM_CREATE,0,0,0,AfxSig_lwl,

(AFX_PMSG)(AFX_PMSGW)

(LRESULT(AFX_MSG_CALLCWnd:

:

*)

(WPARAM,LPARAM))&OnMyCreate},

{WM_PAINT,0,0,0,AfxSig_lwl,

(AFX_PMSG)(AFX_PMSGW)

(LRESULT(AFX_MSG_CALLCWnd:

:

*)

(WPARAM,LPARAM))&OnMyPaint},

{0,0,0,0,AfxSig_end,(AFX_PMSG)0}

};

2宏代码分析

1.2.1_messageEntries[]数组(用结构保存每一个消息和其对应处理函数等消息信息,实

现消息映射机制)其类型为AFX_MSGMAP_ENTRY结构【1】

structAFX_MSGMAP_ENTRY

{

UINTnMessage;//消息ID或者标识(WM_XXXX)★

UINTnCode;//通知码或者控制码(消息的分类)

UINTnID;//空间的ID(是"0"的话代表窗口消息)

UINTnLastID;//指定一个消息的ID范围的最大值

UINTnSig;//消息处理函数的类型

AFX_PMSGpfn;//处理这个消息函数的指针★

};

1.2.2messageMap的类型AFX_MSGMAP(通过这个结构可以找到所有的相关父子类

中消息)【2】

structAFX_MSGMAP

{

//保存“获得父类的AFX_MSGMAP函数”的指针(类似链表)

constAFX_MSGMAP*(PASCAL*pfnGetBaseMap)();【3】

constAFX_MSGMAP_ENTRY*lpEntries;//当前的_messageEntries[]数组的地址【4】

};

3作用

3.1_messageEntries[]数组

静态数组,类型AFX_MSGMAP_ENTRY数组中的每个元素保存了消息ID和与之

对应的处理函数的地址。

3.2messageMap

静态变量,类型是AFX_MSGMAP,分别保存了_messageEntries[]数组的地址,以

及_GetBaseMessageMap函数的地址

3.3_GetBaseMessageMap()

静态函数,获取父类的messageMap变量的地址【5】

3.4GetMessageMap()

虚函数,获取本类的messageMap变量的地址【6】

4调用关系

CMainFrame:

:

GetMessageMap()

★|->messageMap

★|->_messageEntries[]

★|->消息ID,函数指针

★|->_GetBaseMessageMap()

☆|->CFrameWnd:

:

messageMap

☆|->CFrameWnd:

:

_messageEntries[]

☆|->CFrameWnd的消息ID,CFrameWnd的消息处理函数指针

☆|->CFrameWnd:

:

_GetBaseMessageMap()

○|->CWnd:

:

messageMap

○|->CWnd:

:

_messageEntries[]

○|->CWnd的消息ID,CWnd的消息处理函数指针

○|->CWnd:

:

GetMessageMap()

◆|->NULL(直到空结束,链表结束)

1.5执行过程

我们可以定义一些消息的处理,但是许多消息没有自己定义,根据处理机制中的链表关

系,一级一级一直向上找,直至CWnd调用默认处理函数DefWindowProc

★执行过程

1.5.1调用窗口对象的GetMessageMap()(虚函数不是静态的),获得当前类的messageMap

(静态的)地址pMessageMap

1.5.2从pMessageMap的_messageEntries[]数组中查找消息ID所对应的数组元素。

如果

找到执行goto语句。

1.5.3如果没有找到,调用pMessageMap中的pBaseMap,获得父类的pMessageMap,

继续查找

1.5.4如果直到pMessageMap为空还没有找到,结束查找,调用DefWindowProc的默

认处理函数

1.5.5使用查找到的lpEntry,根据数组元素lpEntry中的消息处理函数的类型,调用消息

处理函数。

★根据堆栈调用显示:

1首先CWnd:

:

WindowProc调用CWnd:

:

OnWndMsg

RESULTCWnd:

:

WindowProc(UINTmessage,WPARAMwParam,LPARAMlParam)

{

LRESULTlResult=0;

if(!

OnWndMsg(message,wParam,lParam,&lResult))

//直到CWnd都无这个消息,代表OnWndMsg执行失败,调用默认的DefWindowProc

lResult=DefWindowProc(message,wParam,lParam);

returnlResult;

}

2消息找到了,CWnd:

:

OnWndMsg的执行过程

//首先调用当前的GetMessageMap()

constAFX_MSGMAP*pMessageMap;pMessageMap=GetMessageMap();

//进入消息映射链表循环中

for(;pMessageMap!

=NULL;pMessageMap=pMessageMap->pBaseMap)

{

if(message<0xC000)

{

if((lpEntry=AfxFindMessageEntry(pMessageMap->lpEntries,message,

0,0))!

=NULL)

{

pMsgCache->lpEntry=lpEntry;

AfxUnlockGlobals(CRIT_WINMSGCACHE);

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

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1