Bahamut
http://www.cnpack.org
(reproduced please specify the source and remain intact)
In a previous article, we introduced the interface. If you do not have contact with the COM object, you will feel that the interface is really troublesome, there may be: "Rather than directly define a class more convenient" idea.
Indeed, interfaces without COM encapsulation are really troublesome. In my opinion, an interface without COM encapsulation does not seem to have any meaning. So, what is a COM object? What advantages does it have? The next step is to start with a simple introduction to COM objects:
COM is a binary specification that is independent of the language being implemented. This way, even though COM objects are created in different programming languages, they can also communicate with each other, running on different process spaces and different operating system platforms. COM is both a specification and an implementation that provides a standard interface for accessing the core functionality of COM objects and a set of API functions, which are used to create and manage COM objects, in the form of a COM library. COM is still essentially a client server model. The client (typically the application) requests that the COM object be created and manipulated through the COM object's interface. The server creates and manages COM objects based on customer requests. Of course, both the client and server roles are not absolute.
Remember when I first contacted the COM object, my teacher once said to me: "com is not a DLL, although it may be prefixed with a DLL file to render in front of you, but it is definitely not in our traditional sense of the DLL (dynamic link library)."
In my opinion, the in-process COM object should be a special dynamic link library that provides some special services with DLL as the carrier. Of course, there are also out-of-process COM.
Now, we demonstrate how to build a simple COM model using wizards in Delphi.
First: Open Borland Delphi 7.1 (sorry, I usually use this version.) What the? Why is it 7.1? It's 7.0 plus a Update1 patch pack.-_-| |).
Then: Turn off Delphi By default for the application we created, and select File->new->other in the menu, then locate the ActiveX page in the popup window and double-click the ActiveX library icon.
After double-clicking the icon, we can see that Delphi has built an ActiveX library for us, with the following code:
library
Project1;
uses
ComServ;
exports
DllGetClassObject,
// 返回类工厂的接口
DllCanUnloadNow,
// 是否可以释放该组件
DllRegisterServer,
// 注册函数
DllUnregisterServer;
// 反注册函数
{$R *.RES}
begin
end
.
|
We will see that in the project, Delphi has helped us to define four output functions (more detailed descriptions of these functions, can be consulted more information), we do not care about them first.
Next, we'll use the menu file->new->other and create the COM object in the ActiveX page, and we'll see a dialog: Where classname is our object name, Instancing is the object creation mode, Threading module is thread mode. We use Newcomserver as the object name, other default. OK after you can see a window titled "Project11.tlb", which we can add a new method to the interface in this window, for example, we add a GetMessage method. Then we open Unit1.pas to see the following code:
unit
Unit1;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Windows, ActiveX, Classes, ComObj, Project1_TLB, StdVcl;
// Project1_TLB 接口所在单元
type
TNewComServer =
class
(TTypedComObject, INewComServer)
// 实现接口的类
protected
function
GetMessage: HResult; stdcall;
// 我们刚刚添加的方法
{Declare INewComServer methods here}
end
;
implementation
uses
ComServ;
function
TNewComServer
.
GetMessage: HResult;
begin
MessageBox(
0
, \‘测试\‘, \‘提示\‘,
$40
);
Result:= GetLastError;
// 我添加的代码
end
;
initialization
TTypedComObjectFactory
.
Create(ComServer, TNewComServer, Class_NewComServer, ciMultiInstance, tmApartment);
// 类工厂
end
.
|
After that, we compile the project (CTRL+F9) to generate a Project1.dll file. Save and close the project.
Next, we write a piece of code to test this COM project: Create a common Application project and reference the PROJECT1_TLB unit:
var
// 注意,在测试代码中也需要引用project1_tlb单元,由于我们的接口声明在该单元内
NewComObject: INewComObject;
// 声明接口
begin
NewComObject:= CreateComObject(CLASS_NewComObject)
as
INewComObject;
// 创建COM对象,
//CLASS_NewComObject 的定义可以在Project1_tlb.pas里找到
if
NewComObject <>
nil
then
begin
NewComObject
.
GetMessageInfo;
// 调用接口中的方法
NewComObject:=
nil
;
// 释放接口
end
else
ShowMessage(\‘对象创建不成功\‘);
end
;
|
Note that before we run this exe, we need to register our previous COM project with the system: Start-and-run->regsvr32.exe \ "... Project1.dll\ ". After seeing the prompt for a successful registration, we can now run the test program we just wrote to test our COM object, and see if we have a dialog box titled "Hint" and "test" after executing the test code.
As we can see, when the COM component is created, it is fairly simple when the exe is called, and when the implementation details of one of our methods change, as long as the method declaration is not changed, we can upgrade the COM components we need to upgrade only when the software is upgraded, without having to change the other places. This can effectively reduce the workload of maintenance.
Of course, this demo is just a process of COM, for more detailed instructions, you can refer to more information.
Friendly tip: ActiveX is a component specification for implementing COM under Windows. Please do not equate ActiveX with COM!
Delphi Object-oriented learning essay seven: COM