通过生命周期管理 MAUI 窗口(Windows)

2022年10月31日 1473点热度 0人点赞 0条评论
内容纲要

Microsoft.MauiMicrosoft.Maui.LifecycleEvents 中,有个管理 MAUI 窗口生命周期的扩展。

public static MauiAppBuilder ConfigureLifecycleEvents(
this MauiAppBuilder builder, 
Action<ILifecycleBuilder>? configureDelegate);

本文目的是在 Windows 下,使用 WinUI 的方式将窗口控制的接口。

参考资料:
https://docs.microsoft.com/zh-cn/windows/win32/winmsg/about-windows

https://stackoverflow.com/questions/71806578/maui-how-to-remove-the-title-bar-and-fix-the-window-size

在程序启动时,注入窗口生命周期处理事件,此时可以通过代码管理窗口。

#if WINDOWS            
            builder.ConfigureLifecycleEvents(events =>
            {
                events.AddWindows(wndLifeCycleBuilder =>
                {
                    wndLifeCycleBuilder.OnWindowCreated(window =>
                    {
                        // 是否显示系统自带的标题栏
                        window.ExtendsContentIntoTitleBar = true;

                        IntPtr nativeWindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(window);
                        WindowId win32WindowsId = Win32Interop.GetWindowIdFromWindow(nativeWindowHandle);
                        AppWindow winuiAppWindow = AppWindow.GetFromWindowId(win32WindowsId);
                        if (winuiAppWindow.Presenter is OverlappedPresenter p)
                        {
                            p.SetBorderAndTitleBar(false, false);
                        }
                        const int width = 1200;
                        const int height = 800;

                        // 重新设置默认打开大小
                        winuiAppWindow.MoveAndResize(new RectInt32(1920 / 2 - width / 2, 1080 / 2 - height / 2, width, height));
                        winuiAppWindow.SetPresenter(AppWindowPresenterKind.Overlapped);

                        winuiAppWindow.Changed += (w, e) =>
                        {
                            // 窗口大小调整事件
                            if (e.DidSizeChange)
                            {
                            }
                        };

                    })
                    // 窗口关闭后,
                    .OnClosed((window, args) =>
                    {

                    });
                });
            });
#endif

其中两个窗口对象 AppWindow、Window(winuiAppWindow, window) ,都是我们后续管理窗口所需要的对象。
如果程序只有一个窗口,那么可以通过单例模式,处理这两个对象。

他们的 API 使用方法如下:

        private readonly AppWindow _appWindow;
        private readonly Window _window;

        private WindowService(AppWindow appWindow, Window window)
        {
            _appWindow = appWindow;
            _window = window;
        }
        public bool FullScreenState { get => _appWindow.Presenter.Kind == AppWindowPresenterKind.FullScreen; }

        public void FullScreen()
        {
            _appWindow.SetPresenter(AppWindowPresenterKind.FullScreen);
        }

        public void ExitFullScreen()
        {
            _appWindow.SetPresenter(AppWindowPresenterKind.Default);
        }

        public void Minmize()
        {
#if WINDOWS
            var mauiWindow = App.Current.Windows.First();
            var nativeWindow = mauiWindow.Handler.PlatformView;
            IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);

            PInvoke.User32.ShowWindow(windowHandle, PInvoke.User32.WindowShowStyle.SW_MINIMIZE);
#endif
        }

        public void Exit()
        {
            _window.Close();
        }

        public void SetSize(int _X, int _Y, int _Width, int _Height)
        {
            _appWindow.MoveAndResize(new RectInt32(_X, _Y, _Width, _Height));
        }

        public (int X, int Y) GetPosition()
        {
            var p = _appWindow.Position;
            return (p.X, p.Y);
        }

        public (int Width, int Height, int ClientWidth, int ClientHeight) GetSize()
        {
            var size = _appWindow.Size;
            var clientSize = _appWindow.ClientSize;
            return (size.Width, size.Height, clientSize.Width, clientSize.Height);
        }

        public (PointInt32 Position, SizeInt32 Size, SizeInt32 ClientSize) GetAppSize()
        {
            return (_appWindow.Position, _appWindow.Size, _appWindow.ClientSize);
        }

痴者工良

高级程序员劝退师

文章评论