mfc第五天

一MFC视图

1,相关问题

视图窗口    --一个数据的窗口,可以喝用户进行交互操作

MFC视图类CView及其子类

2.视图窗口的使用            框架窗口带标题栏,是父窗口,而视图窗口不带标题栏,是子窗口

2.1将CView类派生自己的视图类(CMyView),并需要重写一个虚函数OnDraw

在框架窗口的WM_CREATE消息中创建视图窗口

处理WM_PAINT消息,则OnDraw()不执行

一个框架窗口,可以包含多个视图窗口,但只有一个是活动窗口,具有焦点。鼠标点击可以获取焦点。

theApp

|->m_hMainWnd(保存框架类对象地址)

|->m_pViewActive(保存视图类对象地址)

3.命令消息处理。(WM_COMMAND)

CFrameWnd::OnCmdMsg内部代码执行顺序

1利用GetActiveView获取视图类对象地址,遍历视图类这个支脉链表查找消息的处理pView->OnCmdMsg

2.利用隐含的this指针(pFrame)调用OnCmdMsg,遍历框架类这个支脉链表查找消息处理

3.利用theApp对象四肢调用OnCmdMsg,遍历应用程序类这个支脉链表查找消息处理。

View--->Frame--->App

二.运行时类信息机制

1.运行时类信息机制的作用

在程序运行过程中,可以判断类对象的相关类的信息以及继承派生关系

2.使用

2.1 类必须派生自CObject

2.2 类内部必须添加声明宏 DECLARE_DYNAMIC(theClass)

2.3 类外添加实现宏

IMPLEMENT_DYNAMIC(theClass,baseClass)

CObject::IsKindOf

struct CRuntimeClass

{

// Attributes

LPCSTR m_lpszClassName;//类名称

int m_nObjectSize;    //类的大小sizeof

UINT m_wSchema; // schema number of the loaded class    //类的版本

CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class

//动态创建机制使用(运行时类信息为NULL)

#ifdef _AFXDLL

CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();

#else

CRuntimeClass* m_pBaseClass;        //xxxxx

#endif

// Operations

CObject* CreateObject();

BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;

// Implementation

void Store(CArchive& ar) const;

static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);

// CRuntimeClass objects linked together in simple list

CRuntimeClass* m_pNextClass;       // linked list of registered classes  //NULL

};

4展开的各部分

classCDog  --静态变量  保存了类的相关信息  类名/大小/版本....

GeyRuntimeClass  虚函数

获取CDog类的静态变量地址(&classCDog),(获取链表头结点)

RUNTIME_CLASS(类名) -获取括号中指明的类的静态变量的地址

5 IsKindOf函数执行过程

5.1获取对象所属类的静态变量地址(&classCDog)

5.2拿着这个静态变量&classCDog和被判断类型&classCObject进行比较  如果相等证明对象属于该类

5.3如果不相等 获取父类的静态变量地址与被判断类&classCObject循环进行比较,只要有相等情况证

明对象属于该类

5.4无相等情况证明对象不属于该类。

三动态创建机制

1.动态创建机制的作用

在不知道类名的情况下,将类的对象创建出来。

2.动态创建的使用

1.类必须派生自CObject

2.类内部添加声明宏  DECLARE_DYNCREATE(theClass)

3.类外添加实现宏    IMPLEMENT_DYNCREATE(theClass,baseClass)

利用CRuntimeClass::CreateObject动态创建对象

3.宏展开各部分作用

3.1静态变量有变化

AFX_COMDAT const AFX_DATADEF CRuntimeClass CDog::classCDog = {

"CDog",            //

sizeof(class CDog),

0xFFFF,CDog::CreateObject, //

RUNTIME_CLASS(CAnimal),    //

NULL

};

3.2多了一个静态函数CreateObject

new 一个对象,病将对象地址返回。

4.执行过程

4.1首先获取CDog类的静态变量地址(&CDog::classCDog)

4.2利用这个函数地址调用CRuntimeClass::CreateObject函数

4.3在这个函数内部调用CDog::classCDog静态变量的第四个成员(CDog::CreateObject)

4.4在这个函数new了一个CDog类的对象,并返回对象地址。

四。窗口的切分

窗口切分相关问题

1.静态切分  窗口在创建时就完成切分,可以切分多个视图窗口 最多16*16

2.动态切分  程序在运行过程中,根据用户需要实时切分  最多2*2 多个窗口,但是是统一类型的

CSpiltterWnd  -父类为CWnd,一种框架类           CFrameWnd 口字型

静态切分

重写虚函数CFrameWnd::OnCreateClient

在函数内部定义CSplitterWnd类对象

利用对象调用CSplitterWnd::CreateStatic创建框架窗口

调用CSplitterWnd::CreateView给各个部分添加视图窗口

*****************************************************************

运行时类信息伪代码

yellowDog.IsKindOf(RUNTIME_CLASS(CDog){//函数内部this指针为&yellowDog,参数&CObject::classCObject

CRuntimeClass* pClassThis = GetRuntimeClass();//获取链表头结点

return pClassThis->IsDerivedFrom(pClass);{   //pClass  尾节点

//函数内部this指针为pClassThis链表头结点  ==&CDog::classCDog

const CRuntimeClass* pClassThis = this;  //this==&CDog::classCDog

while(pClassThis!-NULL){

if(pClass==&CObject::classCDog){

return TRUE;

}

pClassThis=pClassThis->m_pBaseClass;

}

return FALSE;

}

}

***************************************************************

动态创建机制

RUNTIME_CLASS(CDog)->CreateObject(){//this==&CDog::classCDog

pObject=(*pfnCreateObject)();{

return new CDog;//new 一个对象,并将地址返回.

}

}

*************************************************

BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass* pBaseClass) const

{

ASSERT(this != NULL);

ASSERT(AfxIsValidAddress(this, sizeof(CRuntimeClass), FALSE));

ASSERT(pBaseClass != NULL);

ASSERT(AfxIsValidAddress(pBaseClass, sizeof(CRuntimeClass), FALSE));

// simple SI case

const CRuntimeClass* pClassThis = this;

while (pClassThis != NULL)

{

if (pClassThis == pBaseClass)

return TRUE;

#ifdef _AFXDLL

pClassThis = (*pClassThis->m_pfnGetBaseClass)();

#else

pClassThis = pClassThis->m_pBaseClass;

#endif

}

return FALSE;       // walked to the top, no match

}

BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const

{

ASSERT(this != NULL);

// it better be in valid memory, at least for CObject size

ASSERT(AfxIsValidAddress(this, sizeof(CObject)));

// simple SI case

CRuntimeClass* pClassThis = GetRuntimeClass();  yellowDog->GetRuntimeClass(); 返回头结点

return pClassThis->IsDerivedFrom(pClass);

}

之前该过程与WM_CREATE一致

OnWndMsg(){

OnCommand(){

UINT nID = LOWORD(wParam);    //获取被点击菜单项的ID

...

OnCmdMsg(nID...){

CView* pView = GetActiveView(){;//this==pFrame 获取具有焦点的视图

return m_pViewActive;

}

pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo){;//函数内部指针为pView

}

}

}

}

BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)

{

LRESULT lResult = 0;

// special case for commands

if (message == WM_COMMAND)

{                    //菜单挂在框架窗口上

if (OnCommand(wParam, lParam))    //this==pFrame

{

lResult = 1;

goto LReturnTrue;

}

return FALSE;

}

.....

}

void CView::OnPaint()

{

// standard paint routine

CPaintDC dc(this);

OnPrepareDC(&dc);

OnDraw(&dc);        //父类调用

}

CView* CFrameWnd::GetActiveView() const

{

ASSERT(m_pViewActive == NULL ||

m_pViewActive->IsKindOf(RUNTIME_CLASS(CView)));

return m_pViewActive;

}

CMyView::OnDraw(CDC * 0x0018fa98 {CPaintDC hWnd=0x00060190}) line 16

CView::OnPaint() line 185

CWnd::OnWndMsg(unsigned int 15, unsigned int 0, long 0, long * 0x0018fc08) line 1836

CWnd::WindowProc(unsigned int 15, unsigned int 0, long 0) line 1596 + 30 bytes

AfxCallWndProc(CWnd * 0x028d1680 {CMyView hWnd=0x00060190}, HWND__ * 0x00060190, unsigned int 15, unsigned int 0, long 0) line 215 + 26 bytes

AfxWndProc(HWND__ * 0x00060190, unsigned int 15, unsigned int 0, long 0) line 379

USER32! 760162fa()

USER32! 76017316()

USER32! 76016de8()

USER32! 76016e44()

NTDLL! 776f011a()

CWnd::UpdateWindow() line 118 + 63 bytes

CMyWinApp::InitInstance() line 62

AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x006f588e, int 1) line 39 + 11 bytes

WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x006f588e, int 1) line 30

WinMainCRTStartup() line 198 + 54 bytes

KERNEL32! 767b33ca()

NTDLL! 77719ed2()

NTDLL! 77719ea

CObject* CRuntimeClass::CreateObject()

{

if (m_pfnCreateObject == NULL)   //this->

{

TRACE(_T("Error: Trying to create object which is not ")

_T("DECLARE_DYNCREATE \nor DECLARE_SERIAL: %hs.\n"),

m_lpszClassName);

return NULL;

}

CObject* pObject = NULL;

TRY

{

pObject = (*m_pfnCreateObject)();

}

END_TRY

return pObject;

}

宏展开

#ifdef _AFXDLL
#define DECLARE_DYNAMIC(class_name) protected: 	static CRuntimeClass* PASCAL _GetBaseClass(); public: 	static const AFX_DATA CRuntimeClass class##class_name; 	virtual CRuntimeClass* GetRuntimeClass() const;
#define _DECLARE_DYNAMIC(class_name) protected: 	static CRuntimeClass* PASCAL _GetBaseClass(); public: 	static AFX_DATA CRuntimeClass class##class_name; 	virtual CRuntimeClass* GetRuntimeClass() const;
#else
#define DECLARE_DYNAMIC(class_name) public: 	static const AFX_DATA CRuntimeClass class##class_name; 	virtual CRuntimeClass* GetRuntimeClass() const;
#define _DECLARE_DYNAMIC(class_name) public: 	static AFX_DATA CRuntimeClass class##class_name; 	virtual CRuntimeClass* GetRuntimeClass() const;
#endif

struct CRuntimeClass
{
// Attributes
	LPCSTR m_lpszClassName;
	int m_nObjectSize;
	UINT m_wSchema; // schema number of the loaded class
	CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
#ifdef _AFXDLL
	CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
	CRuntimeClass* m_pBaseClass;
#endif

// Operations
	CObject* CreateObject();
	BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;

// Implementation
	void Store(CArchive& ar) const;
	static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);

	// CRuntimeClass objects linked together in simple list
	CRuntimeClass* m_pNextClass;       // linked list of registered classes
};

#ifdef _AFXDLL
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) 	CRuntimeClass* PASCAL class_name::_GetBaseClass() 		{ return RUNTIME_CLASS(base_class_name); } 	AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name::class##class_name = { 		#class_name, sizeof(class class_name), wSchema, pfnNew, 			&class_name::_GetBaseClass, NULL }; 	CRuntimeClass* class_name::GetRuntimeClass() const 		{ return RUNTIME_CLASS(class_name); }
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) 	CRuntimeClass* PASCAL class_name::_GetBaseClass() 		{ return RUNTIME_CLASS(base_class_name); } 	AFX_COMDAT AFX_DATADEF CRuntimeClass class_name::class##class_name = { 		#class_name, sizeof(class class_name), wSchema, pfnNew, 			&class_name::_GetBaseClass, NULL }; 	CRuntimeClass* class_name::GetRuntimeClass() const 		{ return RUNTIME_CLASS(class_name); }
#else

	AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name::class##class_name = { 		#class_name, sizeof(class class_name), wSchema, pfnNew, 			RUNTIME_CLASS(base_class_name), NULL }; 	CRuntimeClass* class_name::GetRuntimeClass() const 		{ return RUNTIME_CLASS(class_name); }
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) 	AFX_DATADEF CRuntimeClass class_name::class##class_name = { 		#class_name, sizeof(class class_name), wSchema, pfnNew, 			RUNTIME_CLASS(base_class_name), NULL }; 	CRuntimeClass* class_name::GetRuntimeClass() const 		{ return RUNTIME_CLASS(class_name); } \
#define DECLARE_DYNCREATE(class_name) 	DECLARE_DYNAMIC(class_name) 	static CObject* PASCAL CreateObject();

protected: 	static CRuntimeClass* PASCAL _GetBaseClass(); public: 	static AFX_DATA CRuntimeClass class##class_name; 	virtual CRuntimeClass* GetRuntimeClass() const; 

#ifdef _AFXDLL
#define DECLARE_DYNAMIC(class_name) protected: 	static CRuntimeClass* PASCAL _GetBaseClass(); public: 	static const AFX_DATA CRuntimeClass class##class_name; 	virtual CRuntimeClass* GetRuntimeClass() const;
#define _DECLARE_DYNAMIC(class_name) protected: 	static CRuntimeClass* PASCAL _GetBaseClass(); public: 	static AFX_DATA CRuntimeClass class##class_name; 	virtual CRuntimeClass* GetRuntimeClass() const;
#else

#define IMPLEMENT_DYNCREATE(class_name, base_class_name) 	CObject* PASCAL class_name::CreateObject() 		{ return new class_name; } 	IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, 		class_name::CreateObject)

#ifdef _AFXDLL
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) 	CRuntimeClass* PASCAL class_name::_GetBaseClass() 		{ return RUNTIME_CLASS(base_class_name); } 	AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name::class##class_name = { 		#class_name, sizeof(class class_name), wSchema, pfnNew, 			&class_name::_GetBaseClass, NULL }; 	CRuntimeClass* class_name::GetRuntimeClass() const 		{ return RUNTIME_CLASS(class_name); }
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) 	CRuntimeClass* PASCAL class_name::_GetBaseClass() 		{ return RUNTIME_CLASS(base_class_name); } 	AFX_COMDAT AFX_DATADEF CRuntimeClass class_name::class##class_name = { 		#class_name, sizeof(class class_name), wSchema, pfnNew, 			&class_name::_GetBaseClass, NULL }; 	CRuntimeClass* class_name::GetRuntimeClass() const 		{ return RUNTIME_CLASS(class_name); }
#else
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) 	AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name::class##class_name = { 		#class_name, sizeof(class class_name), wSchema, pfnNew, 			RUNTIME_CLASS(base_class_name), NULL }; 	CRuntimeClass* class_name::GetRuntimeClass() const 		{ return RUNTIME_CLASS(class_name); }
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) 	AFX_DATADEF CRuntimeClass class_name::class##class_name = { 		#class_name, sizeof(class class_name), wSchema, pfnNew, 			RUNTIME_CLASS(base_class_name), NULL }; 	CRuntimeClass* class_name::GetRuntimeClass() const 		{ return RUNTIME_CLASS(class_name); }
#endif

****************************

CObject* CRuntimeClass::CreateObject()
{
	if (m_pfnCreateObject == NULL)
	{
		TRACE(_T("Error: Trying to create object which is not ")
			  _T("DECLARE_DYNCREATE \nor DECLARE_SERIAL: %hs.\n"),
			m_lpszClassName);
		return NULL;
	}

	CObject* pObject = NULL;
	TRY
	{
		pObject = (*m_pfnCreateObject)();
	}
	END_TRY

	return pObject;
}
时间: 2024-10-15 21:39:30

mfc第五天的相关文章

【数字图像处理】五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理具体解释

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行解说.主要通过MFC单文档视图实现显示BMP图片点运算处理.包含图像灰度线性变换.灰度非线性变换.图像阈值化处理.图像均衡化处理等知识,并结合前一篇论文灰度直方图进行展示 .同一时候文章比較具体基础,希望该篇文章对你有所帮助,尤其是刚開始学习的人和学习图像处理的学生. [数字图像处理]一.MFC具体解释显示BMP格式图片 [数字图像处理]二.MFC单文档切割窗体显示图片 [数字图像处理]

通过编写串口助手工具学习MFC过程&mdash;&mdash;(五)添加CheckBox复选框

通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个串口助手再次熟悉一下MFC,并做了一下记录,以便方便以后查阅.做的过程中多是遇到问题直接百度和谷歌搜索来的,所以很多都是不求甚解,知其然不知其所以然.另外做此工具只是为了熟悉了解,许多功能还没有完善!(开发工具VS2008) (五)添加CheckBox复选框 属性:Caption用于显示文本内容.

【转】VS2010/MFC编程入门之二十五(常用控件:组合框控件Combo Box)

原文网址:http://www.jizhuomi.com/software/189.html 上一节鸡啄米讲了列表框控件ListBox的使用,本节主要讲解组合框控件Combo Box.组合框同样相当常见,例如,在Windows系统的控制面板上设置语言或位置时,有很多选项,用来进行选择的控件就是组合框控件.它为我们的日常操作提供了很多方便. 组合框控件简介 组合框其实就是把一个编辑框和一个列表框组合到了一起,分为三种:简易(Simple)组合框.下拉式(Dropdown)组合框和下拉列表式(Dro

深入浅出MFC——Document-View深入探讨(五)

1. MFC之所以为Application Framework,最重要的一个特征就是它能够将管理数据的程序代码和负责数据显示的程序代码分离开来,这种能力由MFC的Document/View提供.Document/View是MFC的基石,了解它,对于有效运用MFC有极关键的影响.甚至OLE复合文件(compound document)都是建筑在Document/View的基础之上. 2. Document: 3. View: 注:在MFC里头,一旦WM_PAINT发生,Framework会自动调用

MFC创建一个窗口五大步

.窗口的创建步骤: 1.设计一个窗口类: WNDCLASS结构体参数: (1)       UINT style:窗口类的类型, (2)       WNDPROC lpfnWndProc:窗口的过程,接收一个指针,在程序中会将一个回调函数赋给他,有系统自动调用 (3)       int cbClsExtra:追加一定字节的额外存储空间,附加内存空间,常设置为0 (4)       int cbWndExtra:窗口的附加内存,常置为0 (5)       HINSTANCE hInstanc

(转载)VS2010/MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)

属性页对话框包括向导对话框和一般属性页对话框两类,上一节鸡啄米讲了如何创建并显示向导对话框,本节将继续介绍一般属性页对话框的创建和显示. 实际上,一般属性页对话框的创建和显示过程和向导对话框是很类似的.鸡啄米将上一节中的向导对话框进行少量修改,使其成为一般属性页对话框. 一般属性页对话框的创建步骤: 1.创建属性页对话框资源 属性页对话框资源的创建方法同向导对话框是一样的,上一讲中的对话框资源不需进行任何修改. 2.创建属性页类 属性页类的创建和向导对话框的属性页类也基本一样,只是一般属性页对话

MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)

属性页对话框包括向导对话框和一般属性页对话框两类,上一节讲了如何创建并显示向导对话框,本节将继续介绍一般属性页对话框的创建和显示. 实际上,一般属性页对话框的创建和显示过程和向导对话框是很类似的.将上一节中的向导对话框进行少量修改,使其成为一般属性页对话框. 一般属性页对话框的创建步骤: 1.创建属性页对话框资源 属性页对话框资源的创建方法同向导对话框是一样的,上一讲中的对话框资源不需要进行任何修改. 2.创建属性页类 属性页类的创建和向导对话框的属性页类也基本一样,只是一般属性页对话框中不需要

一步一步开发sniffer(Winpcap+MFC)(五)莫道无人能识君,其实我懂你的心——解析数据包(转)

前文已经讲过,解析数据包主要通过analyze_frame()这个函数实现的,实际上并非这个函数完成了所有的功能,其实从名字就可以看出,它只是完成了对“帧”的解析,也就是链路层数据的解析,还有analyze_arp().analyze_ip().analyze_ip6().analyze_icmp()……等来完成其他协议层的解析工作. 为什么会这样定义?熟悉协议栈工作流程的都知道,数据是由应用层把数据加上应用层协议头后给传输层,传输层在最外面加上它的头部后给网络层,网络层在外面加上它的头部后再给

MFC 小知识总结五

1 移动无标题对话框   响应WM_NCHITTEST 消息 [cpp] view plaincopy LRESULT CTimeJishiDlg::OnNcHitTest(CPoint point) { // TODO: 在此加入消息处理程序代码和/或调用默认值 LRESULT res=CDialogEx::OnNcHitTest (point); if (res==HTCLIENT)        //HTclient  落在客户区 { res=HTCAPTION;    //返回标题栏资源