📄 ch15.htm
字号:
the TMultiply class declaration, just above the protected keyword: <P></DL><BLOCKQUOTE> <PRE>private FX : Integer; FY : Integer;</PRE></BLOCKQUOTE><PRE></PRE><DL> <DT></DT> <DD>These are the declarations for the data fields that will hold the X and Y property values. <P> <DT></DT> <DD><B>2. </B>Scroll down into the implementation section and locate the Get_X method (use the Code Explorer if you like). Type this line of code in the method: <P></DL><BLOCKQUOTE> <PRE>Result := FX;</PRE></BLOCKQUOTE><PRE></PRE><DL> <DT></DT> <DD><B>3. </B>Locate the Get_Y method and add this line: <P></DL><BLOCKQUOTE> <PRE>Result := FY;</PRE></BLOCKQUOTE><PRE></PRE><DL> <DT></DT> <DD><B>4. </B>Locate the DoIt method and add this line of code: <P></DL><BLOCKQUOTE> <PRE>Result := FX * FY;</PRE></BLOCKQUOTE><PRE></PRE><DL> <DT></DT> <DD>This line of code multiplies the value of FX and FY and returns the result. <P> <DT></DT> <DD><B>5. </B>Scroll down further until you see the Set_X method. Type this line of code in the Set_X method: <P></DL><BLOCKQUOTE> <PRE>FX := Value;</PRE></BLOCKQUOTE><PRE></PRE><DL> <DT></DT> <DD><B>6. </B>Locate the Set_Y method and add this line: <P></DL><BLOCKQUOTE> <PRE>FY := Value;</PRE></BLOCKQUOTE><PRE></PRE><P>That's all you need to do. Your code should now look like Listing 15.2.</P><P><H4>LISTING 15.2. THE COMPLETED MultiplyU UNIT.</H4><PRE>unit MultiplyU;interfaceuses Windows, ActiveX, ComObj, ComTest_TLB;type TMultiply = class(TTypedComObject, IMultiply) private FX : Integer; FY : Integer; protected function DoIt: Integer; stdcall; function Get_X: Integer; stdcall; function Get_Y: Integer; stdcall; procedure Set_X(Value: Integer); stdcall; procedure Set_Y(Value: Integer); stdcall; {Declare IMultiply methods here} end;implementationuses ComServ;function TMultiply.DoIt: Integer;begin Result := FX * FY;end; function TMultiply.Get_X: Integer;begin Result := FX;end;function TMultiply.Get_Y: Integer;begin Result := FY;end;procedure TMultiply.Set_X(Value: Integer);begin FX := Value;end;</PRE><PRE>procedure TMultiply.Set_Y(Value: Integer);</PRE><PRE>begin FY := Value;end;initialization TTypedComObjectFactory.Create(ComServer, TMultiply, Class_Multiply, ciMultiInstance, tmSingle);end.</PRE><P>Although you were working on the MulitplyU unit, Delphi was busy building thetype library and a unit to contain the type library code. The unit has the same nameas the project with a trailing _TLB. This project is named ComTest. The full unitname for the type library unit, then, is ComTest_TLB.pas. Listing 15.3 shows thisunit as it exists at this point. Remember, your unit might not look exactly likeListing 15.3.</P><P><H4>LISTING 15.3. THE ComTest_TLB.pas UNIT.</H4><PRE>unit ComTest_TLB;// ******************************************************************** //// WARNING //// ------- //// The types declared in this file were generated from data read from a //// Type Library. If this type library is explicitly or indirectly (via //// another type library referring to this type library) reimported, or //// the `Refresh' command of the Type Library Editor activated while //// editing the Type Library, the contents of this file will be //// regenerated and all manual modifications will be lost. //// ******************************************************************** //// PASTLWTR : $Revision: 1.11.1.55 $// File generated on 6/8/98 7:16:51 PM from Type Library described below.// ******************************************************************** //// Type Lib: D:\Borland\D4\Bin\ComTest.tlb// IID\LCID: {7CDAFB76-FF36-11D1-81F1-0040052A83C4}\0// Helpfile: // HelpString: ComTest Library// Version: 1.0// ******************************************************************** //interfaceuses Windows, ActiveX, Classes, Graphics, OleCtrls, StdVCL; // *********************************************************************//// GUIDS declared in the TypeLibrary. Following prefixes are used: //// Type Libraries : LIBID_xxxx //// CoClasses : CLASS_xxxx //// DISPInterfaces : DIID_xxxx //// Non-DISP interfaces: IID_xxxx //// *********************************************************************//const LIBID_ComTest: TGUID = `{7CDAFB76-FF36-11D1-81F1-0040052A83C4}'; IID_IMultiply: TGUID = `{7CDAFB77-FF36-11D1-81F1-0040052A83C4}'; CLASS_Multiply: TGUID = `{7CDAFB79-FF36-11D1-81F1-0040052A83C4}';type// *********************************************************************//// Forward declaration of interfaces defined in Type Library //// *********************************************************************// IMultiply = interface;// *********************************************************************//// Declaration of CoClasses defined in Type Library //// (NOTE: Here we map each CoClass to its Default Interface) //// *********************************************************************// Multiply = IMultiply;// *********************************************************************//// Interface: IMultiply// Flags: (0)// GUID: {7CDAFB77-FF36-11D1-81F1-0040052A83C4}// *********************************************************************// IMultiply = interface(IUnknown) [`{7CDAFB77-FF36-11D1-81F1-0040052A83C4}'] function Get_X: Integer; stdcall; procedure Set_X(Value: Integer); stdcall; function Get_Y: Integer; stdcall; procedure Set_Y(Value: Integer); stdcall; function DoIt: Integer; stdcall; end; CoMultiply = class class function Create: IMultiply; class function CreateRemote(const MachineName: string): IMultiply; end;implementationuses ComObj;</PRE><PRE>class function CoMultiply.Create: IMultiply;</PRE><PRE>begin Result := CreateComObject(CLASS_Multiply) as IMultiply;end;class function CoMultiply.CreateRemote(const MachineName: string): ÂIMultiply;begin Result := CreateRemoteComObject(MachineName, CLASS_Multiply) as ÂIMultiply;end;end.</PRE><P>Notice that this unit contains the declaration for the IMultiply interface. Asyou can see, IMultiply is derived from IUnknown. Notice also that this unit containsthe coclass Multiply.</P><P>It is important to understand that this unit is regenerated each time you compilean ActiveX library project. It is generated from the type library file. Note thewarning at the top of the unit. The comments are telling you that any changes youmake to this file will be lost the next time the COM object is rebuilt. It reallydoesn't do any good to modify the type library source file, because it will be regeneratedautomatically.</P><P><H4>Building and Registering the COM Object</H4><P>Now you are ready to compile the ActiveX library project. This step compiles theCOM object and builds the DLL in which the COM object resides. After building theCOM object, you can register it. Here are the steps:</P><DL> <DT></DT> <DD><B>1. </B>Choose Project|Build ComTest from the main menu. Delphi will build the DLL containing the COM object. <P> <DT></DT> <DD><B>2. </B>Choose Run|Register ActiveX Server from the main menu. This step registers the COM object with Windows. If you fail to perform this step, you will get an exception that says, "Class not registered" when you attempt to access the COM object. <P></DL><P>Delphi registers the COM object DLL with Windows. After the DLL has been registered,Delphi displays a message box, as shown in Figure 15.4.</P><P><A HREF="javascript:popUp('28671504.gif')"><B>FIGURE 15.4.</B></A><B> </B><I>Delphireporting the COM object successfully registered.</I></P><P></P><P>When Windows registers the COM object, it adds information about the object tothe Registry. Figure 15.5 shows the Registry entry created when the COM object wasregistered with Windows.</P><P><A HREF="javascript:popUp('28671505.gif')"><B>FIGURE 15.5.</B></A><B> </B><I>TheRegistry key created when the COM object was registered.</I></P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> Delphi ships with a utility called TREGSVR.EXE that can be used to register an ActiveX control from the command line. To register a control called MYSTUFF.OCX, you would run TREGSVR from a command prompt like this: <PRE>tregsvr mystuff.ocx</PRE></BLOCKQUOTE><PRE></PRE><BLOCKQUOTE> <P>To unregister an ActiveX, use the -u switch as follows: <PRE>tregsvr -u mystuff.ocx</PRE></BLOCKQUOTE><PRE></PRE><BLOCKQUOTE> <P>Sometimes this is more convenient than loading an ActiveX project in Delphi and registering or unregistering the control from the IDE. <HR><BR> </P> <P><HR><strong>NOTE:</strong> In this exercise I had you create a COM object. You could also have used an automation object. An automation object derives from IDispatch rather than IUnknown. IDispatch provides the additional functionality required for a COM object to act as an automation server (an object that can control one application from another). <HR></BLOCKQUOTE><P>Your COM object is now ready to use.</P><P><H4>Building an Application That Uses the COM Object</H4><P>A COM object doesn't do you much good if you can't use it. In this step, you createan application that uses the COM object you just created. Follow these steps:</P><DL> <DT></DT> <DD><B>1. </B>Create a new application. Place a Button component and a Label component on the form. Save the project as ComApp and the main form's unit as ComAppU. <P> <DT></DT> <DD><B>2. </B>Switch to the Code Editor and locate the uses list for the main unit. Add these units to the uses list: <P></DL><BLOCKQUOTE> <PRE>ComObjComTest_TLB</PRE></BLOCKQUOTE><PRE></PRE><DL> <DD>This ensures that the code that references the COM object will compile. <DT></DT> <DD><B>3. </B>Double-click the form's button to create an OnClick event handler.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -