Ejemplo n.º 1
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="WindowSubclassHandler"/> class.
        /// </summary>
        /// <param name="handle">The window handle of the window to subclass.</param>
        public WindowSubclassHandler(IntPtr handle)
        {
            _handle = handle.OrThrowIfZero();

            // Create a delegate for our window procedure and get a function
            // pointer for it.
            _windowProcDelegate    = NativeWndProc;
            _windowProcDelegatePtr = Marshal.GetFunctionPointerForDelegate(
                _windowProcDelegate);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///   Initializes a new instance of the <see cref="WindowSubclassHandler"/> class.
        /// </summary>
        /// <param name="handle">The window handle of the window to subclass.</param>
        public WindowSubclassHandler(IntPtr handle)
        {
            if (handle == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(handle));
            }

            _handle = handle;

            // Create a delegate for our window procedure and get a function
            // pointer for it.
            _windowProcDelegate    = NativeWndProc;
            _windowProcDelegatePtr = Marshal.GetFunctionPointerForDelegate(
                _windowProcDelegate);
        }
Ejemplo n.º 3
0
            /// <summary>
            ///  Once the classname and style bits have been set, this can be called to register the class.
            /// </summary>
            private unsafe void RegisterClass()
            {
                User32.WNDCLASS windowClass = new User32.WNDCLASS();

                string localClassName = _className;

                if (localClassName == null)
                {
                    // If we don't use a hollow brush here, Windows will "pre paint" us with COLOR_WINDOW which
                    // creates a little bit if flicker.  This happens even though we are overriding wm_erasebackgnd.
                    // Make this hollow to avoid all flicker.

                    windowClass.hbrBackground = Gdi32.GetStockObject(Gdi32.StockObject.HOLLOW_BRUSH);
                    windowClass.style         = _classStyle;

                    _defaultWindProc = DefaultWindowProc;
                    localClassName   = "Window." + Convert.ToString((int)_classStyle, 16);
                }
                else
                {
                    // A system defined Window class was specified, get its info

                    if (!User32.GetClassInfoW(NativeMethods.NullHandleRef, _className, ref windowClass))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error(), SR.InvalidWndClsName);
                    }

                    localClassName   = _className;
                    _defaultWindProc = windowClass.lpfnWndProc;
                }

                _windowClassName        = GetFullClassName(localClassName);
                _windProc               = new User32.WNDPROC(Callback);
                windowClass.lpfnWndProc = Marshal.GetFunctionPointerForDelegate(_windProc);
                windowClass.hInstance   = Kernel32.GetModuleHandleW(null);

                fixed(char *c = _windowClassName)
                {
                    windowClass.lpszClassName = c;

                    if (User32.RegisterClassW(ref windowClass) == 0)
                    {
                        _windProc = null;
                        throw new Win32Exception();
                    }
                }
            }
Ejemplo n.º 4
0
        internal void AssignHandle(IntPtr handle, bool assignUniqueID)
        {
            lock (this)
            {
                CheckReleased();
                Debug.Assert(handle != IntPtr.Zero, "handle is 0");

                Handle = handle;

                _priorWindowProcHandle = User32.GetWindowLong(this, User32.GWL.WNDPROC);
                Debug.Assert(_priorWindowProcHandle != IntPtr.Zero);


                Debug.WriteLineIf(
                    WndProcChoice.TraceVerbose,
                    WndProcShouldBeDebuggable ? "Using debuggable wndproc" : "Using normal wndproc");

                _windowProc = new User32.WNDPROC(Callback);

                AddWindowToTable(handle, this);

                // Set the NativeWindow window procedure delegate and get back the native pointer for it.
                User32.SetWindowLong(this, User32.GWL.WNDPROC, _windowProc);
                _windowProcHandle = User32.GetWindowLong(this, User32.GWL.WNDPROC);

                // This shouldn't be possible.
                Debug.Assert(_priorWindowProcHandle != _windowProcHandle, "Uh oh! Subclassed ourselves!!!");

                if (assignUniqueID &&
                    (unchecked ((int)((long)User32.GetWindowLong(this, User32.GWL.STYLE))) & NativeMethods.WS_CHILD) != 0 &&
                    unchecked ((int)((long)User32.GetWindowLong(this, User32.GWL.ID))) == 0)
                {
                    User32.SetWindowLong(this, User32.GWL.ID, handle);
                }

                if (_suppressedGC)
                {
                    GC.ReRegisterForFinalize(this);
                    _suppressedGC = false;
                }

                OnHandleChange();
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        ///  Constructor.
        /// </summary>
        /// <param name="className">Name, or default will be generated.</param>
        /// <param name="moduleInstance">Module to associate with the window. The entry assembly is the default.</param>
        /// <param name="backgroundBrush">Use (IntPtr)(-1) for no background brush.</param>
        /// <param name="icon">Use (IntPtr)(-1) for no icon.</param>
        /// <param name="cursor">Use (IntPtr)(-1) for no cursor.</param>
        /// <param name="menuName">Menu name, can not set with <paramref name="menuId"/>.</param>
        /// <param name="menuId">Menu id, can not set with <paramref name="menuName"/>.</param>
        public unsafe WindowClass(
            string className       = default,
            IntPtr moduleInstance  = default,
            User32.CS classStyle   = User32.CS.HREDRAW | User32.CS.VREDRAW,
            IntPtr backgroundBrush = default,
            IntPtr icon            = default,
            IntPtr cursor          = default,
            string menuName        = null,
            int menuId             = 0,
            int classExtraBytes    = 0,
            int windowExtraBytes   = 0)
        {
            // Handle default values
            className ??= Guid.NewGuid().ToString();

            if (backgroundBrush == default)
            {
                backgroundBrush = User32.GetSysColorBrush(COLOR_WINDOW);
            }
            else if (backgroundBrush == (IntPtr)(-1))
            {
                backgroundBrush = default;
            }

            if (icon == default)
            {
                icon = LoadIconW(IntPtr.Zero, (IntPtr)IDI_APPLICATION);
            }
            else if (icon == (IntPtr)(-1))
            {
                icon = default;
            }

            if (cursor == default)
            {
                cursor = User32.LoadCursorW(IntPtr.Zero, (IntPtr)User32.CursorResourceId.IDC_ARROW);
            }
            else if (cursor == (IntPtr)(-1))
            {
                cursor = default;
            }

            if (moduleInstance == IntPtr.Zero)
            {
                Marshal.GetHINSTANCE(Assembly.GetCallingAssembly().Modules.First());
            }

            if (menuId != 0 && menuName != null)
            {
                throw new ArgumentException($"Can't set both {nameof(menuName)} and {nameof(menuId)}.");
            }

            _windowProcedure = WNDPROC;
            ModuleInstance   = moduleInstance;

            _className = className;
            _menuName  = menuName ?? string.Empty;

            _wndClass = new User32.WNDCLASS
            {
                style         = classStyle,
                lpfnWndProc   = Marshal.GetFunctionPointerForDelegate(_windowProcedure),
                cbClsExtra    = classExtraBytes,
                cbWndExtra    = windowExtraBytes,
                hInstance     = moduleInstance,
                hIcon         = icon,
                hCursor       = cursor,
                hbrBackground = backgroundBrush,
                lpszMenuName  = (char *)menuId
            };
        }