スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

スクリーンセーバーの作り方

WindowsにおけるスクリーンセーバーのC言語プログラムの例と、MinGWによるコンパイル手順。

以下に紹介するプログラムを雛形(あるいは叩き台)にして、オリジナルのスクリーンセーバーの制作にチャレンジしてみてはいかがでしょうか。

プログラムに関するポイントは、以下の3点です:

  • ヘッダファイル「screensave.h」をインクルードする。
  • ウィンドウプロシージャは「WndProc関数」ではなく「ScreenSaverProc関数」である。
  • 既定の処理は「DefWindowProc関数」ではなく「DefScreenSaverProc関数」が提供する。

コンパイルに関するポイントは、以下の2点です:

  • 「scrnsave.lib」(もしくは「scrnsavw.lib」)をリンクする。
  • 実行形式のファイルの拡張子は「scr」にする。

Windows XP上での作業を前提としています。MinGWのWindows XPにおけるセットアップ方法については、以下の記事をお読みください。

Windows XPにおけるC言語およびC++のセットアップ作業のメモ

プログラム例

リソースファイル

Windowsプログラミングにおいて、メニュー、ダイアログボックス、アイコン、カーソルなどはリソース(resource)と呼ばれます。スクリーンセーバーにおいては、画面のプロパティでの設定に利用されるダイアログボックスの作成にリソースファイルが必要になります。

/* resource.rc */

#include <windows.h>
#include <scrnsave.h>

#define IDC_STATIC -1

/* 設定用ダイアログ */
DLG_SCRNSAVECONFIGURE DIALOG DISCARDABLE  0, 0, 220, 50
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Sample Screensaverの設定"
FONT 9, "MS Pゴシック"
BEGIN
  DEFPUSHBUTTON "OK", IDOK, 85, 30, 50, 14
  ICON          IDI_WARNING, IDC_STATIC, 6, 5, 20, 20
  LTEXT         "これは設定用ダイアログの雛形です。", 
                IDC_STATIC, 35, 12, 230, 12
END

スクリーンセーバー本体のCプログラム

/* screensv.c */

#include <windows.h>
#include <tchar.h>
#include <scrnsave.h>
#include <time.h>
#include <stdlib.h>

#define ID_TIMER 101

/* スクリーンセーバー本体の処理 */
LRESULT WINAPI ScreenSaverProc(
  HWND hWnd,
  UINT msg,
  WPARAM wParam, 
  LPARAM lParam)
{
  HDC hdc;
  RECT rc;
  HPEN hPen;
  int i, x, y, l, r, g, b;

  switch (msg) {
    case WM_CREATE:
      SetTimer(hWnd, ID_TIMER, 100, NULL);  /* タイマーの作成 */
      srand((unsigned)time(NULL));
      break;
    case WM_TIMER:
      /* メインの処理 */
      /* 円をランダムな大きさと場所で描く */
      hdc = GetDC(hWnd);
      GetClientRect(hWnd, &rc);
      x = rand() % rc.right;
      y = rand() % rc.bottom;
      l = rand() % rc.right / 6;
      r = rand() % 256;
      g = rand() % 256;
      b = rand() % 256;
      hPen = CreatePen(PS_SOLID, l, RGB(r, g, b));
      SelectObject(hdc, hPen);
      MoveToEx(hdc, x, y, NULL);  /* 直線の始点 */
      LineTo(hdc, x, y);  /* 直線の終点(=始点で点を描画) */
      ReleaseDC(hWnd, hdc);
      break;
    case WM_DESTROY:
      KillTimer(hWnd, ID_TIMER);  /* タイマーの破棄 */
      PostQuitMessage(0);
      break;
    default:
      break;
  }
  return DefScreenSaverProc(hWnd, msg, wParam, lParam);
}

/* 設定用ダイアログボックスの処理 */
BOOL WINAPI ScreenSaverConfigureDialog(
  HWND hDlg, 
  UINT msg, 
  WPARAM wParam, 
  LPARAM lParam)
{
  switch (msg) {
    case WM_INITDIALOG:
      MessageBox( 
        hDlg, 
        _T("このスクリーンセーバーには、設定オプションがありません。"),
        _T("Sample Screensaver"), 
        MB_OK | MB_ICONWARNING );
      EndDialog(hDlg, IDOK);
      return TRUE;
    case WM_COMMAND:
      switch (LOWORD(wParam)) {
        case IDOK:
          EndDialog(hDlg, IDOK);
          return TRUE;
        case IDCANCEL:
          EndDialog(hDlg, IDCANCEL);
          return TRUE;
      }
      return FALSE;
  }

  return FALSE;
}

/* 設定用ダイアログボックスが必要とする
   非標準のウィンドウクラスを登録する */
BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
  return TRUE;
}

スクリーンセーバーに図形を描画する処理は、ScreenSaverProc関数の case WM_TIMER: の部分に記述しています。ここが、スクリーンセーバーのオリジナリティを決める部分といえます。もっと複雑な処理を行う場合には、そのための関数を別の場所に定義して呼び出す形にするとよいでしょう。

設定用ダイアログボックスは、画面のプロパティにおいてスクリーンセーバーの設定を行うときに呼び出されます。ただし、今回のスクリーンセーバーには設定変更のオプションは用意していません。オプションがないことを知らせるメッセージボックスを表示し、設定用ダイアログボックスは起動しないようにしています。もし設定変更のオプションを用意するのであれば、変更された設定を保存する必要があります。その方法として、レジストリの利用が挙げられます。

コンパイル方法

上に挙げた2つのファイル(resource.rc、screensv.c)を同じフォルダの中に置きます。

コマンドラインにおいて、cdコマンドでソースファイル等の置いてあるディレクトリ(=フォルダ)に移動したのち、以下を実行します:

> gcc -c screensv.c 
> windres resource.rc -o resource.o
> gcc screensv.o resource.o -o screensv.scr -l scrnsave -mwindows

C言語のファイル(screensv.c)とリソースファイル(resource.rc)をそれぞれコンパイルすると、それぞれからオブジェクトファイル(screensv.o, resource.o)が生成されます。それらのオブジェクトファイルをリンクすると、スクリーンセーバーのファイル(screensv.scr)ができあがります。

リソースファイルをコンパイルするときには、windresコマンドを使用します。

gccコマンドでWindowsプログラムをコンパイルする際には、リンク時に「-mwindows」オプションを指定します。

スクリーンセーバーを作成する際には、「scrnsave.lib」(もしくは「scrnsavw.lib」)をリンクする必要があります。そのため、リンク時に「-l scrnsave」オプション(もしくは「-l scrnsavw」オプション)を指定する必要があります。

スクリーンセーバーのファイルの拡張子は「scr」です。

スクリーンセーバーのセットアップ

スクリーンセーバーの設置場所はシステムフォルダです。Windows XPの場合は「C:\WINDOWS\system32」の中です。そこにscrファイルを入れます。

あとは、画面のプロパテイで当該のスクリーンセーバーを選択すればセットアップは完了です。

自作のスクリーンセーバーでトラブルが発生したら

スクリーンセーバーから復帰後に動作がおかしくなるなどの不具合が発生したら、その原因がプログラムにあるのか、それともPC環境のほうにあるのかを判別するために、Windowsに最初から入っているスクリーンセーバーでも同様の現象が起きないかどうか確認してみてください。他のスクリーンセーバーでも同じ不具合が起こる場合、PC環境が原因の可能性も考えられます。

関連記事

MinGWでWindowsプログラミングを行う方法 まとめ

【theme : プログラミング
【genre : コンピュータ

プロフィール

よしいず

Author:よしいず
MATHEMATICS.PDFというウェブサイトを運営しています。

管理の都合上、トラックバックとコメントはオフにしてあります。ブログ経験者なら分かっていただけると思いますが、スパム(アダルトやその他の宣伝)ばかりなのが現実です。

リンクは自由です。当サイトの記事に対する間違いの指摘・意見・感想などを述べた記事からのリンクは歓迎です。ただし、ブログ記事アップ直後はミスが多く、頻繁に修正します。場合によっては削除する可能性もあります。その際、何も断りもなく修正・削除しますがご了承ください。内容を参考にする場合には投稿後一週間ほど様子を見てからにしてください(笑)。

記事の間違いを指摘するときは、その具体的箇所、理由(仕様に反するなど)・根拠(参考にした文献など)、代替案(同じ結果を得るための正しいやり方)も教えてください。そうしないと、(指摘される側および第三者はその時点では無知の状態なので、)どこが間違いなのか分かりませんし、本当に間違っているのかどうかが判断・検証できません。実際、間違いだと指摘されたことが結局は正しかったというケースもありますので。

このブログのタイトル一覧

リンク
月別アーカイブ
カテゴリ
最新記事
検索フォーム
RSSリンクの表示
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。