微软MFC技术简明介绍

news2024/12/23 0:43:41

我是荔园微风,作为一名在IT界整整25年的老兵,今天来看一下微软MFC技术简明介绍

Visual C++ 与 MFC

微软公司于1992年上半年推出了C/C++ 7.0 产品时初次向世人介绍了MFC 1.0,这个产品包含了20,000行C++原始代码,60个以上的Windows相关类,以及其它的一般类如时间、数据处理、文件、内存、诊断、字符串等等等。它所提供的,其实是一个 "thin and efficient C++ transformation of the Windows API"。其32位版亦在1992年下半年随着 Win32 SDK 推出。

MFC 1.0 获得的回响带给 AFX 小组不少鼓舞。他们的下一个目标放在更高阶的架构支持和组件用户接口上。前者成就了Document/View 架构,后者成就了工具栏、状态栏、打印、预览等极受欢迎的UI性质。当然,他们并没有忘记兼容性与移植性。虽然 AFX 小组并未承诺MFC可以跨不同操作系统如 UNIX XWindow、OS/2 PM、Mac System 7,但在其本家(Windows 产品线)身上,在16位Windows 3.x和32位Windows 95 与Windows NT之间的移植性是无庸置疑的。虽然其16位产品和32位产品是分别包装销售,你的原始代码通常只需重新编译链接即可。

Visual C++ 1.0(也就是 C/C++ 8.0)搭配 MFC 2.0 于1993/03 推出,这是针对Windows 3.x 的16位产品。接下来又在1993/08 推出在Windows NT上的 Visual C++ 1.1 for Windows NT,搭配的是MFC 2.1。这两个版本有着相同的基本性质。MFC 2.0 内含近60,000 行 C++ 程序代码,分散在 100 个以上的类中。Visual C++ 整合环境的数个重要工具(如Wizards)本身即以 MFC 2.0 设计完成,它们的出现对于软件生产效率的提升有极大贡献。

微软在 1993年又推出了 16 位的 Visual C++ 1.5,搭配 MFC 2.5。这个版本最大的进步是多了 OLE2 和 ODBC 两组类。整合环境也为了支持这两组类而做了些微改变。

1994年,微软推出Visual C++ 2.0,搭配MFC 3.0,这个32位版本主要的特征在于配合目标操作系统(Windows NT 和Windows 95),支持多线程。所有类都是thread-safe。UI 对象方面,加入了属性表(Property Sheet)、miniframe 窗口、可随处停驻的工具栏。MFC collections 类改良为 template-based。链接器有重大突破,原使用的Segmented Executable Linker 改为 Incremental Linker,这种链接器在对 OBJ 文件做链接时,并不每次从头到尾重新来过,而只是把新数据往后加,旧数据加记作废。想当然耳,EXE 文件会累积许多不用的垃圾,那没关系, 透过Win32 memory-mapped file, 操作系统(Windows NT 及 Windows 95)只把欲使用的部分加载,丝毫不影响执行速度。必要时程序员也可选用传统方式链接,这些垃圾自然就不见了。对我们这些终日受制于edit-build-run-debug 轮回的程序员, Incremental Linker 可真是个好礼物。

1995年,微软又加上了MAPI(Messaging API)和 WinSock 支持,推出 MFC 3.1(32 位元版),并供应13个通用控制组件,也就是 Windows 95 所提供的tree、tooltip、spin、slider、progress、RTF edit 等等控制组件。

1995年,MFC 有了3.2 版,那是不值一提的小改版。

然后就是1995年的32 位MFC 4.0。这个版本纳入了DAO 数据库类、多线程同步控制类,并允许制作 OCX containers。搭配推出的 Visual C++ 4.0 编译器,也终于支持了 template、RTTI 等 C++ 语言特性。IDE 整合环境有重大的改头换面行动,Class View、Resource View、File View 都使得项目的管理更直觉更轻松,Wizardbar 则活脱脱是一个简化的ClassWizard。此外,多了一个极好用的Components Gallery,并允许程序员订制AppWizard。

1996 年上半年又推出了MFC 4.1,最大的焦点在ISAPI(Internet Server API)的支持,提供五个新类 , 分别是CHttpServer 、CHttpFilter 、 CHttpServerContext 、CHttpFilterContext、CHtmlStream,用以建立交互式 Web 应用程序。整合环境方面也对应地提供了一个ISAPI Extension Wizard。在附加价值上,Visual C++ 4.1提供了Game SDK,帮助开发Windows 95上的高效率游戏软件。Visual C++ 4.1 还提供不少个由协力公司完成的OLE控制组件(OCXs),这些 OLE 控制组件技术很快就要全面由桌上跃到网上,称为 ActiveX 控制组件。不过,遗憾的是,Visual C++ 4.1 的编译器有些臭虫,不能够制作 VxD(虚拟装置驱动程序)。

1996 年下半年推出的 MFC 4.2,提供对 ActiveX 更多的技术支持,并整合 Standard C++ Library。它封包一组新的 Win32 Internet 类(统称为 WinInet),使 Internet 上的程序开发更容易。它提供 22 个新类和 40 个以上的新成员函数。它也提供一些控制元件,可以系结(binding)近端和远程的数据源(data sources)。整合环境方面,Visual C++ 4.2提供新的Wizard给ActiveX 程序开发使用,改善了影像编辑器,使它能够处理在Web 服务器上的两个标准图文件格式:GIF 和 JPEG。

1997 年推出的Visual C++ 5.0,主要诉求在编译器的速度改善,并将Visual C++ 合并到微软整个Visual Tools的终极管理软件Visual Studio 97 之中。所有的微软虚拟开发工具,包括 Visual C++、Visual Basic、Visual J++、Visual InterDev、Visual FoxPro、都在Visual Studio 97 的整合之下有更密切的彼此奥援。至于程序设计方面,MFC 本身没有什么变化(4.21 版),但附了一个 ATL(Active Template Library)2.1 版,使 ActiveX 控制组件的开发更轻松些。

我想你会发现,微软正不断地为为什么要使用MFC加上各式各样的强烈理由,并强烈导引它成为Windows 程序设计的 C++ 标准接口。你会看到愈来愈多的 MFC/C++ 程序代码。

MFC概况

MFC非常巨大(其它application framework也不差),MFC 类主要可分为下列数大群组:

  • General Purpose classes——提供字符串类、数据处理类(如数组与串列),异常情况处理类、文件类...等等。

  • Windows API classes - 用来封包Windows API,例如窗口类、对话框类、DC 类...等等。

  • Application framework classes——组成应用程序骨干者,即此组类,包括Document/View、消息捕获、消息映射、消息循环、动态生成、文件读写等等。

  • High level abstractions - 包括工具栏、状态栏、分裂窗口、卷动窗口等等。

  • operation system extensions - 包括OLE、ODBC、DAO、MAPI、WinSock、ISAPI等等。

General Purpose classes

也许你使用 MFC 的第一个目标是为了写 Windows 程序,但并不是整个 MFC 都只为此目的而被发明出来。下面这些类适用于 Windows,也适用于 DOS。

CObject

绝大部分类库,往往以一个或两个类,做为其它绝大部分类的基础。MFC 亦复如此。CObject是万类之首,凡类派生自CObject者,得以继承数个面向对象重要性质,包括RTTI(运行时期类型识别)、Persistence(对象保存)、Dynamic Creation(动态生成)、Diagnostic(错误诊断)。本书第3章对于这些技术已有了一份 DOS 环境下的模拟,第8章另有 MFC 相关原始代码的探讨。其中,对象保存又牵扯到 CArchive,诊断又牵扯到 CDumpContext,运行时期类型识别以及动态生成又牵扯到CRuntimeClass。

数据处理类(collection classes)

所谓collection,意指用来管理一群对象或标准类型的数据。这些类像是Array或List 或 Map 等等,都内含针对元素的加入或删除或巡访等成员函数。Array (数组)和 List(串列)是数据结构这门课程的重头戏,大家比较熟知,Map(可视之为表格)则是由成双成对的两两对象所构成,使你很容易由某一对象得知成对的另一对象;换句话说一个对象是另一个对象的键值(key)。例如,你可以使用 String-to-String Map,管理一个电话-人名数据库;或者使用 Word-to-Ptr Map,以 16 位数值做为一个指针的键值。

最令人侧目的是,由于这些类都支持 Serialization,一整个数组或串列或表格可以单一一进程序代码就写到文件中(或从文件读出)。第8章的 Scribble Step1范例程序中你就会看到它的便利。

MFC 支持的collection classes有:

杂项类

  • Crect——封装Windows 的RECT 结构。这个类在Windows环境中特别有用,因为CRect常常被用作MFC类成员函数的参数。

  • Csize——封装Windows的SIZE结构。

  • Cpoint——封装Windows的POINT 结构。这个类在Windows环境中特别有用,因为CPoint常常被用作MFC类成员函数的参数。

  • Ctime——表现绝对时间,提供许多成员函数,包括取得目前时间 ( static GetCurrentTime)、将时间数据格式化、抽取特定字段(时、分、秒)等等。它对于 +、-、+=、-+ 等运算符都做了重载动作。

  • CtimeSpan——以秒数表现时间,通常用于计时秒表。提供许多成员函数,包括把秒数转换为日、时、分、秒等等。

  • Cstring——用来处理字符串。支持标准的运算符如 =、+=、< 和 >。

异常处理类(exception handling classes)

所谓异常情况(exception),是发生在你的程序运行时期的不正常情况,像是文件打不开、内存不足、写入失败等等等。与异常处理有关的MFC类一共有以下11种:

Windows API classes

这是MFC声名最大的一群类。如果你去看看原始代码,就会看到这些类的成员函数所对应的各个Windows API函数。

  • CwinThread——代表MFC程序中的一个线程。自从3.0 版之后,所有的MFC类就都已经是thread-safe了。SDK 程序中标准的消息循环已经被封装在此一类之中(你会在第6章看到我如何把这一部分开膛剖肚)。

  • CwinApp——代表你的整个MFC应用程序。此类派生自CWinThread;要知道,任何32位Windows程序至少由一个线程构成。CWinApp 内含有用的成员变 数 如 m_szExeName,放置执行文件文件名 ,以及有用的成员函数如ProcessShellCommand,处理命令列选项。

  • CWnd——所有窗口,不论是框架窗口、子框窗口、对话框、控制组件、view 窗口,都有一个对应的C++ 类,你可以想象窗口handle和C++ 对象结盟。这些C++ 类统统派生自 CWnd,也就是说,凡派生自 CWnd 之类才能收到 WM_ 窗口消息(WM_COMMAND 除外)。

    所谓窗口handle和C++ 对象结盟,实际上是CWnd 对象有一个成员变量m_hWnd,就放着对应的窗口handle。所以,只要你手上有一个CWnd 对象或CWnd 对象指针,就可以轻易获得其窗口handle:

    HWND hWnd = pWnd->m_hWnd;
    
  • CcmdTarget——CWnd的父类。派生自它 ,类才能够处理命令消息WM_COMMAND。这个类是消息映射以及命令消息循环的大部分关键,我将在第9章推敲这两大神秘技术。

  • GDI 类、DC 类、Menu 类。

Application framework classes

这一部分最为人认知的便是Document/View,这也是使MFC跻身 application framework的关键。Document/View 的观念是希望把数据的本体,和数据的显示分开处理。由于文件产生之际,必须动态生成 Document/View/Frame 三种对象,所以又必须有所谓的Document Template 管理之。

CDocTemplate、CSingleDocTemplate、CmultiDocTemplate——Document Template 扮演黏胶的角色,把 Document 和 View 和其 Frame(外框窗口)胶黏在一块儿。CSingleDocTemplate 一次只支持一种文件类型,CMultiDocTemplate 可同时支持多种文件类型。注意,这和 MDI 程序或 SDI 程序无关,换句话说,MDI 程序也可以使用CSingleDocTemplate,SDI 程序也可以使用CMultiDocTemplate。

但是,逐渐地,MDI 这个字眼与它原来的意义有了一些出入(要知道,这个字眼早在SDK时代即有了)。因此,你可能会看到有些书籍这么说:MDI 程序使用CMultiDocTemplate,SDI程序使用CSingleDocTemplate。

Cdocument——当你为自己的程序由CDocument 派生出一个子类后,应该在其中加上成员变量,以容纳文件数据;并加上成员函数,负责修改文件内容以及

读写文件。读写文件由虚函数Serialize 负责。第8章的Scribble Step1 范例程序有极佳的示范。

Cview——此类负责将文件内容呈现到显示装置上:也许是屏幕,也许是打印机。文件内容的呈现由虚函数OnDraw负责。由于这个类实际上就是你在屏幕上所看到的窗口(外再罩一个外框窗口),所以它也负责用户输入的第一线服务。例如第8章的 Scribble Step1 范例,其 View 类便处理了鼠标的按键动作。

High level abstractions

视觉性UI对象属于此类,例如工具栏CToolBar、状态栏CStatusBar、对话框列CDialogBar。加强型的View也属此类,如可卷动的ScrollView、以对话框为基础的CFormView、小型文字编辑器CEditView、树状结构的CTreeView,支持RTF文件格式的CRichEditView 等等。

Afx 全局函数

还记得吧,C++ 并不是纯种的面向对象语言(SmallTalk 和Java才是)。所以,MFC之中得以存在有不属于任何类的全局函数,它们统统在函数名称开头冠以Afx。

下面是几个常见的 Afx 全局函数:

函数名称                               说明

MFC宏(macros)

CObject和CRuntimeClass之中封装了数个所谓的object services,包括取得运行时期的类信息(RTTI)、Serialization(文件读写)、动态产生对象...等等。所有派生自CObject的类,都继承这些机能。我想你对这些名词及其代表的意义已经不再陌生 -- 如果你没有错过第3章的「MFC 六大技术模拟」的话。

取得运行时期的类信息(RTTI),使你能够决定一个运行时期的对象的类信息,这样的能力在你需要对函数参数做一些额外的类型检验,或是当你要针对对象属于某种类而做特别的动作时,份外有用。

Serialization 是指将对象内容写到文件中,或从文件中读出。如此一来对象的生命就可以在程序结束之后还延续下去,而在程序重新启动之后,再被读入。

这样的对象可说是 "persistent"(永续存在)。

所谓动态的对象生成(Dynamic object creation),使你得以在运行时期产生一个特定的对象。例如document、view、和frame对象就都必须支持动态对象生成,因为framework 需要在运行时期产生它们。

此外,OLE 常常需要在运行时期做对象的动态生成动作。例如一个OLE server 程序必须能够动态产生 OLE items,用以反应 OLE client 的需求。

MFC 数据类型(data types)

下面所列的这些数据类型,常常出现在 MFC 之中。其中的绝大部分都和一般的Win32程序(SDK 程序)所用的相同。

下面这些是和 Win32 程序(SDK 程序)共同使用的数据类型:

数据类型                                  意义
BOOL                   Boolean值(布尔值,不是TRUE就是FALSE)
BSTR                   32-bit字符指针
BYTE                   8-bit整数,未带正负号
COLORREF               32-bit 数值,代表一个颜色值
DWORD                  32-bit 整数,未带正负号
LONG                   32-bit 整数,带正负号
LPARAM                 32-bit 数值,做为窗口函数或 callback 函数的一个参数
LPCSTR                 32-bit 指针,指向一个常数字符串
LPSTR                  32-bit 指针,指向一个字符串
LPCTSTR                32-bit 指针,指向一个常数字符串。此字符串可移植到Unicode和DBCS(双字节字集)
LPTSTR                 32-bit 指针,指向一个字符串。此字符串可移植到  Unicode和DBCS(双位组字集)
LPVOID                 32-bit 指针,指向一个未指定类型的数据
LPRESULT               32-bit数值,做为窗口函数或callback函数的回返值
UINT                   在Win16中是一个16-bit未带正负号整数,在Win32中是一个  32-bit未带正负号整数。
WNDPROC                32-bit 指针,指向一个窗口函数
WORD                   16-bit 整数,未带正负号
WPARAM                 窗口函数的callback函数的一个参数。在Win16中是  16 bits,在Win32中是32 bits。

下面这些是MFC独特的数据类型:

数据类型                         意义
POSITION     一个数值,代表 collection 对象(例如数组或串列)中的元素位置。常使用于MFC collection classes。
LPCRECT       32-bit指针,指向一个不变的  RECT 结构。

前面所说那些MFC数据类型与C++语言数据类型之间的对应,定义于 WINDEF.H中。我列出其中一部分,并且将不符合(_MSC_VER >= 800) 条件式的部分略去。

#define NULL 0
#define far // 侯俊杰注:Win32 不再有 far 或 near memory model,
#define near // 而是使用所谓的 flat model。pascall 函数调用习惯
#define pascal __stdcall  // 也被 stdcall 函数调用习惯取而代之。
#define cdecl _cdecl
#define CDECL _cdecl
#define CALLBACK __stdcall//侯俊杰注:在Windows programming演化过程中
#define WINAPI __stdcall  // 曾经出现的 PASCAL、CALLBACK、WINAPI、
#define WINAPIV __cdecl// APIENTRY,现在都代表相同的意义,就是 stdcall
#define APIENTRY WINAPI// 函数调用习惯。
#define APIPRIVATE __stdcall
#define PASCAL __stdcall
#define FAR far
#define NEAR near
#define CONST const
typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef float FLOAT;
typedef FLOAT *PFLOAT;
typedef BOOL near *PBOOL;
typedef BOOL far *LPBOOL;
typedef BYTE near *PBYTE;
typedef BYTE far *LPBYTE;
typedef int near *PINT;
typedef int far *LPINT;
typedef WORD near *PWORD;
typedef WORD far *LPWORD;
typedef long far *LPLONG;
typedef DWORD near *PDWORD;
typedef DWORD far *LPDWORD;
typedef void far *LPVOID;
typedef CONST void far *LPCVOID;
typedef int INT;
typedef unsigned int UINT;
typedef unsigned int *PUINT;
/* Types use for passing & returning polymorphic values */
typedef UINT WPARAM;
typedef LONG LPARAM;
typedef LONG LRESULT;
typedef DWORD COLORREF;
typedef DWORD *LPCOLORREF;
typedef struct tagRECT
{
    LONG left;
    LONG top;
    LONG right;
    LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
typedef const RECT FAR* LPCRECT;
typedef struct tagPOINT
{
    LONG  x;
    LONG  y;
} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
typedef struct tagSIZE
{
    LONG cx;
    LONG cy;
} SIZE, *PSIZE, *LPSIZE;

作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/631096.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Leetcode】贪心问题合集 | 摆动序列、K次取反最大和、加油站、分发糖果、柠檬水找零、根据身高重建队列、单调递增的数字

贪心问题感觉还是挺不好想的&#xff0c;因为每一题有每一题的策略&#xff0c;感觉只能尽量做过的记住了。 376 摆动序列 注意&#xff1a;是序列&#xff0c;而不是数组。 求最大摆动序列的长度&#xff0c;即求谷 / 峰的个数。 若走势不为一条直线。 起始count 2&…

LED显示屏静电防护指南

LED显示屏是一种电子设备&#xff0c;对静电敏感。静电放电可能会对LED显示屏的电子元件造成损坏&#xff0c;因此需要采取静电防护措施。以下是LED显示屏静电防护的一些建议和指南&#xff1a; 环境控制&#xff1a;在LED显示屏周围创建适宜的环境条件。控制湿度和温度&#x…

Yolov5(tag v7.0)网络结构解读,以yolov5s为例

最近yolov5用的多&#xff0c;发现确实好用&#xff0c;于是较深入学了一下。下面按照训练的流程梳理一下网络的结构&#xff0c;同时也是自己记一下便于后面查阅。 同时&#xff0c;我也查了一些关于yolov5网络结构介绍的资料&#xff0c;发现大多是v5.0&#xff0c;少数v6.0的…

Linux驱动IO篇——阻塞/非阻塞IO

文章目录 非阻塞IO阻塞IO等待队列等待队列变体 非阻塞IO 在应用程序中&#xff0c;使用open函数打开一个/dev目录下的一个设备文件时&#xff0c;默认是以阻塞的方式打开。 所谓阻塞&#xff0c;就是当我们请求的资源不可用时&#xff08;资源被占用&#xff0c;没有数据到达等…

让车载系统与外部系统无缝对接——掌握SOA跨系统通信技术

车载SOA架构原理 车载 SOA&#xff08;Service-Oriented Architecture&#xff0c;面向服务的架构&#xff09;是一种基于服务的体系结构&#xff0c;旨在提高车载电子系统的可维护性、可扩展性和互操作性。它将车载电子系统划分为独立的、可复用的服务单元&#xff0c;这些服…

NodeJS MongoDB⑦

文章目录 ✨文章有误请指正&#xff0c;如果觉得对你有用&#xff0c;请点三连一波&#xff0c;蟹蟹支持&#x1f618;前言Node&MongoDB 第一步 连接数据库 第二步 创建User Mongodb模型 第三步 简单使用 Mongodb命令 第四步 规范使用 Mongodb命令 &#xff08…

爆款视频批量剪辑生成系统源码部署

创建视频 该接口用于创建抖音视频&#xff08;支持话题, 小程序等功能&#xff09;。该接口适用于抖音。 使用限制 抖音的 OAuth API 以https://open.douyin.com/ 开头。挂载小程序请先完成注册开发者平台账号。创建抖音视频后, 会有一个审核过程, 期间只有自己可见。如果发…

docker数据管理与网络通信

一、管理docker容器中数据 管理Docker 容器中数据主要有两种方式:数据卷(Data Volumes)和数据卷容器( DataVolumes Containers) 。 1、 数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立刻…

leetcode11. 盛最多水的容器(java)

盛最多水的容器 leetcode11. 盛最多水的容器题目描述 解题思路代码演示二叉树专题 leetcode11. 盛最多水的容器 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/container-with-most-water 题目描述 给定一个长度为 n 的…

物联网Lora模块从入门到精通(二) LED灯泡闪烁与呼吸灯

目录 一、前言 二、实践与代码 1.电亮LED1 2.熄灭LED1 3.翻转LED电平 4.LED1与LED2交替闪烁 5.LED1呼吸灯 三、程序代码 一、前言 本篇内容属于新大陆物联网Lora模块开发&#xff0c;使用给定的Lora基础例程&#xff0c;并在其基础上开发完成&#xff0c;并可为其他版本的Lo…

Atcoder Beginner Contest 294

A - Filter AC代码&#xff1a; #include<iostream> #include<algorithm> #include<cstring> using namespace std; int main() {int n;cin>>n;for(int i0;i<n;i){int x;cin>>x;if(x%20)cout<<x<<" ";}return 0; } …

​​INNODB和MyISAM区别

1 存储引擎是MyISAM 如下&#xff1a; CREATE table test_myisam (cli int ) ENGINEMyISAM 存储目录里会有三个文件 test_myisam.frm为“表定义”&#xff0c;是描述数据表结构的文件 test_myisam.MYI文件是表的索引 test_myisam.MYD文件是表的数据 2 存储引擎是INNODB…

LeetCode——比较字符串最小字母出现频次

1、题目 1170. 比较字符串最小字母出现频次 - 力扣&#xff08;Leetcode&#xff09; 定义一个函数 f(s)&#xff0c;统计 s 中&#xff08;按字典序比较&#xff09;最小字母的出现频次 &#xff0c;其中 s 是一个非空字符串。 例如&#xff0c;若 s "dcce"&am…

httprunner 2.x的基本使用(一)

上一章&#xff1a; 下一章&#xff1a; httprunner 2.x的基本使用&#xff08;二&#xff09;_做测试的喵酱的博客-CSDN博客 一、参考地址&#xff1a; 使用说明_httprunner2.0 概述及使用说明 二、介绍 HttpRunner是一款面向 HTTP(S) 协议的通用测试框架&#xff0c;只需…

location.href 和 document.URL 与 document.documentURI

location.href 和 document.URL 与 document.documentURI 相同点 获取到的值相同 不同点 location.hrefurl可以赋值, 效果类似location.assign(url) , 可以后退 document.URL 与 document.documentURI 是只读的, 赋值无效 location.href locationwindow.location true lo…

从源码角度看Linux线程是怎么创建出来的

这篇文章来学习一下线程的创建过程。 线程不是一个完全由内核实现的机制&#xff0c;它是由内核态和用户态合作完成的。 用户态创建线程 pthread_create 不是一个系统调用&#xff0c;是 glibc 库的一个函数&#xff0c;位于 nptl/pthread_create.c 中&#xff1a; int __pth…

redis商户查询缓存

1 什么是缓存? 前言:什么是缓存? 就像自行车,越野车的避震器。 举个例子:越野车,山地自行车,都拥有"避震器",防止车体加速后因惯性,在酷似"U"字母的地形上飞跃,硬着陆导致的损害,像个弹簧一样; 同样,实际开发中,系统也需要"避震器",防止过…

Unity Shader - 兰伯特漫反射

兰伯特漫反射公式&#xff1a; 漫反射&#xff08;Diffuse&#xff09; 光源颜色 * max&#xff08;0&#xff0c;cos&#xff08;光方向和法线的夹角&#xff09;&#xff09; 公式原理&#xff1a; 从上面图片可以看出光照方向 L 与物体法相 N形成的 余弦值越大&#xff0c;反…

力扣笔记(每日随机一题)—— 打折购买糖果的最小开销

问题&#xff08;简单&#xff09; 一家商店正在打折销售糖果。每购买 两个 糖果&#xff0c;商店会 免费 送一个糖果。 免费送的糖果唯一的限制是&#xff1a;它的价格需要小于等于购买的两个糖果价格的 较小值 。 比方说&#xff0c;总共有 4 4 4 个糖果&#xff0c;价格…

开源代码分享(3)—微电网鲁棒定价策略(附matlab代码)

1背景介绍 1.1摘要 本论文聚焦于微电网中的能量失衡管理问题&#xff0c;并从电力市场的角度进行研究。与传统电力网不同&#xff0c;微电网可从可再生能源&#xff08;RES&#xff09;如太阳能电池板或风力涡轮机等获得额外能源。然而&#xff0c;来自RES的随机输入给平衡供需…