2010-01-01 99 views

回答

1

如果調用RxRichEdit的「InsertObjectDialog」的方法,控制執行插入對象對話框,用戶可以選擇對象的類型來創建重新或從現有的文件。

因爲IRichEditOle接口(FRichEditOle)對於類是私有的,所以我不認爲有可能在不使用對話框的情況下插入一個對象。

編輯:

不管所述接口私有或不類,顯然,一個可以直接從RichEdit控件本身通過使用EM_GETOLEINTERFACE請求IRichEditOle接口。下面是D3示例代碼(我使用RX控件的最後一個版本),但它也可能適合JVCL的'TJvRichEdit',它最初是相同的控件。

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對象