A SafeHandle representing an HWND.
HWNDs have very loose ownership semantics. Unlike normal handles, there is no "CloseHandle" API for HWNDs. There are APIs like CloseWindow or DestroyWindow, but these actually affect the window, not just your handle to the window. This SafeHandle type does not actually do anything to release the handle in the finalizer, it simply provides type safety to the PInvoke signatures. The StrongHWND SafeHandle will actually destroy the HWND when it is disposed or finalized. Because of this loose ownership semantic, the same HWND value can be returned from multiple APIs and can be directly compared. Since SafeHandles are actually reference types, we have to override all of the comparison methods and operators. We also support equality between null and HWND(IntPtr.Zero).
Inheritance: System.Runtime.InteropServices.SafeHandle
Example #1
0
 static HWND()
 {
     NULL = new HWND(IntPtr.Zero);
     BROADCAST = new HWND(new IntPtr(0xffff));
     MESSAGE = new HWND(new IntPtr(-3));
     DESKTOP = new HWND(new IntPtr(0));
     TOP = new HWND(new IntPtr(0));
     BOTTOM = new HWND(new IntPtr(1));
     TOPMOST = new HWND(new IntPtr(-1));
     NOTOPMOST = new HWND(new IntPtr(-2));
 }
        /// <summary>
        ///     Transform a point from "screen" coordinate space into the
        ///     "client" coordinate space of the window.
        /// </summary>
        public static Point TransformScreenToClient(this HwndSource hwndSource, Point point)
        {
            HWND hwnd = new HWND(hwndSource.Handle);

            POINT pt = new POINT();
            pt.x = (int)point.X;
            pt.y = (int)point.Y;

            NativeMethods.ScreenToClient(hwnd, ref pt);

            return new Point(pt.x, pt.y);
        }
        /// <summary>
        ///     Hooks into the stream of messages that are dispatched to the
        ///     specified window.
        /// </summary>
        /// <remarks>
        ///     The window must be owned by the calling thread.
        /// </remarks>
        public WindowSubclass(HWND hwnd)
        {
            if (!IsCorrectThread(hwnd)) {
                throw new InvalidOperationException("May not hook a window created by a different thread.");
            }

            _hwnd = hwnd;
            _wndproc = WndProcStub;
            _wndprocPtr = Marshal.GetFunctionPointerForDelegate(_wndproc);

            // Because our window proc is an instance method, it is connected
            // to this instance of WindowSubclass, where we can store state.
            // We do not need to store any extra state in native memory.
            NativeMethods.SetWindowSubclass(hwnd, _wndproc, IntPtr.Zero, IntPtr.Zero);
        }
 public static extern HWND SetParent(HWND hwndChild, HWND hwndNewParent);
        protected override sealed HWND BuildWindowOverride(HWND hwndParent)
        {
            HwndSourceParameters hwndSourceParameters = new HwndSourceParameters();
            hwndSourceParameters.WindowStyle = (int)(WS.VISIBLE | WS.CHILD | WS.CLIPSIBLINGS | WS.CLIPCHILDREN);
            hwndSourceParameters.ParentWindow = hwndParent.DangerousGetHandle();

            _hwndSource = new HwndSource(hwndSourceParameters);
            _hwndSource.SizeToContent = SizeToContent.Manual;

            // Set the root visual of the HwndSource to an instance of
            // HwndSourceHostRoot.  Hook it up as a logical child if
            // we are on the same thread.
            HwndSourceHostRoot root = new HwndSourceHostRoot();
            _hwndSource.RootVisual = root;

            root.OnMeasure += OnRootMeasured;
            AddLogicalChild(_hwndSource.RootVisual);

            SetRootVisual(Child);

            return new HWND(_hwndSource.Handle);
        }
 internal void TransferHandleOwnership(StrongHWND hwnd)
 {
     Debug.Assert(hwnd == _hwnd); // equivalency, not reference equals
     _hwnd = hwnd;
 }
        private IntPtr WndProc(HWND hwnd, WM msg, IntPtr wParam, IntPtr lParam, IntPtr id, IntPtr data)
        {
            IntPtr retval = IntPtr.Zero;

            try {
                retval = WndProcOverride(hwnd, msg, wParam, lParam, id, data);
            } finally {
                if (_hwnd != HWND.NULL) {
                    Debug.Assert(_hwnd == hwnd);

                    if (msg == WM.NCDESTROY) {
                        Dispose();
                    } else if (msg == _disposeMessage && wParam == _wndprocPtr) {
                        DisposeHelper(lParam == IntPtr.Zero ? false : true);
                    }
                }
            }

            return retval;
        }
 protected virtual IntPtr WndProcOverride(HWND hwnd, WM msg, IntPtr wParam, IntPtr lParam, IntPtr id, IntPtr data)
 {
     // Call the next window proc in the subclass chain.
     return NativeMethods.DefSubclassProc(hwnd, msg, wParam, lParam);
 }
 private static extern IntPtr _GetWindowLongPtr(HWND hwnd, GWL nIndex);
 private static extern int _GetClassName(HWND hWnd, StringBuilder lpClassName, int nMaxCount);
 public static extern bool ShowWindow(HWND hWnd, SW nCmdShow);
 public static extern bool SetWindowSubclass(HWND hwnd, SUBCLASSPROC callback, IntPtr id, IntPtr data);
 public static extern bool SetWindowPos(HWND hwnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, SWP uFlags);
 public static IntPtr SetWindowLongPtr(HWND hwnd, GWL nIndex, IntPtr dwNewLong)
 {
     if (IntPtr.Size == 4) {
         // The SetWindowLongPtr entrypoint may not exist on 32-bit
         // OSes, so use the legacy SetWindowLong function instead.
         return new IntPtr(SetWindowLong(hwnd, nIndex, dwNewLong.ToInt32()));
     } else {
         return _SetWindowLongPtr(hwnd, nIndex, dwNewLong);
     }
 }
 public static extern int SetWindowLong(HWND hwnd, GWL nIndex, int dwNewLong);
 private static extern IntPtr _SetWindowLongPtr(HWND hwnd, GWL nIndex, IntPtr dwNewLong);
        protected virtual void Dispose(bool disposing)
        {
            if (_hwnd == null || !IsCorrectThread(_hwnd)) {
                throw new InvalidOperationException("Dispose virtual should only be called by WindowSubclass once on the correct thread.");
            }

            NativeMethods.RemoveWindowSubclass(_hwnd, _wndproc, IntPtr.Zero);
            _hwnd = null;
        }
 public static extern IntPtr CallWindowProc(WNDPROC lpPrevWndFunc, HWND hWnd, int Msg, IntPtr wParam, IntPtr lParam);
        private bool IsCorrectThread(HWND hwnd)
        {
            int processId;
            int threadId = NativeMethods.GetWindowThreadProcessId(hwnd, out processId);

            return (processId == NativeMethods.GetCurrentProcessId() && threadId == NativeMethods.GetCurrentThreadId());
        }
 public static extern bool ClientToScreen(HWND hwnd, ref POINT lpPoint);
 private IntPtr WndProcStub(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, IntPtr id, IntPtr data)
 {
     HWND hwnd2 = new HWND(hwnd);
     return WndProc(hwnd2, (WM)msg, wParam, lParam, id, data);
 }
 public static extern HWND CreateWindowEx(WS_EX dwExStyle, string lpClassName, string lpWindowName, WS dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
Example #23
0
 public bool Equals(HWND other)
 {
     if (Object.ReferenceEquals(other, null)) {
         return handle == IntPtr.Zero;
     } else {
         return other.handle == handle;
     }
 }
 public static extern IntPtr DefSubclassProc(HWND hwnd, WM msg, IntPtr wParam, IntPtr lParam);
        /// <summary>
        ///     Called from WindowClass.CreateWindow to intialize this instance
        ///     when the HWND has been created.
        /// </summary>
        /// <param name="hwnd">
        ///     The HWND that was created.
        /// </param>
        /// <param name="param">
        ///     The creation parameter that was passsed to
        ///     WindowClass.CreateWindow.
        /// </param>
        internal IntPtr InitializeFromFirstMessage(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam)
        {
            _hwnd = new HWND(hwnd);

            // Replace the window proceedure for this window instance.
            IntPtr wndProc = Marshal.GetFunctionPointerForDelegate(_wndProc);
            NativeMethods.SetWindowLongPtr(_hwnd, GWL.WNDPROC, wndProc);

            // Give the window a chance to initialize.
            Initialize();

            // Manually invoke the window proceedure for this message.
            return OnMessage((WM)message, wParam, lParam);
        }
 public static extern IntPtr DefWindowProc(HWND hWnd, WM Msg, IntPtr wParam, IntPtr lParam);
        protected virtual void Dispose(bool disposing)
        {
            if (disposing) {
                StrongHWND strongHwnd = _hwnd as StrongHWND;

                if (strongHwnd != null) {
                    // Replace the StrongHWND reference with a regular "weak"
                    // HWND reference so that messages processed during
                    // disposing do not have to deal with a partially disposed
                    // SafeHandle.
                    _hwnd = new HWND(strongHwnd.DangerousGetHandle());

                    strongHwnd.Dispose();

                    // All done, replace the "weak" HWND reference with null.
                    _hwnd = null;
                }
            }
        }
        public static StrongHWND CreateWindowEx(WS_EX dwExStyle, string lpClassName, string lpWindowName, WS dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam)
        {
            HWND hwnd = NativeMethods.CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);

            return new StrongHWND(hwnd.DangerousGetHandle());
        }
        protected override sealed void DestroyWindowOverride(HWND hwnd)
        {
            Debug.Assert(hwnd.DangerousGetHandle() == _hwndSource.Handle);

            _hwndSource.Dispose();
            _hwndSource = null;
        }
 public static extern bool SetLayeredWindowAttributes(HWND hwnd, uint crKey, byte bAlpha, LWA dwFlags);