開いている WPF ウィンドウがデスクトップの接続されたモニターのいずれかに現在表示されているかどうかを判断する方法はありますか? 目に見えるとは、ウィンドウの境界の四角形が、いずれかのモニターのデスクトップの四角形と交差することを意味します。
アプリケーションの再起動時にモニター構成 (作業領域の境界、モニター数) が変更されたため (ウィンドウの位置が保存されます)、ウィンドウの位置を変更する必要があるかどうかを判断するには、この機能が必要です。
以下のコードを思いつきましたが、動作しているように見えますが、いくつかの問題があります。
- Windowsフォームを参照する必要があります。
- デスクトップの DPI 設定が必要で、Windows フォームの実際のピクセルを WPF 仮想ピクセルに変換します。
- 変換を実行するには、既にレンダリングされている実際の Visual インスタンスが必要です。
上記の 3 つの問題の一部またはすべてを解決するソリューションをご存知ですか?
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
internal static class Desktop
{
private static Size dpiFactor = new Size(1.0, 1.0);
private static bool isInitialized;
public static IEnumerable<Rect> WorkingAreas
{
get
{
return
Screen.AllScreens.Select(
screen =>
new Rect(
screen.WorkingArea.Left * dpiFactor.Width,
screen.WorkingArea.Top * dpiFactor.Height,
screen.WorkingArea.Width * dpiFactor.Width,
screen.WorkingArea.Height * dpiFactor.Height));
}
}
public static void TryInitialize(Visual visual)
{
if (isInitialized)
{
return;
}
var ps = PresentationSource.FromVisual(visual);
if (ps == null)
{
return;
}
var ct = ps.CompositionTarget;
if (ct == null)
{
return;
}
var m = ct.TransformToDevice;
dpiFactor = new Size(m.M11, m.M22);
isInitialized = true;
}
}
(初期化された)Desktop
クラスの使用法:
private bool IsLocationValid(Rect windowRectangle)
{
foreach (var workingArea in Desktop.WorkingAreas)
{
var intersection = Rect.Intersect(windowRectangle, workingArea);
var minVisible = new Size(10.0, 10.0);
if (intersection.Width >= minVisible.Width &&
intersection.Height >= minVisible.Height)
{
return true;
}
}
return false;
}
アップデート
SystemParameters.VirtualScreen*
複数のモニターを使用する場合、「デスクトップ」は単純な長方形ではないため、仮想スクリーン ( ) の使用は機能しません。ポリゴンかもしれません。仮想画面に死角ができます。
- 接続された画面は異なる解像度を持つことができます
- 各画面の位置を設定できます。