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);
}
}
}
}
1条答案
按热度按时间5lhxktic1#
我借用了castorix提供的pInvoke方法,并添加了wndproc来处理
WM_DISPLAYCHANGE
消息,这样您的显示分辨率和方向值就会动态变化。