アークピットのホームページに戻る

WinAPIトピックのトップページに戻る

APIトピックの各章に移動する

ダウンロードのページに移動する
ダウンロードができ
ない場合の対処法
 

ページ移動

2-1-4. クラスの登録

 ウィンドウクラスは、WNDCLASS 構造体を使って、RegisterClass 関数で登録します。または、WNDCLASSEX 構造体を使って、RegisterClassEx 関数で登録します。ここでは登録の方法を少し詳しく述べます。
    WNDCLASSEX wc;                                 // 定義用の構造体
    static LPSTR pClassName = "ApHelloClass";      // クラス名
    static LPSTR pAppName = "ApHello";             // リソース名

    wc.cbSize        = sizeof(WNDCLASSEX);         // 構造体サイズ
    wc.style         = CS_HREDRAW | CS_VREDRAW;    // クラススタイル
    wc.lpfnWndProc   = (WNDPROC)ApHelloProc;       // プロシージャ
    wc.cbClsExtra    = 0;                          // 補足メモリブロック
    wc.cbWndExtra    = 0;                          //   のサイズ
    wc.hInstance     = hInst;                      // インスタンス
    wc.hIcon         = LoadIcon(hInst,pAppName);   // アイコン
    wc.hCursor       = LoadCursor(NULL,IDC_ARROW); // カーソル
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);   // 背景色
    wc.lpszMenuName  = pAppName;                   // メニュー
    wc.lpszClassName = pClassName;                 // クラス名
    wc.hIconSm       = LoadImage(hInst,pAppName    // 小さいアイコン
                                ,IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
    if (!RegisterClassEx(&wc)) return FALSE;       // 登録
 上記に一般的なクラスを登録するコードを示します。このコードは、大部分が、WNDCLASSEX 構造体を設定する作業です。つまりこの構造体の内容が、すなわちクラスの内容と言えます。クラス名やリソース名は、使用部で直接に定義しても良いのですが、複数使用し、さらに後で変更する可能性がありますので、static で静的定義します。

 cbSize と言う変数があり、これに構造体のサイズを設定していますが、なぜでしょう。WIN32では、良く使う技法です。これには2つの大きな意義があります。まず改訂による拡張機能との互換性をこれで吸収します。

    WNDCLASS wc;

    wc.cbSize = sizeof(WNDCLASS);
 Windows v3.1 の16ビットのころは、上記のルーチンでした。これをそのままWIN32環境で実行しても、またWIN32でリコンパイルし直して実行しても、動作に問題はありません。それは、cbSize で、WNDCLASS,WNDCLASSEX のどちらを使用するか明示しているからです。WNDCLASSEX の変数である、hIconSm は、cbSize が sizeof(WNDCLASSEX) のときだけ有効です。この様にしとけば、古い版との互換性の他に、拡張機能が欲しいときだけ、サイズを変えその機能を使えば良いので、非常に便利です。
 またサイズを設定する技法は、互換性のためだけでなく、いろいろなプログラミングの側面で役立ちます。例えば、サイズの後方を使用する時や、いくつかの構造体を連ねた時などです。

クラスのスタイル(style)

 style メンバには、クラスのスタイルを設定します。このスタイルには、検討点が多々あります。
CS_BYTEALIGNCLIENT,CS_BYTEALIGNWINDOW
CS_BYTEALIGNCLIENT は、ウィンドウのクライアント域をバイト境界に揃えて描画を高速化します。CS_BYTEALIGNWINDOW は、ウィンドウをバイト境界に揃えて、移動やサイズ変更を高速化します。この2つは共に表示や操作が高速化される可能性があります。特にエディタのスクロールの様に、高速性が要求される場合に便利です。表示ドライバとの関連で、確実に高速化されると言えないのが残念です。

CS_CLASSDC,CS_OWNDC,CS_PARENTDC

デバイスコンテキストとは、アプリケーションが自分のウィンドウのクライアント領域を描画する際に使用する、1組の特殊な値のことです。Windows は、画面上の各ウィンドウに対してデバイスコンテキストを要求しますが、オペレーティングシステムによるデバイスコンテキストの格納方法とその扱い方については、若干の柔軟性が許されています。デバイス コンテキストのスタイルを特に指定しない場合、各ウィンドウが使用するデバイスコンテキストは、Windows が管理するコンテキストプールから取得されるものとみなされます。このような場合、各ウィンドウは描画の前にデバイスコンテキストの取得と初期化を行い、描画後にそれを解放しなければなりません。
ウィンドウ内を描画する必要が生じるたびにデバイスコンテキストを取得するような手間を省くため、アプリケーションはウィンドウクラスに CS_OWNDC スタイルを指定することができます。このクラススタイルは、プライベートなデバイスコンテキスト、すなわちそのクラスの各ウィンドウに対して一意に割り当てられるデバイスコンテキストを作成するよう、Windows に指示します。この場合、アプリケーションはコンテキストを1回だけ取得するだけでよく、後続の描画操作でそのコンテキストを使うことができます。CS_OWNDC スタイルは便利ですが、デバイスコンテキストはシステムリソースのかなりの部分を占めるので、使うときには注意してください。
CS_CLASSDC スタイルを指定することにより、アプリケーションはクラスデバイスコンテキストを作成できます。クラスデバイスコンテキストはあまり使われない機能ですが、このコンテキストは、1つのプロセス内の同じウィンドウクラスから作成される複数のウィンドウが、描画の際にまったく同じデバイスコンテキストを使用することを可能にするものです。
アプリケーションは、親ウィンドウのデバイスコンテキストを継承する子ウィンドウを作成するために、 CS_PARENTDC スタイルを指定することができます。このスタイルにより、子ウィンドウがその親ウィンドウのクライアント領域内で描画できるようになります。

CS_GLOBALCLASS

ウィンドウクラスがアプリケーショングローバルクラスであることを指定します。詳しくは、「クラスとは何か」のアプリケーショングローバルクラスを参照してください。

CS_HREDRAW,CS_VREDRAW

ウィンドウの移動やサイズ変更によって、クライアント領域の CS_HREDRAW は幅が、CS_VREDRAW は高さが変更されたときに、 ウィンドウ全体を再描画することを指定します。

CS_NOCLOSE

[閉じる]コマンドとコントロールメニューを使用不能にします。

CS_DBLCLKS

マウスカーソルがそのクラスに属するウィンドウの中に置かれている間に、ユーザーがマウスをダブルクリックしたときに、ダブルクリックメッセージをウィンドウプロシージャに送ることを Windows に指示します。

CS_SAVEBITS

別のウィンドウによって隠された自分のウィンドウの画面イメージの一部分を、ビットマップとして保存します。Windows は、別のウィンドウが退いたときに、この保存されたビットマップを使って画面イメージを再作成します。ほかの画面操作によって格納されたイメージが無効化されていなければ、Windows はビットマップを元の位置に表示して、ほかのウィンドウによって隠されたウィンドウに、WM_PAINT メッセージを送りません。このスタイルは、メニューやダイアログボックスのように、短時間だけ表示されて。ほかの画面操作が起こる前にすぐに消去されるような、小さなウィンドウで使うと便利です。このスタイルを使った場合、システムは最初にビットマップを格納するためのメモリを割り当てるので、ウィンドウの表示に多少時間がかかります。

プロシージャの設定(lpfnWndProc)

 WNDCLASS,WNDCLASSEX 構造体の、lpfnWndProc メンバにプロシージャを設定します。これはユーザが作成するコールバック関数を設定します。

補足メモリブロック

 cbClsExtra,cbWndExtra にはメモリブロックのサイズを設定します。cbClsExtra はクラスに付随する補足メモリで、cbWndExtra はウィンドウに付随する補足メモリです。詳しくは、クラスとはをご覧ください。

アイコン(hIcon)

 hIcon には、クラスアイコンを設定します。このメンバは、アイコンを識別するハンドルでなければなりません。通常は、リソースにICON文でアイコンを指定し、それを LoadIcon 関数でロードしハンドルを得ます。そしてそのアイコンのハンドルを設定します。
 このメンバが、NULLのときは、ユーザーがアプリケーションのウィンドウをアイコン化するたびに、アプリケーションがアイコンを描画しなければなりません。

カーソル(hCursor)

 hCursor には、クラスカーソルを設定します。このメンバは、カーソルを識別するハンドルでなければなりません。通常は、システムが用意している矢印のカーソルを、LoadCursor(NULL,IDC_ARROW) 関数でロードしハンドルを得ます。NULL は、システムであることを表し、IDC_ARROW は、矢印の通常カーソルを指定します。ユーザが用意するときは、リソースに CURSOR 文でアイコンを指定し、それを LoadCursor 関数でロードしハンドルを得ます。そしてそのアイコンのハンドルを設定します。
 このメンバが、NULLのときは、マウスがアプリケーションのウィンドウに移動されるたびに、アプリケーションがマウスカーソルの形状を明示的に設定しなければなりません。

背景色(hbrBackground)

 hbrBackground には、クラス背景ブラシを設定します。このメンバは、クライアントエリアの背景の描画に使われる物理ブラシを識別するハンドル、またはカラー値です。カラー値を指定するとき、そのカラー値は次に示す標準システムカラーのいずれかでなければなりません。ただし、選択した色には1を加えなければなりません(たとえば、CCOLOR_WINDOW + 1 はシステム背景色を示します)。
    COLOR_ACTIVEBORDER    COLOR_ACTIVECAPTION  COLOR_APPWORKSPACE
    COLOR_BACKGROUND      COLOR_BTNFACE        COLOR_BTNSHADOW
    COLOR_BTNTEXT         COLOR_CAPTIONTEXT    COLOR_GRAYTEXT
    COLOR_HIGHLIGHT       COLOR_HIGHLIGHTTEXT  COLOR_INACTIVEBORDER
    COLOR_INACTIVECAPTION COLOR_INACTIVECAPTIONTEXT COLOR_MENU
    COLOR_MENUTEXT        COLOR_SCROLLBAR      COLOR_WINDOW
    COLOR_WINDOWFRAME     COLOR_WINDOWTEXT
 システムは、クラスが解放されるときに、クラス背景ブラシを自動的に削除します。クラスはアプリケーションの複数のインスタンスで使われている可能性があるため、アプリケーションでこれらのブラシを削除しないでください。このメンバがNULLのときには、アプリケーションはクライアント領域の描画が要求されるたびに、自分自身の背景を描画しなければなりません。アプリケーションは、WM_ERASEBKGND メッセージを処理したり、BeginPaint 関数が設定する PAINTSTRUCT 構造体の fErase メンバを調べることにより、背景の描画が必要な時期を特定できます。

メニュー(lpszMenuName)

 lpszMenuName には、NULLで終わる文字列を指すポインタを設定します。この文字列は、クラス メニューのリソース名(リソースファイル内での名前と同じです)を示します。整数を使用してメニューを識別するときは、MAKEINTRESOURCE マクロを使います。このメンバがNULLのときには、このクラスに属するウィンドウにデフォルトメニューはありません。

スモールアイコン(hIconSm)

 hIconSm には、スモールアイコンのビットマップを設定します。WIN32では、小さいアイコンを多用します。これを行なわなければ、大きいアイコンをシステムが縮小して表示しますので、非常に見難くなってしまいます。アイコンエディタで大・小の2つのアイコンを作成しましょう。ところでアイコンとは、アプリケーションを示す小さなビットマップのことです。ウィンドウの左上に表示します。またエクスプローラやデスクトップなど、あらゆる個所で表示します。アプリケーションを代表する必要がある場合は、このアイコンで行ないます。

その他(hInstance,lpszClassName)

 hInstance でインスタンスを明示します。lpszClassName でクラス名を指定します。そして、RegisterClassEx 関数でクラスを登録します。間違いがあれば、0を返します。通常、コードに間違いが無ければエラーにはなりません。偶然に同じクラス名が登録されていれば、エラーになりますので、クラス名の命名には気を付けてください。

ページ移動