Richedit 插入对象并以图标 显示
作者:互联网
function TfrmBillattachment.cxRicheditInsertFile(FilePath:string): Boolean; const REO_CP_SELECTION = $FFFFFFFF; REO_IOB_SELECTION = $FFFFFFFF; IID_IUnknown: TGUID = ( D1: $00000000; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46) ); IID_IOleObject: TGUID = ( D1: $00000112; D2: $0000; D3: $0000; D4: ($C0, $00, $00, $00, $00, $00, $00, $46) ); REO_RESIZABLE = $00000001; // Object may be resized procedure ReleaseObject(var AObj); begin if IUnknown(AObj) <> nil then IUnknown(AObj)._Release; IUnknown(AObj) := nil; end; function GetOleMetaPict(AOleObject:IOleObject; ALable:string):HGlobal; var AClassID: TCLSID; begin Result := 0; OleCheck(AOleObject.GetUserClassID(AClassID)); Result := OleGetIconOfClass(AClassID, PWideChar(WideString(ALable)), False); end; var ReOle: IcxRichEditOle; OleSite: IOleClientSite; Storage: IStorage; SubSTG: IStorage; LockBytes: ILockBytes; OleObject: IOleObject; ReObj: TReObject; TempOle: IUnknown; FormatEtc: TFormatEtc; ASelection: TCharRange; IST :IStream; OST :TOLESTream; FileName :Pchar; FileName2 :array[1..1024] of char; FileM: TmemoryStream; IconMetaPict: HGlobal; begin Result := False; if not FileExists(FilePath) then Exit; if not cxRichEditGetOleInterface(TcxRichInnerEdit(cxDBRichEdit1.InnerControl).Handle,ReOle) then Exit; Assert(ReOle <> nil, 'RichEditOle is null!'); try ReOle.GetClientSite(OleSite); OleCheck(CreateILockBytesOnHGlobal(0, True, LockBytes)); Assert(LockBytes <> nil, 'LockBytes is null!'); OleCheck(StgCreateDocfileOnILockBytes(LockBytes, STGM_SHARE_EXCLUSIVE or STGM_CREATE or STGM_READWRITE, 0, Storage)); Assert(Storage <> nil, 'Storage is null!'); FormatEtc.dwAspect := DVASPECT_ICON; OleCheck(OleCreateFromFile(GUID_NULL, PWideChar(WideString(FilePath)), IID_IUnknown, 0, @FormatEtc, OleSite, Storage, TempOle)); OleCheck(TempOle.QueryInterface(IID_IOleObject, OleObject)); OleCheck(OleSetContainedObject(OleObject, True)); Assert(OleObject <> nil, 'OleObject is null!'); FillChar(ReObj, Sizeof(ReObj), 0); FileName := PansiCHar(ExtractFileName(FilePath)); olecheck( Storage.CreateStorage('substorage', stgm_create or stgm_write or stgm_share_exclusive, 0,0,subSTG)); //创建IStream //文件名 olecheck(substg.createstream('filename', stgm_create or stgm_write or stgm_share_exclusive, 0,0,IST)); //创建OLEStream OST:=TOLEStream.create(IST); OST.write(FileName^,length(string(FileName))); //写入数据 OST.Free; //文件内容 olecheck(substg.createstream('filecontent', stgm_create or stgm_write or stgm_share_exclusive, 0,0,IST)); //创建OLEStream FileM := TmemoryStream.Create; FileM.LoadFromFile(FilePath); FileM.Position := 0; OST:=TOLEStream.create(IST); OST.CopyFrom(FileM, FileM.size); OST.Free; FileM.Free; ReObj.cbStruct := Sizeof(ReObj); OleCheck(OleObject.GetUserClassID(ReObj.clsid)); ReObj.cp := REO_CP_SELECTION; ReObj.dvaspect := DVASPECT_CONTENT; ReObj.oleobj := OleObject; ReObj.olesite := OleSite; ReObj.stg := Storage; ReObj.dwUser := 0; ReObj.dwFlags := REO_RESIZABLE;//ULong(REO_STATIC) or ULong(REO_BELOWBASELINE); ReObj.sizel.cx := 0; ReObj.sizel.cy := 0; // if cxDBRichEdit1.Lines.Count =0 then // begin //// cxDBRichEdit1.Text := ExtractFileName(FilePath)+': '; //// cxDBRichEdit1.SelStart := Length(cxDBRichEdit1.Text); // end // else // begin // try // cxDBRichEdit1.Lines.Add(''); // except // end; // end; if TcxRichInnerEdit(cxDBRichEdit1.InnerControl).HandleAllocated then begin SendMessage(TcxRichInnerEdit(cxDBRichEdit1.InnerControl).Handle, EM_SCROLLCARET, 0, 0); end; if TcxRichInnerEdit(cxDBRichEdit1.InnerControl).HandleAllocated then begin SendMessage(TcxRichInnerEdit(cxDBRichEdit1.InnerControl).Handle, EM_EXGETSEL, 0, LPARAM(@ASelection)); ASelection.cpMax := ASelection.cpMin + 1; end; //获取该对象的图标 图片也是一样。不显示图片内容 IconMetaPict := GetOleMetaPict(OleObject, FileName); OleCheck(cxSetDrawAspect(OleObject, True, IconMetaPict, ReObj.dvaspect)); if Succeeded(ReOle.InsertObject(ReObj))then begin // if TcxRichInnerEdit(cxDBRichEdit1.InnerControl).HandleAllocated then // begin // SendMessage(TcxRichInnerEdit(cxDBRichEdit1.InnerControl).Handle, EM_EXSETSEL, 0, LPARAM(@ASelection)); // SendMessage(TcxRichInnerEdit(cxDBRichEdit1.InnerControl).Handle, EM_SCROLLCARET, 0, 0); // end; // ReOle.SetDvaspect(Longint(REO_IOB_SELECTION), ReObj.dvaspect); Result := True; end; // if Pos(ExtractFileExt(FilePath),'.doc,.docx,.xls,.xlsx') >0 then // begin // try // cxDBRichEdit1.Lines.Add(ExtractFileName(FilePath)); // except // end; // end; finally ReleaseObject(OleObject); ZeroMemory(@ReObj,SizeOf(ReObj)); // FileInfo.Free; qry_Data.Tag := 1; end; end;
以下是摘抄dev的处理方式。
function cxSetDrawAspect(AOleObject: IOleObject; AIconic: Boolean; AIconMetaPict: HGlobal; var ADrawAspect: Cardinal): HResult; var AOleCache: IOleCache; AEnumStatData: IEnumStatData; AOldAspect: Cardinal; AAdviseFlags, AConnection: Longint; ATempMetaPict: HGlobal; AFormatEtc: TFormatEtc; AMedium: TStgMedium; AClassID: TCLSID; AStatData: TStatData; AViewObject: IViewObject; begin AOldAspect := ADrawAspect; if AIconic then begin ADrawAspect := DVASPECT_ICON; AAdviseFlags := ADVF_NODATA; end else begin ADrawAspect := DVASPECT_CONTENT; AAdviseFlags := ADVF_PRIMEFIRST; end; if (ADrawAspect <> AOldAspect) or (ADrawAspect = DVASPECT_ICON) then begin AOleCache := AOleObject as IOleCache; if ADrawAspect <> AOldAspect then begin OleCheck(AOleCache.EnumCache(AEnumStatData)); if AEnumStatData <> nil then while AEnumStatData.Next(1, AStatData, nil) = 0 do if AStatData.formatetc.dwAspect = Integer(AOldAspect) then AOleCache.Uncache(AStatData.dwConnection); FillChar(AFormatEtc, SizeOf(FormatEtc), 0); AFormatEtc.dwAspect := ADrawAspect; AFormatEtc.lIndex := -1; OleCheck(AOleCache.Cache(AFormatEtc, AAdviseFlags, AConnection)); if AOleObject.QueryInterface(IViewObject, AViewObject) = 0 then AViewObject.SetAdvise(ADrawAspect, 0, nil); end; if ADrawAspect = DVASPECT_ICON then begin ATempMetaPict := 0; if AIconMetaPict = 0 then begin OleCheck(AOleObject.GetUserClassID(AClassID)); ATempMetaPict := OleGetIconOfClass(AClassID, nil, True); AIconMetaPict := ATempMetaPict; end; try with AFormatEtc do begin cfFormat := CF_METAFILEPICT; ptd := nil; dwAspect := DVASPECT_ICON; lindex := -1; tymed := TYMED_MFPICT; end; with AMedium do begin tymed := TYMED_MFPICT; hMetaFilePict := AIconMetaPict; unkForRelease := nil; end; OleCheck(AOleCache.SetData(AFormatEtc, AMedium, False)); finally DestroyMetaPict(ATempMetaPict); end; end; if ADrawAspect <> DVASPECT_ICON then AOleObject.Update; end; Result := S_OK; end;
function cxRichEditGetOleInterface(AH: HWnd; out AOleInterface: IcxRichEditOle): Boolean; begin Result := SendMessage(AH, EM_GETOLEINTERFACE, 0, LPARAM(@AOleInterface)) <> 0; end; function cxRichEditSelectedIsPic(cxRichEdit: TcxRichEdit; out Pic: TPicture; IsOutPic: Boolean=False): Boolean; var FRichEditOle: IUnknown; i: Integer; AReObject: TReObject; pDataObject: IDataObject; fm: TFormatEtc; em: IEnumFormatEtc; stg: TStgMedium; TmpPic1, TmpPic2: TPicture; g: TGPGraphics; img: TGPImage; MemStream: TMemoryStream; MyIStream: TStreamAdapter; RootSTG,SubSTG :IStorage; begin Result := False; try FRichEditOle := nil; if not cxRichEditGetOleInterface(TcxRichInnerEdit(cxRichEdit.InnerControl).Handle,IcxRichEditOle(FRichEditOle)) then Exit; with IcxRichEditOle(FRichEditOle) do begin for i := 0 to GetObjectCount -1 do begin FillChar(AReObject, SizeOf(AReObject), 0); AReObject.cbStruct := SizeOf(AReObject); OleCheck(GetObject(LongInt(i), AReObject, REO_GETOBJ_ALL_INTERFACES)); //不是选中状态跳过 if (AReObject.dwFlags and REO_SELECTED) <> REO_SELECTED then Continue; pDataObject := nil; OleCheck(AReObject.oleobj.QueryInterface(IDataObject, pDataObject)); if pDataObject <> nil then begin em := nil; pDataObject.EnumFormatEtc(DATADIR_GET, em); if em <> nil then begin FillChar(fm, SizeOf(fm), 0); while em.Next(1, fm, nil) <> S_FALSE do begin Result := fm.cfFormat in [CF_BITMAP, CF_DIB, CF_METAFILEPICT]; if not Result then Break; end; end; end; end; end; if Result and IsOutPic then begin TmpPic1 := TPicture.Create; TmpPic2 := TPicture.Create; MemStream := TMemoryStream.Create; if fm.cfFormat in [CF_BITMAP,CF_DIB] then begin fm.cfFormat := CF_BITMAP; fm.ptd := nil; fm.dwAspect := DVASPECT_CONTENT; fm.lindex := -1; fm.tymed := TYMED_GDI; if Succeeded(pDataObject.GetData(fm, stg)) then begin TmpPic1.Bitmap.Handle := stg.hBitmap; TmpPic2.Bitmap.Width := TmpPic1.Bitmap.Width; TmpPic2.Bitmap.Height := TmpPic1.Bitmap.Height; TmpPic2.Bitmap.Canvas.CopyRect(TmpPic1.Bitmap.Canvas.ClipRect, TmpPic1.Bitmap.Canvas, TmpPic1.Bitmap.Canvas.ClipRect); TmpPic2.Bitmap.SaveToStream(MemStream); ReleaseStgMedium(stg); end; end //图元文件 以emf文件格式存在 else if fm.cfFormat = CF_METAFILEPICT then begin SendMessage(TcxRichInnerEdit(cxRichEdit.InnerControl).Handle, WM_COPY, 0, 0); try if OpenClipboard(0) then begin TmpPic2.Metafile.LoadFromClipboardFormat(0,0,0); TmpPic2.Metafile.SaveToStream(MemStream); MemStream.Position := 0; end; finally CloseClipboard; end; end; MyIStream := TStreamAdapter.Create(MemStream); img := TGPImage.Create(MyIStream); pic := TPicture.Create; pic.Bitmap.Width := img.GetWidth; pic.Bitmap.Height :=img.GetHeight; g := TGPGraphics.Create(pic.Bitmap.Canvas.Handle); { 缩放时的算法模式 } g.SetInterpolationMode(TInterpolationMode(InterpolationModeHighQualityBicubic)); g.DrawImage(img, MakeRect(0, 0, img.GetWidth, img.GetHeight), 0, 0, img.GetWidth, img.GetHeight, UnitPixel); g.Free; img.Free; FreeAndNil(MemStream); TmpPic1.Free; TmpPic2.Free; end; finally em := nil; pDataObject := nil; FRichEditOle := nil; end; end;
标签:begin,end,Richedit,nil,ReObj,插入,cxDBRichEdit1,OleCheck,图标 来源: https://www.cnblogs.com/BTag/p/15666932.html