(delphi11最新学习资料) Object Pascal 学习笔记---第10章第3节( 委托的概念)

10.3.2 委托的概念

​ 乍一看,委托这项技术的目标可能并不明确,但它却是Object Pascal 组件技术的基石之一。秘密就在委托这个词上。如果有人创建了一个对象,这个对象有一些方法指针,那么你只需把新的方法赋值给这些指针,就可以自由地改变这个对象的行为。听起来耳熟吗?是的,应该很熟悉。

​ 当你为一个按钮添加 OnClick 事件处理器时,开发环境也正是这样做的。按钮有一个名为 OnClick 的方法指针,你可以直接或间接地将窗体的一个方法赋值给它。当用户点击按钮时,这个方法就会被调用,即使你是在其他类(通常是窗体)中定义了这个方法。

​ 下面列出了 Delphi 库中实际用于定义按钮组件的事件处理程序和窗体的相关方法的代码:

type
TNotifyEvent = procedure(Sender: TObject) of object;

TMyButton = class
	OnClick: TNotifyEvent;
end;

TForm1 = class(TForm)
	procedure Button1Click(Sender: TObject);
	Button1: TMyButton;
end; 

var
Form1: TForm1;

​ 现在,在过程中,你能这么编写代码:

MyButton.OnClick := Form1.Button1Click;

​ 这段代码与库代码真正唯一的区别在于,OnClick 是一个属性名称,而它实际所引用的数据称为FOnClick。事实上,显示在对象检查器 "事件 "页面中的事件只不过是一个方法指针属性。举例来说,这意味着你可以在设计时动态修改附加到组件上的事件处理程序,甚至可以在运行时创建一个新组件并为其分配一个事件处理程序。

DynamicEvents 示例展示了这两种情况。窗体中有一个按钮,按钮关联了一个标准的 OnClick 事件处理器。不过,我在窗体中又添加了具有相同签名(相同参数)的public方法:

public
	procedure BtnTest2Click(Sender: TObject);

​ 当按钮被按下时,除了显示一个消息外,还把事件处理器切换到第二个,改变了这个点击操作以后的行为。

procedure TForm1.BtnTestClick(Sender: TObject);
begin
	ShowMessage('Test message');
	BtnTest.OnClick := BtnTest2Click;
end;

procedure TForm1.BtnTest2Click(Sender: TObject);
begin
	ShowMessage('Test message, again');
end;

​ 现在,当你第一次点击按钮时,第一个(默认)事件处理程序就会被执行,而接下来的所有点击都会触发第二个事件处理程序。

注意 当您键入代码将方法赋值给事件时,IDE的"代码自动完成 "会向您推荐可用的事件名称,并将其转化为实际的函数调用,在末尾加上括号。这是不正确的。您必须将方法本身赋值给事件,而不是调用它。否则,编译器会尝试赋值方法调用的结果(作为一个过程,它并不存在),从而导致错误。

​ 项目的第二部分演示了一个完全的动态事件关联。当您点击窗体的表面时,会动态创建一个新按钮,该按钮的事件处理程序会显示关联按钮的标题(Sender 对象将指向调用事件处理程序动态创建的按钮):

procedure TForm1.BtnNewClick(Sender: TObject);
begin
	ShowMessage('You selected ' + (Sender as TButton).Text);
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
	Shift: TShiftState; X, Y: Single);
var
	AButton: TButton;
begin
	AButton := TButton.Create(Self);
	AButton.Parent := Self;
	AButton.SetBounds(X, Y, 100, 40);
	Inc(FCounter);
	AButton.Text := 'Button' + IntToStr(FCounter);
	AButton.OnClick := BtnNewClick;
end;

​ 由于使用了事件的Sender参数,即使只使用一个事件处理程序,每个动态创建的按钮也会对鼠标点击做出反应,显示与按钮相关的信息。输出示例见图 10.1。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Odoo:全球排名第一的免费开源PLM管理系统介绍

概述 利用开源智造OdooPLM产品生命周期管理应用,重塑创新 实现产品生命周期管理数字化,高效定义、开发、交付和管理创新的可持续产品,拥抱数字化供应链。 通过开源智造基于Odoo开源技术平台打造数字化的产品生命周期管理(PLM&am…

Java UUID 类中的 getMostSignificantBits 和 leastSignificantBits 方法

getMostSignificantBits() 方法的一些介绍: getMostSignificantBits 这个方法主要用于在 UUID 中获取高64 位的有效位后返回 Long 数据类型。 在获取最高有效位时不会引发异常。 对应的还有一个 getLeastSignificantBits() 方法。 这个方式是从 UUID 中获取低 6…

阳光能源,创造永远:光模块的未来”:随着大数据、区块链、云计算和5G的发展,光模块成为满足不断增长的数据流量需求的关键技术

光模块的类型介绍: 为了适应不同的应用需求,不同参数和功能的光模块应运而生。光模块的分类方式及类型详见如下: 🔎封装形式🔍: 📣📢光模块按照封装形式来分有以下几种常见类型&a…

如何将本地Android studio项目上传到GitHub

操作步骤: 1、在GitHub上创建账户 2、在androd studio中添加上述创建的GitHub账号 3、在android studio上找到"share project on GitHub",点击此选项上传当前项目到GitHub 上传成功后,会在GitHub上创建默认仓库repository 注&a…

LeetCode - LCR 008.长度最小的子数组

一. 题目链接 LeetCode - 209. 长度最小的子数组 二. 思路分析 由于此问题分析的对象是「⼀段连续的区间」,因此可以考虑「滑动窗口」的思想来解决这道题。 让滑动窗口满足:从 i 位置开始,窗口内所有元素的和小于target (那么当…

图像处理到神经网络:线性代数的跨领域应用探索

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。 会一些的技术:数据分析、算法、SQL、大数据相关、python 欢迎加入社区:码上找工作 作者专栏每日更新: LeetCode解锁1000题: 打怪升级之旅 python数据分析…

Python爬虫--Scrapy框架安装

Scrapy框架安装 , Scrapy 是 Python 领域专业的爬虫开发框架,已经完成爬虫程序的大部分通用工具 它使用了 Twisted 异步网络库来处理网络通讯。整体架构大致如下 第一步:挂小灰机或者将要安装的文件下载到本地 Scrapy 框架安装踩坑中 为什…

ubuntu的镜像源+bionic版本

首先第一步 查找和你自己ubuntu版本匹配的版本号 匹配代号如下 在终端输入lsb_release -a查看自己系统上的版本号 可以看到我这个版本号的代号是bionic。 每个版本的镜像文件都是有规律的。 bionic版本的源如下 # 阿里源 deb http://mirrors.aliyun.com/ubuntu/ bionic ma…

前端用a标签实现静态资源文件(excel/word/pdf)下载

接上文实现的 前端实现将二进制文件流,并下载为excel文件后, 实际项目中一般都会有一个模版下载的功能,一般都由服务端提供一个下载接口,返回文件流或url地址,然后前端再处理成对应需要的类型的文件。 但是&#xff…

HTML5(1)

目录 一.HTML5(超文本&#xff08;链接&#xff09;标记&#xff08;标签<>&#xff09;语言) 1.开发环境&#xff08;写代码&#xff0c;看效果&#xff09; 2.vscode 使用 3.谷歌浏览器使用 4.标签语法 5.HTML基本骨架&#xff08;网页模板&#xff09; 6.标签的…

排序 “肆” 之归并排序

1. 归并排序 1.1 原理介绍 归并排序的基本原理是将一个未排序的数组分解为较小的子数组&#xff0c;然后递归地对这些子数组进行排序&#xff0c;最后再将排好序的子数组合并成一个有序数组。其核心操作是将一维数组中前后相邻的两个有序序列归并为一个有序序列。 其主要步骤包…

【区块链】椭圆曲线数字签名算法(ECDSA)

本文主要参考&#xff1a; 一文读懂ECDSA算法如何保护数据 椭圆曲线数字签名算法 1. ECDSA算法简介 ECDSA 是 Elliptic Curve Digital Signature Algorithm 的简称&#xff0c;主要用于对数据&#xff08;比如一个文件&#xff09;创建数字签名&#xff0c;以便于你在不破坏它…

【Flutter】GetX

前言 状态管理 / 路由管理 / 依赖管理 这三部分之间存在联系 参考文章 建议看官网文章&#xff0c;很详细 &#xff0c;pub.dev搜索get pub.dev的文档 状态管理文章相关链接 状态管理 案例 实现一个计算器&#xff0c;运用GetX去管理它 构建界面 构建一个计算器界面 …

基于SpringBoot的“房产销售平台”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“房产销售平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统整体模块图 登录窗口界面 房源信息管理窗口界…

解决HttpServletRequest中的InputStream/getReader只能被读取一次的问题

一、事由 由于我们业务接口需要做签名校验&#xff0c;但因为是老系统了签名规则被放在了Body里而不是Header里面&#xff0c;但是我们不能在每个Controller层都手动去做签名校验&#xff0c;这样不是优雅的做法&#xff0c;然后我就写了一个AOP&#xff0c;在AOP中实现签名校…

Linux--进程控制(2)--进程的程序替换(夺舍)

目录 进程的程序替换 0.相关函数 1.先看现象 2.解释原理 3.将代码改成多进程版 4.使用其它的替换函数&#xff0c;并且认识函数参数的含义 5.其它 进程的程序替换 0.相关函数 关于进程替换我们需要了解的6个函数&#xff1a; 函数解释&#xff1a; 这些函数如果调用成功则…

【Web UI自动化】Python+Selenium 环境配置

安装Python 官网地址&#xff1a;https://www.python.org/&#xff0c;Downloads菜单下选择适合自己的系统版本&#xff0c;我的是Windows。 点击进入以后&#xff0c;可以看到当前最新版本。 点击上面的链接&#xff0c;页面下滑&#xff0c;找到下载链接&#xff0c;根据…

网站推荐——文本对比工具

在线文字对比工具-BeJSON.com 文本对比/字符串差异比较 - 在线工具 在线文本对比-文本内容差异比较-校对专用

OpenCV C++实现区域面积筛选以及统计区域个数

目录 1、背景介绍 2、代码实现 2.1 获取原图 2.1.1 区域图像imread 2.1.2 具体实现 2.2 获取图像大小 2.3 阈值分割 2.3.1 阈值分割threshold 2.3.2 具体实现 2.4 区域面积筛选 2.4.1 获取轮廓findContours 2.4.2 获取轮廓面积contourArea 2.4.3 填充区域fil…

PotatoPie 4.0 实验教程(28) —— FPGA实现sobel算子对摄像头图像进行边缘提取

什么是sobel算子&#xff1f; Sobel 算子是一种常用的边缘检测算子&#xff0c;用于在图像中检测边缘。它基于对图像进行梯度运算&#xff0c;可以帮助识别图像中灰度值变化较大的区域&#xff0c;从而找到图像中的边缘。 Sobel 算子通过计算图像的水平和垂直方向的一阶导数来…