{ ******************************************** } { UEditHost ver 1.0 (Oct. 10, 2003) } { } { For Delphi 4, 5 and 6 } { } { Copyright (C) 1999-2003, Kurt Senfer. } { All Rights Reserved. } { } { Support@ks.helpware.net } { } { Documentation and updated versions: } { } { http://KS.helpware.net } { } { ******************************************** } { This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } unit UEditHost; //this unit implements a combined IHTMLEditHost & IHTMLEditHost2 interface. interface uses windows, Classes, //kt mshtml_tlb, MSHTML_EWB, EmbeddedED; type tagRECT = TRect; //kt //this is only declared if IE 6 is imported to mshtml_tlb IHTMLEditHost2 = interface(IHTMLEditHost) ['{3050F848-98B5-11CF-BB82-00AA00BDCE0D}'] function PreDrag: HResult; stdcall; end; TEditHost = class(TInterfacedObject, IHTMLEditHost, IHTMLEditHost2) private function SnapRect(const pIElement: IHTMLElement; var prcNew: tagRECT; eHandle: _ELEMENT_CORNER): HResult; stdcall; function PreDrag: HResult; stdcall; public FSnapEnabled: Boolean; FGridX: Integer; FGridY: Integer; //kt FExtSnapRect: TSnapRect; FOnPreDrag: TNotifyEventEx; constructor Create(Ovner: TEmbeddedED); procedure BeforeDestruction; override; function QueryService(const rsid, iid: TGuid; out Obj): HResult; end; implementation uses ActiveX, ComObj, IeConst; const SID_SHTMLEditHost: TGUID = '{3050F6A0-98B5-11CF-BB82-00AA00BDCE0B}'; //------------------------------------------------------------------------------ function TEditHost.QueryService(const rsid, iid: TGuid; out Obj): HResult; const IID_IHTMLEditHost2: TGUID = '{3050F848-98B5-11CF-BB82-00AA00BDCE0D}'; begin //asm int 3 end; //trap //we only come heir if TEmbeddedED is queryed for SID_SHTMLEDitHost //MSHTML asks either for a IHTMLEditHost or a IHTMLEditHost2 if IsEqualGUID(iid, IID_IHTMLEditHost2) then IUnknown(obj) := self as IHTMLEditHost2 //new in IE 6 else IUnknown(obj) := self as IHTMLEditHost; Result := S_OK; end; //------------------------------------------------------------------------------ function TEditHost.PreDrag: HResult; stdcall; var Cancel: Boolean; begin //asm int 3 end; //trap result := S_OK; if assigned(FOnPreDrag) then begin FOnPreDrag(Self, Cancel); if not Cancel then result := S_FALSE; end; end; //------------------------------------------------------------------------------ function TEditHost.SnapRect(const pIElement: IHTMLElement; var prcNew: tagRECT; eHandle: _ELEMENT_CORNER): HResult; stdcall; //------------------------------------------------------------- function GetNextAviablePoint(aPoint, GridSpacing, Offset: integer): Integer; begin result := ((aPoint + (GridSpacing div 2)) div GridSpacing) * GridSpacing + Offset; end; //------------------------------------------------------------- var Width : Integer; Height: Integer; aElement: IHTMLElement2; P: tagPOINT; Pr: tagRECT; aDisplays: IDisplayServices; aevent: IHTMLEventObj; begin //asm int 3 end; //trap { //kt If assigned(FExtSnapRect) then begin FExtSnapRect(Self, pIElement, prcNew, eHandle, Result); exit; end; } //dont snap if not enabled or the Control key is down if (not FSnapEnabled) or (GetAsyncKeyState(VK_CONTROL) < 0) then begin result := S_FALSE; //do default handling exit; end; result := S_OK; case eHandle of ELEMENT_CORNER_NONE: // Code for moving the element begin Width := prcNew.right - prcNew.left; Height := prcNew.bottom - prcNew.top; prcNew.top := GetNextAviablePoint(prcNew.top, FGridY, -2); prcNew.left := GetNextAviablePoint(prcNew.left, FGridX, -2); prcNew.bottom := prcNew.top + Height; prcNew.right := prcNew.left + Width; end; ELEMENT_CORNER_TOP: // Code for resizing the element prcNew.top := GetNextAviablePoint(prcNew.top, FGridY, -2); ELEMENT_CORNER_LEFT: // Code for resizing the element prcNew.left := GetNextAviablePoint(prcNew.left, FGridX, -2); ELEMENT_CORNER_BOTTOM: // Code for resizing the element prcNew.bottom := GetNextAviablePoint(prcNew.bottom, FGridY, 1); ELEMENT_CORNER_RIGHT: // Code for resizing the element prcNew.right := GetNextAviablePoint(prcNew.right, FGridX, 1); ELEMENT_CORNER_TOPLEFT: // Code for resizing the element begin prcNew.top := GetNextAviablePoint(prcNew.top, FGridY, -2); prcNew.left := GetNextAviablePoint(prcNew.left, FGridX, -2); end; ELEMENT_CORNER_TOPRIGHT: // Code for resizing the element begin prcNew.top := GetNextAviablePoint(prcNew.top, FGridY, -2); prcNew.right := GetNextAviablePoint(prcNew.right, FGridX, 1); end; ELEMENT_CORNER_BOTTOMLEFT: // Code for resizing the element begin prcNew.left := GetNextAviablePoint(prcNew.left, FGridX, -2); prcNew.bottom := GetNextAviablePoint(prcNew.bottom, FGridY, 1); end; ELEMENT_CORNER_BOTTOMRIGHT: // Code for resizing the element begin prcNew.bottom := GetNextAviablePoint(prcNew.bottom, FGridY, 1); prcNew.right := GetNextAviablePoint(prcNew.right, FGridX, 1); end; end; end; //------------------------------------------------------------------------------ constructor TEditHost.Create(Ovner: TEmbeddedED); begin Inherited Create; _AddRef; //dont die automatically end; //------------------------------------------------------------------------------ procedure TEditHost.BeforeDestruction; begin FRefCount := 0; end; //------------------------------------------------------------------------------ end.