第127章 スクリーンセーバー その1


今回から、スクリーンセーバーの作り方を解説します。 最初に断っておきますが、Windows95にIE4.0がインストールして あると次のようなちょっと困った現象が起こります。 画面のプロパティから「スクリーンセーバー」タブ を選んで、「ラインアート」などの既存のものを選択します。 そして、プレビューボタンを押します。マウスを 動かすなり、キーを押すなりしてスクリーンセーバーを 終了させます。すると、タイミングによってはタスクバーに 何も表示されていないアイコン(と言うかボタンというか) が残ってしまいます。これをクリックするとこのボタンは 消えてなくなりますので実害はないようです。 (メモリーリークが有るのかもしれませんが筆者は知りません)
IE4.01以降がインストールされている場合は上記の症状は出ません。


それは、ともかく作り方を見てみましょう。

1.いつものようにWin32Applicationの設定でプロジェクトを新規作成 2.このプロジェクトに必要なものはソースファイル、scrnsave.lib 3.ソースファイルに必須の関数は   ScreenSaverProc ScreenSaverConfigureDialog RegisterDialogClasses 4.ScreenSaverProcはいつものウィンドウプロシージャの感じ 5.ソースファイルにはscrnsave.hをインクルードします 6.ビルドして完成した*.EXEは*.SCRにRENAMEしてWindowsのディレクトリにコピー

WinMain関数はスクリーンセーバーライブラリの方で面倒をみてくれているので 自分で書く必要はありません。(スクリーンセーバーライブラリを使用しない で書く方法もあります。この場合は当然WinMain関数は必要です。) また、scrnsave.hにはHWND hMainWindow, HINSTANCE hMainInstanceが externされています。 前者はスクリーンセーバーの親ウィンドウ、このインスタンスハンドルです。 また、hMainWindowはScreenSaverProc関数の第1引数の親ウィンドウでもあります。

さて、早速プログラムを見てみましょう。今回は 単に動作するだけで、設定のダイアログなどは一切付けていません。 従って、「画面のプロパティ」の「スクリーンセーバー」タブ のところにある「設定」ボタンは押さないでください。

// saver01.rcの一部 ///////////////////////////////////////////////////////////////////////////// // // Bitmap // MYBMP1 BITMAP DISCARDABLE "cat1.bmp" MYBMP2 BITMAP DISCARDABLE "cat2.bmp"

スクリーンセーバーに表示するビットマップを2つ用意します。 このビットマップをランダムに次々と表示しようというものです。 プロジェクトにはこのリソース・スクリプトも参加させておきます。

// saver01.cpp #include <windows.h> #include <scrnsave.h> #define ID_TIMER 32767 LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { RECT rc; HDC hdc, hdc_mem; static int wx, wy; int x1, x2, y1, y2, r, g, b, bmp_w, bmp_h; HBRUSH hBrush, hOldBrush; HBITMAP hBitmap; BITMAP bmp_info; switch(msg) { case WM_CREATE: GetClientRect(hWnd, &rc); wx = rc.right - rc.left; wy = rc.bottom - rc.top; SetTimer(hWnd, ID_TIMER, 100, NULL); break; case WM_TIMER: r = rand() % 256; g = rand() % 256; b = rand() % 256; hdc = GetDC(hWnd); hBrush = CreateSolidBrush(RGB(r, g, b)); hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); x1 = rand() % wx; y1 = rand() % wy; x2 = rand() % wx; y2 = rand() % wy; Rectangle(hdc, x1, y1, x2, y2); if (r % 2 == 0) hBitmap = LoadBitmap(hMainInstance, "MYBMP1"); else hBitmap = LoadBitmap(hMainInstance, "MYBMP2"); GetObject(hBitmap, sizeof(BITMAP), &bmp_info); bmp_w = bmp_info.bmWidth; bmp_h = bmp_info.bmHeight; hdc_mem = CreateCompatibleDC(hdc); SelectObject(hdc_mem, hBitmap); x1 = rand() % wx; y1 = rand() % wy; x2 = rand() % wx; y2 = rand() % wy; BitBlt(hdc, x1, y1, bmp_w, bmp_h, hdc_mem, 0, 0, SRCCOPY); DeleteDC(hdc_mem); DeleteObject(hBitmap); SelectObject(hdc, hOldBrush); DeleteObject(hBrush); ReleaseDC(hWnd, hdc); break; case WM_DESTROY: KillTimer(hWnd, ID_TIMER); PostQuitMessage(0); return 0; default: break; } return DefScreenSaverProc(hWnd, msg, wParam, lParam); } BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { return TRUE; } BOOL WINAPI RegisterDialogClasses(HANDLE hInst) { return TRUE; }

ソースファイルを一気に表示しました。 多くの場合、WM_CREATEのところで、タイマーをセットして、 WM_TIMERメッセージが来たら描画をします。 そして、WM_DESTROYのところで後始末をします。

自分で処理しないメッセージはDefWindowProcではなく DefScreenSaverProcに渡します。

左の図は実際にスクリーンセーバーを起動したときの画面の様子です。 猫のビットマップ(2種類)といろいろな色の長方形が ランダムに表示されます。



ところで、デジタルカメラなどでとったGIFやJPEGの画像を 画像ソフトでコピーして、VC++5.0のイメージエジタに貼り付けると 色落ちして困っている方はいませんか? コピーを使うとあまりうまくいきません。 まず、GIFやJPEGのColor Depthをパレットイメージの256色に 減色します。そして、これをBMPとして保存します。 つぎに、VC++の「挿入」「ビットマップ」「インポート」で取り込むと きれいに取り込めます。


[SDK第2部 Index] [総合Index] [Previous Chapter] [Next Chapter]

Update 31/May/1998 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。