zoukankan      html  css  js  c++  java
  • 向TRichEdit插入图片的单元

    很简单, 就3个函数, 直接看代码吧

    unit RichEditBmp;
    
    {
     2005-03-04 LiChengbin
     Added:
       Insert bitmap or gif into RichEdit controls from source file.
    
     2005-01-31 LiChengbin
     Usage:
       Insert bitmap into RichEdit controls by IRichEditOle interface and
       implementation of IDataObject interface.
    
     Example:
       InsertBitmap(RichEdit1.Handle, Image1.Picture.Bitmap);
    }
    
    interface
    
    uses
      Windows, Messages, Graphics, ActiveX, ComObj;
    
    const
    
    // Flags to specify which interfaces should be returned in the structure above
     REO_GETOBJ_NO_INTERFACES = $00000000;
     REO_GETOBJ_POLEOBJ = $00000001;
     REO_GETOBJ_PSTG = $00000002;
     REO_GETOBJ_POLESITE = $00000004;
     REO_GETOBJ_ALL_INTERFACES = $00000007;
    
    // Place object at selection
     REO_CP_SELECTION = $FFFFFFFF;
    
    // Use character position to specify object instead of index
     REO_IOB_SELECTION = $FFFFFFFF;
     REO_IOB_USE_CP  = $FFFFFFFF;
    
    // Object flags
     REO_NULL = $00000000; // No flags
     REO_READWRITEMASK = $0000003F; // Mask out RO bits
     REO_DONTNEEDPALETTE = $00000020; // Object doesn't need palette
     REO_BLANK = $00000010; // Object is blank
     REO_DYNAMICSIZE = $00000008; // Object defines size always
     REO_INVERTEDSELECT = $00000004; // Object drawn all inverted if sel
     REO_BELOWBASELINE = $00000002; // Object sits below the baseline
     REO_RESIZABLE = $00000001; // Object may be resized
     REO_LINK = $80000000; // Object is a link (RO)
     REO_STATIC = $40000000; // Object is static (RO)
     REO_SELECTED = $08000000; // Object selected (RO)
     REO_OPEN = $04000000; // Object open in its server (RO)
     REO_INPLACEACTIVE = $02000000; // Object in place active (RO)
     REO_HILITED = $01000000; // Object is to be hilited (RO)
     REO_LINKAVAILABLE = $00800000; // Link believed available (RO)
     REO_GETMETAFILE = $00400000; // Object requires metafile (RO)
    
    // flags for IRichEditOle::GetClipboardData(),
    // IRichEditOleCallback::GetClipboardData() and
    // IRichEditOleCallback::QueryAcceptData()
     RECO_PASTE = $00000000; // paste from clipboard
     RECO_DROP = $00000001; // drop
     RECO_COPY = $00000002; // copy to the clipboard
     RECO_CUT = $00000003; // cut to the clipboard
     RECO_DRAG = $00000004; // drag
    
     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));
    
     IID_IGifAnimator: TGUID = '{0C1CF2DF-05A3-4FEF-8CD4-F5CFC4355A16}';
     CLASS_GifAnimator: TGUID = '{06ADA938-0FB0-4BC0-B19B-0A38AB17F182}';
    
    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;
    
     TCharRange = record
       cpMin: Integer;
       cpMax: Integer;
     end;
    
     TFormatRange = record
       hdc: Integer;
       hdcTarget: Integer;
       rectRegion: TRect;
       rectPage: TRect;
       chrg: TCharRange;
     end;
    
     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;
    
    // *********************************************************************//
    // Interface: IGifAnimator
    // Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable
    // GUID:      {0C1CF2DF-05A3-4FEF-8CD4-F5CFC4355A16}
    // *********************************************************************//
     IGifAnimator = interface(IDispatch)
       ['{0C1CF2DF-05A3-4FEF-8CD4-F5CFC4355A16}']
       procedure LoadFromFile(const FileName: WideString); safecall;
       function  TriggerFrameChange: WordBool; safecall;
       function  GetFilePath: WideString; safecall;
       procedure ShowText(const Text: WideString); safecall;
     end;
    
    // *********************************************************************//
    // DispIntf:  IGifAnimatorDisp
    // Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable
    // GUID:      {0C1CF2DF-05A3-4FEF-8CD4-F5CFC4355A16}
    // *********************************************************************//
     IGifAnimatorDisp = dispinterface
       ['{0C1CF2DF-05A3-4FEF-8CD4-F5CFC4355A16}']
       procedure LoadFromFile(const FileName: WideString); dispid 1;
       function  TriggerFrameChange: WordBool; dispid 2;
       function  GetFilePath: WideString; dispid 3;
       procedure ShowText(const Text: WideString); dispid 4;
     end;
    
     TBitmapOle = class(TInterfacedObject, IDataObject)
     private
       FStgm: TStgMedium;
       FFmEtc: TFormatEtc;
    
       procedure SetBitmap(hBitmap: HBITMAP);
       procedure GetOleObject(OleSite: IOleClientSite; Storage: IStorage;
         var OleObject: IOleObject);
     public
       { ======================================================================= }
       { Implementation of IDataObject interface }
       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;
       { ======================================================================= }
     end;
    
    function InsertBitmap(AREHandle: THandle; const FileName: string): Boolean; overload;
    function InsertBitmap(AREHandle: THandle; Bitmap: TBitmap): Boolean; overload;
    function InsertGif(AREHandle: THandle; const FileName: string): Boolean;
    
    implementation
    
    function GetRichEditOle(hRichEdit: THandle): IRichEditOle;
    begin
     SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, Longint(@Result));
    end;
    
    function GetImage(Bitmap: TBitmap): HBITMAP;
    var
    Dest: HBitmap;
    DC, MemDC: HDC;
     OldBitmap: HBITMAP;
    begin
     DC := GetDC(0);
     MemDC := CreateCompatibleDC(DC);
     try
       Dest := CreateCompatibleBitmap(DC, Bitmap.Width, Bitmap.Height);
       OldBitmap := SelectObject(MemDC, Dest);
       BitBlt(MemDC, 0, 0, Bitmap.Width, Bitmap.Height, Bitmap.Canvas.Handle, 0, 0, SRCCOPY);
       SelectObject(MemDC, OldBitmap);
     finally
       DeleteDC(MemDC);
       ReleaseDC(0, DC);
     end;
    Result := Dest;
    end;
    
    function TBitmapOle.GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium): HResult; stdcall;
    begin
     medium.tymed := TYMED_GDI;
     medium.hBitmap := OleDuplicateData(FStgm.hBitmap, CF_BITMAP, 0);
     medium.unkForRelease := nil;
     if medium.hBitmap = 0 then
       Result := E_HANDLE
     else
       Result := S_OK;
    end;
    
    function TBitmapOle.GetDataHere(const formatetc: TFormatEtc; out medium: TStgMedium): HResult; stdcall;
    begin
     Result := E_NOTIMPL;
    end;
    
    function TBitmapOle.QueryGetData(const formatetc: TFormatEtc): HResult; stdcall;
    begin
     Result := E_NOTIMPL;
    end;
    
    function TBitmapOle.GetCanonicalFormatEtc(const formatetc: TFormatEtc;
     out formatetcOut: TFormatEtc): HResult; stdcall;
    begin
     Result := E_NOTIMPL;
    end;
    
    function TBitmapOle.SetData(const formatetc: TFormatEtc; var medium: TStgMedium;
     fRelease: BOOL): HResult; stdcall;
    begin
     FStgm  := medium;
     FFmEtc := formatetc;
     Result := S_OK;
    end;
    
    function TBitmapOle.EnumFormatEtc(dwDirection: Longint; out enumFormatEtc:
     IEnumFormatEtc): HResult; stdcall;
    begin
     Result := E_NOTIMPL;
    end;
    
    function TBitmapOle.DAdvise(const formatetc: TFormatEtc; advf: Longint;
     const advSink: IAdviseSink; out dwConnection: Longint): HResult; stdcall;
    begin
     Result := E_NOTIMPL;
    end;
    
    function TBitmapOle.DUnadvise(dwConnection: Longint): HResult; stdcall;
    begin
     Result := E_NOTIMPL;
    end;
    
    function TBitmapOle.EnumDAdvise(out enumAdvise: IEnumStatData): HResult; stdcall;
    begin
     Result := E_NOTIMPL;
    end;
    
    procedure TBitmapOle.GetOleObject(OleSite: IOleClientSite;
     Storage: IStorage; var OleObject: IOleObject);
    begin
     OleCheck(OleCreateStaticFromData(Self, IID_IOleObject,
       OLERENDER_FORMAT, @FFmEtc, OleSite, Storage, OleObject));
    end;
    
    procedure TBitmapOle.SetBitmap(hBitmap: HBITMAP);
    var
     Stgm: TStgMedium;
     FmEtc: TFormatEtc;
    begin
     Stgm.tymed := TYMED_GDI;            // Storage medium = HBITMAP handle
     Stgm.hBitmap := hBitmap;
     Stgm.unkForRelease := nil;
    
     FmEtc.cfFormat := CF_BITMAP;        // Clipboard format = CF_BITMAP
     FmEtc.ptd := nil;                   // Target Device = Screen
     FmEtc.dwAspect := DVASPECT_CONTENT; // Level of detail = Full content
     FmEtc.lindex := -1;                 // Index = Not applicaple
     FmEtc.tymed := TYMED_GDI;           // Storage medium = HBITMAP handle
    
     SetData(FmEtc, Stgm, True);
    end;
    
    function InsertBitmap(AREHandle: THandle; const FileName: string): Boolean;
    var
     ReOle: IRichEditOle;
     OleSite: IOleClientSite;
     Storage: IStorage;
     LockBytes: ILockBytes;
     OleObject: IOleObject;
     ReObj: TReObject;
     TempOle: IUnknown;
     FormatEtc: TFormatEtc;
    begin
     ReOle := GetRichEditOle(AREHandle);
     Assert(ReOle <> nil, 'RichEditOle is null!');
    
     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!');
    
     OleCheck(OleCreateFromFile(GUID_NULL, PWideChar(WideString(FileName)),
       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);
     ReObj.cbStruct := Sizeof(ReObj);
     OleCheck(OleObject.GetUserClassID(ReObj.clsid));
     ReObj.cp := REO_CP_SELECTION;
     ReObj.dvaspect := DVASPECT_CONTENT;
     ReObj.poleobj := OleObject;
     ReObj.polesite := OleSite;
     ReObj.pstg := Storage;
     ReObj.dwUser := 0;
     ReObj.sizel.cx := 0;
     ReObj.sizel.cy := 0;
    
     ReOle.InsertObject(ReObj);
     Result := True;
    end;
    
    function InsertBitmap(AREHandle: THandle; Bitmap: TBitmap): Boolean;
    var
      nIRE: IRichEditOle;
      nBMP: TBitmapOle;
      nIOleSite: IOleClientSite;
      nIStorage: IStorage;
      nILockBytes: ILockBytes;
      nIOleObject: IOleObject;
      nREObj: TReObject;
    begin
      nIRE := GetRichEditOle(AREHandle);
      Assert(nIRE <> nil, 'RichEditOle is null');
      nBMP := TBitmapOle.Create;
      try
        nBMP.SetBitmap(GetImage(Bitmap));
        nIRE.GetClientSite(nIOleSite);
    
        OleCheck(CreateILockBytesOnHGlobal(0, True, nILockBytes));
        Assert(nILockBytes <> nil, 'LockBytes is null');
    
        OleCheck(StgCreateDocfileOnILockBytes(nILockBytes,
        STGM_SHARE_EXCLUSIVE or STGM_CREATE or STGM_READWRITE, 0, nIStorage));
        Assert(nIStorage <> nil, 'Storage is null');
    
        nBMP.GetOleObject(nIOleSite, nIStorage, nIOleObject);
        OleCheck(OleSetContainedObject(nIOleObject, True));
    
        FillChar(nREObj, Sizeof(nREObj), 0);
        nREObj.cbStruct := Sizeof(nREObj);
        OleCheck(nIOleObject.GetUserClassID(nREObj.clsid));
        nREObj.cp := REO_CP_SELECTION;
        nREObj.dvaspect := DVASPECT_CONTENT;
        nREObj.poleobj := nIOleObject;
        nREObj.polesite := nIOleSite;
        nREObj.pstg := nIStorage;
    
        nIRE.InsertObject(nREObj);
        Result := True;
      finally
        nBMP.Free;
      end;
    end;
    
    function InsertGif(AREHandle: THandle; const FileName: string): Boolean;
    var
     ReOle: IRichEditOle;
     OleSite: IOleClientSite;
     Storage: IStorage;
     LockBytes: ILockBytes;
     OleObject: IOleObject;
     ReObj: TReObject;
     Animator: IGifAnimator;
    begin
     ReOle := GetRichEditOle(AREHandle);
     Assert(ReOle <> nil, 'RichEditOle is null!');
     Assert(FileName <> '', 'FileName is null!');
    
     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!');
    
     Animator := IUnknown(CreateComObject(CLASS_GifAnimator)) as IGifAnimator;
     Animator.LoadFromFile(PWideChar(WideString(FileName)));
     OleCheck(Animator.QueryInterface(IID_IOleObject, OleObject));
    
     OleCheck(OleSetContainedObject(OleObject, True));
     FillChar(ReObj, Sizeof(ReObj), 0);
     ReObj.cbStruct := Sizeof(ReObj);
     OleCheck(OleObject.GetUserClassID(ReObj.clsid));
     ReObj.cp := REO_CP_SELECTION;
     ReObj.dvaspect := DVASPECT_CONTENT;
     ReObj.dwFlags := REO_STATIC or REO_BELOWBASELINE;
     ReObj.dwUser := 0;
     ReObj.poleobj := OleObject;
     ReObj.polesite := OleSite;
     ReObj.pstg := Storage;
     ReObj.sizel.cx := 0;
     ReObj.sizel.cy := 0;
    
     ReOle.InsertObject(ReObj);
     Result := True;
    end;
    
    end.
  • 相关阅读:
    web 学习资源整理
    CodeSmith 学习资料收集
    常用 T_SQL 语句
    SQL Server 2000查询分析器自定义查询快捷键
    插入标识列 identity_insert
    c# 上传FTP文件
    (.Net 3.5Sp1)WebForm使用System.Web.Routing
    SPQuery.ViewAttributes
    ChatterBot之linux下安装mongodb 02
    linux端口开放指定端口的两种方法
  • 原文地址:https://www.cnblogs.com/lzl_17948876/p/7723535.html
Copyright © 2011-2022 走看看