RichEdit 中插入图象 (Delphi)

unit InsRich;

interface

uses
  SysUtils, Windows, Messages, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ActiveX, ComCtrls;

const
  REO_CP_SELECTION   = ULONG(-1);
  REO_BELOWBASELINE  = $00000002;
  REO_RESIZEABLE     = $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;
    cp: ULONG;
    clsid: TCLSID;
    pOleObj: IOleObject;
    pstg: IStorage;
    sizel: TSize;
    dvAspect: Longint;
    dwFlags: DWORD;
    dwUser: DWORD;
  end;
  TReObject = _ReObject;

  TCharRange = record
    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;

function InsertBitmap(Editor: TRichEdit; BmpFile: string): Boolean;

implementation

function InsertBitmap(Editor: TRichEdit; BmpFile: string): Boolean;
var
  FRTF: IRichEditOle;
  FOle: IOleObject;
  FormatEtc: tagFormatETC;
  FStorage: ISTORAGE;
  FClientSite: IOleClientSite;
  FLockBytes: ILockBytes;
  ReObject: TReObject;
  xt: TGUID;
  FTemp: IUnknown;
begin
  Result := False;  
  if not FileExists(BmpFile) then
    Exit;

  try
    SendMessage(Editor.Handle, em_GetOleInterFace, 0, Longint(@FRTF));
    if not Assigned(FRTF) then
      Exit;
    if CreateILockBytesOnHGlobal(0, true, FLockBytes) <> S_OK then
      Exit;
    if StgCreateDocfileOnILockBytes(FLockBytes, STGM_SHARE_EXCLUSIVE or STGM_CREATE or STGM_READWRITE, 0, FStorage) <> S_OK then
      Exit;
    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(BmpFile)), IID_IUnknown, 0,@FormatEtc, FClientSite, FStorage,FOle) <> S_OK then
      Exit;
    FTemp := FOle;
    FTemp.QueryInterface(IID_IOleObject, FOle);
    OleSetContainedObject(FOle, true);
    ReObject.cbStruct:=SizeOf(TReObject);
    FOle.GetUserClassID(xt);
    ReObject.clsid := xt;
    ReObject.cp := ULONG(REO_CP_SELECTION);
    ReObject.dvaspect := DVASPECT_CONTENT;
    ReObject.dwFlags := ULONG(REO_STATIC) 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);
  finally
    FRTF := nil;
    FOle := nil;
  end;

  Result := True;
end;

end.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
不用第三方控件,让richEdit支持图片与表格换行 DELPHI 6 提供的RICHEDIT是1.0,并不支持图片,对复杂表格也会乱成一团,如何在DELPHI原有控件的基础上做少量修改,使之支持显示图片与正确显示表格,其实只需要几行就好了,方法如下: 找到richEdit控件所在单元ComCtrls.pas (在SOURCE\VCL) //第一步 procedure TCustomRichEdit.CreateParams(var Params: TCreateParams); const // RichEditModuleName = 'RICHED32.DLL';//原来语句 // RichEditClassName = 'RICHEDIT'; //原来语句 RichEditModuleName = 'Msftedit.dll'; //改后语句 RichEditClassName = 'RichEdit50W'; //改后语句 //第二步 procedure TCustomRichEdit.CreateWnd; .... //加入一行要放在 CreateWnd 因为此时 HANDLE已建立 Perform(EM_SetOleCallback, 0, Longint(TRichEditOleCallback.Create(TRichEdit(self)) as IRichEditOleCallback)) ; //第三步 procedure TCustomRichEdit.WMRButtonUp(var Message: TWMRButtonUp); begin inherited; // RichEd20 does not pass the WM_RBUTTONUP message to defwndproc, // so we get no WM_CONTEXTMENU message. Simulate message here. // if Win32MajorVersion < 5 then //是原有1.0的要去掉 Perform(WM_CONTEXTMENU, Handle, LParam(PointToSmallPoint( ClientToScreen(SmallPointToPoint(Message.Pos))))); end; //第四步 procedure TRichEditStrings.Insert(Index: Integer; const S: string); .... //要去掉后面两名 // 1.0 uses, 2.0 will error happened 2011 // if RichEdit.SelStart (Selection.cpMax + Length(Str)) then //是原有1.0的要去掉 // raise EOutOfResources.Create(sRichEditInsertError); //是原有1.0的要去掉

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值