この回答を調べて、それを改善し、さらに情報を追加して、より完全なソリューションを形成することにしました。
チャレンジ
フォームが現在レンダリングされている画面を追跡します。これは、ユーザーがフォームを別のモニターにドラッグしたり、モニターのプラグを抜いたりすると変化する可能性があります。ユーザーが手動でウィンドウを別のディスプレイにドラッグするか、解像度を直接変更すると、解像度が変わる可能性があります。
まず、フォームの場所を追跡します。フォーム コンテキストの Move イベントにフックする必要があります。幸いなことに、.Net フレームワークはそのようなイベントを提供し、それはControl.Move Eventという名前です。
次に、画面解像度変更イベントにフックする必要があります。これは、SystemEvents.DisplaySettingsChangedイベントで実行できます。
で、まとめるとこうなりました。
struct Resolution
{
public int Width;
public int Height;
}
int previous = -1;
int current = -1;
private bool CheckScreenChanged()
{
bool changed = false;
current = GetScreenIndex();
if (current != -1 && previous != -1 && current != previous) // form changed screen.
{
changed = true;
}
previous = current;
return changed;
}
private int GetScreenIndex()
{
return Array.IndexOf(Screen.AllScreens, Screen.FromControl(this));
}
private Resolution GetCurrentResolution()
{
Screen screen = Screen.FromControl(this);
Resolution res = new Resolution();
res.Width = screen.Bounds.Width;
res.Height = screen.Bounds.Height;
return res;
}
private void SetResolutionLabel()
{
Resolution res = GetCurrentResolution();
label2.Text = String.Format("Width: {0}, Height: {1}", res.Width, res.Height);
}
private void ScreenChanged()
{
label1.Text = "Screen " + current.ToString();
}
private void Form_Moved(object sender, System.EventArgs e)
{
bool changed = CheckScreenChanged();
if (changed == true)
{
ScreenChanged();
SetResolutionLabel();
}
}
public void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
SetResolutionLabel();
}
public void Initialize()
{
this.Move += Form_Moved;
SystemEvents.DisplaySettingsChanged += new
EventHandler(SystemEvents_DisplaySettingsChanged);
previous = GetScreenIndex();
current = GetScreenIndex();
ScreenChanged();
SetResolutionLabel();
}
上記のコードは、label1 と label2 という 2 つのラベルを持つ単純なフォームでテストされています。ラベルは、フォームが表示されている画面が変更されたり、解像度が変更されたりすると更新されます。
プライマリ画面/ディスプレイでの動作中の画像
そして、フォームがドラッグされたときの私の二次画面/ディスプレイで:
