windows Winui3:如何从设置中获取显示分辨率和显示方向的值,并将其添加到组合框中

qyswt5oh  于 2023-05-01  发布在  Windows
关注(0)|答案(1)|浏览(284)

描述问题Hi,
我在一个winui3应用程序工作,在那里我有2个组合框命名为显示分辨率和显示方向。我的要求是,我需要从显示设置[Resolution & Orientation ]中获取数据,并将值添加到combox框中。每个系统的分辨率将相应地改变,所以我不能硬编码该值。我需要动态获取数据,并需要添加到组合框的值。如何做到这一点?
先谢了
硬编码工作,但我需要从系统中获取分辨率和方向的数据,然后需要将其添加到我的组合框中

5lhxktic

5lhxktic1#

我借用了castorix提供的pInvoke方法,并添加了wndproc来处理WM_DISPLAYCHANGE消息,这样您的显示分辨率和方向值就会动态变化。

public sealed partial class MainWindow : Window
{

    public MainWindow()
    {
        this.InitializeComponent();

        MainWindow.WndProc._coreWindowHwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
        _oldWndProc = MainWindow.WndProc.SetWndProc(WindowProcess);

        UpdateResolutionAndoRientation();
    }

    private IntPtr WindowProcess(IntPtr hwnd, uint message, IntPtr wParam, IntPtr lParam)
    {
        switch (message)
        {
            case WM_DISPLAYCHANGE:
                UpdateResolutionAndoRientation();
                break;
            default:
                break;
        }
        return MainWindow.Interop.CallWindowProc(_oldWndProc, hwnd, message, wParam, lParam);
    }

    private void UpdateResolutionAndoRientation()
    {
        DEVMODE devmode = new DEVMODE();
        devmode.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE));
        bool bRet = EnumDisplaySettingsEx(IntPtr.Zero, ENUM_CURRENT_SETTINGS, ref devmode, 0);
        if (!bRet)
        {
            devmode.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE));
            bRet = EnumDisplaySettingsEx(IntPtr.Zero, ENUM_REGISTRY_SETTINGS, ref devmode, 0);
        }
        Debug.WriteLine("Bits Per Pel : " + devmode.dmBitsPerPel);
        Debug.WriteLine("Display Frequency (Htz) : " + devmode.dmDisplayFrequency);
        Debug.WriteLine("Log Pixels : " + devmode.dmLogPixels);
        Debug.WriteLine("Pels Width : " + devmode.dmPelsWidth);
        Debug.WriteLine("Pels Height : " + devmode.dmPelsHeight);
        Debug.WriteLine("Position X : " + devmode.dmPositionX);
        Debug.WriteLine("Position Y : " + devmode.dmPositionY);
        float nRatio = (float)((float)devmode.dmPelsWidth / (float)devmode.dmPelsHeight);
        string sOrientation = "";
        if (nRatio > 1) sOrientation = "Landscape"; else sOrientation = "Portrait";
        Debug.WriteLine("Orientation : " + devmode.dmDisplayOrientation.ToString() + " (" + sOrientation + ")");
        
    }

    private void myButton_Click(object sender, RoutedEventArgs e)
    {
        myButton.Content = "Clicked";   
    }
  
    [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern bool EnumDisplaySettingsEx(IntPtr lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode, int dwFlags);

   
    public const int ENUM_CURRENT_SETTINGS = -1;
    public const int ENUM_REGISTRY_SETTINGS = -2;

    public const int EDS_RAWMODE = 0x00000002;
    public const int EDS_ROTATEDMODE = 0x00000004;

    public const int WM_DISPLAYCHANGE = 0x007E;

    private IntPtr _oldWndProc;

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct DEVMODE
    {
        private const int CCHDEVICENAME = 32;
        private const int CCHFORMNAME = 32;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
        public string dmDeviceName;
        public short dmSpecVersion;
        public short dmDriverVersion;
        public short dmSize;
        public short dmDriverExtra;
        public int dmFields;
        public int dmPositionX;
        public int dmPositionY;
        public DISPLAYORIENTATION dmDisplayOrientation;
        public int dmDisplayFixedOutput;
        public short dmColor;
        public short dmDuplex;
        public short dmYResolution;
        public short dmTTOption;
        public short dmCollate;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHFORMNAME)]
        public string dmFormName;
        public short dmLogPixels;
        public int dmBitsPerPel;
        public int dmPelsWidth;
        public int dmPelsHeight;
        public int dmDisplayFlags;
        public int dmDisplayFrequency;
        public int dmICMMethod;
        public int dmICMIntent;
        public int dmMediaType;
        public int dmDitherType;
        public int dmReserved1;
        public int dmReserved2;
        public int dmPanningWidth;
        public int dmPanningHeight;
    }

    public enum DISPLAYORIENTATION : int
    {
        DMDO_DEFAULT = 0,
        DMDO_90 = 1,
        DMDO_180 = 2,
        DMDO_270 = 3
    }

    [ComImport, Guid("45D64A29-A63E-4CB6-B498-5781D298CB4F")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ICoreWindowInterop
    {
        IntPtr WindowHandle { get; }
        bool MessageHandled { get; }
    }

    public class Interop
    {
        [DllImport("user32.dll", EntryPoint = "SetWindowLong")] //32-bit
        public static extern IntPtr SetWindowLong32(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

        [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")] // 64-bit
        public static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);
    }

    public static class WndProc
    {
        public delegate IntPtr WndProcDelegate(IntPtr hwnd, uint message, IntPtr wParam, IntPtr lParam);
        private const int GWLP_WNDPROC = -4;

        public static IntPtr _coreWindowHwnd;

        private static WndProcDelegate _currDelegate = null;

        public static IntPtr SetWndProc(WndProcDelegate newProc)
        {
            _currDelegate = newProc;

            IntPtr newWndProcPtr = Marshal.GetFunctionPointerForDelegate(newProc);

            if (IntPtr.Size == 8)
            {
                return Interop.SetWindowLongPtr64(_coreWindowHwnd, GWLP_WNDPROC, newWndProcPtr);
            }
            else
            {
                return Interop.SetWindowLong32(_coreWindowHwnd, GWLP_WNDPROC, newWndProcPtr);
            }
        }

    }
}

相关问题