Beispiel #1
0
        /// <summary>
        /// Runs a specified application and starts the main loop to update its state.
        /// This is the entry point for a given application of type <typeparamref name="T"/>, and it should be
        /// called as soon as the process is launched, excluding any other additional initialization needed.
        /// <para>To launch an application, simply add this line to the project being used:</para>
        /// <c>Win32ApplicationRunner.Run&lt;MyApplication>();</c>
        /// </summary>
        /// <typeparam name="T">The type of application being launched.</typeparam>
        /// <returns>The exit code for the application.</returns>
        public static int Run(Win32Application application)
        {
            Win32ApplicationRunner.application = application;

            IntPtr hInstance = FX.GetModuleHandleW(null);

            fixed(char *name = Assembly.GetExecutingAssembly().FullName)
            fixed(char *windowTitle = application.GetType().ToString())
            {
                // Initialize the window class
                WNDCLASSEXW windowClassEx = new()
                {
                    cbSize        = (uint)sizeof(WNDCLASSEXW),
                    style         = FX.CS_HREDRAW | FX.CS_VREDRAW,
                    lpfnWndProc   = &WindowProc,
                    hInstance     = hInstance,
                    hCursor       = FX.LoadCursorW(IntPtr.Zero, FX.MAKEINTRESOURCE(32512)),
                    lpszClassName = (ushort *)name
                };

                // Register the window class
                _ = FX.RegisterClassExW(&windowClassEx);

                Rectangle windowRect = new(0, 0, 1280, 720);

                // Set the target window size
                _ = FX.AdjustWindowRect((RECT *)&windowRect, FX.WS_OVERLAPPEDWINDOW, FX.FALSE);

                uint
                    height = (uint)(windowRect.Bottom - windowRect.Top),
                    width  = (uint)(windowRect.Right - windowRect.Left);

                // Create the window and store a handle to it
                hwnd = FX.CreateWindowExW(
                    0,
                    windowClassEx.lpszClassName,
                    (ushort *)windowTitle,
                    FX.WS_OVERLAPPEDWINDOW,
                    FX.CW_USEDEFAULT,
                    FX.CW_USEDEFAULT,
                    (int)width,
                    (int)height,
                    HWND.NULL,
                    HMENU.NULL,
                    hInstance,
                    (void *)GCHandle.ToIntPtr(GCHandle.Alloc(application))
                    );

                MARGINS margins = default;

                margins.cxLeftWidth    = -1;
                margins.cxRightWidth   = -1;
                margins.cyTopHeight    = -1;
                margins.cyBottomHeight = -1;

                _ = FX.DwmExtendFrameIntoClientArea(hwnd, &margins);
            }

            // Initialize the application
            application.OnInitialize(hwnd);

            // Display the window
            _ = FX.ShowWindow(hwnd, FX.SW_SHOWDEFAULT);

            MSG msg = default;

            // Setup the render thread that enables smooth resizing of the window
            renderThread = new Thread(static args =>