将ole对象插入TRxRichEdit [英] Inserting ole object to TRxRichEdit

查看:60
本文介绍了将ole对象插入TRxRichEdit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在程序中使用TRxRichEdit.如何在运行时将ole对象插入RxRichEdit.

I'm using TRxRichEdit in my program. How can I insert ole object to RxRichEdit at run time.

推荐答案

如果调用RxRichEdit的"InsertObjectDialog"方法,则控件将执行插入对象"对话框,用户可以在其中选择要重新创建对象的类型或从中选择对象的类型.现有文件.

If you call "InsertObjectDialog" method of the RxRichEdit, the control executes the Insert Object dialog where the user can choose the type of the object to create anew or from an existing file.

我认为不使用对话框就不可能插入对象,因为IRichEditOle接口(FRichEditOle)对于该类是私有的.

无论接口是私有类还是非私有类,显然,人们都可以请求 EM_GETOLEINTERFACE .下面是D3示例代码(我使用RX控件的最新版本),但它也可能适合JVCL的"TJvRichEdit",它最初是相同的控件.该代码在运行时从文件名插入一个Ole对象:

Regardless the interface being private or not to the class, apparently, one can request the IRichEditOle interface directly from the RichEdit control itself by using EM_GETOLEINTERFACE. Below is D3 sample code (the last version I used RX controls with), but it would also probably suit the 'TJvRichEdit' of JVCL, which is originally the same control. The code inserts an Ole object from a file name at run-time:

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;

这篇关于将ole对象插入TRxRichEdit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆