据我所知,COM基于其clsid创建对象。这是一个唯一标识该类的GUID。
HKEY_CLASSES_ROOT
\Clsid
\{AE8530CF-D204-4877-9CAB-F052BF1F661F}
然后使用该类创建对象。COM现在需要知道保存该COM对象的DLL的位置。在我这个特定的案例中,展示COM对象的“服务器”是一个DLL,并且将是“进程内”的。我们通过添加以下内容来将COM指向该“进程内”dll:
HKEY_CLASSES_ROOT
\Clsid
\{AE8530CF-D204-4877-9CAB-F052BF1F661F}
\InprocServer32
(default) = "c:\foo\myActiveX.ocx"
COM还需要了解COM服务器对象支持的线程模型。最简单、最常见且在此示例中使用的是“单元”线程模型:
HKEY_CLASSES_ROOT
\Clsid
\{AE8530CF-D204-4877-9CAB-F052BF1F661F}
\InprocServer32
(default) = "c:\foo\myActiveX.ocx"
ThreadingModel = "Apartment"
接下来是ProgID。这类似于DNS将友好的名称转换为IP地址的方式。在这里,我们将友好的名称"MyCoolLibrary.MyCoolControl"
转换成丑陋的clsid"{AE8530CF-D204-4877-9CAB-F052BF1F661F}"
HKEY_CLASSES_ROOT
\Clsid
\{AE8530CF-D204-4877-9CAB-F052BF1F661F}
\InprocServer32
(default) = "c:\foo\myActiveX.ocx"
ThreadingModel = "Apartment"
HKEY_CLASSES_ROOT
\MyCoolLibrary.MyCoolControl
\Clsid
(default) = "{AE8530CF-D204-4877-9CAB-F052BF1F661F}"
现在有人可以请求
MyCoolLibrary.MyCoolControl
COM可以将其转换为ClassID。
{AE8530CF-D204-4877-9CAB-F052BF1F661F}
一旦 COM 获得了 classid,它就可以在注册表中查找 HKCR\Clsid\{AE8530CF-D204-4877-9CAB-F052BF1F661F}
下的实际信息。
为了好玩,ProgID 添加到 Clsid 部分,这样人们就可以对这个类有一些想法:
HKEY_CLASSES_ROOT
\Clsid
\{AE8530CF-D204-4877-9CAB-F052BF1F661F}
\InprocServer32
(default) = "c:\foo\myActiveX.ocx"
ThreadingModel = "Apartment"
\ProgID
(default) = "MyCoolLibrary.MyCoolControl"
HKEY_CLASSES_ROOT
\MyCoolLibrary.MyCoolControl
\Clsid
(default) = "{AE8530CF-D204-4877-9CAB-F052BF1F661F}"
接下来是类型库。对于任何进程内的内容,这基本上不重要,但如果COM对象在另一个“公寓”中,那么函数参数需要进行封送处理。如果有一个定义了所有类方法的类型库,COM会自动为您执行此操作。
通过添加TypeLib键,clsid部分将指向适当的类型库:
HKEY_CLASSES_ROOT
\Clsid
\{AE8530CF-D204-4877-9CAB-F052BF1F661F}
\InprocServer32
(default) = "c:\foo\myActiveX.ocx"
ThreadingModel = "Apartment"
\ProgID
(default) = "MyCoolLibrary.MyCoolControl"
\TypeLib
(default) = "{17A5A3D4-439C-4C2A-8AB4-749B7771CDE1}"
HKEY_CLASSES_ROOT
\MyCoolLibrary.MyCoolControl
\Clsid
(default) = "{AE8530CF-D204-4877-9CAB-F052BF1F661F}"
这个类型库的信息也存储在注册表中,但通过调用RegisterTypeLib来为我们添加这些键。但它会为我们添加类似于以下的键:
HKEY_CLASSES_ROOT
\Clsid
\{AE8530CF-D204-4877-9CAB-F052BF1F661F}
\InprocServer32
(default) = "c:\foo\myActiveX.ocx"
ThreadingModel = "Apartment"
\ProgID
(default) = "MyCoolLibrary.MyCoolControl"
\TypeLib
(default) = "{17A5A3D4-439C-4C2A-8AB4-749B7771CDE1}"
HKEY_CLASSES_ROOT
\MyCoolLibrary.MyCoolControl
\Clsid
(default) = "{AE8530CF-D204-4877-9CAB-F052BF1F661F}"
HKEY_CLASSES_ROOT
\TypeLib
\{AE8530CF-D204-4877-9CAB-F052BF1F661F}
\1.0
(default) = "My Cool ActiveX Library"
...
现在我们进入棘手的部分,这些是让一个ActiveX控件有望工作所需的东西。
一篇MSDN文章指出,您必须添加一个虚假的Programmable键来表示它是一个ActiveX控件:
HKEY_CLASSES_ROOT
\Clsid
\{AE8530CF-D204-4877-9CAB-F052BF1F661F}
\Programmable
然而,这个MSDN Library页面说关键字是Control,而不是Programmable,且没有Programmable关键字。
但是这并不妨碍一些ActiveX使用Control,有些使用Programmable,还有一些同时使用两者。
我找不到任何提到需要其他任何内容的信息。
因此,有人能找到一些明确的文档吗?