スクリーンセーバーを簡単に作る方法はいろいろ あるだろうけれど、とりあえず、Cを使って作る場合 の取っ掛かりについて(スクリーンセーバー自体の出来とかは 問わないで……自分自身のwinプログラミングの練習のためだから:-)。
(Windowsでの)スクリーンセーバーはドライバーみたいな 特殊なもんでなくWindowsアプリケーション。 ただ、ちょっと満たすべきことがあって、
タイトルや枠線無しで最大化して常に手前表示で、 多重起動できないくて、 キーやマウス入力があれば終了し、 起動時オプションとして、/s スクリーンセーバーの実行 /c 設定ウインドウの表示 /p [xxx] プレビュー /a [xxx] パスワードが必要。 拡張子を.scr にし、 c:\windows\system にいれれば画面のプロパティでの選択肢に現れる。
ちょっとめんどいなあ、ってしろものだけれども、MS の Visual C++ には
scrnsave.lib というライブラリがあって、これを使えば簡単に
スクリーンセーバーが作れるようだ。
しかし、どうもこの scrnsave.lib は Win標準ではなくVC用で、
他の BCC や Watcom 等では scrnsave.lib がついて来ないので
自前で何とかしないと駄目なよう・・・
[2001-12追記]
が、
LCC-Win32
や
MinGW
には scrnsave.lib がついてくるようだ。
とくに MinGW の win32apiライブラリはソースが公開されているようで
他のコンパイラでも使えるみたい(ライセンス的にも?)。
ためしに下記のサンプルを bcc でもコンパイルするために
win32apiライブラリソースから scrnsave.lib の分を抜き出してみたのが
これ。
ということで、下記サンプルは vc, bcc, lcc でコンパイルできそ
(MinGW はリソースのコンパイルで怒られてしまったので、挫折^^;)。
bccで行うときは各サンプルと同じディレクトリに
scrnsave.h とscrnsave.libをコピーしてから mk_bcc.batを実行してください。
逆に他のコンパイラでコンパイルするときは入れちゃ駄目。
http://www2s.biglobe.ne.jp/~maekawa/dev/vc/scrnsave/index.html
上記Webページからすると、ユーザーは以下の
ScreenSaverConfigureDialog() 引数 /c または無しで起動されたとき用。 ユーザが設定するオプション画面など。 ScreenSaverProc( ) スクリーンセーバー本体処理. (/s指定起動時). RegisterDialogClasses( ) 特殊な用途用(?). 普通は真を返すだけでよい模様.
の3つの関数(実質2つ)を作製するのみで、ウィンドウの初期化や
起動時引数の処理はまかせられるようだ。
あとは,普通のWin用ゲーム(アプリケーション)を作るのと要領は同じ
(キー操作や途中の画面サイズ変更などがありえないので、ずっと楽)。
※上記 URL のサンプルプログラムは実行すると、c:\windows に
UserStrSS.INI という設定保存ファイルを作る……のでいらなくなったら
自分で消す、と.
先のURL に十分なサンプルがあるけれど、理解のために別パターンとして サンプルを(いくつか)作ってみた. どちらかというと、自力描画のサンプルなのかもしれないけれど。
□動作
画面いっぱいに、約1/60秒ごとに 約8000個の点を
適当な色でランダムに表示する。
設定画面での設定は無し。
□ソース
参照元にあったユーザー設定画面は不要なので取っ払った。
自力描画のサンプルでもあるので、GDIの描画でなく 仮想バッファをとってそこに書き込んだものを最後に 表示するスタイルになっている。
約 1/60秒ごとにタイマーは設定しているがあまり精度 はよくないし、画面が広いと処理落ちもかなりある。 (32ビット色モードなのでメモリ食い、でもあろう)。
また、スクリーンセーバーという前提なので、Window サイズ変更などの面倒を考えなくてすむので、シングル バッファであったりと、いろいろ端折っている。
VisualStudio上でデバッグすると、デバッグのための キー操作でスクリーンセーバーが終わってしまうことが あって、なかなか不便だった。 リモートデバッグするのも手なんだろうけど、それは それで面倒なので、ルート通過チェックのためのルーチン (printf系)を用意して今回はしのいだ(その時のソースが main_dbg.c)。
□動作
640x480の画面で 一定時間ごとに 点や線、箱を10個づつ
適当に上書きしていく。
設定画面で、真中の640x480 で表示するか、画面イッパイに拡大して表示するか
を選べる。
□ユーザー設定
レジストリでなく、いわゆるiniファイル方式
(単に参照元と同様なだけ、と)。
設定画面(ScrnSvr.scr を直接実行など)のダイアログで OK すると
ユーザー設定項目のセーブファイルとして
c:\windows\ScrnSvr.tmp
が作られる。
不要になったら直接消してください。
□ソース
scrnsvr1.c を改造。
自力描画としては、点以外に線、箱線、箱塗を追加。
また、とりあえず、1ピクセルの色数は 16 or 32ビット色
どちらかソース中で指定できるようにした。
設定では 1/60秒間隔にしているけれど、処理落ちやら精度やら でもっと開いてそう…… 画面全体を毎フレーム転送するので遅い。特に拡大表示は ビデオカードの性能が頼りで、このままでは余り実用的でないような。
□動作
先のサンプルでは、いったん画面をクリアした状態(真っ暗)になるけれど、
これはデスクトップが表示されたままの画面の上に点をイッパイ
打って埋め尽くし、最初は明るく、後、画面を暗くして消してしまう。
ユーザ設定画面の項目はなし。
□ソース
デスクトップ画面の取得の必要から内部の仮想VRAMの管理を変更。
やはし基本はdibにしなきゃ不便なのだなあ。
今回は使っていないけれど scrnsvr2 の線やら箱やらのルーチンも
混ざったままになっている。
画面を消さずにすます方法はお札ばらばら ソース
を参照しました。
とりあえず MinGWのwin32apiライブラリを流用すれば scrnsave.lib の機能が
使えるし、そのソースをみれば何やってるかもわかるのだろうけれど、
とりあえず、
「スクリーンセーバ工作室」
(ホーム)
というページで、APIのみで作る手順の説明と、C++Builder専用の
作成例があるんで、参考になると思います。
ちなみに VC 付属のサンプル中にも、scrnsave.lib の元ネタのような サンプルがあったと思います(リコンパイルすると scrnsave.lib ができる…… ちゃんと試してないのでよくわかんないけれど)。あと英語だけど MSDN に スクリーンセーバ/ScrnSave作成の解説頁があるみたい。