Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Как вставить Bitmap в TRichEdit?

01.01.2007

Вот так можно вставить картинку в формате Bitmap в позицию курсора в TRichEdit:

unit re_bmp;
 
interface
 
uses
Windows;
 
procedure
InsertBitmapToRE(Wnd:HWND; Bmp:HBITMAP);
 
implementation
 
uses
Activex, RichEdit;
 
const
  IID_IDataObject
: TGUID = (
   D1
:$0000010E;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_CP_SELECTION    
= ULONG(-1);
  REO_IOB_SELECTION  
= ULONG(-1);
  REO_GETOBJ_POLEOBJ  
=  $00000001;
 
type
 
TReobject = record
    cbStruct
: DWORD;
    cp
: ULONG;
    clsid
: TCLSID;
    poleobj
: IOleObject;
    pstg
: IStorage;
    polesite
: IOleClientSite;
    sizel
: TSize;
    dvAspect
: Longint;
    dwFlags
: DWORD;
    dwUser
: DWORD;
 
end;
 
type
 
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;
 
 
TImageDataObject=class(TInterfacedObject,IDataObject)
 
private
   
FBmp:HBITMAP;
   
FMedium:TStgMedium;
   
FFormatEtc: TFormatEtc;
   procedure
SetBitmap(bmp:HBITMAP);
   
function GetOleObject(OleClientSite:IOleClientSite; Storage:IStorage):IOleObject;
   destructor
Destroy;override;
 
   
// IDataObject
   
function GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium): HResult; stdcall;
   
function GetDataHere(const formatetc: TFormatEtc; out medium: TStgMedium): HResult; stdcall;
   
function QueryGetData(const formatetc: TFormatEtc): HResult; stdcall;
   
function GetCanonicalFormatEtc(const formatetc: TFormatEtc; out formatetcOut: TFormatEtc): HResult; stdcall;
   
function SetData(const formatetc: TFormatEtc; var medium: TStgMedium; fRelease: BOOL): HResult; stdcall;
   
function EnumFormatEtc(dwDirection: Longint; out enumFormatEtc: IEnumFormatEtc): HResult; stdcall;
   
function DAdvise(const formatetc: TFormatEtc; advf: Longint;
                     
const advSink: IAdviseSink; out dwConnection: Longint): HResult; stdcall;
   
function DUnadvise(dwConnection: Longint): HResult; stdcall;
   
function EnumDAdvise(out enumAdvise: IEnumStatData): HResult; stdcall;
 
public
   procedure
InsertBitmap(wnd:HWND; Bitmap:HBITMAP);
 
end;
 
 
{ TImageDataObject }
 
function TImageDataObject.DAdvise(const formatetc: TFormatEtc; advf: Integer;
 
const advSink: IAdviseSink; out dwConnection: Integer): HResult;
begin
 
Result:=E_NOTIMPL;
end;
 
function TImageDataObject.DUnadvise(dwConnection: Integer): HResult;
begin
 
Result:=E_NOTIMPL;
end;
 
function TImageDataObject.EnumDAdvise(out enumAdvise: IEnumStatData): HResult;
begin
 
Result:=E_NOTIMPL;
end;
 
function TImageDataObject.EnumFormatEtc(dwDirection: Integer; out enumFormatEtc: IEnumFormatEtc): HResult;
begin
 
Result:=E_NOTIMPL;
end;
 
function TImageDataObject.GetCanonicalFormatEtc(const formatetc: TFormatEtc; out formatetcOut: TFormatEtc): HResult;
begin
 
Result:=E_NOTIMPL;
end;
 
function TImageDataObject.GetDataHere(const formatetc: TFormatEtc; out medium: TStgMedium): HResult;
begin
 
Result:=E_NOTIMPL;
end;
 
function TImageDataObject.QueryGetData(const formatetc: TFormatEtc): HResult;
begin
 
Result:=E_NOTIMPL;
end;
 
destructor
TImageDataObject.Destroy;
begin
 
ReleaseStgMedium(FMedium);
end;
 
function TImageDataObject.GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium): HResult;
begin
 medium
.tymed := TYMED_GDI;
 medium
.hBitmap :=  FMedium.hBitmap;
 medium
.unkForRelease := nil;
 
Result:=S_OK;
end;
 
function TImageDataObject.SetData(const formatetc: TFormatEtc; var medium: TStgMedium; fRelease: BOOL): HResult;
begin
 
FFormatEtc := formatetc;
 
FMedium := medium;
 
Result:= S_OK;
end;
 
procedure
TImageDataObject.SetBitmap(bmp: HBITMAP);
var
 stgm
: TStgMedium;
 fm
:TFormatEtc;
begin
 stgm
.tymed := TYMED_GDI;
 stgm
.hBitmap := bmp;
 stgm
.UnkForRelease := nil;
 
 fm
.cfFormat := CF_BITMAP;
 fm
.ptd := nil;
 fm
.dwAspect := DVASPECT_CONTENT;
 fm
.lindex := -1;
 fm
.tymed := TYMED_GDI;
 
SetData(fm, stgm, FALSE);
end;
 
function TImageDataObject.GetOleObject(OleClientSite: IOleClientSite; Storage: IStorage):IOleObject;
begin
 
if (Fmedium.hBitmap=0) then Result:=nil else
 
OleCreateStaticFromData(self, IID_IOleObject, OLERENDER_FORMAT, @FFormatEtc, OleClientSite, Storage, Result);
end;
 
procedure
TImageDataObject.InsertBitmap(wnd:HWND; Bitmap: HBITMAP);
var
 
OleClientSite:IOleClientSite;
 
RichEditOLE:IRichEditOLE;
 
Storage:IStorage;
 
LockBytes:ILockBytes;
 
OleObject:IOleObject;
 reobject
:TReobject;
 clsid
:TGUID;
begin
 
if (SendMessage(wnd, EM_GETOLEINTERFACE, 0, cardinal(@RichEditOle))=0) then exit;
 
 
FBmp:=CopyImage(Bitmap,IMAGE_BITMAP,0,0,0);
 
if  FBmp=0 then exit;
 
try
   
SetBitmap(Fbmp);
   
RichEditOle.GetClientSite(OleClientSite);
   
if (OleClientSite=nil) then exit;
   
CreateILockBytesOnHGlobal(0, TRUE,LockBytes);
   
if (LockBytes = nil) then exit;
   
if (StgCreateDocfileOnILockBytes(LockBytes, STGM_SHARE_EXCLUSIVE or STGM_CREATE or STGM_READWRITE, 0,Storage)<> S_OK) then
   
begin
     
LockBytes._Release;
     
exit
   
end;
 
   
if (Storage = nil) then exit;
   
OleObject:=GetOleObject(OleClientSite, Storage);
   
if (OleObject = nil) then exit;
   
OleSetContainedObject(OleObject, TRUE);
 
   
ZeroMemory(@reobject, sizeof(TReobject));
   reobject
.cbStruct := sizeof(TReobject);
   
OleObject.GetUserClassID(clsid);
   reobject
.clsid := clsid;
   reobject
.cp := REO_CP_SELECTION;
   reobject
.dvaspect := DVASPECT_CONTENT;
   reobject
.poleobj := OleObject;
   reobject
.polesite := OleClientSite;
   reobject
.pstg := Storage;
 
   
RichEditOle.InsertObject(reobject);
 
finally
   
DeleteObject(FBmp)
 
end
end;
 
 
procedure
InsertBitmapToRE(Wnd:HWND; bmp:HBITMAP);
begin
 
with TImageDataObject.Create do
 
try
 
InsertBitmap(Wnd,Bmp);
 
finally
 
Free
 
end
end;
 
end.
Примеры использования:

 

uses re_bmp;
 
procedure TForm1
.Button1Click(Sender: TObject);
begin
 
InsertBitmapToRE(RichEdit1.Handle,Image1.Picture.Bitmap.Handle);
end;
 
...
 
procedure TForm1
.Button2Click(Sender: TObject);
var
 bmp
:TBitmap;
begin
 
if (not OpenPictureDialog1.Execute) then exit;
 bmp
:=TBitmap.Create;
 
try
   bmp
.LoadFromFile(OpenPictureDialog1.Filename);
   
InsertBitmapToRE(RichEdit1.Handle,bmp.Handle);
 
finally
   bmp
.Free
 
end
end;

Таким же образом можно вставлять картинки не только в TRichEdit, но и в RxRichEdit, стандартный виндовый RichEdit, etc.
 
 

Взято из https://forum.sources.ru

Автор: Krid

 


uses
   
RichEdit;
 
 
// Stream Callback function
type
   
TEditStreamCallBack = function(dwCookie: Longint; pbBuff: PByte;
     cb
: Longint; var pcb: Longint): DWORD;
   stdcall
;
 
   
TEditStream = record
     dwCookie
: Longint;
     dwError
: Longint;
     pfnCallback
: TEditStreamCallBack;
   
end;
 
 
// RichEdit Type
type
   
TMyRichEdit = TRxRichEdit;
 
 
// EditStreamInCallback callback function
function EditStreamInCallback(dwCookie: Longint; pbBuff: PByte;
   cb
: Longint; var pcb: Longint): DWORD; stdcall;
   
// by P. Below
var
   theStream
: TStream;
   dataAvail
: LongInt;
 
begin
   theStream
:= TStream(dwCookie);
   
with theStream do
   
begin
     dataAvail
:= Size - Position;
     
Result := 0;
     
if dataAvail <= cb then
     
begin
       pcb
:= read(pbBuff^, dataAvail);
       
if pcb <> dataAvail then
         
Result := UINT(E_FAIL);
     
end
     
else
     
begin
       pcb
:= read(pbBuff^, cb);
       
if pcb <> cb then
         
Result := UINT(E_FAIL);
     
end;
   
end;
 
end;
 
 
// Insert Stream into RichEdit
procedure
PutRTFSelection(RichEdit: TMyRichEdit; SourceStream: TStream);
   
// by P. Below
var
   
EditStream: TEditStream;
 
begin
   
with EditStream do
   
begin
     dwCookie
:= Longint(SourceStream);
     dwError
:= 0;
     pfnCallback
:= EditStreamInCallBack;
   
end;
   
RichEdit.Perform(EM_STREAMIN, SF_RTF or SFF_SELECTION, Longint(@EditStream));
 
end;
 
 
// Convert Bitmap to RTF Code
function BitmapToRTF(pict: TBitmap): string;
 
// by D3k
var
   bi
, bb, rtf: string;
   bis
, bbs: Cardinal;
   achar
: ShortString;
   hexpict
: string;
   I
: Integer;
 
begin
   
GetDIBSizes(pict.Handle, bis, bbs);
   
SetLength(bi, bis);
   
SetLength(bb, bbs);
   
GetDIB(pict.Handle, pict.Palette, PChar(bi)^, PChar(bb)^);
   rtf
:= '{\rtf1 {\pict\dibitmap ';
   
SetLength(hexpict, (Length(bb) + Length(bi)) * 2);
   I
:= 2;
   
for bis := 1 to Length(bi) do
   
begin
     achar
:= Format('%x', [Integer(bi[bis])]);
     
if Length(achar) = 1 then
       achar
:= '0' + achar;
     hexpict
[I - 1] := achar[1];
     hexpict
[I] := achar[2];
     
Inc(I, 2);
   
end;
   
for bbs := 1 to Length(bb) do
   
begin
     achar
:= Format('%x', [Integer(bb[bbs])]);
     
if Length(achar) = 1 then
       achar
:= '0' + achar;
     hexpict
[I - 1] := achar[1];
     hexpict
[I] := achar[2];
     
Inc(I, 2);
   
end;
   rtf
:= rtf + hexpict + ' }}';
   
Result := rtf;
 
end;
 
 
 
// Example to insert image from Image1 into RxRichEdit1
procedure TForm1
.Button1Click(Sender: TObject);
 
var
   SS
: TStringStream;
   BMP
: TBitmap;
 
begin
   BMP
:= TBitmap.Create;
   BMP
:= Image1.Picture.Bitmap;
   SS  
:= TStringStream.Create(BitmapToRTF(BMP));
   
try
     
PutRTFSelection(RxRichEdit1, SS);
   
finally
     SS
.Free;
   
end;
 
end;

Взято с сайта: https://www.swissdelphicenter.ch