Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   OleVariant PSafeArray (https://www.delphipraxis.net/209654-olevariant-psafearray.html)

Berni68 5. Jan 2022 14:32

OleVariant PSafeArray
 
Hallo,

in einer Typbibliothek ist folgende Funktion definiert:
Delphi-Quellcode:
// *********************************************************************//
// DispIntf: ModelState
// Flags:    (4096) Dispatchable
// GUID:     {B0D75815-A121-4964-BE90-7B8C0422C2DD}
// *********************************************************************//
  ModelState = dispinterface
    ['{B0D75815-A121-4964-BE90-7B8C0422C2DD}']
    ...
    procedure GetReferenceKey(var ReferenceKey: {NOT_OLEAUTO(PSafeArray)}OleVariant;
                              KeyContext: Integer); dispid 2130706454;
    ...
  end;
Damit will ich die Funktion aufrufen:
Delphi-Quellcode:
...
var
  test: OleVariant;

begin
  ...
  MS.Item[i].Name // <- funktioniert
  ...
  test:= VarArrayCreate([0,1000],varByte);
  MS.Item[i].GetReferenceKey(test); // <- funktioniert NICHT
  ...
Der Aufruf der Prozedur scheitert. ich erhalte bei der Zeile "MS.Item[i].GetReferenceKey(test)" die Fehlermeldung Typenkonflikt.

bedeutet wohl daß
VarArrayCreate([0,1000],varByte)
falsch ist.
Aber wie muß das definiert werden?
Wie erzeuge ich hier ein PSafeArray ?

peterbelow 5. Jan 2022 15:05

AW: OleVariant PSafeArray
 
Zitat:

Zitat von Berni68 (Beitrag 1500116)
Hallo,

in einer Typbibliothek ist folgende Funktion definiert:
Delphi-Quellcode:
// *********************************************************************//
// DispIntf: ModelState
// Flags:    (4096) Dispatchable
// GUID:     {B0D75815-A121-4964-BE90-7B8C0422C2DD}
// *********************************************************************//
  ModelState = dispinterface
    ['{B0D75815-A121-4964-BE90-7B8C0422C2DD}']
    ...
    procedure GetReferenceKey(var ReferenceKey: {NOT_OLEAUTO(PSafeArray)}OleVariant;
                              KeyContext: Integer); dispid 2130706454;
    ...
  end;
Damit will ich die Funktion aufrufen:
Delphi-Quellcode:
...
var
  test: OleVariant;

begin
  ...
  MS.Item[i].Name // <- funktioniert
  ...
  test:= VarArrayCreate([0,1000],varByte);
  MS.Item[i].GetReferenceKey(test); // <- funktioniert NICHT
  ...
Der Aufruf der Prozedur scheitert. ich erhalte bei der Zeile "MS.Item[i].GetReferenceKey(test)" die Fehlermeldung Typenkonflikt.

bedeutet wohl daß
VarArrayCreate([0,1000],varByte)
falsch ist.
Aber wie muß das definiert werden?
Wie erzeuge ich hier ein PSafeArray ?

Was ist MS? So wie GetReferenceKey definiert ist würde ich erwarten, das diese Prozedur den array erzeugt und in dem test-OleVariant zurückgibt. Du übergibst auch keinen Wert für den KeyContext-Parameter. GetReferenceKey gibt auch keinen Result zurück, den Du einer Variablen zuweisen kannst.

Berni68 5. Jan 2022 15:22

AW: OleVariant PSafeArray
 
Die ganze Prozedur sieht so aus:

Delphi-Quellcode:
procedure TMain.MI_InfoPartClick(Sender: TObject);
var
  doc: Document;
  ipt: PartDocument;
  MS: ModelStates;
  i: integer;
  test:OleVariant;
begin
  doc:= InventorApp.ActiveDocument;
  memo.Lines.Add(doc.FullDocumentName);
 
  if doc.DocumentType <> PartDocumentObject then exit;
  ipt:= PartDocument(doc);
  MS:= ipt.ComponentDefinition.ModelStates;

  test:= VarArrayCreate([0,1000],varByte);

  for i:=1 to MS.Count do begin
    memo.Lines.Add(MS.Item[i].Name); // funktioniert
    //MS.Item[i].Activate;          // funktioniert
    memo.Lines.Add(MS.Item[i].Document.PropertySets.Item[1].Item[1].Value); // funktioniert (auch schreibend)

    MS.Item[i].GetReferenceKey(test, 0); // Typkonflikt  
  end;
end;
Nur der Aufruf der Prozedur
GetReferenceKey(test, 0);
geht nicht: Typenkonflikt

Berni68 5. Jan 2022 15:54

AW: OleVariant PSafeArray
 
Habe gerade das für VB gefunden (soll auch funktionieren):

Dim refKey() As Byte = New Byte() {}
oFeature.GetReferenceKey(refKey)
MsgBox(ThisDoc.Document.ReferenceKeyManager.KeyToS tring(refKey))

kann man das nach Delphi übersetzen?

Berni68 7. Jan 2022 10:57

AW: OleVariant PSafeArray
 
Hallo,

ich habe nun fogendes herausbekommen:
der OLE-server erwartet ein Array mit 12 Byte.
Die Schnittstelle lässt nur OleVariant zu: (var ReferenceKey: {NOT_OLEAUTO(PSafeArray)}OleVariant; KeyContext: Integer)
der KeyContext ist in diesem Kontext egal.

Ich will jetz ein OleVariant bauen das das 12 Byte array enthält:
Delphi-Quellcode:
function test:OleVariant;
var i: integer;
  Pb: Pointer;
  Vb: OleVariant;
  b: TBytes;
    tsa: TSafeArray;
    psa: PSafeArray;
    tag: TSafeArrayBound;
  P: Pointer;
  V: OleVariant;
begin
  SetLength(b,12); for i:=0 to 11 do b[i]:=0;
  Vb:= VarArrayCreate([0, 12], varByte);
  Pb:= VarArrayLock(Vb);
  Move(b[0], Pb^, 12);
  VarArrayUnlock(Vb);

  tsa.cDims:= 1;
  tsa.fFeatures:= 0001;    // <-??   
  tsa.cbElements:= 12;
  tsa.cLocks:= 0001;       // <-?? 
  tsa.pvData:= Pb; ;
    tag.lLbound:= 0;
    tag.cElements:= 12;
    tsa.rgsabound[0]:=tag;
  psa:= @tsa;

  V:= VarArrayCreate([0,0], varDispatch); // nicht: varVariant,varDispatch
  P:= VarArrayLock(V);
  Move(psa, P^, SizeOf(psa));
  VarArrayUnlock(V);

  Result:= V;
end;
wenn ich das nun Aufrufe:

Delphi-Quellcode:
MS.Item[1].GetReferenceKey(test, 0);
erhalte ich als Fehlermeldung nicht mehr "Typenkonflikt" sondern
"Variante oder sicheres Array ist gesperrt"
(Zumindest wird die OleVariant mal akzeptiert)

Weiß jemand Rat?
tsa.fFeatures
tsa.cLocks

himitsu 7. Jan 2022 15:44

AW: OleVariant PSafeArray
 
Delphi-Referenz durchsuchenSafeArrayCreate ? :stupid:

aus System.VarUtils (aber gibt es auch nochmal in Winapi.ActiveX und Winapi.Ole2, falls das Eine nicht reicht)




https://www.delphipraxis.net/181879-...safearray.html
https://de.comp.lang.delphi.misc.nar...iant-ubergeben
http://www.delphigroups.info/2/3a/266174.html
...

Berni68 9. Jan 2022 13:03

AW: OleVariant PSafeArray
 
Hallo himitsu,

danke für den Hinweis.
Hilft mir aber nicht weiter.

Ich interpretiere
Delphi-Quellcode:
    procedure GetReferenceKey(var ReferenceKey: {NOT_OLEAUTO(PSafeArray)}OleVariant;
                              KeyContext: Integer); dispid 2130706454;
analog dazu liefert Free Pascal
Delphi-Quellcode:
//  Warning: 'PSafeArray' not automatable in ModelStatedisp.GetReferenceKey
nun so, daß das mit Pascal nicht geht und gebe auf.

peterbelow 10. Jan 2022 14:35

AW: OleVariant PSafeArray
 
Zitat:

Zitat von Berni68 (Beitrag 1500339)
Hallo himitsu,

danke für den Hinweis.
Hilft mir aber nicht weiter.

Ich interpretiere
Delphi-Quellcode:
    procedure GetReferenceKey(var ReferenceKey: {NOT_OLEAUTO(PSafeArray)}OleVariant;
                              KeyContext: Integer); dispid 2130706454;
analog dazu liefert Free Pascal
Delphi-Quellcode:
//  Warning: 'PSafeArray' not automatable in ModelStatedisp.GetReferenceKey
nun so, daß das mit Pascal nicht geht und gebe auf.

Liefert der type library import auch ein dual interface neben dem dispinterface? Wenn ja solltest Du lieber das verwenden, da kann man notfalls die generierte Deklaration der Methode anpassen wenn der type library importer das nicht richtig gemacht hat.

Ich hatte mal ein dispinterface, das nicht wirklich automation-kompatible Methoden enthielt. Da half dann sowas:

Delphi-Quellcode:
   {PB 2005-10-07 The VoidPtrToBufID function does not work as declared by the
     type library importer. Removing the Var for the buffer parameter makes it
     work, though. }
    function VoidPtrToBufID({var} buffer: {??Pointer} OleVariant; bufflen: Integer): Integer; dispid 20007;
Verwendung:
Delphi-Quellcode:
{!
<summary>
  CreateSketchFromBuffer is a helper routine, it reads a sketch from
  a memory buffer.</summary>
<returns>
 an ISIS sketch handle, or INVALID_ID, if the read failed. The caller
     has to eventually release this handle via the DeleteSketch method of
     the ISIS automation server.</returns>
<param name="pData">
 is the buffer's address.</param>
<param name="len">is the length of the data, in bytes.</param>
}
function TIsisMolinfoHelper.CreateSketchFromBuffer(pData: Pointer; Len:
    integer): Integer;
var
  hSketch: Integer;
  V: TVarData;
  BufID: Integer;
begin
  {$IFDEF LOGDETAIL}
  Logmanager.Log('Start - TIsisMolinfoHelper.CreateSketchFromBuffer');
  {$ENDIF}

  Result := INVALID_ID;
  V.VType := VT_PTR;
  V.VPointer := pData;
  {$IFDEF LOGDETAIL}
  Logmanager.Log('TIsisMolinfoHelper.CreateSketchFromBuffer - calling VoidPtrToBufID');
  {$ENDIF}
  BufID := Isis.VoidPtrToBufID(Olevariant(V), Len);
  if BufID > 0 then
    try
      {$IFDEF LOGDETAIL}
      Logmanager.Log('TIsisMolinfoHelper.CreateSketchFromBuffer - calling ReadSketchFromBuffer');
      {$ENDIF}
      hSketch := Isis.ReadSketchFromBuffer(BufID);
      {$IFDEF LOGDETAIL}
      Logmanager.Log('TIsisMolinfoHelper.CreateSketchFromBuffer - ReadSketchFromBuffer returned');
      {$ENDIF}
      if hSketch <> INVALID_ID then
        Result := hSketch
      else begin
        {$IFDEF DEBUG}
        Logmanager.Log('CreateSketchFromBuffer: ReadSketchFromBuffer failed.');
        {$ENDIF}
      end; { Else }
    finally
      isis.DeleteBuffer(BufID);
    end { finally }
  else begin
    {$IFDEF DEBUG}
    Logmanager.Log('CreateSketchFromBuffer: VoidPtrToBufID failed.');
    {$ENDIF}
  end; { Else }
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz