Autor Beitrag
bruechix
Hält's aus hier
Beiträge: 2

Win 2000
Delphi 6 Enterprise
BeitragVerfasst: Mo 03.07.06 09:50 
Mit hat gerade das folgende Tutorial von Peter van Ooijen in Sachen COM-Programmierung weitergeholfen und ich wollte hier mal darauf aufmerksam machen.
Die Hilfe in Delphi hat leider nicht sehr viel Details zu COM am Start.

www.gekko-software.nl/Delphi/index.htm

Die Arbeit mit SafeArrays ist hier sehr gut erklärt.

Gruss, Thorsten

Folgenden Zeilen sind hilfreich, wenn man im Bsp. statt auf ein Array of Interger auf ein Array of Widestrings zugreifen möchte. Dieser Typ ist in Delphi noch nicht deklariert.

type
BstringArray = Array of WideString;

Nebenbei hatte ich auch noch ein Problem in Delphi 6 bei der Generierung der TLB Datei aus einem ActiveX-Control.

Das Interface wird nicht vom ActiveX-Control implementiert, sondern muss vom Nutzer implementiert werden.
Delphi hat folgendes generiert.

// *********************************************************************//
// Interface: ISLIKBrowser2
// Flags: (256) OleAutomation
// GUID: {A754481E-F92D-4D54-BC84-2ED8F3AE344F}
// *********************************************************************//
//ISLIKBrowser2 = interface(IUnknown)
//['{A754481E-F92D-4D54-BC84-2ED8F3AE344F}']
function QueryOrganization(var NameSpaceType: NameSpaceTypesEnum): HResult; stdcall;
function ChangeBrowsePosition(BrowseDirection: BrowseDirsEnum; const Branch: WideString;
out Result: Integer): HResult; stdcall;
function Browse(BrowseFilterType: BrowseFilterTypesEnum; const FilterString: WideString;
DataTypeFilter: Integer; AccessRightsFilter: Integer; var Items: PSafeArray;
out Result: Integer): HResult; stdcall;
function GetFullyQualifiedTagName(const ItemName: WideString; var TagName: WideString;
var Flags: Integer; out Result: Integer): HResult; stdcall;
function GetAccessPaths(const TagName: WideString; var AccessPaths: PSafeArray;
out Result: Integer): HResult; stdcall;
end;

Hier ist schonmal das Problem, das in der Signatur der function's ein Parametername Result generiert wurde und dieser Parametername ist in Delphi schon für den Rückgabewert der function reserviert.

Ich habe mal versucht in Delphi ein ganz neues COM-Objekt zu bauen, das einfach diese schon im System registrierte Schnittstelle implementiert und dabei hat Delphi die tlb-Datei wie folgt generiert.

ISLIKBrowser2 = interface(IUnknown)
['{A754481E-F92D-4D54-BC84-2ED8F3AE344F}']
procedure QueryOrganization(var NameSpaceType: NameSpaceTypesEnum); safecall;
function ChangeBrowsePosition(BrowseDirection: BrowseDirsEnum;
const Branch: WideString): Integer; safecall;
function Browse(BrowseFilterType: BrowseFilterTypesEnum; const FilterString: WideString;
DataTypeFilter: Integer; AccessRightsFilter: Integer;
var Items: PSafeArray): Integer; safecall;
function GetFullyQualifiedTagName(const ItemName: WideString; var TagName: WideString;
var Flags: Integer): Integer; safecall;
function GetAccessPaths(const TagName: WideString;
var AccessPaths: PSafeArray): Integer; safecall;
end;

Ich habe die tlb in meinem Projekt in dem ich das ActiveX-Control nutze einfach von Hand abgeändert (Was leider nicht sehr glücklich ist, wenn ich das ActiveX update)

So funktioniert es auf jeden Fall.

Gruss, Thorsten

Mit OleView von Microsoft habe ich folgende IDL für die Schnittstelle aus dem ActiveX Control extrahiert.

[
odl,
uuid(A754481E-F92D-4D54-BC84-2ED8F3AE344F),
helpstring("ISLIKBrowser2 Interface"),
oleautomation
]
interface ISLIKBrowser2 : IUnknown {
[helpstring("Query the namespace organization.")]
HRESULT _stdcall QueryOrganization([in, out] NameSpaceTypesEnum* NameSpaceType);
[helpstring("Change the current browse position.")]
HRESULT _stdcall ChangeBrowsePosition(
[in] BrowseDirsEnum BrowseDirection,
[in] BSTR Branch,
[out, retval] long* Result);
[helpstring("Get a list of branch or leaf names at the current browse position, possibly matching some filters.")]
HRESULT _stdcall Browse(
[in] BrowseFilterTypesEnum BrowseFilterType,
[in] BSTR FilterString,
[in] long DataTypeFilter,
[in] long AccessRightsFilter,
[in, out] SAFEARRAY(BSTR)* Items,
[out, retval] long* Result);
[helpstring("Determine the fully qualified tag name, given an item name returned from Browse().")]
HRESULT _stdcall GetFullyQualifiedTagName(
[in] BSTR ItemName,
[in, out] BSTR* TagName,
[in, out] long* Flags,
[out, retval] long* Result);
[helpstring("Get the available access paths for a tag.")]
HRESULT _stdcall GetAccessPaths(
[in] BSTR TagName,
[in, out] SAFEARRAY(BSTR)* AccessPaths,
[out, retval] long* Result);
};