Exemple #1
0
        static LRESULT WindowProcedure(WindowHandle window, WindowMessage message, WPARAM wParam, LPARAM lParam)
        {
            switch (message)
            {
            case WindowMessage.Create:
                window.SetTimer(ID_TIMER, 1000);
                return(0);

            case WindowMessage.Timer:
                Windows.MessageBeep();
                fFlipFlop = !fFlipFlop;
                window.Invalidate();
                return(0);

            case WindowMessage.Paint:
                using (DeviceContext dc = window.BeginPaint())
                {
                    RECT rect = window.GetClientRectangle();
                    using (BrushHandle brush = fFlipFlop ? Windows.CreateSolidBrush(255, 0, 0) : Windows.CreateSolidBrush(0, 0, 255))
                    {
                        dc.FillRectangle(rect, brush);
                    }
                }
                return(0);

            case WindowMessage.Destroy:
                window.KillTimer(ID_TIMER);
                Windows.PostQuitMessage(0);
                return(0);
            }

            return(Windows.DefaultWindowProcedure(window, message, wParam, lParam));
        }
Exemple #2
0
        protected override LResult WindowProcedure(WindowHandle window, MessageType message, WParam wParam, LParam lParam)
        {
            switch (message)
            {
            case MessageType.Create:
                window.SetTimer(ID_TIMER, 1000);
                return(0);

            case MessageType.Timer:
                Windows.MessageBeep();
                fFlipFlop = !fFlipFlop;
                window.Invalidate();
                return(0);

            case MessageType.Paint:
                using (DeviceContext dc = window.BeginPaint())
                {
                    using (BrushHandle brush = Gdi.CreateSolidBrush(fFlipFlop ? Color.Red : Color.Blue))
                    {
                        dc.FillRectangle(window.GetClientRectangle(), brush);
                    }
                }
                return(0);

            case MessageType.Destroy:
                window.KillTimer(ID_TIMER);
                break;
            }

            return(base.WindowProcedure(window, message, wParam, lParam));
        }
Exemple #3
0
 private static void TimerProcedure(WindowHandle window, MessageType message, TimerId timerId, uint time)
 {
     Windows.MessageBeep();
     s_fFlipFlop             = !s_fFlipFlop;
     using DeviceContext dc  = window.GetDeviceContext();
     using BrushHandle brush = Gdi.CreateSolidBrush(s_fFlipFlop ? Color.Red : Color.Blue);
     dc.FillRectangle(window.GetClientRectangle(), brush);
 }
        /// <summary>
        /// Creates a solid brush, and sets it as a background brush.
        /// </summary>
        private void SetBackgroundBrush()
        {
            if (_nativeBackgroundBrush != null)
            {
                _nativeBackgroundBrush.Dispose();
            }

            // using some native tricks so we can set our background
            // brush to match our back color, so everything draws nicely on resize.
            _nativeBackgroundBrush = this.CreateNativeSolidBrush(BackColor);
            this.SetBackgroundBrush(_nativeBackgroundBrush);
        }
Exemple #5
0
        public void GetSystemColorBrush()
        {
            // System color brushes are special- they'll always give the same value
            BrushHandle brush  = GdiMethods.GetSystemColorBrush(SystemColor.MenuBar);
            long        handle = (long)brush.DangerousGetHandle();

            handle = handle & 0xFFFF00;

            // This changed in RS4 from C5 to BF for the last byte. Checking the first
            // bytes to make sure we're in the right ballpark.
            handle.Should().Be(0x100000);
        }
Exemple #6
0
 static void TimerProcedure(WindowHandle window, WindowMessage message, TimerId timerId, uint time)
 {
     Windows.MessageBeep();
     fFlipFlop = !fFlipFlop;
     using (DeviceContext dc = window.GetDeviceContext())
     {
         RECT rect = window.GetClientRectangle();
         using (BrushHandle brush = fFlipFlop ? Windows.CreateSolidBrush(255, 0, 0) : Windows.CreateSolidBrush(0, 0, 255))
         {
             dc.FillRectangle(rect, brush);
         }
     }
 }
Exemple #7
0
        static LRESULT WindowProcedure(WindowHandle window, WindowMessage message, WPARAM wParam, LPARAM lParam)
        {
            switch (message)
            {
            case WindowMessage.Create:
                hBrushRed = Windows.CreateSolidBrush(255, 0, 0);
                window.SetTimer(ID_TIMER, 1000);
                return(0);

            case WindowMessage.SettingChange:
                f24Hour   = Windows.LocaleInfo.GetIs24HourClock();
                fSuppress = Windows.LocaleInfo.GetHoursHaveLeadingZeros();
                window.Invalidate(true);
                return(0);

            case WindowMessage.Size:
                cxClient = lParam.LowWord;
                cyClient = lParam.HighWord;
                return(0);

            case WindowMessage.Timer:
                window.Invalidate(true);
                return(0);

            case WindowMessage.Paint:
                using (DeviceContext dc = window.BeginPaint())
                {
                    dc.SetMapMode(MapMode.Isotropic);
                    dc.SetWindowExtents(276, 72);
                    dc.SetViewportExtents(cxClient, cyClient);
                    dc.SetWindowOrigin(138, 36);
                    dc.SetViewportOrigin(cxClient / 2, cyClient / 2);
                    dc.SelectObject(StockPen.Null);
                    dc.SelectObject(hBrushRed);
                    DisplayTime(dc, f24Hour, fSuppress);
                }
                return(0);

            case WindowMessage.Destroy:
                window.KillTimer(ID_TIMER);
                hBrushRed.Dispose();
                Windows.PostQuitMessage(0);
                return(0);
            }

            return(Windows.DefaultWindowProcedure(window, message, wParam, lParam));
        }
Exemple #8
0
        protected override LResult WindowProcedure(WindowHandle window, MessageType message, WParam wParam, LParam lParam)
        {
            switch (message)
            {
            case MessageType.Create:
                hBrushRed = Gdi.CreateSolidBrush(Color.Red);
                window.SetTimer(ID_TIMER, 1000);
                return(0);

            case MessageType.SettingChange:
                f24Hour   = Windows.LocaleInfo.GetIs24HourClock();
                fSuppress = Windows.LocaleInfo.GetHoursHaveLeadingZeros();
                window.Invalidate(true);
                return(0);

            case MessageType.Size:
                cxClient = lParam.LowWord;
                cyClient = lParam.HighWord;
                return(0);

            case MessageType.Timer:
                window.Invalidate(true);
                return(0);

            case MessageType.Paint:
                using (DeviceContext dc = window.BeginPaint())
                {
                    dc.SetMappingMode(MappingMode.Isotropic);
                    dc.SetWindowExtents(new Size(276, 72));
                    dc.SetViewportExtents(new Size(cxClient, cyClient));
                    dc.SetWindowOrigin(new Point(138, 36));
                    dc.SetViewportOrigin(new Point(cxClient / 2, cyClient / 2));
                    dc.SelectObject(StockPen.Null);
                    dc.SelectObject(hBrushRed);
                    DisplayTime(dc, f24Hour, fSuppress);
                }
                return(0);

            case MessageType.Destroy:
                window.KillTimer(ID_TIMER);
                hBrushRed.Dispose();
                break;
            }

            return(base.WindowProcedure(window, message, wParam, lParam));
        }
Exemple #9
0
        static void DrawRectangle(WindowHandle window)
        {
            if (cxClient == 0 || cyClient == 0)
            {
                return;
            }

            RECT rect = new RECT(rand.Next() % cxClient, rand.Next() % cyClient,
                                 rand.Next() % cxClient, rand.Next() % cyClient);

            using (BrushHandle brush = Windows.CreateSolidBrush((byte)(rand.Next() % 256), (byte)(rand.Next() % 256), (byte)(rand.Next() % 256)))
            {
                using (DeviceContext dc = window.GetDeviceContext())
                {
                    dc.FillRectangle(rect, brush);
                }
            }
        }
Exemple #10
0
        static void DrawRectangle(WindowHandle window)
        {
            if (cxClient == 0 || cyClient == 0)
            {
                return;
            }

            Rectangle rect = Rectangle.FromLTRB(
                rand.Next() % cxClient,
                rand.Next() % cyClient,
                rand.Next() % cxClient,
                rand.Next() % cyClient);

            using (BrushHandle brush = Gdi.CreateSolidBrush(
                       Color.FromArgb((byte)(rand.Next() % 256), (byte)(rand.Next() % 256), (byte)(rand.Next() % 256))))
            {
                using (DeviceContext dc = window.GetDeviceContext())
                {
                    dc.FillRectangle(rect, brush);
                }
            }
        }
Exemple #11
0
        static unsafe LRESULT WindowProcedure(WindowHandle window, WindowMessage message, WPARAM wParam, LPARAM lParam)
        {
            switch (message)
            {
            case WindowMessage.Create:
                ModuleInstance hInstance = window.GetWindowLong(WindowLong.InstanceHandle);

                // Create the white-rectangle window against which the
                // scroll bars will be positioned. The child window ID is 9.

                hwndRect = Windows.CreateWindow("static", null,
                                                WindowStyles.Child | WindowStyles.Visible | (WindowStyles)StaticStyles.WhiteRectangle,
                                                ExtendedWindowStyles.None,
                                                0, 0, 0, 0,
                                                window, (IntPtr)9, hInstance, IntPtr.Zero);

                for (int i = 0; i < 3; i++)
                {
                    // The three scroll bars have IDs 0, 1, and 2, with
                    // scroll bar ranges from 0 through 255.
                    hwndScroll[i] = Windows.CreateWindow("scrollbar", null,
                                                         WindowStyles.Child | WindowStyles.Visible | WindowStyles.TabStop | (WindowStyles)ScrollBarStyles.Veritcal,
                                                         ExtendedWindowStyles.None,
                                                         0, 0, 0, 0,
                                                         window, (IntPtr)i, hInstance, IntPtr.Zero);

                    hwndScroll[i].SetScrollRange(ScrollBar.Control, 0, 255, false);
                    hwndScroll[i].SetScrollPosition(ScrollBar.Control, 0, false);

                    // The three color-name labels have IDs 3, 4, and 5,
                    // and text strings “Red”, “Green”, and “Blue”.
                    hwndLabel[i] = Windows.CreateWindow("static", szColorLabel[i],
                                                        WindowStyles.Child | WindowStyles.Visible | (WindowStyles)StaticStyles.Center,
                                                        ExtendedWindowStyles.None,
                                                        0, 0, 0, 0,
                                                        window, (IntPtr)i + 3, hInstance, IntPtr.Zero);

                    // The three color-value text fields have IDs 6, 7,
                    // and 8, and initial text strings of “0”.
                    hwndValue[i] = Windows.CreateWindow("static", "0",
                                                        WindowStyles.Child | WindowStyles.Visible | (WindowStyles)StaticStyles.Center,
                                                        ExtendedWindowStyles.None,
                                                        0, 0, 0, 0,
                                                        window, (IntPtr)i + 6, hInstance, IntPtr.Zero);

                    OldScroll[i] = hwndScroll[i].SetWindowProcedure(s_ScrollProcedure);

                    hBrush[i] = Windows.CreateSolidBrush(crPrim[i]);
                }

                hBrushStatic = Windows.GetSystemColorBrush(SystemColor.ButtonHighlight);
                cyChar       = Windows.GetDialogBaseUnits().cy;

                return(0);

            case WindowMessage.Size:
                int cxClient = lParam.LowWord;
                int cyClient = lParam.HighWord;
                rcColor = new RECT(cxClient / 2, 0, cxClient, cyClient);
                hwndRect.MoveWindow(0, 0, cxClient / 2, cyClient, true);

                for (int i = 0; i < 3; i++)
                {
                    hwndScroll[i].MoveWindow((2 * i + 1) * cxClient / 14, 2 * cyChar,
                                             cxClient / 14, cyClient - 4 * cyChar, true);
                    hwndLabel[i].MoveWindow((4 * i + 1) * cxClient / 28, cyChar / 2,
                                            cxClient / 7, cyChar, true);
                    hwndValue[i].MoveWindow((4 * i + 1) * cxClient / 28, cyClient - 3 * cyChar / 2,
                                            cxClient / 7, cyChar, true);
                }

                window.SetFocus();
                return(0);

            case WindowMessage.SetFocus:
                hwndScroll[idFocus].SetFocus();
                return(0);

            case WindowMessage.VerticalScroll:
                int id = (int)((WindowHandle)lParam).GetWindowLong(WindowLong.Id);

                switch ((ScrollCommand)wParam.LowWord)
                {
                case ScrollCommand.PageDown:
                    color[id] += 15;
                    goto case ScrollCommand.LineDown;

                case ScrollCommand.LineDown:
                    color[id] = Math.Min(255, color[id] + 1);
                    break;

                case ScrollCommand.PageUp:
                    color[id] -= 15;
                    goto case ScrollCommand.LineUp;

                case ScrollCommand.LineUp:
                    color[id] = Math.Max(0, color[id] - 1);
                    break;

                case ScrollCommand.Top:
                    color[id] = 0;
                    break;

                case ScrollCommand.Bottom:
                    color[id] = 255;
                    break;

                case ScrollCommand.ThumbPosition:
                case ScrollCommand.ThumbTrack:
                    color[id] = wParam.HighWord;
                    break;

                default:
                    return(0);
                }

                hwndScroll[id].SetScrollPosition(ScrollBar.Control, color[id], true);

                hwndValue[id].SetWindowText(color[id].ToString());

                BrushHandle brush = Windows.CreateSolidBrush((byte)color[0], (byte)color[1], (byte)color[2]);
                brush.SetHandleAsInvalid();     // We'll dispose when we set the next brush

                window.SetClassBackgroundBrush(brush).Dispose();
                window.InvalidateRectangle(rcColor, true);
                return(0);

            case WindowMessage.ControlColorScrollBar:
                return((IntPtr)hBrush[(int)((WindowHandle)lParam).GetWindowLong(WindowLong.Id)]);

            case WindowMessage.ControlColorStatic:
                id = (int)((WindowHandle)lParam).GetWindowLong(WindowLong.Id);

                if (id >= 3 && id <= 8)
                {
                    DeviceContext dc = new DeviceContext((IntPtr)wParam, false);
                    dc.SetTextColor(crPrim[id % 3]);
                    dc.SetBackgroundColor(Windows.GetSystemColor(SystemColor.ButtonHighlight));
                    return(hBrushStatic.DangerousGetHandle());
                }
                break;

            case WindowMessage.SystemColorChange:
                hBrushStatic = Windows.GetSystemColorBrush(SystemColor.ButtonHighlight);
                return(0);

            case WindowMessage.Destroy:
                window.SetClassBackgroundBrush(StockBrush.White).Dispose();

                for (int i = 0; i < 3; i++)
                {
                    hBrush[i].Dispose();
                }

                Windows.PostQuitMessage(0);
                return(0);
            }

            return(Windows.DefaultWindowProcedure(window, message, wParam, lParam));
        }
Exemple #12
0
        protected override LResult WindowProcedure(WindowHandle window, MessageType message, WParam wParam, LParam lParam)
        {
            switch (message)
            {
            case MessageType.Create:
                // Create the white-rectangle window against which the
                // scroll bars will be positioned. The child window ID is 9.

                hwndRect = Windows.CreateWindow(
                    className: "static",
                    style: WindowStyles.Child | WindowStyles.Visible | (WindowStyles)StaticStyles.WhiteRectangle,
                    parentWindow: window,
                    menuHandle: (MenuHandle)9,
                    instance: ModuleInstance);

                for (int i = 0; i < 3; i++)
                {
                    // The three scroll bars have IDs 0, 1, and 2, with
                    // scroll bar ranges from 0 through 255.
                    hwndScroll[i] = Windows.CreateWindow(
                        className: "scrollbar",
                        style: WindowStyles.Child | WindowStyles.Visible | WindowStyles.TabStop | (WindowStyles)ScrollBarStyles.Veritcal,
                        parentWindow: window,
                        menuHandle: (MenuHandle)i,
                        instance: ModuleInstance);

                    hwndScroll[i].SetScrollRange(ScrollBar.Control, 0, 255, false);
                    hwndScroll[i].SetScrollPosition(ScrollBar.Control, 0, false);

                    // The three color-name labels have IDs 3, 4, and 5,
                    // and text strings “Red”, “Green”, and “Blue”.
                    hwndLabel[i] = Windows.CreateWindow(
                        className: "static",
                        windowName: szColorLabel[i],
                        style: WindowStyles.Child | WindowStyles.Visible | (WindowStyles)StaticStyles.Center,
                        parentWindow: window,
                        menuHandle: (MenuHandle)(i + 3),
                        instance: ModuleInstance);

                    // The three color-value text fields have IDs 6, 7,
                    // and 8, and initial text strings of “0”.
                    hwndValue[i] = Windows.CreateWindow(
                        className: "static",
                        windowName: "0",
                        style: WindowStyles.Child | WindowStyles.Visible | (WindowStyles)StaticStyles.Center,
                        parentWindow: window,
                        menuHandle: (MenuHandle)(i + 6),
                        instance: ModuleInstance);

                    OldScroll[i] = hwndScroll[i].SetWindowProcedure(_scrollProcedure = ScrollProcedure);

                    hBrush[i] = Gdi.CreateSolidBrush(crPrim[i]);
                }

                hBrushStatic = Gdi.GetSystemColorBrush(SystemColor.ButtonHighlight);
                cyChar       = Windows.GetDialogBaseUnits().Height;

                return(0);

            case MessageType.Size:
                int cxClient = lParam.LowWord;
                int cyClient = lParam.HighWord;
                rcColor = Rectangle.FromLTRB(cxClient / 2, 0, cxClient, cyClient);
                hwndRect.MoveWindow(new Rectangle(0, 0, cxClient / 2, cyClient), repaint: true);

                for (int i = 0; i < 3; i++)
                {
                    hwndScroll[i].MoveWindow(
                        new Rectangle((2 * i + 1) * cxClient / 14, 2 * cyChar, cxClient / 14, cyClient - 4 * cyChar),
                        repaint: true);
                    hwndLabel[i].MoveWindow(
                        new Rectangle((4 * i + 1) * cxClient / 28, cyChar / 2, cxClient / 7, cyChar),
                        repaint: true);
                    hwndValue[i].MoveWindow(
                        new Rectangle((4 * i + 1) * cxClient / 28, cyClient - 3 * cyChar / 2, cxClient / 7, cyChar),
                        repaint: true);
                }

                window.SetFocus();
                return(0);

            case MessageType.SetFocus:
                hwndScroll[idFocus].SetFocus();
                return(0);

            case MessageType.VerticalScroll:
                int id = (int)((WindowHandle)lParam).GetWindowLong(WindowLong.Id);

                switch ((ScrollCommand)wParam.LowWord)
                {
                case ScrollCommand.PageDown:
                    color[id] += 15;
                    goto case ScrollCommand.LineDown;

                case ScrollCommand.LineDown:
                    color[id] = Math.Min(255, color[id] + 1);
                    break;

                case ScrollCommand.PageUp:
                    color[id] -= 15;
                    goto case ScrollCommand.LineUp;

                case ScrollCommand.LineUp:
                    color[id] = Math.Max(0, color[id] - 1);
                    break;

                case ScrollCommand.Top:
                    color[id] = 0;
                    break;

                case ScrollCommand.Bottom:
                    color[id] = 255;
                    break;

                case ScrollCommand.ThumbPosition:
                case ScrollCommand.ThumbTrack:
                    color[id] = wParam.HighWord;
                    break;

                default:
                    return(0);
                }

                hwndScroll[id].SetScrollPosition(ScrollBar.Control, color[id], true);

                hwndValue[id].SetWindowText(color[id].ToString());

                // We'll dispose when we set the next brush
                BrushHandle brush = Gdi.CreateSolidBrush(Color.FromArgb(color[0], color[1], color[2]));

                window.SetClassBackgroundBrush(brush).Dispose();
                window.InvalidateRectangle(rcColor, true);
                return(0);

            case MessageType.ControlColorScrollBar:
                return((BrushHandle)hBrush[(int)((WindowHandle)lParam).GetWindowLong(WindowLong.Id)]);

            case MessageType.ControlColorStatic:
                id = (int)((WindowHandle)lParam).GetWindowLong(WindowLong.Id);

                if (id >= 3 && id <= 8)
                {
                    DeviceContext dc = (DeviceContext)wParam;
                    dc.SetTextColor(crPrim[id % 3]);
                    dc.SetBackgroundColor(Windows.GetSystemColor(SystemColor.ButtonHighlight));
                    return((BrushHandle)hBrushStatic);
                }
                break;

            case MessageType.SystemColorChange:
                hBrushStatic = Gdi.GetSystemColorBrush(SystemColor.ButtonHighlight);
                return(0);

            case MessageType.Destroy:
                window.SetClassBackgroundBrush(StockBrush.White).Dispose();

                for (int i = 0; i < 3; i++)
                {
                    hBrush[i].Dispose();
                }

                break;
            }

            return(base.WindowProcedure(window, message, wParam, lParam));
        }
 /// <summary>
 /// Sets the background brush for the window class. Returns the previous background brush.
 /// </summary>
 /// <param name="ownsHandle">
 /// Whether or not the returned brush should own the handle. If true the brush handle
 /// will be deleted when disposed / finalized.
 /// </param>
 public static BrushHandle SetClassBackgroundBrush(this WindowHandle window, BrushHandle brush, bool ownsHandle = true)
 => new BrushHandle(window.SetClassLong(ClassLong.BackgroundBrush, brush.DangerousGetHandle()), ownsHandle);
Exemple #14
0
        public unsafe WindowClass(
            string className = default,
            ModuleInstance moduleInstance = default,
            ClassStyle classStyle         = ClassStyle.HorizontalRedraw | ClassStyle.VerticalRedraw,
            BrushHandle backgroundBrush   = default,
            IconHandle icon      = default,
            IconHandle smallIcon = default,
            CursorHandle cursor  = default,
            string menuName      = null,
            int menuId           = 0,
            int classExtraBytes  = 0,
            int windowExtraBytes = 0)
        {
            // Handle default values
            className = className ?? Guid.NewGuid().ToString();

            if (backgroundBrush == default)
            {
                backgroundBrush = SystemColor.Window;
            }
            else if (backgroundBrush == BrushHandle.NoBrush)
            {
                backgroundBrush = default;
            }

            if (icon == default)
            {
                icon = IconId.Application;
            }
            else if (icon == IconHandle.NoIcon)
            {
                icon = default;
            }

            if (cursor == default)
            {
                cursor = CursorId.Arrow;
            }
            else if (cursor == CursorHandle.NoCursor)
            {
                cursor = default;
            }

            // Unfortunately GetHINSTANCE isn't part of .NET Standard
            if (moduleInstance == default)
            {
                var    method = typeof(Marshal).GetMethod("GetHINSTANCE");
                Module module = Assembly.GetCallingAssembly().Modules.First();
                moduleInstance = (IntPtr)method.Invoke(null, new object[] { module });
            }

            if (menuId != 0 && menuName != null)
            {
                throw new ArgumentException("Can only set menu name or ID.");
            }

            _windowProcedure = WindowProcedure;
            ModuleInstance   = moduleInstance;

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

            _wndClass = new WNDCLASSEX
            {
                cbSize        = (uint)sizeof(WNDCLASSEX),
                style         = classStyle,
                lpfnWndProc   = Marshal.GetFunctionPointerForDelegate(_windowProcedure),
                cbClassExtra  = classExtraBytes,
                cbWndExtra    = windowExtraBytes,
                hInstance     = (IntPtr)moduleInstance,
                hIcon         = icon,
                hCursor       = cursor,
                hbrBackground = backgroundBrush,
                hIconSm       = smallIcon,
                lpszMenuName  = (char *)menuId
            };
        }
 public static bool FrameRectangle(this DeviceContext deviceContext, RECT rectangle, BrushHandle brush)
 => GdiMethods.FrameRectangle(deviceContext, rectangle, brush);
Exemple #16
0
        public unsafe WindowClass(
            string?className = default,
            ModuleInstance?moduleInstance = default,
            ClassStyle classStyle         = ClassStyle.HorizontalRedraw | ClassStyle.VerticalRedraw,
            BrushHandle backgroundBrush   = default,
            IconHandle icon      = default,
            IconHandle smallIcon = default,
            CursorHandle 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 = SystemColor.Window;
            }
            else if (backgroundBrush == BrushHandle.NoBrush)
            {
                backgroundBrush = default;
            }

            if (icon == default)
            {
                icon = IconId.Application;
            }
            else if (icon == IconHandle.NoIcon)
            {
                icon = default;
            }

            if (cursor == default)
            {
                cursor = CursorId.Arrow;
            }
            else if (cursor == CursorHandle.NoCursor)
            {
                cursor = default;
            }

            moduleInstance ??= new ModuleInstance(Marshal.GetHINSTANCE(Assembly.GetCallingAssembly().Modules.First()));

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

            _windowProcedure = WindowProcedure;
            ModuleInstance   = moduleInstance;

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

            _wndClass = new WNDCLASSEX
            {
                cbSize        = (uint)sizeof(WNDCLASSEX),
                style         = classStyle,
                lpfnWndProc   = Marshal.GetFunctionPointerForDelegate(_windowProcedure),
                cbClassExtra  = classExtraBytes,
                cbWndExtra    = windowExtraBytes,
                hInstance     = (IntPtr)moduleInstance,
                hIcon         = icon,
                hCursor       = cursor,
                hbrBackground = backgroundBrush,
                hIconSm       = smallIcon,
                lpszMenuName  = (char *)menuId
            };
        }