ainer can define whatever ambient properties it wants to expose. ActiveX defines a standard set of ambient properties, which includes: BackColor, DisplayName, and others. A container is not required to provide any or all of these properties, but if it does, Microsoft defines which dispids to use for each.
ActiveX allows you to access ambient properties through the site''''s IDispatch interface. Delphi provides a dispinterface, IAmbientDispatch, which can be used to access the standard interfaces. Since it''''s a dispinterface, it''''s really just an IDispatch pointer and can be cast to any other dispinterface. If you''''re interested in querying the container for a nonstandard ambient property you''''ll need to define a new dispinterface that defines the property and its dispid, then cast FAmbientDispatch to the new dispinterface. Here''''s the declaration of IAmbientDispatch: IAmbientDispatch = dispinterface
[''''{00020400-0000-0000-C000-000000000046}'''']
property BackColor: Integer dispid DISPID_AMBIENT_BACKCOLOR;
property DisplayName: WideString dispid DISPID_AMBIENT_DISPLAYNAME;
property Font: IFontDisp dispid DISPID_AMBIENT_FONT;
property ForeColor: Integer dispid DISPID_AMBIENT_FORECOLOR;
property LocaleID: Integer dispid DISPID_AMBIENT_LOCALEID;
property MessageReflect: WordBool dispid DISPID_AMBIENT_MESSAGEREFLECT;
property ScaleUnits: WideString dispid DISPID_AMBIENT_SCALEUNITS;
property TextAlign: Smallint dispid DISPID_AMBIENT_TEXTALIGN;
property UserMode: WordBool dispid DISPID_AMBIENT_USERMODE;
property UIDead: WordBool dispid DISPID_AMBIENT_UIDEAD;
property ShowGrabHandles: WordBool dispid DISPID_AMBIENT_SHOWGRABHANDLES;
property ShowHatching: WordBool dispid DISPID_AMBIENT_SHOWHATCHING;
property DisplayAsDefault: WordBool dispid DISPID_AMBIENT_DISPLAYASDEFAULT;
property SupportsMnemonics: WordBool dispid DISPID_AMBIENT_SUPPORTSMNEMONICS;
property AutoClip: WordBool dispid DISPID_AMBIENT_AUTOCLIP;
end;
Example: The following code responds to the button click, and sets the button''''s caption to the DisplayName ambient property. The DisplayName property is usually the control''''s name in its container. procedure TButtonX.Click;
var
Site: IOleClientSite;
Ambients: IDispatch;
begin
GetClientSite( Site );
if Site <> nil then
Site.QueryInterface(IDispatch, Ambients);
if Ambients <> nil then
begin
Caption := IAmbientDispatch(Ambients).DisplayName;
end;
end;
Tracking Changes to Ambient Properties
When the container changes the value of one of its ambient properties, it informs the control by calling the object''''s OnAmbientPropertyChange method. In Delphi, you can implement your own handler for this method by overriding the method and re-implementing the IOleControl interface in your class.
Bug: Ambient Confusion
As if the ActiveX specification wasn''''t confusing enough, Microsoft has been confused about how to implement ambient properties. Certain MS containers, such as Access 97, incorrectly assume the IDispatch interface it provides for ambient properties can be the same as the event sink. To make matters worse, some versions of MFC assume they must be the same IDispatch pointers. The lesson here is that over the years ActiveX has become enough of an architectural mess that nobody can ensure-or for that matter define-complete compliance. What this means for you as an ActiveX control developer is that you need to be diligent about testing your control in a variety of containers, and be prepared to encounter some strange and unexpected behaviors. Even Microsoft has published controls that work in Internet Explorer but not in other containers, and each container has different reactions to the control''''s incompatibility.
Adding Custom Registry Entries
You may want to add new registry entries for your control. For example, Microsoft recently published a specification, called component categories, that involves adding registry entries under the Component Categories key. DAX provides a means of adding registry entries in the factory class.
Every Delphi COM factory provides a virtual UpdateRegistry method that gets called when the library is registered or unregistered. If you want to add new items to the registry when the library is registered, derive a new factory class from TActiveXControlFactory and override its UpdateRegistry method. Then replace the factory Create call at the bottom of the control''''s implementation unit with a call that creates an instance of your new factory class.
Example:
The following code defines a special factory class called TSpecialFactory that adds a sub-key of the class key called "SpecialKey". This key has a numeric value, which you set in the constructor.
type TSpecialFactory = class(TActiveXControlFactory)
public
constructor Create(ComServer: TComServerObject; ActiveXControlClass: TActiveXControlClass; WinControlClass:
TWinControlClass; const ClassID: TGUID; ToolboxBitmapID:
Integer; const LicStr: string; MiscStatus: Integer; SpecialKeyValue:
Integer); override;
procedure UpdateRegistry(Register: Boolean); override;
protected
FSpecialKeyValue: Integer;
end;
constructor TSpecialFactory.Create(ComServer: TComServerObject;
ActiveXControlClass: TActiveXControlClass; WinControlClass: TWinControlClass;
const ClassID: TGUID; ToolboxBitmapID: Integer;
const LicStr: string; MiscStatus: Integer;
SpecialKeyValue: Integer);
var
TypeAttr: PTypeAttr;
begin
FSpecialKeyValue := SpecialKeyValue;
inherited Create(ComServer, ActiveXControlClass, WinControlClass,
ClassID, ToolboxBitmapID, LicStr, MiscStatus);
end;
procedure TSpecialFactory.UpdateRegistry(Register: Boolean);
var
ClassKey: string;
begin
ClassKey := ''''CLSID\'''' + GUIDToString(ClassID);
if Register then
begin
inherited UpdateRegistry(Register);
CreateRegKey(ClassKey + ''''\SpecialKey'''', '''''''', IntToStr(FSpecialKeyValue));
end
else
begin
DeleteRegKey(ClassKey + ''''\SpecialKey'''');
inherited UpdateRegistry(Register);
end;
end;
To use this class factory, simply replace the existing class factory creation code in the initialization section of your ActiveX library: The last line in the example below sets the value of "SpecialKey" to 1234. initialization
TSpecialFactory.Create(ComServer, TButtonX, TButton,
Class_ButtonX, 1, '''''''', 0, 1234);
end.
Web Deployment and Code Signing
Web DeploymentActiveX controls built with Delphi can be deployed to a web site for downloading into Internet Explorer. Before you can deploy your control, there are several things you need to figure out:
- Where the binary codebase will reside on your server. This could be an URL like "http://www.mycorp.com/code/DAXSamp.ocx".
- A directory where Delphi can copy the HTML file. If the HTTP server is running on your machine, this could be a local filename like "c:\https\codebase\".
- A directory where Delphi can copy the codebase file. If the HTTP server is running on your machine, this could be a local filename like "c:\https\pages\".
Once you''''ve specified these basic options, you can copy the code to the server by invoking the Project|Web Deploy command. When you invoke the Web Deploy command, Delphi generates a web page that refers to your control and copies it to the HTML destination directory. Delphi then copies the codebase to the web server''''s codebase destination directory.
The generated HTML code looks like the following code. Using the above example directories, Delphi copies it to a file called c:\https\pages\DAXSamp.HTM.
Delphi ActiveX Test Page
You should see your Delphi forms or controls embedded in the form below.
It the server is a remote Web server that you don''''t have file-system access to, you will need to tell Delphi to put the files in a local directory. Then, you can use your usual web-page deployment method (for example, FTP or FrontPage) to deploy the code to your server.
Code Signing
Signing your ActiveX control accomplishes two things. First, it identifies you or your organization as the author of the code. Second, it gives the recipient of the code the ability to verify that what they received is what you made and it hasn''''t been tampered with.
The key element in code signing is your certificate, which is a code key assigned to you by a company called a certificate authority. The certificate file appears in the form of a .SPC (Software Publisher''''s Certificate) file, delivered to you by the certificate authority. You also need a private key file (.PVK), which you created as part of your application to the CA for the SPC file.
Microsoft also provides you with a means of creating untrusted keys for testing purposes. See Microsoft''''s web site, http://www.microsoft.com/workshop/prog/security/authcode/codesign.htm for the paper, "Signing Code with Microsoft''''s Authenticode". The process is also described in the Microsoft INET SDK, which is where you will find the tools required for manufacturing the untrusted test keys.
Delphi 3 provides a project options page where you can specify your code signature information, including the file that contains the cr 上一页 [1] [2] [3] [4] [5] [6] [7] [8] 下一页 |