私はこの投稿に出くわし、私がやろうとしていたことを完全に捉えた答えはどれもなかったことがわかりました。私は3840x2160の解像度のラップトップと1920x1080の解像度の2台のモニターを持っています。WPFアプリケーションで正しいモニターサイズを取得するには、アプリケーションをDPI対応にする必要がありました。次に、Win32APIを使用してモニターサイズを取得しました。
これを行うには、最初にウィンドウを、サイズを取得したいモニターに移動します。次に、アプリケーションのMainWindowのhwnd(メインウィンドウである必要はありませんが、私のアプリケーションには1つのウィンドウしかない)とIntPtrをモニターに取得します。次に、MONITORINFOEX構造体の新しいインスタンスを作成し、GetMonitorInfoメソッドを呼び出しました。
MONITORINFOEX構造体には、作業領域と画面のフル解像度の両方があるため、必要なものを返すことができます。これにより、System.Windows.Formsへの参照を省略できるようになります(アプリケーションで他の何かが必要ない場合)。このソリューションを考え出すために、System.Windows.Forms.Screenの.NETFrameworkリファレンスソースを使用しました。
public System.Drawing.Size GetMonitorSize()
{
var window = System.Windows.Application.Current.MainWindow;
var hwnd = new WindowInteropHelper(window).EnsureHandle();
var monitor = NativeMethods.MonitorFromWindow(hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST);
NativeMethods.MONITORINFO info = new NativeMethods.MONITORINFO();
NativeMethods.GetMonitorInfo(new HandleRef(null, monitor), info);
return info.rcMonitor.Size;
}
internal static class NativeMethods
{
public const Int32 MONITOR_DEFAULTTONEAREST = 0x00000002;
[DllImport("user32.dll")]
public static extern IntPtr MonitorFromWindow(IntPtr handle, Int32 flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool GetMonitorInfo(HandleRef hmonitor, MONITORINFO info);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
public class MONITORINFO
{
internal int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
internal RECT rcMonitor = new RECT();
internal RECT rcWork = new RECT();
internal int dwFlags = 0;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public RECT(System.Drawing.Rectangle r)
{
left = r.Left;
top = r.Top;
right = r.Right;
bottom = r.Bottom;
}
public static RECT FromXYWH(int x, int y, int width, int height) => new RECT(x, y, x + width, y + height);
public System.Drawing.Size Size => new System.Drawing.Size(right - left, bottom - top);
}
}