Re[7]: Как передать в API функцию ссылку на массив структур
От: ayap Россия  
Дата: 22.12.05 11:12
Оценка:
Здравствуйте, Oleg A. Bachin, Вы писали:

OAB>Здравствуйте, ekamaloff, Вы писали:


E>>Здравствуйте, Oleg A. Bachin, Вы писали:


OAB>>>при кол-ве структур 1 — разницы никакой.

E>>Не совсем понял, о чем это.
OAB>сорри, не вчитался... подумал что как всегда массив указателей на структуры...

OAB>>>а вот packed record надо бы на автопилоте приучиться писать.

E>>Там и record в моем посте не было.
OAB>это я в продолжение, чтоб 2 поста не писать

За всё спасибо, конечно, но я примерно так всё и делал — не работает однако

Привожу полный код для внесения ясности:


unit uTestForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComObj, ActiveX;

type
  TTestForm = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  DSOP_UPLEVEL_FILTER_FLAGS = packed record
    flBothModes: Longint;
    flMixedModeOnly: Longint;
    flNativeModeOnly: Longint;
  end;

  DSOP_FILTER_FLAGS = packed record
    Uplevel: DSOP_UPLEVEL_FILTER_FLAGS;
    flDownlevel: Longint;
  end;

  DSOP_SCOPE_INIT_INFO = packed record
    cbSize: Longint;
    flType: Longint;
    flScope: Longint;
    FilterFlags: DSOP_FILTER_FLAGS;
    pwzDcName: LPWSTR;
    pwzADsPath: LPWSTR;
    hr: HResult;
  end;

  PDSOP_SCOPE_INIT_INFO = ^DSOP_SCOPE_INIT_INFO;

  DSOP_INIT_INFO = packed record
    cbSize: Longint;
    pwzTargetComputer: LPWSTR;
    cDsScopeInfos: Longint;
    aDsScopeInfos: PDSOP_SCOPE_INIT_INFO;
    flOptions: LongInt;
    cAttributesToFetch: Longint;
    apwzAttributeNames: PLPWSTR;
  end;
  PDSOP_INIT_INFO = ^DSOP_INIT_INFO;

  IDsObjectPicker = interface(IUnknown)
    ['{0C87E64E-3B7A-11D2-B9E0-00C04FD8DBF7}']
     function Initialize(pInitInfo: PDSOP_INIT_INFO ): HResult; stdcall;
     function InvokeDialog(Parent: HWND; doSelections: IUnknown): HResult; stdcall;
  end;

var
  TestForm: TTestForm;

const
  CLSID: TGUID = '{17D6CCD8-3B7B-11D2-B9E0-00C04FD8DBF7}';
  IID: TGUID   = '{0C87E64E-3B7A-11D2-B9E0-00C04FD8DBF7}';
  DSOP_FLAG_MULTISELECT = $00000001;
  DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK = $00000002;

implementation

{$R *.dfm}

procedure TTestForm.Button2Click(Sender: TObject);
var
  obj: IUnknown;
  InitInfo: PDSOP_INIT_INFO;
  CompName: WideString;
  aScopeInit: array[0..0] of DSOP_SCOPE_INIT_INFO;
begin
  CoInitialize(nil);
  try
    CompName := 'LOCALHOST';
    CoCreateInstance(CLSID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IID, obj);

    aScopeInit[0].cbSize := sizeof(DSOP_SCOPE_INIT_INFO);
    aScopeInit[0].flType := $0000037F;
    aScopeInit[0].flScope := $000000C3;
    aScopeInit[0].FilterFlags.Uplevel.flBothModes    := $00000042;
    aScopeInit[0].FilterFlags.Uplevel.flMixedModeOnly    := $00000000;
    aScopeInit[0].FilterFlags.Uplevel.flNativeModeOnly := $00000000;
    aScopeInit[0].FilterFlags.flDownlevel := $80000005;

    InitInfo := GetMemory(sizeof(DSOP_INIT_INFO));
    InitInfo.cbSize := sizeof(DSOP_INIT_INFO);
    InitInfo.pwzTargetComputer := LPWSTR(CompName);
    InitInfo.cDsScopeInfos := Length(aScopeInit);
    InitInfo.aDsScopeInfos := @aScopeInit[0];
    InitInfo.flOptions := DSOP_FLAG_MULTISELECT or DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK;
    InitInfo.cAttributesToFetch := 0;
    InitInfo.apwzAttributeNames := nil;

    (obj as IDsObjectPicker).Initialize(InitInfo); // Здесь Access Violation in "objsel.dll"
  finally
    FreeMemory(InitInfo);
    CoUnInitialize;
  end;
end;

end.



Ещё раз обратите внимание на выделенные места, особенно правильно ли я определил следующий тип:

PDSOP_SCOPE_INIT_INFO = ^DSOP_SCOPE_INIT_INFO;

Всем большое спасибо за обсуждение
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.