|
|
|
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つの大きな意義があります。まず改訂による拡張機能との互換性をこれで吸収します。
クラスのスタイル(style) style メンバには、クラスのスタイルを設定します。このスタイルには、検討点が多々あります。
CS_CLASSDC,CS_OWNDC,CS_PARENTDC
ウィンドウ内を描画する必要が生じるたびにデバイスコンテキストを取得するような手間を省くため、アプリケーションはウィンドウクラスに CS_OWNDC スタイルを指定することができます。このクラススタイルは、プライベートなデバイスコンテキスト、すなわちそのクラスの各ウィンドウに対して一意に割り当てられるデバイスコンテキストを作成するよう、Windows に指示します。この場合、アプリケーションはコンテキストを1回だけ取得するだけでよく、後続の描画操作でそのコンテキストを使うことができます。CS_OWNDC スタイルは便利ですが、デバイスコンテキストはシステムリソースのかなりの部分を占めるので、使うときには注意してください。 CS_CLASSDC スタイルを指定することにより、アプリケーションはクラスデバイスコンテキストを作成できます。クラスデバイスコンテキストはあまり使われない機能ですが、このコンテキストは、1つのプロセス内の同じウィンドウクラスから作成される複数のウィンドウが、描画の際にまったく同じデバイスコンテキストを使用することを可能にするものです。 アプリケーションは、親ウィンドウのデバイスコンテキストを継承する子ウィンドウを作成するために、 CS_PARENTDC スタイルを指定することができます。このスタイルにより、子ウィンドウがその親ウィンドウのクライアント領域内で描画できるようになります。 CS_GLOBALCLASS
CS_HREDRAW,CS_VREDRAW
CS_NOCLOSE
CS_DBLCLKS
CS_SAVEBITS
プロシージャの設定(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を返します。通常、コードに間違いが無ければエラーにはなりません。偶然に同じクラス名が登録されていれば、エラーになりますので、クラス名の命名には気を付けてください。
|