private static List<SciterEventHandler> _attached_handlers = new List<SciterEventHandler>(); // we keep a copy of all attached instances to guard from GC removal #endregion Fields #region Constructors public SciterEventHandler() { _proc = EventProc; Name = this.GetType().FullName; }
// Notification handler private uint HandleNotification(IntPtr ptrNotification, IntPtr callbackParam) { SciterXDef.SCITER_CALLBACK_NOTIFICATION scn = (SciterXDef.SCITER_CALLBACK_NOTIFICATION)Marshal.PtrToStructure(ptrNotification, typeof(SciterXDef.SCITER_CALLBACK_NOTIFICATION)); switch (scn.code) { case SciterXDef.SC_LOAD_DATA: SciterXDef.SCN_LOAD_DATA sld = (SciterXDef.SCN_LOAD_DATA)Marshal.PtrToStructure(ptrNotification, typeof(SciterXDef.SCN_LOAD_DATA)); return((uint)OnLoadData(sld)); case SciterXDef.SC_DATA_LOADED: SciterXDef.SCN_DATA_LOADED sdl = (SciterXDef.SCN_DATA_LOADED)Marshal.PtrToStructure(ptrNotification, typeof(SciterXDef.SCN_DATA_LOADED)); OnDataLoaded(sdl); return(0); case SciterXDef.SC_ATTACH_BEHAVIOR: SciterXDef.SCN_ATTACH_BEHAVIOR sab = (SciterXDef.SCN_ATTACH_BEHAVIOR)Marshal.PtrToStructure(ptrNotification, typeof(SciterXDef.SCN_ATTACH_BEHAVIOR)); SciterEventHandler elementEvh; bool res = OnAttachBehavior(new SciterElement(sab.elem), Marshal.PtrToStringAnsi(sab.behaviorName), out elementEvh); if (res) { SciterXBehaviors.FPTR_ElementEventProc proc = elementEvh._proc; IntPtr ptrProc = Marshal.GetFunctionPointerForDelegate(proc); IntPtr EVENTPROC_OFFSET = Marshal.OffsetOf(typeof(SciterXDef.SCN_ATTACH_BEHAVIOR), "elementProc"); IntPtr EVENTPROC_OFFSET2 = Marshal.OffsetOf(typeof(SciterXDef.SCN_ATTACH_BEHAVIOR), "elementTag"); Marshal.WriteIntPtr(ptrNotification, EVENTPROC_OFFSET.ToInt32(), ptrProc); Marshal.WriteInt32(ptrNotification, EVENTPROC_OFFSET2.ToInt32(), 1234); return(1); } return(0); case SciterXDef.SC_ENGINE_DESTROYED: if (_window_evh != null) { _api.SciterWindowDetachEventHandler(_hwnd, _window_evh._proc, IntPtr.Zero); _window_evh = null; } OnEngineDestroyed(); return(0); case SciterXDef.SC_POSTED_NOTIFICATION: SciterXDef.SCN_POSTED_NOTIFICATION spn = (SciterXDef.SCN_POSTED_NOTIFICATION)Marshal.PtrToStructure(ptrNotification, typeof(SciterXDef.SCN_POSTED_NOTIFICATION)); IntPtr lreturn = IntPtr.Zero; if (spn.wparam.ToInt32() == INVOKE_NOTIFICATION) { GCHandle handle = GCHandle.FromIntPtr(spn.lparam); Action cbk = (Action)handle.Target; cbk(); handle.Free(); } else { lreturn = OnPostedNotification(spn.wparam, spn.lparam); } IntPtr OFFSET_LRESULT = Marshal.OffsetOf(typeof(SciterXDef.SCN_POSTED_NOTIFICATION), "lreturn"); Marshal.WriteIntPtr(ptrNotification, OFFSET_LRESULT.ToInt32(), lreturn); return(0); case SciterXDef.SC_GRAPHICS_CRITICAL_FAILURE: SciterXDef.SCN_GRAPHICS_CRITICAL_FAILURE cgf = (SciterXDef.SCN_GRAPHICS_CRITICAL_FAILURE)Marshal.PtrToStructure(ptrNotification, typeof(SciterXDef.SCN_GRAPHICS_CRITICAL_FAILURE)); OnGraphicsCriticalFailure(cgf.hwnd); return(0); default: Debug.Assert(false); break; } return(0); }