在RichEdit中插入GIF图片的方法

简介:
今天在整理自己以前写的棋牌游戏的时候,在RICHEDIT中插入图片的方法想不起来了。因此在网上找了一番,现将找的文章记录下来便于以后再次查找呵呵。
 
许多人在找RichEdit中插入GIF图片的方法,这里摘录一段我的一个程序的片段,
程序中使用了QQ中的OleImage.dll,要先象安装OCX控件一样安装,安装后产生一ImageOleLib_TLB文件,
要加入到工程中,并要安装rxRichEdit控件。
首先加入一单元InsRich(见下),再调用函数InsertGif(见下),下面还摘选了一段我使用的
代码。

unit InsRich;

interface
uses
   Windows, Messages, ActiveX;
const
   REO_CP_SelectION = ULONG(-1);
   REO_BELOWBASELINE = $00000002;
   REO_RESIZABLE = $00000001;
   REO_STATIC = $40000000;
   EM_GETOLEINTERFACE = WM_USER + 60;
   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));
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憇 use }
   end;
   TReObject = _ReObject;
   TCharRange = record {Copy From RichEdit.pas}
     cpMin: Integer;
     cpMax: Integer;
   end;
   TFormatRange = record
     hdc: Integer;
     hdcTarget: Integer;
     rectRegion: TRect;
     rectPage: TRect;
     chrg: TCharRange;
   end;
   IRichEditOle = interface(System.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;
implementation
end.

插入到re中,sFileName是GIF图的路径,dwUser是标识别,用一随机数。
procedure InsertGif(re: TRxRichEdit; sFileName: string; dwUser: integer);
type
   tagSize = TSize;
var
   FRTF: IRichEditOle;
   FLockBytes: ILockBytes;
   FStorage: ISTORAGE;
   FClientSite: IOLECLIENTSITE;
   m_lpObject: IOleObject;
   m_lpAnimator: TGifAnimator;
   i_GifAnimator: IGifAnimator;
   reobject: TReObject;
   clsid: TGuid;
   sizel: tagSize;
   Rect: TRect;
begin
   try
     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;
   //??RichEdit???
     Sendmessage(re.handle, EM_GETOLEINTERFACE, 0, LongInt(@FRTF));

     if FRTF.GetClientSite(FClientSite) <> S_OK then
     begin
       //ShowMessage('Error to get ClentSite');
       Exit;
     end;
     CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
     m_lpAnimator := TGifAnimator.Create(re);
     i_GifAnimator := m_lpAnimator.ControlInterface;
     i_GifAnimator.LoadFromFile(sFileName);
     i_GifAnimator.QueryInterface(IID_IOleObject, m_lpObject);
     OleSetContainedObject(m_lpObject, True);
     FillChar(ReObject, SizeOf(ReObject), 0);
     ReObject.cbStruct := SizeOf(ReObject);
     m_lpObject.GetUserClassID(clsid);
     ReObject.clsid := clsid;
     reobject.cp := REO_CP_SelectION;
   //content, but not static
     reobject.dvaspect := DVASPECT_CONTENT;
   //goes in the same line of text line
     reobject.dwFlags := REO_BELOWBASELINE; //REO_RESIZABLE |
     reobject.dwUser := 0;
   //the very object
     reobject.poleobj := m_lpObject;
   //client site contain the object
     reobject.polesite := FClientSite;
   //the storage
     reobject.pstg := FStorage;
     sizel.cx := 0;
     sizel.cy := 0;
     reobject.sizel := sizel;

   //Sel all text
     re.SelText := '';
     re.SelLength := 0;
     re.SelStart := re.SelStart;
     reobject.dwUser := dwUser;

   //Insert after the line of text
     FRTF.InsertObject(reobject);
     SendMessage(re.Handle, EM_SCROLLCARET, 0, 0);
   //VARIANT_BOOL ret;
   //do frame changing
     m_lpAnimator.TriggerFrameChange();
   //show it
     m_lpObject.DoVerb(OLEIVERB_UIACTIVATE, nil, FClientSite, 0, re.Handle, Rect);
// m_lpObject.DoVerb(
     m_lpObject.DoVerb(OLEIVERB_SHOW, nil, FClientSite, 0, re.Handle, Rect);
   //redraw the window to show animation
     RedrawWindow(re.Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ERASENOW or RDW_ALLCHILDREN);
   finally
     FRTF := nil;
     FClientSite := nil;
     FStorage := nil;
   end;
end;

以下是我程序中使用该函数的代码,供大家参考。
procedure TTextObject.AddGif(re: TRxRichEdit; sFile, sShortCut: string);
var
   GifIDMap: TGifIDMap;
   i, iGifID: integer;
   sFileName: string;
begin
   if Pos('\customface\', LowerCase(sFile)) <> 0 then
     sFileName := ExtractFilePath(Application.ExeName) + sNumber + sFile
   else
     sFileName := ExtractFilePath(Application.ExeName) + sFile;

   if not FileExists(sFileName) then Exit; // 文件不存在

   Randomize;
   iGifID := Random(2147483647);
   i := 0;
   while i < GifIDList.Count do
   begin
     if TGifIDMap(GifIDList.Items).iGifID = iGifID then
     begin
       iGifID := Random(2147483647);
       i := 0;
       Continue;
     end;
     Inc(i);
   end;
   InsertGif(re, sFileName, iGifID);// 调用
   GifIDMap := TGifIDMap.Create;
   GifIDMap.iGifID := iGifID;
   GifIDMap.sFileName := sFile;
   GifIDMap.sShortCut := sShortCut;
   GifIDList.Add(GifIDMap);
end;

procedure TTextObject.ShowRichEdit(re: TRxRichEdit; sHeadStr: string);
var
   i, iGifID, iCp: integer;
   iShift: integer;
   sFileName: string;
begin
   re.Lines.BeginUpdate;

   // 图行位置偏移量
   iShift := Length(sHeadStr);

   // 文本
   re.Lines.BeginUpdate;
   re.Clear;
   re.Text := sHeadStr + Text;
   re.Lines.EndUpdate;

   // 插入Gif
   for i := 0 to OleObjectList.Count - 1 do
   begin
     iCp := TOleObjectMap(OleObjectList.Items).iCp;
     iGifID := TOleObjectMap(OleObjectList.Items).iGifID;
     sFileName := GetFileName(iGifID);

     if sFileName <> '' then // 文件存在时
     begin
       re.SelStart := iCp + iShift;
       re.SelLength := 1;
       re.SelText := '';
       InsertGif(re, sFileName, iGifID); // 插入
     end;
   end;

   re.Lines.EndUpdate;
end;
本文转自狗窝博客51CTO博客,原文链接http://blog.51cto.com/fxh7622/540516如需转载请自行联系原作者

fxh7622
相关文章
|
5月前
|
Web App开发 XML 存储
一篇文章讲明白JPG、PNG、GIF、SVG等格式图片区别
一篇文章讲明白JPG、PNG、GIF、SVG等格式图片区别
如何复制同一张图片,生成50张排列名称为1.jpg,2.jpg,3.jpg,4.jpg,顺序1-50张的图片,同一张图片生成50份,名字排序不一样怎样写
如何复制同一张图片,生成50张排列名称为1.jpg,2.jpg,3.jpg,4.jpg,顺序1-50张的图片,同一张图片生成50份,名字排序不一样怎样写
|
机器学习/深度学习 计算机视觉
【图片操作】提取GIF的图片帧
gif是我们日常生活中常用的一种图片,它介于视频和图片之间。我们可以用图片的内存体验到一些视频的感觉。但是有时候我们会想把gif的图片全部提取出来,今天我们就来实现一下这个操作。
418 0
|
JavaScript 前端开发
图片转base64、判断图片大小、图片压缩、图片上传
文章主要介绍 `js` 实现压缩上传图片转base64,其他的框架(如React、Vue、Angular)也可借此参考。**这个方法真实可用,已在实际项目中运行**。
317 0
|
Web App开发 存储 iOS开发
一日一技:把webp图片保存为png
一日一技:把webp图片保存为png
235 0
|
计算机视觉
【图片操作】生成动态图片
动态图片我们使用的还是比较频繁的,平时的表情包有很多动图。今天我们要做的就是自己制作动态图片,其实就是将视频转换成动图,操作起来非常简单。下面我们就来看看如何实现吧。
576 0
Halcon打开图片:单个图片以及遍历读取文件夹里的所有图片
Halcon打开图片:单个图片以及遍历读取文件夹里的所有图片
979 0
|
存储 JavaScript 前端开发
Image图片查找不存在时(九)
在实际的开发中,常常会遇到关于图片的问题。 如图片显示的问题,然而在显示图片的过程中,常常也会遇到一些问题,如图片不存在,图片引用的路径不匹配等。
315 0
|
Python
将8位的tif图片改为png图片
将8位的tif图片改为png图片
215 0