たびとの旅路 ~電脳砂漠の冒険譚~

フロッピー頼りに歩き、クラウドの地平を見つめる今日まで。見つけたオアシス、迷い込んだ砂の迷宮、全てこの羊皮紙に。

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

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

遥か昔、Windows XPという時代。私は.NET Frameworkという魔法を手に、Win32 APIという古の呪文を数多く詠唱していた。しかし、時代は流れ、魔法体系は.NET 6へと進化した。果たして、現代の言葉で、あの古の魔法は再び詠唱できるのだろうか?

その答えを探すため、私は一つの実験を試みることにした。「タスクバーを自動的に隠す」…Windowsという世界の、境界線を操るささやかな魔法。これを、.NET 6という新たな大地で再現する。これは、失われし古の魔法を、現代の技術で蘇らせる、一人の魔法使いの冒険の記録である。

この羊皮紙のあらまし

この羊皮紙が導く者

  • Win32 APIという古の魔法を、現代の言葉で詠唱することに興味がある探求者
  • .NET 6という新たな大地で、失われた魔法を蘇らせる術を知りたい冒険者
  • Windowsという世界の、根源的な理を書き換えることに喜びを感じる者

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

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

// 世界の境界線(タスクバー)を見つけ出す魔法
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
extern static IntPtr FindWindow(...);

// 境界線に命令を下す魔法
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
extern static UIntPtr SHAppBarMessage(...);

同時に、魔法に必要なAppBarDataという神器の構造も、StructLayoutの呪文で正確に再現せねばならない。

最終儀式:魔法の詠唱と、世界の書き換え(ソースコード)

全ての準備は整った。いよいよ、世界の境界線の理を書き換える、究極の呪文を詠唱する。 祭壇は、Visual Studio 2022で創り出した、.NET 6のコンソールアプリという、ごく簡素なものだ。

using System.Drawing;
using System.Runtime.InteropServices;

// ...(DllImportと構造体の定義は前述の通り)...

// Windowsという大地でなければ、儀式は執り行えない
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
    Console.Error.WriteLine("Windows で実行してください。");
    return;
}

// 現在の境界線の状態を読み解き、逆の状態へと書き換える
if (ABS_AUTOHIDE == GetTaskbarStatus())
{
    Console.WriteLine("Auto hide -> Always on top"); // 隠れているなら、常に表示せよ
    SetTaskbarStatus(ABS_ALWAYSONTOP);
}
else
{
    Console.WriteLine("Always on top -> Auto hide."); // 表示されているなら、自動で隠れよ
    SetTaskbarStatus(ABS_AUTOHIDE);
}

// 境界線の現在の状態を読み解く呪文
uint GetTaskbarStatus()
{
    var data = new AppBarData { hWnd = FindWindow("System_TrayWnd", null) };
    data.cbSize = (UInt32)Marshal.SizeOf(data);
    return (uint)SHAppBarMessage(ABM_GETSTATE, ref data);
}

// 境界線の状態を書き換える呪文
uint SetTaskbarStatus(uint option)
{
    var data = new AppBarData
    {
        hWnd = FindWindow("System_TrayWnd", null),
        lParam = (Int32)option
    };
    data.cbSize = (UInt32)Marshal.SizeOf(data);
    return (uint)SHAppBarMessage(ABM_SETSTATE, ref data);
}

この呪文を唱えるたび、世界の境界線はその姿を変える。

タスクバーが常に表示されている状態

常に表示されている、世界の境界線

タスクバーを自動的に隠す状態

そして、主の呼びかけを待つ、控えめな境界線へ

異世界での実験:WSL2 Ubuntu

興味深いことに、このWindows専用の古の魔法を、WSL2 Ubuntuという異世界で詠唱しようとしても、ビルドは成功してしまう。しかし、実行すれば「ここはWindowsではない」と、我々の世界の理が正しく作動し、儀式は失敗に終わる。

$ dotnet run
Windows で実行してください。

羊皮紙を巻く前に

.NET 6という現代の魔法体系の中で、Win32 APIという古の魔法を詠唱する旅は、想像以上にスムーズなものだった。.NET Framework時代とほぼ同じ感覚で、失われたはずの力を呼び覚ますことができる。これは、過去の膨大な資産を持つ我々冒険者にとって、大きな希望だ。

ただし、注意せねばならない。かつての古文書に記された呪文は、マーシャリングという、異世界との橋渡しの作法が不完全なものが多い。現代で蘇らせる際は、その作法を注意深く見直す必要があるだろう。

この羊皮紙が、同じようにWindowsという世界の深淵を覗き込み、その理を書き換えようと挑む、未来の冒険者の助けとなることを願う。

おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。

砂漠で見つけた魔法のランプ

ラクダの独り言

ご主人が「世界の境界線を消したり出したりする!」とか言って、また黒い画面に呪文を打ち込んでいる。俺に言わせりゃ、そんなもん、必要な時に見えりゃそれでいいだろうに。まったく、人間ってのは、どうでもいいことにこだわるもんだ。おっと、喉が渇いてきやがった。