2010-01-01 3 views

답변

1

RxRichEdit의 "InsertObjectDialog"메서드를 호출하면 컨트롤은 개체 삽입 대화 상자를 실행하여 사용자가 새로 만들거나 기존 파일에서 개체를 만들 수 있습니다.

IRichEditOle 인터페이스 (FRichEditOle)가 클래스 전용이므로 대화 상자를 사용하지 않고 개체를 삽입 할 수 있다고 생각하지 않습니다.

편집 : 인

에 상관없이 인터페이스 클래스에, 분명히, 하나 EM_GETOLEINTERFACE를 사용하여 RichEdit 컨트롤 자체에서 직접 IRichEditOle 인터페이스를 요청할 수 없습니다 또는 개인. 아래는 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;