unit RichEx;
{ 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(hRichEdit: THandle; const FileName: string): Boolean; overload; function InsertBitmap(hRichEdit: THandle; Bitmap: TBitmap): Boolean; overload; function InsertGif(hRichEdit: 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;
|
请发表评论