1

プログラムで TRxRichEdit を使用しています。実行時に ole オブジェクトを RxRichEdit に挿入するにはどうすればよいですか。

4

1 に答える 1

1

RxRichEdit の「InsertObjectDialog」メソッドを呼び出すと、コントロールはオブジェクトの挿入ダイアログを実行し、ユーザーはオブジェクトのタイプを選択して新規に作成するか、既存のファイルから作成できます。

IRichEditOle インターフェイス (FRichEditOle) はクラスに対してプライベートであるため、ダイアログを使用せずにオブジェクトを挿入することはできないと思います。

編集:

インターフェイスがクラスに対してプライベートであるかどうかに関係なく、明らかに、IRichEditOleを使用して RichEdit コントロール自体からインターフェイスを直接要求できますEM_GETOLEINTERFACE。以下は D3 のサンプル コード (私が RX コントロールを使用した最後のバージョン) ですが、元は同じコントロールである JVCL の「TJvRichEdit」にも適していると思われます。このコードは、実行時にファイル名から Ole オブジェクトを挿入します。

uses
  activex, richedit, comobj;

type
  _ReObject = record
    cbStruct: DWORD;
    cp: ULONG;
    clsid: TCLSID;
    poleobj: IOleObject;
    pstg: IStorage;
    polesite: IOleClientSite;
    sizel: TSize;
    dvAspect: Longint;
    dwFlags: DWORD;
    dwUser: DWORD;
  end;
  TReObject = _ReObject;

  IRichEditOle = interface(IUnknown)
    ['{00020d00-0000-0000-c000-000000000046}']
    function GetClientSite(out clientSite: IOleClientSite): HResult; stdcall;
    function GetObjectCount: HResult; stdcall;
    function GetLinkCount: HResult; stdcall;
    function GetObject(iob: Longint; out reobject: TReObject;
        dwFlags: DWORD): HResult; stdcall;
    function InsertObject(var reobject: TReObject): HResult; stdcall;
    function ConvertObject(iob: Longint; rclsidNew: TIID;
        lpstrUserTypeNew: LPCSTR): HResult; stdcall;
    function ActivateAs(rclsid: TIID; rclsidAs: TIID): HResult; stdcall;
    function SetHostNames(lpstrContainerApp: LPCSTR;
        lpstrContainerObj: LPCSTR): HResult; stdcall;
    function SetLinkAvailable(iob: Longint; fAvailable: BOOL): HResult; stdcall;
    function SetDvaspect(iob: Longint; dvaspect: DWORD): HResult; stdcall;
    function HandsOffStorage(iob: Longint): HResult; stdcall;
    function SaveCompleted(iob: Longint; const stg: IStorage): HResult; stdcall;
    function InPlaceDeactivate: HResult; stdcall;
    function ContextSensitiveHelp(fEnterMode: BOOL): HResult; stdcall;
    function GetClipboardData(var chrg: TCharRange; reco: DWORD;
        out dataobj: IDataObject): HResult; stdcall;
    function ImportDataObject(dataobj: IDataObject; cf: TClipFormat;
        hMetaPict: HGLOBAL): HResult; stdcall;
  end;

const
  REO_CP_SELECTION    = ULONG(-1);
  REO_RESIZABLE       = $00000001;
  IID_IOleObject: TGUID = (
      D1:$00000112;D2:$0000;D3:$0000;D4:($C0,$00,$00,$00,$00,$00,$00,$46));

procedure InsertOleObjectFromFile(RichEdit: TRxRichEdit; FileName: string);
var
  RichEditOle: IRichEditOle;
  LockBytes: ILockBytes;
  Storage: IStorage;
  FormatEtc: TFormatEtc;
  ClientSite: IOleClientSite;
  OleObject: IOleObject;
  ClassID: TCLSID;
  ReObject: TReObject;
begin
  SendMessage(RichEdit.Handle, EM_GETOLEINTERFACE, 0, Longint(@RichEditOle));
  if not Assigned(RichEditOle) then
    raise EOleError.Create('Failed to retrieve IRichEditOle');
  OleCheck(CreateILockBytesOnHGlobal(0, True, LockBytes));
  OleCheck(StgCreateDocfileOnILockBytes(LockBytes,
      STGM_SHARE_EXCLUSIVE or STGM_CREATE or STGM_READWRITE, 0, Storage));
  LockBytes := nil;

  OleCheck(RichEditOle.GetClientSite(ClientSite));
  FillChar(FormatEtc, SizeOf(FormatEtc), 0);
  FormatEtc.dwAspect := DVASPECT_CONTENT;
  FormatEtc.lIndex := -1;
  OleCheck(OleCreateFromFile(GUID_NULL, PWideChar(WideString(FileName)),
      IID_IOleObject, OLERENDER_DRAW, @FormatEtc, ClientSite, Storage,
      OleObject));
  OleCheck(OleSetContainedObject(OleObject, True));

  OleCheck(OleObject.GetUserClassID(ClassID));
  FillChar(ReObject, SizeOf(TReObject), 0);
  ReObject.cbStruct := SizeOf(TReObject);
  ReObject.cp := REO_CP_SELECTION;
  ReObject.clsid := ClassID;
  ReObject.poleobj := OleObject;
  ReObject.pstg := Storage;
  ReObject.polesite := ClientSite;
  ReObject.dvAspect := DVASPECT_CONTENT;
  ReObject.dwFlags := REO_RESIZABLE;
  OleCheck(RichEditOle.InsertObject(ReObject));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  InsertOleObjectFromFile(RxRichEdit1,
      ExtractFilePath(Application.ExeName) + 'xltest.xls');
end;
于 2010-01-13T21:42:10.380 に答える