Пример #1
0
        protected override void SetSize(Vector2 value)
        {
            // Scale the rect, and set it.
            Rect r      = GetFullWindowRect((int)value.X, (int)value.Y);
            int  width  = r.Right - r.Left;
            int  height = r.Bottom - r.Top;

            // Center on the monitor.
            Monitor monitor = GetMonitorOfWindow();

            if (monitor == null)
            {
                Engine.Log.Warning("No monitor attached?", MessageSource.Win32);
                return;
            }

            Vector2 center = monitor.Position + new Vector2(monitor.Width, monitor.Height) / 2 - new Vector2(width, height) / 2;

            User32.SetWindowPos(_windowHandle, (IntPtr)HwndZOrder.HWND_NOTOPMOST,
                                (int)center.X + r.Left,
                                (int)center.Y + r.Top,
                                r.Right - r.Left,
                                r.Bottom - r.Top,
                                WindowPositionFlags.SWP_NOACTIVATE | WindowPositionFlags.SWP_SHOWWINDOW
                                );
        }
Пример #2
0
        protected override void UpdateDisplayMode()
        {
            // Get the monitor
            Monitor monitor = GetMonitorOfWindow();

            if (monitor == null)
            {
                Engine.Log.Warning("No monitor attached?", MessageSource.Win32);
                return;
            }

            switch (_mode)
            {
            case DisplayMode.Windowed:
                WindowStyles style = DetermineWindowStyle();
                IntPtr       res   = User32.SetWindowLongPtr(_windowHandle, WindowLongFlags.GWL_STYLE, (IntPtr)style);
                if (res == IntPtr.Zero)
                {
                    CheckError("Couldn't change display mode to windowed.", true);
                }

                if (_windowModeSize != null)
                {
                    Size            = (Vector2)_windowModeSize;
                    _windowModeSize = null;
                }

                // Center window on screen. (This will also apply the SetWindowLongPtr changes, and remove the topmost status when exiting out of fullscreen)
                Position = monitor.Position + (new Vector2(monitor.Width, monitor.Height) / 2 - Size / 2);

                break;

            case DisplayMode.Fullscreen:
                IntPtr resp = User32.SetWindowLongPtr(_windowHandle, WindowLongFlags.GWL_STYLE, (IntPtr)FULLSCREEN_STYLE);
                if (resp == IntPtr.Zero)
                {
                    CheckError("Couldn't change display mode to fullscreen, couldn't apply window style.", true);
                    return;
                }

                bool successful = User32.SetWindowPos(
                    _windowHandle, (IntPtr)HwndZOrder.HWND_NOTOPMOST,
                    (int)monitor.Position.X, (int)monitor.Position.Y,
                    monitor.Width, monitor.Height,
                    WindowPositionFlags.SWP_NOACTIVATE | WindowPositionFlags.SWP_NOCOPYBITS | WindowPositionFlags.SWP_FRAMECHANGED
                    );
                if (!successful)
                {
                    CheckError("Couldn't change display mode to fullscreen, couldn't apply window rect.", true);
                }

                // Center cursor on screen/window.
                User32.SetCursorPos((int)(monitor.Position.X + monitor.Width / 2), (int)(monitor.Position.Y + monitor.Height / 2));

                break;
            }
        }
Пример #3
0
        protected override void SetPosition(Vector2 position)
        {
            if (DisplayMode != DisplayMode.Windowed)
            {
                return;
            }

            // Get the size and scale it.
            Vector2 size = Size;
            Rect    rect = GetFullWindowRect((int)size.X, (int)size.Y);

            // Set the size and position.
            User32.SetWindowPos(_windowHandle, (IntPtr)HwndZOrder.HWND_NOTOPMOST,
                                (int)position.X + rect.Left,
                                (int)position.Y + rect.Top,
                                0,
                                0,
                                WindowPositionFlags.SWP_NOACTIVATE | WindowPositionFlags.SWP_NOCOPYBITS | WindowPositionFlags.SWP_SHOWWINDOW | WindowPositionFlags.SWP_NOSIZE);
        }
Пример #4
0
 public static bool SetWindowPos(IntPtr hwnd, HwndZOrder order, int x, int y, int cx, int cy,
                                 WindowPositionFlags flags)
 {
     return(User32Methods.SetWindowPos(hwnd, new IntPtr((int)order), x, y, cx, cy, flags));
 }
        /// <inheritdoc />
        protected override void SetupPlatform(Configurator config)
        {
            // todo: load libraries - if any
            // probably XInput

            // Initialize audio - Try to create WasApi - otherwise return the fake context so execution can go on.
            Audio = WasApiAudioContext.TryCreate() ?? (AudioContext) new NullAudioContext();
            Engine.Log.Trace("Audio init complete.", MessageSource.Win32);

            PopulateKeyNames();

            if (IsWindows10CreatorsUpdateOrGreaterWin32)
            {
                User32.SetProcessDpiAwarenessContext(DpiAwarenessContext.DpiAwarenessContextPerMonitorAwareV2);
            }
            else if (IsWindows81OrGreater)
            {
                User32.SetProcessDpiAwareness(ProcessDpiAwareness.ProcessPerMonitorDpiAware);
            }
            else
            {
                User32.SetProcessDPIAware();
            }

            RegisterWindowClass();
            CreateHelperWindow();
            PollMonitors();
            Engine.Log.Trace("Platform init complete.", MessageSource.Win32);

            var windowInitialSize = new Rect
            {
                Right  = (int)config.HostSize.X,
                Bottom = (int)config.HostSize.Y
            };

            Win32Window.GetFullWindowRect(Win32Window.DEFAULT_WINDOW_STYLE, Win32Window.DEFAULT_WINDOW_STYLE_EX, DEFAULT_DPI, ref windowInitialSize);
            int    initialWidth  = windowInitialSize.Right - windowInitialSize.Left;
            int    initialHeight = windowInitialSize.Bottom - windowInitialSize.Top;
            IntPtr handle        = User32.CreateWindowEx(
                Win32Window.DEFAULT_WINDOW_STYLE_EX,
                CLASS_NAME,
                config.HostTitle,
                Win32Window.DEFAULT_WINDOW_STYLE,
                (int)CreateWindowFlags.CW_USEDEFAULT, (int)CreateWindowFlags.CW_USEDEFAULT, // Position - default
                initialWidth, initialHeight,                                                // Size - initial
                IntPtr.Zero,                                                                // No parent window
                IntPtr.Zero,                                                                // No window menu
                Kernel32.GetModuleHandle(null),
                IntPtr.Zero
                );

            if (handle == IntPtr.Zero)
            {
                CheckError("Couldn't create window.", true);
                return;
            }

            Engine.Log.Trace("Window created.", MessageSource.Win32);

            // Create graphics context - OpenGL.
            GraphicsContext context = null;

            try
            {
                var wgl = new WglGraphicsContext();
                wgl.Init(handle, this);
                if (wgl.Valid)
                {
                    context = wgl;
                }
            }
            catch (Exception ex)
            {
                Engine.Log.Warning($"Couldn't create WGL context, falling back to MESA if possible.\n{ex}", MessageSource.Win32);
            }

            if (context == null)
            {
                try
                {
                    var gallium = new GalliumGraphicsContext();
                    gallium.Init(handle, this);
                    if (gallium.Valid)
                    {
                        context = gallium;
                    }
                }
                catch (Exception ex)
                {
                    Engine.SubmitError(new Exception("Couldn't create MESA context.", ex));
                }
            }

            if (context == null)
            {
                Engine.SubmitError(new Exception("Couldn't create graphics context!"));
                return;
            }

            // Create Emotion representation of the window.
            var windowInstance = new Win32Window(handle, context, this);

            // Adjust window size to account for DPI scaling of the window frame and optionally DPI scaling of the content area.
            // This cannot be done until we know what monitor it was placed on - so it's done post creation.
            var rect = new Rect
            {
                Right  = (int)config.HostSize.X,
                Bottom = (int)config.HostSize.Y
            };

            rect.ClientToScreen(windowInstance.Handle);
            windowInstance.GetFullWindowRect(ref rect);
            User32.SetWindowPos(windowInstance.Handle, IntPtr.Zero,
                                rect.Left, rect.Top,
                                rect.Right - rect.Left, rect.Bottom - rect.Top,
                                WindowPositionFlags.SWP_NOACTIVATE | WindowPositionFlags.SWP_NOZORDER);
            Window = windowInstance;
        }
Пример #6
0
        /// <inheritdoc />
        protected override void SetupInternal(Configurator config)
        {
            IsWindows7OrGreater = IsWindowsVersionOrGreaterWin32(
                NativeHelpers.HiByte((ushort)NtDll.WinVer.Win32WinNTWin7),
                NativeHelpers.LoByte((ushort)NtDll.WinVer.Win32WinNTWin7),
                0);
            IsWindows8OrGreater = IsWindowsVersionOrGreaterWin32(
                NativeHelpers.HiByte((ushort)NtDll.WinVer.Win32WinNTWin8),
                NativeHelpers.LoByte((ushort)NtDll.WinVer.Win32WinNTWin8),
                0);
            IsWindows81OrGreater = IsWindowsVersionOrGreaterWin32(
                NativeHelpers.HiByte((ushort)NtDll.WinVer.Win32WinNTWinBlue),
                NativeHelpers.LoByte((ushort)NtDll.WinVer.Win32WinNTWinBlue),
                0);
            IsWindows10AnniversaryUpdateOrGreaterWin32 = IsWindows10BuildOrGreaterWin32(14393);
            IsWindows10CreatorsUpdateOrGreaterWin32    = IsWindows10BuildOrGreaterWin32(15063);

            var windowsVersionFlags = new List <string>();

            if (IsWindows7OrGreater)
            {
                windowsVersionFlags.Add(nameof(IsWindows7OrGreater));
            }
            if (IsWindows8OrGreater)
            {
                windowsVersionFlags.Add(nameof(IsWindows8OrGreater));
            }
            if (IsWindows81OrGreater)
            {
                windowsVersionFlags.Add(nameof(IsWindows81OrGreater));
            }
            if (IsWindows10AnniversaryUpdateOrGreaterWin32)
            {
                windowsVersionFlags.Add(nameof(IsWindows10AnniversaryUpdateOrGreaterWin32));
            }
            if (IsWindows10CreatorsUpdateOrGreaterWin32)
            {
                windowsVersionFlags.Add(nameof(IsWindows10CreatorsUpdateOrGreaterWin32));
            }
            Engine.Log.Trace(string.Join(", ", windowsVersionFlags), MessageSource.Win32);

            if (IsWindows10CreatorsUpdateOrGreaterWin32)
            {
                User32.SetProcessDpiAwarenessContext(DpiAwarenessContext.DpiAwarenessContextPerMonitorAwareV2);
            }
            else if (IsWindows81OrGreater)
            {
                User32.SetProcessDpiAwareness(ProcessDpiAwareness.ProcessPerMonitorDpiAware);
            }
            else
            {
                User32.SetProcessDPIAware();
            }

            // todo: load libraries - if any, probably XInput?

            // Initialize audio.
            AudioContext ctx = null;

#if OpenAL
            ctx ??= OpenALAudioAdapter.TryCreate(this);
#endif
            ctx ??= WasApiAudioContext.TryCreate(this);
            ctx ??= new NullAudioContext();
            Audio = ctx;
            Engine.Log.Trace("Audio init complete.", MessageSource.Win32);

            PopulateKeyCodes();
            RegisterWindowClass();
            CreateHelperWindow();
            PollMonitors();
            Engine.Log.Trace("Platform helpers created.", MessageSource.Win32);

            var windowInitialSize = new Rect
            {
                Right  = (int)config.HostSize.X,
                Bottom = (int)config.HostSize.Y
            };
            GetFullWindowRect(DEFAULT_WINDOW_STYLE, DEFAULT_WINDOW_STYLE_EX, DEFAULT_DPI, ref windowInitialSize);
            int initialWidth  = windowInitialSize.Right - windowInitialSize.Left;
            int initialHeight = windowInitialSize.Bottom - windowInitialSize.Top;

            WindowStyles windowStyle = DEFAULT_WINDOW_STYLE;
            if (config.HiddenWindow)
            {
                windowStyle &= ~WindowStyles.WS_VISIBLE;
                windowStyle &= ~WindowStyles.WS_MINIMIZE;

                // This will override the hide otherwise
                config.InitialDisplayMode = DisplayMode.Initial;
            }

            IntPtr windowHandle = User32.CreateWindowEx(
                DEFAULT_WINDOW_STYLE_EX,
                CLASS_NAME,
                config.HostTitle,
                windowStyle,
                (int)CreateWindowFlags.CW_USEDEFAULT, (int)CreateWindowFlags.CW_USEDEFAULT, // Position - default
                initialWidth, initialHeight,                                                // Size - initial
                IntPtr.Zero,                                                                // No parent window
                IntPtr.Zero,                                                                // No window menu
                Kernel32.GetModuleHandle(null),
                IntPtr.Zero
                );
            if (windowHandle == IntPtr.Zero)
            {
                CheckError("Couldn't create window.", true);
                return;
            }

            Engine.Log.Trace("Window created.", MessageSource.Win32);

            string[] args       = Environment.GetCommandLineArgs();
            bool     forceAngle = CommandLineParser.FindArgument(args, "angle", out string _);
            bool     forceMesa  = CommandLineParser.FindArgument(args, "software", out string _);

            // Create graphics context.

            if (!forceAngle && !forceMesa)
            {
                try
                {
                    var wgl = new WglGraphicsContext();
                    wgl.Init(User32.GetDC(_helperWindowHandle), windowHandle, this);
                    if (wgl.Valid)
                    {
                        Context = wgl;
                    }
                }
                catch (Exception ex)
                {
                    Engine.Log.Warning($"Couldn't create WGL context, falling back if possible.\n{ex}", MessageSource.Win32);
                }
            }

#if ANGLE
            if (Context == null && !forceMesa)
            {
                try
                {
                    var egl = new EglGraphicsContext();
                    egl.Init(User32.GetDC(windowHandle), windowHandle, this);
                    if (egl.Valid)
                    {
                        Context = egl;
                    }
                }
                catch (Exception ex)
                {
                    Engine.Log.Warning($"Couldn't create EGL context, falling back if possible.\n{ex}", MessageSource.Win32);
                }
            }
#endif

            if (Context == null)
            {
                try
                {
                    var gallium = new GalliumGraphicsContext();
                    gallium.Init(windowHandle, this);
                    if (gallium.Valid)
                    {
                        Context = gallium;
                    }
                }
                catch (Exception ex)
                {
                    Engine.CriticalError(new Exception("Couldn't create MESA context.", ex));
                }
            }

            if (Context == null)
            {
                Engine.CriticalError(new Exception("Couldn't create graphics context!"));
                return;
            }

            // Adjust window size to account for DPI scaling of the window frame and optionally DPI scaling of the content area.
            // This cannot be done until we know what monitor it was placed on - so it's done post creation.
            var rect = new Rect
            {
                Right  = (int)config.HostSize.X,
                Bottom = (int)config.HostSize.Y
            };
            rect.ClientToScreen(windowHandle);
            GetFullWindowRect(ref rect);
            User32.SetWindowPos(_windowHandle, IntPtr.Zero,
                                rect.Left, rect.Top,
                                rect.Right - rect.Left, rect.Bottom - rect.Top,
                                WindowPositionFlags.SWP_NOACTIVATE | WindowPositionFlags.SWP_NOZORDER);

            _windowHandle = windowHandle;
        }