U盘PE| w764位旗舰版下载 | U盘装win7系统 | U盘启动 |win7pe | win10下载 |加入收藏土豆PE官网U盘PE,U盘装win7系统,win7pe,U盘启动,U盘装系统,w764位旗舰版下载站!
当前位置:主页 > 帮助中心 > 帮助中心 >

Windows MFC 工程应用开发与框架原理完全剖析视频教程(中)之上部

来源:http://www.tudoupe.com时间:2022-07-18

Windows MFC 工程应用开发与框架原理完全剖析视频教程(中)之上部

  • 第3章 原则2 MFC核心框架的全面实施
    • 3.1MFC高级级结构设计及RTTI和CRunTimeClass设计思想的分析
    • 3.2RTTI设计及核查
    • 3.3动态类型识别技术:动态类型识别技术的设计和实现
    • 3.4动态创造技术-宣布宏
    • 3.5CWinThread的深入分析和实现(1):CWinThread的实现
    • 3.6CWinThread(2)的深入分析和实现:MFC工人线性设计-CTypedSimpleList和CSimpleList的泛建模实现
    • 3.7CWinThread(3)的深入分析和实现:MFC工人线性设计-NnoTrackObject的实现
    • 3.8CWinThread(4)的深入分析和实现:MFC工人线性设计-MFC线性进步的覆盖基础-WindowsTLS机制的详细说明
    • 3.9CWinThread(5)的深入分析和实现:MFC工人线性设计-MFC封装TLS的原理分析
    • 3. 10 个 MFC 工作线的设计-- MFC 封装 TLS 头文件编码的实现
    • 3.11MFC工人线性设计-MFC接口TLS1
    • 3. 12 个 MFC 工人线的设计-MFC 接口 TLS2
    • 3.13CThreadSlotData分析、DeltaValues编码和CThreadLocalObject函数
    • 3.14MFC工人线性设计-单元测试和MFC封装TLS的总结
    • 3. 15 个 MFC 工人线的设计-CWinThread全面实施
    • 3.16 MFC工作线设计-CWinThread和错误删除的单元测试
    • 3.17 MFC工人线程的设计-CWinThread过程运行的概述


第3章 原则2 MFC核心框架的全面实施

3.1MFC高级级结构设计及RTTI和CRunTimeClass设计思想的分析

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

CObject CRuntimeClass::CreateObject(void)可以生成类变量。该函数与新函数类似,但在某些特殊情况下具有独特的函数。

在 上面例子中,CreateWnd返回的是CWnd* 其实它是一个CWndA*。你可以进行由父类到子类的强制转换而不必要担心出错。
使用CRuntimeClass可以取代一些简单的使用开关生产类的例子。请考虑一下它的使用.当你发现它的好处时,你一定会大吃一惊,M$使用宏实现类动态检测,如果您有兴趣,请查阅MFC的源代码。)
注: IMPLEMENT_DYNCREATE在类定义中使用后会生效。

MFC中经常只需要构建类,程序就可以运行了,并没有看到创建对象的过程。那么对象是如何创建的呢?
这是动态创造机制。
动态创建允许MFC自动为您写的类创建对象,因此您只需要在写代码的过程中编辑该类。

为了实现对象的自动创建,必须在每个类中创建一个结构, CRuntimeClass,主要记录类的信息:类名、几个标记和构造函数CreateObject。
指针用于程序中的所有类序列化(包括您创建的类和MFC自动创建的类),在整个程序中创建一个类的链表。需要指出,这个链是水平的和垂直的。横向是指,每个类通过m_pNextClass根据构造序列(pfirst和pnext的字符串)连接,用简单的链接表连接所有CRuntimeClass对象。纵向是指,在结构m_pBaseClass中还有一个指针,指向该类的父类。这样可以更容易查询该类的导数关系。

用于构造类对象的构造函数。CreateObject()函数是可动态创建的类中。
动态创建类CRuntimeClass结构中的m_pfnCreateObject字段最初被分配给CreateObject,如果它是NULL,则不能动态创建。
上述构造函数可参阅: https://ww.cnblogs.com/tinaluo/p/7826678.html

有了这些准备,动态创造是很容易的.例如,在主程序中,提供一个类名,创建该类的对象。只要写一个搜索函数,有了类的链表,搜索函数可以轻易地搜索相应的类,搜索成功后,调用该类内置函数,就可以产生对象。

上述搜索功能可以在 https://blog.csdn.armman/article/details/1527409 找到


3.2RTTI设计及核查

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

上图return pClassThis->IsDerivedFrom函数的参数错了,应由pClassThis改为pClass。

在这里插入图片描述

上面显示的RUNTIME_CLASS宏定义,其中CRuntimClass应变为CRuntimeClass。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3.3动态类型识别技术:动态类型识别技术的设计和实现

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3.4动态创造技术-宣布宏

在这里插入图片描述

上面的图显示了一个错误,我们通过设置下图的输出预处理文件,在宏扩展后检查代码声明。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

你可以看到,图片的末端有一个反向栏,应该被删除。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3.5CWinThread的深入分析和实现(1):CWinThread的实现

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3.6CWinThread(2)的深入分析和实现:MFC工人线性设计-CTypedSimpleList和CSimpleList的泛建模实现

在这里插入图片描述

在这里插入图片描述

上图有误,应改为:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3.7CWinThread(3)的深入分析和实现:MFC工人线性设计-NnoTrackObject的实现

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

如果我们的数据节点不继承CNoTrackObject:
在这里插入图片描述

在这里插入图片描述

它调用的是通用的new和delete操作符。


3.8CWinThread(4)的深入分析和实现:MFC工人线性设计-MFC线性进步的覆盖基础-WindowsTLS机制的详细说明

在这里插入图片描述

在这里插入图片描述

这是我们一开始使用的非常简单的工人线条,我们直接使用AfxBeginThread进行主要功能,根据微软的讲法,在MFC中,我们不需要去CloseHandle,而且你不需要做一系列的线圈关闭,我们可以直接使用这些参数。我们不需要删除对象,我们不需要管理手柄.

在这里插入图片描述

对于线程本地存储,我们需要集中注意两个概念:
(一)在一个线程中本地存储的位子集;
(二)线程和位群之间的通信。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3.9CWinThread(5)的深入分析和实现:MFC工人线性设计-MFC封装TLS的原理分析

在这里插入图片描述

我们希望线程和线程之间的数据也能够有逻辑访问:
在这里插入图片描述

MFC使用线性本地存储扩展,使得它可以无限扩展,因为我们以前有固定数量的线性本地存储。

在这里插入图片描述


3. 10 个 MFC 工作线的设计-- MFC 封装 TLS 头文件编码的实现

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

我们定义了CThreadLocalObject类,它是一个辅助数据结构,我们定义以完成分区分配,即在分区数据中提到的实际用户数据。
在这里插入图片描述

这实际上是我们线程本地存储中的那个空格中的对象,所以必须有一个空格数。

我们将MFC的内容复制到CThreadLocalObject模板中:
在这里插入图片描述

在这里插入图片描述

在我们的开发过程中,为什么,当MFC做这个工人的线程时,它不允许通过线程访问非MFC对象,因为一旦跨线访问被从我们的TLS管理中删除,为了使这种实现超越了我们的供应链管理,让你的记忆管理无法控制,因为您也知道它的内存不再在C++中运行,事实上,它对于操作系统至关重要,所以它不能跨线访问。


3.11MFC工人线性设计-MFC接口TLS1

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3. 12 个 MFC 工人线的设计-MFC 接口 TLS2

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3.13CThreadSlotData分析、DeltaValues编码和CThreadLocalObject函数

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3.14MFC工人线性设计-单元测试和MFC封装TLS的总结

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在我们的召唤过程中,它与MFC的CWinThread输入点函数AfxThreadEntry非常相似,换句话说,我们只需要从上面的图片中删除78到81行。转换为AfxThreadEntry函数调用是好的,但我们还没有_bgeinthreadex和WaitForMultipleObjects,以及CloseHandle来做一些事情(要把它们封装起来),我们不能自动关闭内容(程序处理、同步事件、程序本地对象等),然后我们开始编码CWinThread工人的线程。


3. 15 个 MFC 工人线的设计-CWinThread全面实施

为CWinThread class.h新定义的 _ AFXWIN头条:
在这里插入图片描述

在这里插入图片描述

这个m_hThread说,因为CWinThread是一个C++语法,它应该能够在头上保存一个手柄,这实际上是调用WindowsSDK来帮助我们创建这个线程;
重载一个括号运算符, 其实现是返回m_hThread.

在这里插入图片描述

这个进程中可能有多个线程,每个线程都有不同的模块(线程有私人数据),在这些模块中,这个一个线程对我们来说是私有的,例如,线程1有一个自己的模块,2号线也有自己的模块,这些模块必须作为线程保持其状态,因为这些可执行对象(模块)也会被推广,推进到哪里也会被记录,现在我们必须重新设计一个班级来记录这个状态,我们称之为状态AFX_MODULE_THREAD_STATE,很明显,这个线程的状态必须取决于TLS。

在这里插入图片描述

换句话说,我们的MFC内部维护每个模块独立于每个线程;
我们还必须维持它,让它能够用链条捆绑它,为了管理每个线程的状态,使用THREAD_LOCAL宏把表示线程状态的全局变量_afxModuleThreadState改写成线程局部变量(通过我们自己的线程局部存储),即CThreadLocal<AFX_MODULE_THREAD_STATE> _afxModuleThreadState

在这里插入图片描述

在这里插入图片描述

除了AFX_MODULE_THREAD_STATE的定义之外,我们还得想一想,当我们的用户使用CWinThread创建线程时,除了设置线程的状态之外,进入消息循环,我们还必须适当地设置线程的函数地址,但我们也不能直接暴露给用户。那时我们开始想,我们需要一个设计来帮助我们设计在Windows SDK中的C++函数。

在这里插入图片描述

AFX_THREADPROC 这个类型的函数将用于初始化我们的线程参数,帮助我们运行我们的线程。

在这里插入图片描述

在这里插入图片描述

让我们回顾使用MFC的过程,我们需要提供一个AfxThreadEntry来帮助我们输入函数的输入点,然后我们实现了AfxThreadEntry,CWinThread类, ThreadCore.cpp的新实现文件:

在这里插入图片描述

换句话说,为了推进子程序,我需要为子程序(例如同步机制)创建一个特定的环境,因此我们现在还必须有一个名为AFX_THREAD_STARTUP的包。

在这里插入图片描述

通过这种结构,把它放在Win32中的 CreateThread函数中,可以这么讲,我们正在将CWinThread结合到CreateThread中,完成CWinThread输入点函数AfxThreadEntry.

两个线程(主线程和子线程)之间的交互是事件对象:
在这里插入图片描述

第一个hEvent告诉您在创建子线程后触发,告诉父亲线程我们已经创建它,告诉父亲线程您可以继续;
第二个hEvent2就是说,当我完成为这个调用线程准备的所有粒子并再次触发它时,换句话说,告诉下线程你可以继续。

_AfxThreadEntry:
在这里插入图片描述

这个时候呢,既然有了AFX_THREAD_STARTUP,我们就可以为CWinThread对象组合进来提供帮助了。
通过AFX_THREAD_STARTUP获得我们将要推进的CWinThread对象,即pStatup->pThread

接下来我们将设置线程的状态并查看内容:
在这里插入图片描述

让我们看看我们是否能从这个对象中获取该模块的当前状态,同时我们指定当前状态,指向这个CWinThread对象的当前pThread;
通过try…catch语句看看这个转换是否OK,有没有异常,因为线程当中有可能会被其他打断,这个时候我们就不能往下执行了,设置bError为TRUE,告诉父线程新创建的这个子线程初始化出错。

在这里插入图片描述

在这里插入图片描述

CommonConstruct函数它的任务是建立我们的对象。

此外,我们还为用户提供两个全球功能:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

我们回到 ThreadCore.inside cpp,上图这个地方,当父线作为进入点向前走时,我们会考虑,这个pStartup指的内存空间是我们的新线程的空间,我们开始了新的线程的初始化后,如果新线程堆栈无法构造,这个线程的空间(指向pStartup的内存空间)可能被侵蚀,所以我们需要能够正常地启动CreateThread,然后才能完成。我们先保存下pStartup->hEvent2的值,确保线程初始化完成(避免子线程僵局)。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

要返回当前线程CWinThread对象的指针, 我们必须取其状态.

在这里插入图片描述

这意味着AFX_MODULE_THREAD_STATE总是包含我们的CWinThread对象。

在这里插入图片描述

这是我们自己编写的线程的本地存储,因为CWinThread对象不存在,我们也将释放我们自己分配的内存空间,否则它将占用内存资源;
FALSE参数表示只有当前线程被删除当前线程的本地存储空间。

在这里插入图片描述

vs智能感知不到_afxThreadData变量,它是放在AFXTLS.cpp文件当中的,所以需要调整一下位置,放到_AFXSTAT.h里面:
在这里插入图片描述

在这里插入图片描述

当我们先让它挂起来时,我们创建一个线程的原因是考虑父母线程和子线程之间的相互作用,并给子线程足够的时间来载入其中资源。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

如果成功创建的线程手柄存在,则我们将恢复线程的执行。
坦率地说,它告诉你,当父亲线创造了这个孩子线之后,你先把所有空间放在里面,然后推你向前。

这个时候在ResumeThread之后,我们就要开始让子线程去把相应的空间初始化完毕,所以要等待你(子线程)告诉我初始化完毕好了,告诉我什么时候能够推进,由你子线程完成告诉我。
在这里插入图片描述

如果用户一上来并不是要求你直接推进,你创建的是一个挂起的线程,我就先让你暂时停止推进,等什么时候需要推进的时候由你来推进。
用户可以创建悬挂线程, 这是常见的操作.

由于资源不足,创建一个线程很可能失败.
在这里插入图片描述

在这里插入图片描述


3.16 MFC工作线设计-CWinThread和错误删除的单元测试

在这里插入图片描述

让我们看看 MFC工人线程是如何实现的。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

你看,这个AfxBeginThread非常接近MFC的工作流程,所以这是我们对CWinThread的基本工作。

在这里插入图片描述

注意,我们只是把它弄错了,它应该在_AFXTLS_上。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这个时候就会出现上图这种重定义的问题,这个原因是什么呢?
这是因为重复涉及造成,为了解决这种重复内容,我们将修订标题,因为在C/C++中我们又做了混合编程,请特别注意这个问题,因为C没有所谓的空间的概念,因此, 它 将 以 文件 统一,在我们的 ThreadCore.the _afxThreadData中,在cpp中的AFXTLS.the _afxThreadData,会有重复冲突的现象,所以没有办法在obj文件中有一个独特的生成。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

同样, _ AFXSTAT.h 和 _ AFXWIN.h 应该在两个标题上进行同样的修正:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在选择中切开两个行并将其放在AFXTLS中。 在cpp文件中:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3.17 MFC工人线程的设计-CWinThread过程运行的概述

让我们看看工人的线条做了些什么。
让我们开始创建父线:

在这里插入图片描述

新线程创建,现在,让我们看看我们的操作系统中创建新的线程,它实际上给你一个堆栈的线条和一些空间,但它尚未立即实施,为什么呢,因为你知道我们可能会得到一些手柄,一些模块啊,还有一些相应的执行器可以推入Windows,同时,如果它还没有完全启动,不能执行,所以怎么办呢,它先挂起,这就是子程序做的。

在这里插入图片描述

左上是MFC做的,MFC帮助我们推新的线程(右),这样新的线程开始执行AfxThreadEntry。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这是我们的CWinThread过程。可以这么讲,虽然这个CWinThread对我们来说很方便,但是,MFC已经做了很多工作来推进我们的应用,每个人都必须了解这个过程,因此,我们的新轨迹不会被推向上。

现在要知道的基本上有两件事,第一个,CWinThread能够封装函数WinMain,而且因为它可以被看作是函数执行器,如线程等命令序列的聚合物向前推进,所以我们的MFC用CWinThread完成WinMain功能;
第二个,当我们的MFC正在推进这一方向时,它考虑到这个线程交互的状态,所以我们做了一系列事情,能够管理自己的记忆力,您可以在线程中管理自己的数据,同时通过技术,如TLS,使线程的相互作用更加统一和协调,在这个过程当中,可以说它是使用Windows操作系统底层的更复杂的机制。

Copyright © 2012-2014 Www.tudoupe.Com. 土豆启动 版权所有 意见建议:tdsky@tudoupe.com

土豆系统,土豆PE,win7系统下载,win7 64位旗舰版下载,u盘启动,u盘装系统,win10下载,win10正式版下载,win10 RTM正式版下载,win8下载,电脑蓝屏,IE11修复,网络受限,4K对齐,双系统,隐藏分区,系统安装不了,U盘装系统,笔记本装系统,台式机装系统,diskgenius运用,GHSOT装系统,U盘修复,U盘技巧,U盘速度,U盘不能格式化,U盘复制发生错误,U盘加密,U盘选购,开机黑屏,蓝屏,进不了系统,上不了网,打不开程序,点击无反应,系统设置,PE个性化,PE添加网络,PE维护系统

点击这里给我发消息