내 프로그램에서 TRxRichEdit을 사용하고 있습니다. 런타임에 OLE 개체를 RxRichEdit에 삽입하려면 어떻게해야합니까?OLE 개체를 TRxRichEdit에 삽입
1
A
답변
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;