Delphi COM编程学习笔记(1)
释放接口对象,既不是调用MyObj.Free,也不是MyObj.Release;
破坏对象的正确方法是将它们设置为nil:
MyInterface := nil;
一个接口不能离开实现它的对象而独立存活。这个接口仅仅是一个抽象,它仅仅是一个想法。
接口具有即插即用的功能,它建立了供应商必须遵守的规范。
接口可以仅仅在一层深度上运行,比较简单。不像OOP,一层套一层,一旦改了中间层,即容易引起更下层的错误。
在本质上,接口并不鼓励创建深分层结构,而鼓励相对简单的具有较好的性能特征的程序。
GUID是128位的数字(16个字节),在统计上是唯一的。
为了产生自己的GUID,必须首先调用WINAPI函数CoInitialize来初始化,然后调用CoCreateGuid得到唯一的实例:
CoInitialize(nil);
CoCreateGuid(FGUID);
在32位的Windows中,除了向CoInitialize传递nil之外的任何东西都是错误的。
就COM对象而言,注册表是一个简单的数据库,它只有一个任务:把一个数字值与系统中每一个可用的COM对象联系起来。
这些值存放在HKEY_CLASSES_ROOT的CLSID
注册表是一个数据库,它会建立CLSID与程序的名字以及其它相关信息之间的关联,例如版本号和文件的存储位置。
------------------------------------------------
微软白送几个API
function StringFromCLSID; external ole32 name 'StringFromCLSID';
function CLSIDFromString; external ole32 name 'CLSIDFromString';
function StringFromIID; external ole32 name 'StringFromIID';
function IIDFromString; external ole32 name 'IIDFromString';
function ProgIDFromCLSID; external ole32 name 'ProgIDFromCLSID';
function CLSIDFromProgID; external ole32 name 'CLSIDFromProgID';
function StringFromGUID2; external ole32 name 'StringFromGUID2';
function CoCreateGuid; external ole32 name 'CoCreateGuid';
另外还有几个常见的:
function CoInitialize; external ole32 name 'CoInitialize';
function CoInitializeEx; external ole32 name 'CoInitializeEx';
procedure CoUninitialize; external ole32 name 'CoUninitialize';
function CoGetCurrentProcess; external ole32 name 'CoGetCurrentProcess';
function CoGetClassObject; external ole32 name 'CoGetClassObject';
function CoRegisterClassObject; external ole32 name 'CoRegisterClassObject';
function CoLoadLibrary; external ole32 name 'CoLoadLibrary';
procedure CoFreeLibrary; external ole32 name 'CoFreeLibrary';
------------------------------------------------
最有趣的事情是自己实现IUnknown:
function TUserUnknown.QueryInterface(const IID: TGUID; out Obj): HResult;
const
E_NOINTERFACE = $80004002
begin
// GetInterface是TOjbect的方法。也可这样写:Obj:=Pointer(Self);
// GetInterface用奇妙的方法返回一个小型VMT,它只包含用户需要的接口的方法,而只把Self作为一个可以返回对象中的所有方法的指针
if GetInterface(IID, obj) then result :=0;
else reslut := E_NOINTERFACE;
end;
function TUserUnknown._AddRef : integer;
begin
Inc(FRefCount);
Result := FRefCount;
end;
function TUserUnknown._Release: Integer;
begin
Dec(FRefCount);
Result := FRefCount;
if Result = 0 then Destroy;
end;
------------------------------------------------
为指定接口加上GUID
IName = interface(IUnknown)
['{C25A86F1-579A-419A-8CB1-D1B5C6BCB8CB}']
function GetName : String;
end;
它的优越性在于,它允许你在需要在程序中使用GUID的时候,只需说明一个类名称就可以了。
例如,现在你知道这调用QueryInterface的时候,必须在第一个参数中传递一个GUID,方法只是编写如下代码:
var
Unknown : IUnknown;
Name : IName;
begin
FName.QueryInterface(IUnknown, Unknown);
FName.QueryInterface(IName, Name);
end;
Delphi接口编程比标准Delphi面向对象的编程更为简单,原因是不必为销毁对象而烦恼,一般它将被自动销毁。
------------------------------------------------
参考:《Delphi4 编程技术内幕》第13章
Delphi COM编程学习笔记(1)的更多相关文章
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- Linux Shell编程学习笔记——目录(附笔记资源下载)
LinuxShell编程学习笔记目录附笔记资源下载 目录(?)[-] 写在前面 第一部分 Shell基础编程 第二部分 Linux Shell高级编程技巧 资源下载 写在前面 最近花了些时间学习She ...
- DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)
本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com 注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...
- 多线程编程学习笔记——async和await(一)
接上文 多线程编程学习笔记——任务并行库(一) 接上文 多线程编程学习笔记——任务并行库(二) 接上文 多线程编程学习笔记——任务并行库(三) 接上文 多线程编程学习笔记——任务并行库(四) 通过前面 ...
- 多线程编程学习笔记——async和await(二)
接上文 多线程编程学习笔记——async和await(一) 三. 对连续的异步任务使用await操作符 本示例学习如何阅读有多个await方法方法时,程序的实际流程是怎么样的,理解await的异步 ...
- 多线程编程学习笔记——async和await(三)
接上文 多线程编程学习笔记——async和await(一) 接上文 多线程编程学习笔记——async和await(二) 五. 处理异步操作中的异常 本示例学习如何在异步函数中处理异常,学习如何对多 ...
- 多线程编程学习笔记——使用异步IO(一)
接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...
- 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端
接上文 多线程编程学习笔记——使用异步IO 二. 编写一个异步的HTTP服务器和客户端 本节展示了如何编写一个简单的异步HTTP服务器. 1.程序代码如下. using System; using ...
- 多线程编程学习笔记——异步调用WCF服务
接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...
随机推荐
- today's learning of english 1
1.curriculum 必修课 主修课 2.sought seek的过去式 3.blessed with a wonderful marriage 有个幸福美满的婚姻 4.al ...
- 火球-UML大战需求分析(体验版3.0.2).pdf
火球-UML大战需求分析(体验版3.0.2).pdf http://files.cnblogs.com/files/happlyonline/%E7%81%AB%E7%90%83-UML%E5%A4% ...
- 统计学习导论:基于R应用——第四章习题
第四章习题,部分题目未给出答案 1. 这个题比较简单,有高中生推导水平的应该不难. 2~3证明题,略 4. (a) 这个问题问我略困惑,答案怎么直接写出来了,难道不是10%么 (b) 这个答案是(0. ...
- [CSS3] Text ellipsis
Link: http://www.w3schools.com/cssref/tryit.asp?filename=trycss3_text-overflow div{ white-space: now ...
- 在 Java 中高效使用锁的技巧--转载
竞争锁是造成多线程应用程序性能瓶颈的主要原因 区分竞争锁和非竞争锁对性能的影响非常重要.如果一个锁自始至终只被一个线程使用,那么 JVM 有能力优化它带来的绝大部分损耗.如果一个锁被多个线程使用过,但 ...
- TCP 连接的要点
概念 TIME_WAIT: socket 仍然有数据在内核中待发送直到发送成功或超时,此socket不能被内核删除,同时等待是否要重传Ack对端还已发过来的FIN Linger Time:socket ...
- 使用jQuery Mobile和Phone Gap开发Android应用程序(转)
经过了一段时间的学习,初步了解了该如何使用jQuery Mobile和 Phone Gap来开发一个Android应用程序,也想把这些东西介绍给大家. 1. 软件准备 要进行android app的开 ...
- C#比较dynamic和Dictionary性能
开发中需要传递变参,考虑使用 dynamic 还是 Dictionary(准确地说是Dictionary<string,object>).dynamic 的编码体验显著优于 Diction ...
- 安卓开机启动service后台运行
安卓开机启动service后台运行 Android开机启动时会发送一个广播android.intent.action.BOOT_COMPLETED,捕捉到这个广播,然后可以进行相应的操作,比如:通过捕 ...
- Oracle创建表空间以及用户,并授权
//创建临时表空间 create temporary tablespace testtemp tempfile 'D:/app/Administrator/oradata/testdata/te ...