2010-01-01 10 views

Répondre

1

Si vous appelez la méthode "InsertObjectDialog" de RxRichEdit, le contrôle exécute la boîte de dialogue Insérer un objet dans laquelle l'utilisateur peut choisir le type de l'objet à créer à nouveau ou à partir d'un fichier existant.

Je ne pense pas qu'il serait possible d'insérer un objet sans utiliser la boîte de dialogue, car l'interface IRichEditOle (FRichEditOle) est privée à la classe.

modifier:

Quelle que soit l'interface étant privée ou non à la classe, apparemment, on peut demander l'interface IRichEditOle directement à partir du contrôle RichEdit lui-même en utilisant EM_GETOLEINTERFACE. Ci-dessous un exemple de code D3 (la dernière version avec laquelle j'ai utilisé les contrôles RX), mais il conviendrait probablement aussi au 'TJvRichEdit' de JVCL, qui est à l'origine le même contrôle. Le code insère un objet Ole à partir d'un nom de fichier lors de l'exécution:

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;