以下の内容はhttps://sabakunotabito.hatenablog.com/entry/2023/03/19/205518より取得しました。


古の魔法を、現代に蘇らせよ ~.NETとWin32APIで、世界の解像度を操る~

どうやら、一筋縄ではいかない砂の迷宮に迷い込んだらしい。この顛末を書き残しておくか。

仕事で、ディスプレイの解像度を自在に操る魔法が必要になった。しかし、その魔法は、Win32 APIという、古の時代に記された難解な魔導書にしか記されていない。私は、.NET 6という現代の魔法体系を使いながら、この失われし古の魔法を再現する、という禁断の錬金術に挑むことにした。

旅の舞台は、コンソールアプリという簡素な祭壇。しかし、マルチディスプレイという複数の世界を認識するためには、WinFormsという、かつて栄華を誇った神殿の力の一部を借りる必要がある。これは、新旧の魔法を融合させ、世界の理(ことわり)そのものを書き換える、一人の魔法使いの冒険の記録である。

この羊皮紙のあらまし

この羊皮紙が導く者

  • ディスプレイの解像度を、プログラムという名の呪文で操りたいと願う者
  • Win32 APIという古の魔法を、現代の言葉で詠唱することに興味がある探求者
  • .NET 6という新たな大地で、失われた魔法を蘇らせる術を知りたい冒険者

第一の儀式:古の魔法との契約(Win32 APIの定義)

我々が呼び覚ますのは、EnumDisplayDevicesChangeDisplaySettingsExという、二つの古の魔法だ。これをC#という現代の言葉で詠唱できるよう、DllImportという契約の呪文で、その存在を定義する。

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern int EnumDisplayDevices(...);

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
static extern int ChangeDisplaySettingsEx(...);

同時に、魔法に必要なDISPLAY_DEVICEDEVMODEという、二つの神器の構造も、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 | 世界を書き換える魔法の古文書

ラクダの独り言

ご主人が「せかいのかいぞうどをかきかえる!」とか言って、また黒い画面に呪文を打ち込んでいる。俺に言わせりゃ、世界の解像度なんて、自分の目が良けりゃそれで済む話だろうに。まったく、人間ってのは、道具に頼ってばかりだな。おっと、また腹が鳴っちまった。




以上の内容はhttps://sabakunotabito.hatenablog.com/entry/2023/03/19/205518より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14