using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; namespace onlyconnect { /// /// Implements the site on which mshtml is hosted /// /// public class HtmlSite : IDisposable, IOleClientSite, IOleContainer, IDocHostUIHandler, IOleInPlaceFrame, IOleInPlaceSite, IOleInPlaceSiteEx, IOleDocumentSite, IAdviseSink, IHTMLEditDesigner, IServiceProvider, IDocHostShowUI, IOleInPlaceUIWindow, HTMLDocumentEvents2, IPropertyNotifySink { HtmlEditor container; IOleObject m_document; internal IOleDocumentView view; IOleInPlaceActiveObject activeObject; int iAdviseCookie = 0; int iEventsCookie = 0; internal int iPropertyNotifyCookie = 0; internal IConnectionPoint icp; IntPtr m_docHwnd = IntPtr.Zero; internal bool mFullyActive = false; internal CSnap snapper; ~HtmlSite() { Dispose(); } public void Dispose() { //doc should already be closed, this //is defensive this.CloseDocument(); } [DispId(dispids.DISPID_AMBIENT_DLCONTROL)] public int setFlags() { //This determines which features are enabled in the editor if (this.container.mEnableActiveContent) { return (int)constants.DLCTL_DLIMAGES | (int)constants.DLCTL_VIDEOS | (int)constants.DLCTL_BGSOUNDS | 0; } else { return (int)constants.DLCTL_NO_SCRIPTS | (int)constants.DLCTL_NO_JAVA | (int)constants.DLCTL_NO_DLACTIVEXCTLS | (int)constants.DLCTL_NO_RUNACTIVEXCTLS | (int)constants.DLCTL_SILENT | (int)constants.DLCTL_DLIMAGES | 0; } } public HtmlSite(HtmlEditor container) { if ((container == null) || (container.IsHandleCreated == false)) throw new ArgumentException(); this.container = container; container.Resize += new EventHandler(this.Container_Resize); } public Object Document { get { return m_document; } } public IntPtr DocumentHandle { get { return m_docHwnd; } } public void CreateDocument() { Debug.Assert(m_document == null, "Must call Close before recreating."); Boolean created = false; try { m_document = (IOleObject)new HTMLDocument(); int iRetval; iRetval = win32.OleRun(m_document); iRetval = m_document.SetClientSite(this); Debug.Assert(iRetval == HRESULT.S_OK, "SetClientSite failed"); // Lock the object in memory iRetval = win32.OleLockRunning(m_document, true, false); m_document.SetHostNames("HtmlEditor", "HtmlEditor"); m_document.Advise(this, out iAdviseCookie); //hook up HTMLDocumentEvents2 Guid guid = new Guid("3050f613-98b5-11cf-bb82-00aa00bdce0b"); IConnectionPointContainer icpc = (IConnectionPointContainer)m_document; icpc.FindConnectionPoint(ref guid, out icp); icp.Advise(this, out iEventsCookie); created = true; } finally { if (created == false) m_document = null; } } internal void SetPropertyNotifyEvents() { //hook up PropertyNotify events //get IPropertyNotifySink interface Guid g = new Guid("9BFBBC02-EFF1-101A-84ED-00AA00341D07"); IConnectionPointContainer icpc = (IConnectionPointContainer)container.Document; icpc.FindConnectionPoint(ref g, out icp); //pass a pointer to the host to the connection point icp.Advise(this, out iPropertyNotifyCookie); } public void ActivateDocument() { if (m_document == null) return; if (!container.Visible) return; RECT rect = new RECT(); win32.GetClientRect(container.Handle, rect); int iRetVal = m_document.DoVerb(OLEIVERB.UIACTIVATE, IntPtr.Zero, this, 0, container.Handle, rect); if (iRetVal == 0) { this.container.bNeedsActivation = false; } } public void CloseDocument() { try { container.releaseWndProc(); container.Resize -= new EventHandler(this.Container_Resize); if (m_document == null) return; try { //this may raise an exception, however it does work and must //be called if (view != null) { view.Show(-1); view.UIActivate(-1); view.SetInPlaceSite(null); view.CloseView(0); } } catch (Exception e) { Debug.WriteLine("CloseView raised exception: " + e.Message); } try { //this could raise an exception too, but it must be called m_document.Close((int)tagOLECLOSE.OLECLOSE_NOSAVE); } catch (Exception e) { Debug.WriteLine("Close document raised exception: " + e.Message); } m_document.SetClientSite(null); win32.OleLockRunning(m_document, false, false); if (this.iAdviseCookie != 0) { m_document.Unadvise(this.iAdviseCookie); } if (this.iEventsCookie != 0) { m_document.Unadvise(this.iEventsCookie); } if (this.iPropertyNotifyCookie != 0) { m_document.Unadvise(this.iPropertyNotifyCookie); } if (container.changeCookie != 0) { ((IMarkupContainer2)m_document).UnRegisterForDirtyRange(container.changeCookie); container.changeCookie = 0; } //release COM objects int RefCount = 0; if (m_document != null) do { RefCount = Marshal.ReleaseComObject(m_document); } while (RefCount > 0); if (view != null) do { RefCount = Marshal.ReleaseComObject(view); } while (RefCount > 0); if (activeObject != null) do { RefCount = Marshal.ReleaseComObject(activeObject); } while (RefCount > 0); if (snapper != null) { IntPtr ppinterface = Marshal.GetComInterfaceForObject(snapper, typeof(IHTMLEditHost)); if (ppinterface != null) { do { RefCount = Marshal.Release(ppinterface); } while (RefCount > 0); } snapper = null; } m_document = null; view = null; activeObject = null; container.mHtmlDoc = null; container.mDocHTML = null; } catch (Exception e) { Debug.WriteLine("CloseDocument raised exception: " + e.Message); } } void Container_Resize(Object src, EventArgs e) { if (view == null) return; RECT rect = new RECT(); win32.GetClientRect(container.Handle, rect); view.SetRect(rect); } public Boolean CallTranslateAccelerator(MSG msg) { //returns true if Mshtml handled the message if (activeObject != null) if (activeObject.TranslateAccelerator(msg) != HRESULT.S_FALSE) return true; return false; } #region IOleClientSite // IOleClientSite public int SaveObject() { return HRESULT.S_OK; } public int GetMoniker(uint dwAssign, uint dwWhichMoniker, out Object ppmk) { ppmk = null; return HRESULT.E_NOTIMPL; } public int GetContainer(out IOleContainer ppContainer) { ppContainer = (IOleContainer)this; return HRESULT.S_OK; } public int ShowObject() { return HRESULT.S_OK; } public int OnShowWindow(int fShow) { return HRESULT.S_OK; } public int RequestNewObjectLayout() { return HRESULT.S_OK; } #endregion #region IOleContainer // IOleContainer /* * used to enumerate objects in a compound document * or lock a container in the running state. * * Container and object applications both implement this interface * */ public int ParseDisplayName(Object pbc, String pszDisplayName, int[] pchEaten, Object[] ppmkOut) { return HRESULT.E_NOTIMPL; } public int EnumObjects(uint grfFlags, Object[] ppenum) { return HRESULT.E_NOTIMPL; } public int LockContainer(bool fLock) { return HRESULT.S_OK; } #endregion #region IOleDocumentSite // IOleDocumentSite Implementation public int ActivateMe(IOleDocumentView pViewToActivate) { Debug.Assert(pViewToActivate != null, "The view to activate was null"); if (pViewToActivate == null) return HRESULT.E_INVALIDARG; RECT rect = new RECT(); win32.GetClientRect(container.Handle, rect); view = pViewToActivate; int iResult = view.SetInPlaceSite((IOleInPlaceSite)this); iResult = view.UIActivate(1); iResult = view.SetRect(rect); int iShow = 1; iResult = view.Show(iShow); //1 is a boolean for True return HRESULT.S_OK; } #endregion #region IOleWindow //IOleWindow implementation public int GetWindow(ref IntPtr hwnd) { hwnd = IntPtr.Zero; if (this.container != null) { hwnd = this.container.Handle; return HRESULT.S_OK; } else { return HRESULT.E_FAIL; } } #endregion #region IOleInPlaceSite // IOleInPlaceSite Implementation public int ContextSensitiveHelp(bool fEnterMode) { return HRESULT.E_NOTIMPL; } public int CanInPlaceActivate() { return HRESULT.S_OK; } public int OnInPlaceActivate() { return HRESULT.S_OK; } public int OnUIActivate() { //Debug.WriteLine("RequestUIActivate"); //return HESULT.S_FALSE prevents focus grab //but means no caret //return HRESULT.S_FALSE; return HRESULT.S_OK; } public int GetWindowContext(out IOleInPlaceFrame ppFrame, out IOleInPlaceUIWindow ppDoc, RECT lprcPosRect, RECT lprcClipRect, tagOIFI lpFrameInfo) { ppDoc = null; //set to null because same as Frame window ppFrame = (IOleInPlaceFrame)this; if (lprcPosRect != null) { win32.GetClientRect(container.Handle, lprcPosRect); } if (lprcClipRect != null) { win32.GetClientRect(container.Handle, lprcClipRect); } //lpFrameInfo.cb = Marshal.SizeOf(typeof(tagOIFI)); //This value is set by the caller lpFrameInfo.fMDIApp = 0; lpFrameInfo.hwndFrame = container.Handle; lpFrameInfo.hAccel = IntPtr.Zero; lpFrameInfo.cAccelEntries = 0; return HRESULT.S_OK; } public int Scroll(tagSIZE scrollExtant) { return HRESULT.E_NOTIMPL; } public int OnUIDeactivate(int fUndoable) { return HRESULT.S_OK; } public int OnInPlaceDeactivate() { activeObject = null; return HRESULT.S_OK; } public int DiscardUndoState() { return HRESULT.E_NOTIMPL; } public int DeactivateAndUndo() { return HRESULT.S_OK; } public int OnPosRectChange(RECT lprcPosRect) { return HRESULT.S_OK; } #endregion #region IOLEInPlaceSiteEx // IOLEInPlaceSiteEx public int OnInPlaceActivateEx(out bool pfNoRedraw, int dwFlags) { pfNoRedraw = false; //false means object needs to redraw return HRESULT.S_OK; } public int OnInPlaceDeactivateEx(bool fNoRedraw) { if (!fNoRedraw) { //redraw container this.container.Invalidate(); } return HRESULT.S_OK; } public int RequestUIActivate() { //return S_FALSE to prevent activation //solves focus problems, but no editing // Debug.WriteLine("RequestUIActivate"); if (this.container.mAllowActivation) { return HRESULT.S_OK; } else { return HRESULT.S_FALSE; } } #endregion #region IOLEInPlaceUIWindow // IOLEInPlaceUIWindow public int GetBorder(RECT lprectBorder) { return HRESULT.E_NOTIMPL; } public int RequestBorderSpace(RECT pborderwidths) { return HRESULT.E_NOTIMPL; } public int SetBorderSpace(RECT pborderwidths) { return HRESULT.E_NOTIMPL; } #endregion #region iOleinPlaceFrame // IOleInPlaceFrame Implementation public int SetActiveObject(IOleInPlaceActiveObject pActiveObject, String pszObjName) { try { if (pActiveObject == null) { container.releaseWndProc(); if (this.activeObject != null) { Marshal.ReleaseComObject(this.activeObject); } this.activeObject = null; this.m_docHwnd = IntPtr.Zero; this.mFullyActive = false; } else { this.activeObject = pActiveObject; this.m_docHwnd = new IntPtr(); pActiveObject.GetWindow(ref this.m_docHwnd); this.mFullyActive = true; //we have the handle to the doc so set up WndProc override container.setupWndProc(); } } catch (Exception e) { Debug.WriteLine("Exception: " + e.Message + e.StackTrace); } return HRESULT.S_OK; } public int InsertMenus(IntPtr hmenuShared, tagOleMenuGroupWidths lpMenuWidths) { return HRESULT.E_NOTIMPL; } public int SetMenu(IntPtr hmenuShared, IntPtr holemenu, IntPtr hwndActiveObject) { return HRESULT.E_NOTIMPL; } public int RemoveMenus(IntPtr hmenuShared) { return HRESULT.E_NOTIMPL; } public int SetStatusText(String pszStatusText) { return HRESULT.E_NOTIMPL; } public int TranslateAccelerator(MSG lpmsg, short wID) { return HRESULT.S_FALSE; } #endregion #region IDocHostUIHandler // IDocHostUIHandler Implementation public int ShowContextMenu(uint dwID, ref win32POINT ppt, [MarshalAs(UnmanagedType.IUnknown)] object pcmdtReserved, [MarshalAs(UnmanagedType.IDispatch)]object pdispReserved) { if (container.IsContextMenuEnabled) { if ( (container.ContextMenu != null) || (container.ContextMenuStrip != null) ) { //show the assigned ContextMenu System.Drawing.Point pt = new System.Drawing.Point(ppt.x, ppt.y); pt = container.PointToClient(pt); if (container.ContextMenuStrip != null) { container.ContextMenuStrip.Show(container, pt); } else { container.ContextMenu.Show(container, pt); } return HRESULT.S_OK; } else { //show the default IE ContextMenu Debug.WriteLine("Show context menu"); return HRESULT.S_FALSE; } } else { return HRESULT.S_OK; } } public int GetHostInfo_(DOCHOSTUIINFO info) { //Debug.WriteLine("GetHostInfo"); info.cbSize = Marshal.SizeOf(typeof(DOCHOSTUIINFO)); info.dwDoubleClick = DOCHOSTUIDBLCLICK.DEFAULT; info.dwFlags = (int)(DOCHOSTUIFLAG.NO3DBORDER | DOCHOSTUIFLAG.ENABLE_INPLACE_NAVIGATION | DOCHOSTUIFLAG.DISABLE_SCRIPT_INACTIVE | DOCHOSTUIFLAG.FLAT_SCROLLBAR); info.dwReserved1 = 0; info.dwReserved2 = 0; return HRESULT.S_OK; } public int GetHostInfo(DOCHOSTUIINFO info) { //Debug.WriteLine("GetHostInfo"); int iFlags = (int)(DOCHOSTUIFLAG.NO3DBORDER | DOCHOSTUIFLAG.ENABLE_INPLACE_NAVIGATION | DOCHOSTUIFLAG.DISABLE_SCRIPT_INACTIVE); if (container.IsAutoCompleteEnabled) { iFlags = iFlags | (int)DOCHOSTUIFLAG.ENABLE_FORMS_AUTOCOMPLETE; iFlags = iFlags | (int)DOCHOSTUIFLAG.DISABLE_EDIT_NS_FIXUP; } else { iFlags = iFlags & ~(int)DOCHOSTUIFLAG.ENABLE_FORMS_AUTOCOMPLETE; } if (container.IsDivOnEnter) { iFlags = iFlags | (int)DOCHOSTUIFLAG.DIV_BLOCKDEFAULT; } else { iFlags = iFlags & ~(int)DOCHOSTUIFLAG.DIV_BLOCKDEFAULT; } if (container.IsScrollBarShown) { iFlags = iFlags & ~(int)DOCHOSTUIFLAG.SCROLL_NO; iFlags = iFlags | (int)DOCHOSTUIFLAG.FLAT_SCROLLBAR; } else { iFlags = iFlags | (int)DOCHOSTUIFLAG.SCROLL_NO; iFlags = iFlags & ~(int)DOCHOSTUIFLAG.FLAT_SCROLLBAR; } info.cbSize = Marshal.SizeOf(typeof(DOCHOSTUIINFO)); info.dwDoubleClick = DOCHOSTUIDBLCLICK.DEFAULT; info.dwFlags = iFlags; info.dwReserved1 = 0; info.dwReserved2 = 0; return HRESULT.S_OK; } public int EnableModeless(Boolean fEnable) { //Debug.WriteLine("EnableModeless"); return HRESULT.S_OK; } public int ShowUI(int dwID, IOleInPlaceActiveObject activeObject, IOleCommandTarget commandTarget, IOleInPlaceFrame frame, IOleInPlaceUIWindow doc) { //Debug.WriteLine("ShowUI"); return HRESULT.S_OK; } public int HideUI() { // Debug.WriteLine("HideUI"); return HRESULT.S_OK; } public int UpdateUI() { //return 0; //Debug.WriteLine("UpdateUI"); if (this.mFullyActive && (this.m_document != null) && (this.container.mDesignMode == true)) { try { HTMLDocument thisdoc = (HTMLDocument)m_document; //we need IDisplayServices to get the caret position IDisplayServices ds = (IDisplayServices)thisdoc; if (ds == null) { return HRESULT.S_OK; } IHTMLCaret caret; int iRetVal = ds.GetCaret(out caret); if (caret == null) { return HRESULT.S_OK; } win32POINT pt = new win32POINT(); caret.GetLocation(out pt, true); IHTMLDocument2 htmldoc = (IHTMLDocument2)this.m_document; IHTMLElement el = htmldoc.ElementFromPoint(pt.x, pt.y); if (el == null) { return HRESULT.S_OK; } container.mcurrentElement = el; container.InvokeUpdateUI(el); } catch (Exception e) { Debug.WriteLine(e.Message + e.StackTrace); } } //should always return S_OK unless error return HRESULT.S_OK; } public int OnDocWindowActivate(Boolean fActivate) { //Debug.WriteLine("OnDocWindowActivate"); return HRESULT.E_NOTIMPL; } public int OnFrameWindowActivate(Boolean fActivate) { //Debug.WriteLine("OnFrameWindowActivate"); return HRESULT.E_NOTIMPL; } public int ResizeBorder(RECT rect, IOleInPlaceUIWindow doc, bool fFrameWindow) { //Debug.WriteLine("ResizeBorder"); return HRESULT.E_NOTIMPL; } public int GetOptionKeyPath(out IntPtr pbstrKey, uint dw) { Debug.WriteLine("GetOptionKeyPath"); //use this to set your own app-specific preferences //eg pbstrKey = Marshal.StringToBSTR("Software\\myapp\\mysettings\\mshtml"); if ((this.container.OptionKeyPath == null) | (this.container.OptionKeyPath == String.Empty)) { pbstrKey = IntPtr.Zero; } else { pbstrKey = Marshal.StringToBSTR(this.container.OptionKeyPath); } return HRESULT.S_OK; } public int GetDropTarget(IOleDropTarget pDropTarget, out IOleDropTarget ppDropTarget) { // Debug.WriteLine("GetDropTarget"); ppDropTarget = null; return HRESULT.E_NOTIMPL; } public int GetExternal(out Object ppDispatch) { //Debug.WriteLine("GetExternal"); //Note from Jamie re the container is dead and the container's parent is null. //Wasn't handled before and was causing an error. if (container == null) { ppDispatch = null; return HRESULT.S_FALSE; } ppDispatch = container.Parent; return HRESULT.S_OK; //Note from Stephen Wood //1. GetExternal function. //Please change the following line //ppDispatch = container; //to //ppDispatch = container.Parent; //This allows the user to do something like window.external.MyFunction; //and get the function fired in the parent container. } public int TranslateAccelerator(MSG msg, ref Guid group, int nCmdID) { //illustrates how to trap and cancel an accelerator command // Debug.WriteLine("Translate Accel"); if (nCmdID == commandids.IDM_PASTE) { BeforePasteArgs e = new BeforePasteArgs(); container.OnBeforePaste(e); if (e.Cancel) { return HRESULT.S_OK; //cancel the paste } } return HRESULT.S_FALSE; } public int TranslateUrl(int dwTranslate, String strURLIn, out String pstrURLOut) { pstrURLOut = null; BeforeNavigateEventArgs e = new BeforeNavigateEventArgs(strURLIn); container.OnBeforeNavigate(e); bool translated = false; if (e.Cancel) { if (e.Target.StartsWith("javascript")) { pstrURLOut = null; } else { pstrURLOut = " "; } translated = true; } else if (e.NewTarget != e.Target) { pstrURLOut = e.NewTarget; translated = true; } //if scripts are disabled we can't navigate to javascript links else if ((e.Target.StartsWith("javascript")) & (!container.mEnableActiveContent)) { pstrURLOut = null; translated = true; } else if ((container.mLinksNewWindow)) { pstrURLOut = " "; //Load the link in an external window. System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo.FileName = e.NewTarget; p.Start(); translated = true; } if (e.Target.StartsWith("res://shdoclc")) { //error condition - redirect to about blank pstrURLOut = "about:blank"; translated = true; } if (translated) { return HRESULT.S_OK; } else { return HRESULT.S_FALSE; //False = not translated. } } public int FilterDataObject(IOleDataObject pDO, out IOleDataObject ppDORet) { // Debug.WriteLine("FilterDataObject"); ppDORet = null; return HRESULT.E_NOTIMPL; } #endregion #region IDocHostShowUI --show message boxes and Help ====================== //IDocHostShowUI /* * A host can supply mechanisms that will * show message boxes and Help * by implementing the IDocHostShowUI interface * */ public int ShowMessage(IntPtr hwnd, String lpStrText, String lpstrCaption, uint dwType, String lpHelpFile, uint dwHelpContext, IntPtr lpresult) { return HRESULT.E_NOTIMPL; } public int ShowHelp(IntPtr hwnd, String lpHelpFile, uint uCommand, uint dwData, win32POINT ptMouse, Object pDispatchObjectHit) { return HRESULT.E_NOTIMPL; } #endregion IDocHostShowUI ============= #region HTMLDocumentEvents2 //HTMLDocumentEvents2 implementation //return false to prevent mshtml further handling the event //return true for normal processing public bool onhelp(IHTMLEventObj o) { return true; } public bool onclick(IHTMLEventObj o) { return true; } public bool ondblclick(IHTMLEventObj o) { return true; } public void onkeydown(IHTMLEventObj o) { } public void onkeyup(IHTMLEventObj o) { } public bool onkeypress(IHTMLEventObj o) { return true; } public void onmousedown(IHTMLEventObj o) { } public void onmousemove(IHTMLEventObj o) { } public void onmouseup(IHTMLEventObj o) { } public void onmouseout(IHTMLEventObj o) { } public void onmouseover(IHTMLEventObj o) { } public void onreadystatechange(IHTMLEventObj o) { container.ReadyStateChangeActions(o); } public bool onbeforeupdate(IHTMLEventObj o) { return true; } public void onafterupdate(IHTMLEventObj o) { } public bool onrowexit(IHTMLEventObj o) { return true; } public void onrowenter(IHTMLEventObj o) { } public bool ondragstart(IHTMLEventObj o) { return true; } public bool onselectstart(IHTMLEventObj o) { return true; } public bool onerrorupdate(IHTMLEventObj o) { return true; } public bool oncontextmenu(IHTMLEventObj o) { return true; } public bool onstop(IHTMLEventObj o) { return true; } public void onrowsdelete(IHTMLEventObj o) { } public void onrowsinserted(IHTMLEventObj o) { } public void oncellchange(IHTMLEventObj o) { } public void onpropertychange(IHTMLEventObj o) { } public void ondatasetchanged(IHTMLEventObj o) { } public void ondataavailable(IHTMLEventObj o) { } public void ondatasetcomplete(IHTMLEventObj o) { } public void onbeforeeditfocus(IHTMLEventObj o) { } public void onselectionchange(IHTMLEventObj o) { } public bool oncontrolselect(IHTMLEventObj o) { return true; } public bool onmousewheel(IHTMLEventObj o) { return true; } public void onfocusin(IHTMLEventObj o) { } public void onfocusout(IHTMLEventObj o) { } public void onactivate(IHTMLEventObj o) { } public void ondeactivate(IHTMLEventObj o) { } public bool onbeforeactivate(IHTMLEventObj o) { return true; } public bool onbeforedeactivate(IHTMLEventObj o) { return true; } //IAdviseSink implementation public void OnClose() { } public void OnDataChange(object pStgmed, object pFormatEtc) { } public void OnRename(IMoniker pmk) { } public void OnSave() { } public void OnViewChange(int dwAspect, int lindex) { } #endregion #region IServiceProvider -- retrieve a service object ======================== //implementation of IServiceProvider /* * Defines a mechanism for retrieving a service object; * that is, an object that provides custom support to other objects * */ public int QueryService(ref System.Guid guidservice, ref System.Guid interfacerequested, out IntPtr ppserviceinterface) { int hr = HRESULT.E_NOINTERFACE; System.Guid iid_htmledithost = new System.Guid("3050f6a0-98b5-11cf-bb82-00aa00bdce0b"); System.Guid sid_shtmledithost = new System.Guid("3050F6A0-98B5-11CF-BB82-00AA00BDCE0B"); if ((guidservice == sid_shtmledithost) & (interfacerequested == iid_htmledithost)) { this.snapper = new CSnap(); ppserviceinterface = Marshal.GetComInterfaceForObject(snapper, typeof(IHTMLEditHost)); if (ppserviceinterface != IntPtr.Zero) { hr = HRESULT.S_OK; } } else { ppserviceinterface = IntPtr.Zero; } return hr; } #endregion IServiceProvider ======================== #region IHTMLEditDesigner change the IE editor's default behavior ========== // IHTMLEditDesigner /* * This custom interface provides methods that enable clients using the editor * to intercept Microsoft® Internet Explorer events * so that they can change the editor's default behavior * */ public int PreHandleEvent(int inEvtDispID, IHTMLEventObj pIEventObj) { //CGID_MSHTML //Guid pguidCmdGroup = new Guid("d4db6850-5385-11d0-89e9-00a0c90a90ac"); System.Guid pguidCmdGroup = new Guid("DE4BA900-59CA-11CF-9592-444553540000"); onlyconnect.IOleCommandTarget ct = (onlyconnect.IOleCommandTarget)this.m_document; switch (inEvtDispID) { case dispids.DISPID_IHTMLELEMENT_ONCLICK: break; case dispids.DISPID_IHTMLELEMENT_ONKEYDOWN: break; case dispids.DISPID_IHTMLELEMENT_ONKEYUP: break; case dispids.DISPID_IHTMLELEMENT_ONKEYPRESS: break; case dispids.DISPID_MOUSEMOVE: break; case dispids.DISPID_MOUSEDOWN: break; case dispids.DISPID_KEYDOWN: //Need to trap Del here if (pIEventObj.keyCode == 46) { //delete // this.container.DeleteSelection(); } break; case dispids.DISPID_KEYPRESS: //Gets called on keypress // no longer needed thanks to wndproc implementation // see doShortCut in HtmlEditor.cs container.InvokeHtmlKeyPress(ref pIEventObj); break; case dispids.DISPID_EVMETH_ONDEACTIVATE: break; default: // Debug.WriteLine("Eventobj: " + pIEventObj.EventType); break; } return HRESULT.S_FALSE; } public int PostHandleEvent(int inEvtDispID, IHTMLEventObj pIEventObj) { return HRESULT.S_FALSE; } public int TranslateAccelerator(int inEvtDispID, IHTMLEventObj pIEventObj) { return HRESULT.S_FALSE; } public int PostEditorEventNotify(int inEvtDispID, IHTMLEventObj pIEventObj) { return HRESULT.S_FALSE; } #endregion IHTMLEditDesigner ================ #region IPropertyNotifySink -- notifications of property changes ===================== //implementation of IPropertyNotifySink -- notifications of property changes /* * The IPropertyNotifySink interface is implemented * by a sink object * to receive notifications about property changes * from an object that supports IPropertyNotifySink as an "outgoing" interface. * */ public int OnChanged(int iDispID) { return HRESULT.S_OK; } public int OnRequestEdit(int iDispID) { return HRESULT.S_OK; //indicates change is allowed } #endregion IPropertyNotifySink =============== } }