打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Richedit中插入图片

Richedit中插入图片

时间:2011-5-31来源:yang 作者: peng点击: 25次

 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 := ‘{{‘;

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;

****************************************

下面的代码可以不调用那个InsertObject的对话框而直接插入一张图片:

var

Bmp:TBitmap;

begin

if not OpenPictureDialog1.Execute then exit;

Bmp:=TBitmap.Create;

Bmp.LoadFromFile(OpenPictureDialog1.FileName);

Clipboard.Assign(BMP);

RxRichEdit201.PasteFromClipboard;

Bmp.Free;

end;

**************************************

: TechnoFantasy(http://www.applevb.com)/

RichEdit中,插入图片

代码:

procedure proPrintRTFWithBMP(strCaption,strPic,strTitle:string;rtf:TRichEdit);

{strText为要打印的文本 strCaption为打印标题 strPic为图像文件目录

strTitle为要显示在图像右侧的图像标题}

var

FRTF:IRichEditOle;

FOLE:IOLEObject;

formatEtc:tagFORMATETC;

FStorage :ISTORAGE;

FClientSite:IOLECLIENTSITE;

FLockBytes:ILockBytes;

ReObject:TReObject;

xt:TGuid;

FTemp:IUnknown;

strTemp:string;

bCreateNew:boolean;

ABMP:TBitmap;

Ajpeg:TJpegImage;

i:Longint;

begin

// rtfTemp:=TRichEdit.Create(frmPrintFrame);

try

{ with rtfTemp do

begin

Parent := frmPrintFrame;

width:=200;

height:=200;

visible:=false;

Text := strText;

end; }

//图片文件不存在,直接打印文本并退出

if not fileexists(strPic)then

begin

PrintRichEdit(strCaption,rtf);

exit;

end;

abmp:=TBitmap.Create;

ajpeg:= TJpegImage.Create;

try

if ExtractFileExt(strPic)=‘.jpg‘ then

begin

bCreateNew:=true;

ajpeg.LoadFromFile(strPic);

abmp.Assign(ajpeg);

strTemp:=ExtractFilePath(strPic)+‘0099http://www.bmp/

abmp.SaveToFile(strTemp);

for i:=1 to 30000 do

application.ProcessMessages;

end

else

strTemp:= strPic;

finally

abmp.Free;

ajpeg.free;

abmp:=nil;

ajpeg:=nil;

end;

sendmessage(rtf.handle,EM_GETOLEINTERFACE,0,LongInt(@FRTF));

if not assigned(FRTF)then

begin

showmessage(‘Error to get Richedit OLE interface‘);

exit;

end;

//建立一个可以访问全局内存的Byte数组 FLockBytes

//返回ILockBytes接口

if CreateILockBytesOnHGlobal(0,true,FLockBytes)<>S_OK then

begin

showmessage(‘Error to create Global Heap‘);

exit;

end;

//建立一个混合文档存取对象

if StgCreateDocfileOnILockBytes(FLockBytes,STGM_SHARE_EXCLUSIVE or

STGM_CREATE or STGM_READWRITE,0,FStorage)<>S_OK then

begin

showmessage(‘Error to create storage‘);

exit;

end;

 

formatEtc.cfFormat := 0;

FormatEtc.ptd := nil;

FormatEtc.dwAspect := DVASPECT_CONTENT;

FormatEtc.lindex := -1;

FormatEtc.tymed := TYMED_NULL;

FRTF.GetClientSite(FClientSite);

//从文件中创建一个OLE对象

if OleCreateFromFile(GUID_NULL,PWideChar(WideString(strTemp)),IID_IUnknown,0,@formatEtc,

FClientSite,FStorage,FOLE)<>S_OK then

begin

showmessage(‘Error‘);

exit;

end;

//现在的FOLE还是一个IUnKnown接口,将其转换为一个 IOleObject接口

FTemp:=FOLE;

FTemp.QueryInterface(IID_IOleObject, FOle);

OleSetContainedObject(FOle, TRUE);

 

//step 2

reobject.cbStruct := sizeof(TReObject);

FOLE.GetUserClassID(xt);

ReObject.clsid := xt;

reobject.cp := ULong(REO_CP_SELECTION);

reobject.dvaspect := DVASPECT_CONTENT;

reobject.dwFlags := ULong(REO_RESIZABLE) or ULong(REO_BELOWBASELINE);

reobject.dwUser := 0;

reobject.poleobj := FOle;

reobject.polesite := FClientSite;

reobject.pstg := FStorage;

reobject.sizel.cx := 0;

reobject.sizel.cy := 0;

FRTF.InsertObject(reobject);

PrintRichEdit(strCaption,rtf);

finally

if bCreateNew then

Deletefile(strTemp);

FRTF:=nil;

FOLE:=nil;

end;

end;

上面的代码是一个在RTF控件当前位置插入图像并打印的,你运行上面的代码需要首先引用

ActiveX, ComObj, RichEdit, Jpeg

并且将PrintRichEdit(strCaption,rtf);去掉

以下的结构是需要手工加入的:

type

_ReObject = record

cbStruct: DWORD; { Size of structure }

cp: ULONG; { Character position of object }

clsid: TCLSID; { Class ID of object }

poleobj: IOleObject; { OLE object interface }

pstg: IStorage; { Associated storage interface }

polesite: IOleClientSite; { Associated client site interface }

sizel: TSize; { Size of object (may be 0,0) }

dvAspect: Longint; { Display aspect to use }

dwFlags: DWORD; { Object status flags }

dwUser: DWORD; { Dword for user‘s use }

end;

TReObject = _ReObject;

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;

Type TCharRange=record

cpMin:integer;

cpMax:integer;

End;

Type TFormatRange=record

hdc : Integer;

hdcTarget:integer;

rectRegion:trect;

rectPage:trect;

chrg : TCharRange;

End;

************************************

以下不通过剪切板而直接在Richedit中插入一张图片:

var

frmMain: TfrmMain;

implementation

{$R *.DFM}

{$R Smiley.res}

uses

RichEdit;

type

TEditStreamCallBack = function(dwCookie: Longint; pbBuff: PByte;

cb: Longint; var pcb: Longint): DWORD;

stdcall;

TEditStream = record

dwCookie: Longint;

dwError: Longint;

pfnCallback: TEditStreamCallBack;

end;

type

TMyRichEdit = TRxRichEdit;

// EditStreamInCallback callback function

function EditStreamInCallback(dwCookie: Longint; pbBuff: PByte;

cb: Longint; var pcb: Longint): DWORD; stdcall;

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);

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;

// Load a smiley image from resource

function GetSmileyCode(ASimily: string): string;

var

dHandle: THandle;

pData, pTemp: PChar;

Size: Longint;

begin

pData := nil;

dHandle := FindResource(hInstance, PChar(ASimily), RT_RCDATA);

if dHandle <> 0 then

begin

Size := SizeofResource(hInstance, dHandle);

dhandle := LoadResource(hInstance, dHandle);

if dHandle <> 0 then

try

pData := LockResource(dHandle);

if pData <> nil then

try

if pData[Size - 1] = #0 then

begin

Result := StrPas(pTemp);

end

else

begin

pTemp := StrAlloc(Size + 1);

try

StrMove(pTemp, pData, Size);

pTemp[Size] := #0;

Result := StrPas(pTemp);

finally

StrDispose(pTemp);

end;

end;

finally

UnlockResource(dHandle);

end;

finally

FreeResource(dHandle);

end;

end;

end;

procedure InsertSmiley(ASmiley: string);

var

ms: TMemoryStream;

s: string;

begin

ms := TMemoryStream.Create;

try

s := GetSmileyCode(ASmiley);

if s <> ‘‘ then

begin

ms.Seek(0, soFromEnd);

ms.Write(PChar(s)^, Length(s));

ms.Position := 0;

PutRTFSelection(frmMain.RXRichedit1, ms);

end;

finally

ms.Free;

end;

end;

procedure TfrmMain.SpeedButton1Click(Sender: TObject);

begin

InsertSmiley(‘Smiley1‘);

end;

procedure TfrmMain.SpeedButton2Click(Sender: TObject);

begin

InsertSmiley(‘Smiley2‘);

end;

// Replace a :-) or :-( with a corresponding smiley

procedure TfrmMain.RxRichEdit1KeyPress(Sender: TObject; var Key: Char);

var

sCode, SmileyName: string;

procedure RemoveText(RichEdit: TMyRichEdit);

begin

with RichEdit do

begin

SelStart := SelStart - 2;

SelLength := 2;

SelText := ‘‘;

end;

end;

begin

If (Key = ‘)‘) or (Key = ‘(‘) then

begin

sCode := Copy(RxRichEdit1.Text, RxRichEdit1.SelStart-1, 2) + Key;

SmileyName := ‘‘;

if sCode = ‘:-)‘ then SmileyName := ‘Smiley1‘;

if sCode = ‘:-(‘ then SmileyName := ‘Smiley2‘;

if SmileyName <> ‘‘ then

begin

Key := #0;

RemoveText(RxRichEdit1);

InsertSmiley(‘Smiley1‘);

end;

end;

end;  

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
"网络蚂蚁"和"FlashGet"的悬浮窗口的实现
用Delphi实现一个IE安全的ActiveXObject
Delphi不注册COM直接使用ActiveX控件并绑定事件
Delphi 之 接口
Delphi制作DLL
在游戏中切出外挂delphi代码(hook)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服