どうやら、一筋縄ではいかない砂の迷宮に迷い込んだらしい。この顛末を書き残しておくか。
仕事で、ディスプレイの解像度を自在に操る魔法が必要になった。しかし、その魔法は、Win32 APIという、古の時代に記された難解な魔導書にしか記されていない。私は、.NET 6という現代の魔法体系を使いながら、この失われし古の魔法を再現する、という禁断の錬金術に挑むことにした。
旅の舞台は、コンソールアプリという簡素な祭壇。しかし、マルチディスプレイという複数の世界を認識するためには、WinFormsという、かつて栄華を誇った神殿の力の一部を借りる必要がある。これは、新旧の魔法を融合させ、世界の理(ことわり)そのものを書き換える、一人の魔法使いの冒険の記録である。
この羊皮紙のあらまし
- この羊皮紙のあらまし
- この羊皮紙が導く者
- 第一の儀式:古の魔法との契約(Win32 APIの定義)
- 第二の儀式:禁断の融合(コンソールアプリでWinFormsを呼ぶ)
- 最終儀式:魔法の詠唱と、世界の書き換え(ソースコード)
- 羊皮紙を巻く前に
- 砂漠で見つけた魔法のランプ
- ラクダの独り言
この羊皮紙が導く者
- ディスプレイの解像度を、プログラムという名の呪文で操りたいと願う者
- Win32 APIという古の魔法を、現代の言葉で詠唱することに興味がある探求者
- .NET 6という新たな大地で、失われた魔法を蘇らせる術を知りたい冒険者
第一の儀式:古の魔法との契約(Win32 APIの定義)
我々が呼び覚ますのは、EnumDisplayDevicesとChangeDisplaySettingsExという、二つの古の魔法だ。これをC#という現代の言葉で詠唱できるよう、DllImportという契約の呪文で、その存在を定義する。
[DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern int EnumDisplayDevices(...); [DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern int ChangeDisplaySettingsEx(...);
同時に、魔法に必要なDISPLAY_DEVICEとDEVMODEという、二つの神器の構造も、StructLayoutの呪文で正確に再現せねばならない。
第二の儀式:禁断の融合(コンソールアプリでWinFormsを呼ぶ)
通常、簡素な祭壇(コンソールアプリ)では、豪華な神殿(WinForms)の力は使えない。しかし、プロジェクトファイルという名の「世界の設計図」を直接書き換えることで、この禁忌を破ることができる。

設計図に<UseWindowsForms>true</UseWindowsForms>という一文を刻み込み、魂を再び呼び覚ます。すると、依存関係という名の祭壇に、WinFormsの力が宿っているのがわかるだろう。

最終儀式:魔法の詠唱と、世界の書き換え(ソースコード)
全ての準備は整った。いよいよ、世界の理を書き換える、究極の呪文を詠唱する。
// ...(DllImportと構造体の定義は前述の通り)... // 神殿の力で、全てのディスプレイ(世界)を認識する var screens = Screen.AllScreens...; // ...(ディスプレイ情報を取得する処理)... // 新たな世界の理(解像度)を定義する var pDevMode = new DEVMODE(); pDevMode.dmSize = (UInt16)Marshal.SizeOf(pDevMode); pDevMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; pDevMode.dmPelsWidth = 3840; // 横 pDevMode.dmPelsHeight = 2160; // 縦 // まずは、テストモードで、この理が受け入れられるか神託を仰ぐ if (0 != ChangeDisplaySettingsEx(name, ref pDevMode, ..., CDS_TEST, ...)) { Console.Error.WriteLine("神託は下りなかった。変更は不可能だ。"); return; } // 神託が下りたなら、ついに世界の理を書き換える if (0 != ChangeDisplaySettingsEx(name, ref pDevMode, ..., CDS_UPDATEREGISTRY | CDS_FULLSCREEN, ...)) { Console.Error.WriteLine("世界の書き換えに失敗した!"); return; } Console.WriteLine("世界の理は、正常に書き換えられた。");
羊皮紙を巻く前に
.NET 6という現代の魔法体系の中で、Win32 APIという古の魔法を詠唱する旅は、想像以上にスリリングなものだった。特に、コンソールアプリにWinFormsの力を宿らせるという禁断の儀式は、我々の世界の可能性を大きく広げてくれるだろう。
ただし、この融合魔法は、WSL2 Ubuntuという異世界では通用しないことも、今回の旅で明らかになった。古の魔法は、やはりそれが生まれた大地でしか、真の力を発揮しないようだ。
この羊皮紙が、同じようにWindowsという世界の深淵を覗き込み、その理を書き換えようと挑む、未来の冒険者の助けとなることを願う。
東の空が白んできた。次のオアシスへ向けて、そろそろ荷造りを始めるとしよう。
砂漠で見つけた魔法のランプ
- EnumDisplayDevicesW | 古の魔法の古文書
- ChangeDisplaySettingsW | 世界を書き換える魔法の古文書
ラクダの独り言
ご主人が「せかいのかいぞうどをかきかえる!」とか言って、また黒い画面に呪文を打ち込んでいる。俺に言わせりゃ、世界の解像度なんて、自分の目が良けりゃそれで済む話だろうに。まったく、人間ってのは、道具に頼ってばかりだな。おっと、また腹が鳴っちまった。