最初に

スクリーンセーバーなんて作るのは久しぶりで、たいしたことを覚えていないので再調査しつつ作成することになるのですが、なんせインターネットに繋がっていないので調査するのも面倒です。

まずは覚えている範囲で、

  • スクリーンセーバーは専用のウィンドウステーション上で動作する*1
  • ファイル名を SC + 6文字 + .SCR とする*2
  • RESOURCE ID 1 で文字列リソースに名前を設定する
  • コマンドラインオプションに /s /c /p くらいがあり、引数にプレビューウィンドウの親ハンドルが16進数文字列で渡される

くらいかな?

Visual Studio.NET 2003 の Platform SDK の about Screen Saver を流し読みしてみますが、相変わらず Windows NT 3.51 の時代の内容から更新されていないようで、もともと使う気はなかった SCRNSAVE.LIB も Windows NT 3.51 用に作成されて Windows 95 の修正がちょっと入ったところで放置されたままのようでした。

逆に言えば、スクリーンセーバーには大きな変更は入っていない...って、

To have a screen saver display on all monitors, link with the latest version of SCRNSAVE.LIB.
Otherwise, the screen saver may only appear on the primary monitor and leave the other monitors untouched.
Screen savers linked with the latest SCRNSAVE.LIB will work on both single and multiple monitor systems.

なんて見つけてしまいました。私の PC はモニタ2つ繋がるんだし、これは重要っぽいです(笑)
それで、今月送られてきたばかりの最新版の MSDN*3 の Platform SDK を見ると 2003-Feb...これ、Visual Studio.NET 2003 付属より新しい..?(苦笑)一応、VS.NET 2003 付属の SCRNSAVE.LIB の更新日付は 2002.08.09 で、PSDK のほうは 2003.03.26 なので Platform SDK のほうが新しいようです。ただ、

To have a different screen saver on each monitor, use the multiple monitor functions to handle each monitor separately.

と続くので、たぶん GetSystemMetrics API の引数が SM_CXSCREEN/SM_CYSCREEN から SM_CXVIRTUALSCREEN/SM_CYVIRTUALSCREEN にかわったぐらいじゃないでしょうか。
実際に私の環境で Windows XP 標準のスクリーンセーバーを動かしてみると、そのような感じで動作していますし、それらの実行ファイルや SCRNSAVE.LIB の IAT を開いても EnumDisplayMonitors API とか GetMonitorInfo API は乗っかっていませんでした。

*1:Win95/98/Me 以外の話ね

*2:間違ってます

*3:DVD 2426.4 Feb 2004