private void HookWindowProc(IntPtr hwnd, NativeStructs.WndProc newWndProc, IntPtr oldWndProc) { _hwndAttached = hwnd; _hwndHandleRef = new HandleRef(null, _hwndAttached); _bond = Bond.Attached; _attachedWndProc = newWndProc; _oldWndProc = oldWndProc; IntPtr oldWndProc2 = NativeMethods.SetWindowLong(_hwndAttached, NativeConstants.GWL_WNDPROC, _attachedWndProc); // Track this window so that we can rip out the managed window proc // when the CLR shuts down. ManagedWndProcTracker.TrackHwnd(_hwndAttached); }
// This method should only be called from Dispose. Otherwise // assumptions about the disposing/finalize state could be violated. private void UnhookWindowProc() { if (_bond == Bond.Attached || _bond == Bond.Orphaned) { ManagedWndProcTracker.UnhookHwnd(_hwndAttached, false /* don't hook up defWindowProc */); try { NativeMethods.SetWindowLong(_hwndHandleRef.Handle, NativeConstants.GWL_WNDPROC, _oldWndProc); } catch (System.ComponentModel.Win32Exception e) { if (e.NativeErrorCode != 1400) // ERROR_INVALID_WINDOW_HANDLE { throw; } } } _bond = Bond.Detached; _oldWndProc = IntPtr.Zero; _attachedWndProc = null; _hwndAttached = IntPtr.Zero; _hwndHandleRef = new HandleRef(null, IntPtr.Zero); // un-Pin this object. // Note: the GC is free to collect this object at anytime // after we have freed this handle - that is, once all // other managed references go away. //AvDebug.Assert(_gcHandle.IsAllocated, "External GC handle has not been allocated."); if (_gcHandle.IsAllocated) { _gcHandle.Free(); } }