예제 #1
0
        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);
        }
예제 #2
0
        /// <summary>
        ///     This method subclasses the specified window, such that the
        ///     delegate specified to the constructor will be called to process
        ///     the messages that are sent or posted to this window.
        /// </summary>
        /// <param name="hwnd">
        ///     The window to subclass.
        /// </param>
        /// <returns>
        ///     An identifier that can be used to reference this instance of
        ///     the HwndSubclass class in the static RequestDetach method.
        /// </returns>
        public IntPtr Attach(IntPtr hwnd)
        {
            if (hwnd == IntPtr.Zero)
            {
                throw new ArgumentNullException("hwnd");
            }
            if (_bond != Bond.Unattached)
            {
                throw new InvalidOperationException();
            }

            NativeStructs.WndProc newWndProc = new NativeStructs.WndProc(SubclassWndProc);
            IntPtr oldWndProc = NativeMethods.GetWindowLong(hwnd, NativeConstants.GWL_WNDPROC);

            HookWindowProc(hwnd, newWndProc, oldWndProc);

            // Return the GC handle as a unique identifier of this
            return((IntPtr)_gcHandle);
        }
예제 #3
0
        /// <summary>
        ///     This method unsubclasses this HwndSubclass object from the window
        ///     it previously subclassed. The HwndSubclass object is not thread
        ///     safe, and should thus be called only by the thread that owns
        ///     the window being unsubclassed.
        /// </summary>
        /// <param name="force">
        ///     Whether or not the unsubclassing should be forced.  Due to the
        ///     way that Win32 implements window subclassing, it is not always
        ///     possible to safely remove a window proc from the WNDPROC chain.
        ///     However, the delegate will not be called again after this
        ///     method returns.
        /// </param>
        /// <returns>
        ///     Whether or not this HwndSubclass object was actually removed from
        ///     the WNDPROC chain.
        /// </returns>
        public bool Detach(bool force)
        {
            bool detached = false;
            bool cleanup  = force;

            // If we have already detached, return immediately.
            if (_bond == Bond.Detached || _bond == Bond.Unattached)
            {
                detached = true;
            }
            else
            {
                // When we detach, we simply make a note of it.
                _bond = Bond.Orphaned;

                // If we aren't going to force our removal from the window proc chain,
                // at least check to see if we can safely remove us.
                if (!force)
                {
                    NativeStructs.WndProc currentWndProc = NativeMethods.GetWindowLongWndProc(_hwndAttached, NativeConstants.GWL_WNDPROC);

                    //AvDebug.Assert(currentWndProc != null, "A window should always have a window proc.");

                    // If the current window proc is us, then we can clean up.
                    if (currentWndProc == _attachedWndProc)
                    {
                        cleanup = true;
                    }
                }

                // Cleanup if we can.
                if (cleanup)
                {
                    Dispose();
                    detached = true;
                }
            }

            return(detached);
        }