C#2.0時代のゲームプログラミング(23)

前回書いたように

いま二つのアプリを立ち上げて、ひとつを画面2でフルスクリーン化、もうひとつを画面1で最大化したとしよう。画面1の最大化にともなって、画面2の仮想スクリーン座標におけるBoundsは変更になる。これに伴って、画面2でフルスクリーン化しているアプリは自分のLocationを変更しなければならない。

のだが、この変更をするのが意外に難しいのだ。


なぜなら、global::System.Windows.Forms.Screen.AllScreensプロパティは、すべての画面の情報を返すが、この情報は、このアプリの起動時のものであって、画面解像度をChangeDisplaySettingsExで変更してもそれに追随するわけではないからだ。


それでいて、global::System.Windows.Forms.Screen.FromHandleはWin32APIのMonitorFromWindowを呼び出しているだけなので、Formに対してそれFormの最大面積が属する画面を正しく返してくる。つまり、AllScreensは起動時の画面情報、FromHandleは現在の画面情報に基づくのだ。


よって、AllScreensは決して使うべきではない。EnumDisplayDevicesで毎回地道に列挙すべきだ。そして、自分がフルスクリーン化(解像度を変更した)DeviceNameを覚えておいて、ウィンドゥモードに戻すときは、そのDeviceNameを持つ画面を探して元に戻すべきだ。決して、FromHandleでScreenを特定して、ChangeDisplaySettingsExを呼び出してはいけない。(つづく)