4 章基本的なイベントハンドリン m—CIassWizard の使用 あたって、 3 つの特別な Windows のメッセージは特に注目に値する。ウインドウの初期化時に送 られる WM-CREATE とは対象的に、これら 3 つのメッセージはすべてウインドウのシャットダウ ン処理中に送られる。 ÄWM_CLOSE メッセージ ューザーがシステムメニューによりウインドウをクローズしたとき、親ウインドウがクローズした ときに、 Windows は WM-CLOSE メッセージを送る。 0 C / 0 メッセージマップ関数を派生ビュー クラス中に実装した場合、クローズ処理を制御することができる。たとえば変更をファイルに保存 するかどうかをユーザーに問い合わせる場合、これを 0 C あ内で行なうことができる。ウインド ウを安全にクローズできると判断したときのみ、クローズ処理を続行するべースクラスの OnClose 関数を呼び出しを行なう。ビューオプジェクトと対応するウインドウはどちらもまだアクテイプで ある。 情報読者がアプリケーションフレームワークをフルに活用しているなら、おそらく WM- CLOSE メッセージハンドラを使わないだろう。第 24 章で示すように、代わりに高度に構造化 されたアプリケーションフレームワークの終了手続きである、 C. 〃 0 7 怩厩の立怩財 0 e 仮想関数をオーバーライドするだろう。 ÄWM_QUERYENDSESSION メッセージ ューザーが Windows を終了するときに、 Windows は WM_QUERYENDSESSION メッセー ジを実行中のすべてのアプリケーションに送る。 0 Q 怩 E S ぉ s あ〃メッセージマップ関数はこれを ハンドルする。読者が WM-CLOSE 用にハンドラを書く場合には、 WM-QUERYENDSESSION 用のハンドラも書く。 DWM_DESTROY メッセージ Windows はこのメッセージを WM-CLOSE メッセージの後に送り、 0 〃 es の , メッセージマッ プ関数がこれをハンドルする。プログラムがこのメッセージを受けたら、画面上のビューウインド ウはすでに見えていないが、それはまだアクテイプであり、またその子ウインドウもまだアクティ プであると仮定しなければならない。このメッセージハンドラは、下位のウインドウの存在に依存 するクリーンアップを行なう。このとき、べースクラスの 0 D おの , 関数を呼び出すこと。読者の ビューの 0 D 関数内では、ウインドウの破棄処理を「アポート」することはできない。これ ウインドウの破棄中に Windows が送る最後のメッセージである。すべての子ウインド ZWM_NCDESTROY メッセージ を行なうことが可能なのは 0 刃 C ん中である。 これは、
11 章 タイマの同時使用 ピットマップボタン、 タイマ、アイドル中の処理 Windows バージョン 3.1 は、合計 32 個のタイマの同時使用を許している。実際のアプ 207 イバスするために決して見ることはない。 WM-COMMAND メッセージに変換する。 WM_PAINT メッセージも、メッセージがキューをノ タンをクリックした場合には、その結果生成される WM_LBUTTONDOWN メッセージを適切な は、 WM-KEYDOWN メッセージを WM_CHAR メッセージに変換し、ユーザーがダイアログボ 4 撝財ぉ望 gge の呼び出し後まで生成されないので、それらを見ることはない。この変換関数 P ん盟ぉ s 〃 ge 呼び出しの後で WM-COMMAND 、あるいは WM_CHAR メッセージを探しても、 :DispatchMessage(&Message) ; :TransIateMessage(&Message) ; Message . message , Message . wParam, Message. IParam) ; %x, IParam = %lx\n" 0/oX , wParam TRACE("message if ( : :PeekMessage(&Message, NULL, 0 , 0 , PM_REMOVE)) { while ( 1 ) { / / 無限ループ MSG Message ; / / Windows のメッセージ構造体 プログラムのほとんどどこに置いても、入力される生のメッセージを見ることができる。 ジキュー内のこれらのメッセージへの直接のアクセスを提供している。以下のコードを Windows メッセージへの応答として呼び出される。 Windows は、開発の基本的な部分においては、メッセー ハンドリングメンバ関数は、 BN_CLICKED( 実際には WM_COMMAND メッセージ ) といった リング処理を少し詳しく調べなければならない。読者はすでに処理の末端を見ている。メッセージ どのようにして制御を拠出するのか ? 答えを理解するためには、 Windows のメッセージハンド プログラムが制御を拠出しない限り、タイマは動作しない。 サーが別のアプリケーションに切り換えたいかもしれない。読者がこれらを想定しない場合でも、 を終了させるために [ キャンセル ] ボタンをクリックする必要があるかもしれないし、あるいはユー 限り、コンピュータの全制御を奪ってしまう。それではなぜ制御を拠出するのか ? ューザーが処理 らかである。プログラムが長い計算のループに入った場合、制御を定期的に他に渡すようにしない 16 ビット形式の Windows が先制的なマルチタスクのオペレーティングシステムでないことは明 0 制御の拠出 ばならない。この状態は、 S 石襯げの返り値 0 により示される。 リケーションでは、すべてのタイマが使用中であるという可能性に対しても準備しなけれ
PART 1 Windows 、 Visual C 十十、アプリケーションフレームワークの基本 もう一度例を見て欲しい。今回は大きなイメージを描いてみよう。アプリケーションの機能のほ とんどは、クラスライプラリのべースクラスの C ル加第力と C. ん〃花ル〃中にある。 MYAPP を 書く際、私たちはいくっかの単純な構造ルールに従った、キーになる関数を派生クラス内に書いて いる。 C 十十は私たちに、たくさんのコードをコピーすることなしに「貸し出してくれる」。これを、 私たちとアプリケーションフレームワークとの間の共同作業と考えよう。アプリケーションフレー ムワークは構造を提供し、私たちはアプリケーションをユニークなものとするコードを提供する。 今読者は、なぜアプリケーションフレームワークがクラスライプラリを超えるものなのかを学び 始めている。アプリケーションフレームワークはアプリケーションの構造を定義するだけではなく、 C 十十のべースクラス以上のものを含んでいる。すでに隠されたル切〃が動作しているのを見 た。その他の要素は、メッセージ処理、診断、 DLL などをサポートしている。 クラスライプラリのメッセージマッピング 前述の例の 0 ん召 4 ″ 0 メンバ関数を参照して欲しい。 0 ん B ″物〃は仮想関数の理想的な候補で あると思うかもしれない。ウインドウのべースクラスはマウスイベントメッセージ、その他の標準 メッセージ用に仮想関数を定義し、派生ウインドウクラスは、必要に応して関数をオーバーライド することができる。いくつかの Windows クラスライプラリはこの方法で動作する。 クラスライプラリアプリケーションフレームワークは、 Windows 中で使用されるメッセージ用 に仮想関数を使用しない。その代わりに、指定されたメッセージを派生クラスのメンバ関数に「マッ プ」するマクロを使用する。なぜ仮想関数を排除したのか ? 次のような状況を考えよう。 Windows 中に 5 つのウインドウクラスの階層があり、べースクラスは 140 のメッセージ用の仮想関数を定義 する。 C 十十は「 vtable 」と呼ばれる仮想関数ディスパッチ構造体を必要とし、これはべースクラス 中で関数が実際にオーバーライドされるかどうかにかかわらす、それぞれ、クラスー仮想関数の組 み合わせに 4 バイトのエントリを持つ。それゆえ仮想メッセージハンドラをサポートするために 別個のタイプのウインドウやコントロールごとに、アプリケーションは 2.8KB のテープルを必要と する。 メニューコマンドメッセージとボタンのクリックによるメッセージでメニューハンドラはどうな るだろうか ? 各アプリケーションは異なるメニューとボタンのセットを持つので、これらをウイン ドウべースクラス中の仮想関数として定義することはできない。クラスライプラリのメッセージマッ プシステムは大きな vtable を排除し、そしてアプリケーション固有のコマンドメッセージを収容す ドキュメントクラス、アプリケーションクラスなどの非ウインドウ ることができる。これはまた、 クラスがコマンドメッセージをハンドルすることを可能にする。 BorIand が OWL の一部として提 クラスライプラリメッセージハンドラは、関数のプロトタイプ、関数のボディ、メッセージマップ 供している「ダイナミックディスパッチテープル」システムと異なり、メッセージマップは C 十十言 46 語になんら拡張を求めない。
ホ ポインタを介したオプジェクトの参照・ ポインタ宣言・ ポインタデータメンパ・ ポインタで渡される CDC オプジェクト・ ・・ 94 , 100 ・・ 95 ・・ 592 ・・ 590 ・・ 589 メ メイクファイル・・ メイクプログラム・ メインウインドウがない メインウインドウの作成・ メインフレームウインドウ・ ・・ 33 , 34 ・・ 33 ・・ 445 ・ 27 ・・ 45 , 219 , 346 ポインタの参照・ ポインタへの参照・ ポイント・ ~ サイズ・ ~ に対応させられるマッピングモード・ ポーダー ポストイット・ ポリゴン・ ~ の挿入・ ポップアップメニュー ポップアップダイアログ・・ ポップアップスタイル・・ ポップアップジャンプ・・ ~ のタイトル・・ ~ の状態・ ~ イベント・ ~ をグループ化する・ ボタン・ ( 矩形を含む ) と楕円の組み合わせ・ マッピングモード・ マウスメッセージノ、ンドラ・ ~ と追跡・ マウスの捕捉・ マウスのダブルクリックメッセージの禁止・ マウスの衝突テスト・ マウスを捕捉する・ マ ~ の塗り潰しモード・ ~ と楕円の組み合わせ・ ・・ 594 ・・ 590 ・・ 108 ・・ 110 ・・ 108 ・・ 543 ・・ 124 ・・ 244 ・・ 140 ・・ 243 ・・ 159 ・・ 396 ・・ 148 ・・ 211 ・・ 233 ・・ 93 ・・ 84 ・・ 95 ・・ 83 ・・ 99 ・・ 429 ・・ 411 ・・ 80 ・・ 109 ・・ 220 , 233 ~ はアプリケーションオプジェクトを介して見つけ ・・ 245 ・・ 451 ・・ 346 ・・ 438 ・・ 454 ・・ 164 ・・ 173 ・・ 162 ・・ 252 ・・ 251 ・・ 615 ・・ 27 ・・ 47 メインフレームとドキュメントテンプレートリソース メインフレームオプジェクト・ なければならない メインメニュー ~ の右から 2 番目・ メソッドを起動・ メソッド関数・ メソッド対メンバ関数・ メタファイル・・ メッセージノ、ンドラ・ メッセージ処理・ メッセージクラッカマクロ・ 区画・・ メッセージ行・ ~ デバイスコンテキスト・ ・・ 519 , 525 , 542 ・・ 542 , 547 関数の内部でデバイスコンテキストオプジェクトを 生成する場合・・ メッセージハンドリング・ 関数・ メッセージボックス・ メッセージマッピング・ メッセージマップ . ~ マクロ・ ~ 工デイタ・ ~ オプジェクト・ 項目のイネープル / ディスエープル・ ・・ 94 ・ 45 ・・ 72 ・・ 160 , 400 ・・ 34 , 228 ・・ 58 , 94 ・・ 72 , 234 ・・ 71 , 72 ・・ 39 , 45 ・・ 85 , 93 , 95 , 102 , 118 ~ を論理 twips に設定する・ ~ は OnPrint が呼び出される前に設定されなけれ 項目のないツールバーボタン・ 項目のヘルプを問い合わせているかどうか・ ・・ 245 ・・ 226 ・・ 243 ・・ 407 ・・ 411 ・・ 29 ・・ 234 ばならない・ マップ・ ~ ファイノレ・ マルチスレッディング・・ マルチタスク・ マルチューザーのアクセス制御・ ム 無効矩形・・ 2 ・・ 366 ・・ 40 , 45 ・・ 183 ・・ 30 ・・ 30 ・・ 482 ・・ 73 ・・ 515 , 536 , 538 , 546 ~ コマンド処理・・ 定義・ 内部でグラフィックを使用・ ~ の下部に子ウインドウのリストを挿入させる ~ の中間への項目の挿入・・ ~ ノ、ンドノレ・ ~ プロンプト・ メモ帳・ メモリイメージ・ ・・ 454 ・・ 229 ・・ 219 ・・ 234 ・・ 241 ・・ 52 ・・ 180
PART 1 Windows 、 VisualC 十十、アプリケーションフレームワークの基本 プログラムではユーサー入力をオペレーティングシステムからのメッセージを介して処理するとい う点である。 注意 Microsoft 基本クラスライプラリ (MFC) バージョン 2.0 を使う Microsoft Visual C 十十を含む、多くの Windows 用の開発環境は、ルか財〃を隠すことと、メッセージハ ンドリング処理を構造化することで、プログラミングを単純化している。クラスライプラ リを使用する場合、ル切盟〃関数を書く必要はないが、オペレーティングシステムとプ ログラムの関係を理解しておくことは有意義である。 多くの Windows のメッセージは厳密に定義されており、すべてのアプリケーションに適用される。 たとえば、 W ー CREATE メッセージはウインドウが作成されるときに送られ、 WM-LBUTTON DOWN メッセージは、ユーザーがマウスの左ボタンを押したときに、 WM_CHAR メッセージは ューザーが文字をタイプしたときに、 WM-CLOSE メッセージはユーザーがウインドウをクロー ズしたときに送られる。その他のメッセージ ( いわゆる「コマンド」メッセージ ) は、ユーサーのメ ー選択の応答としてアプリケーションウインドウに送られる。これらのメッセージはアプリケー ションのメニューレイアウトに依存する。プログラマは、それ以外に「ユーザーメッセージ」という メッセージを定義することができる。 読者のコードがこれらのメッセージをどのように処理するのかについて、 こではまだ悩むこと はない。これはアプリケーションフレームワークの仕事である。しかし、 Windows のメッセージ処 理の必要性は、プログラムに多くの構造を課するということに気付いて欲しい。 Windows プログ ラムを無理やり古い MS-DOS プログラムに似せようと試みないこと。本書内の例題で勉強し、新 たに始めるために準備をしよう。 ■ Windows グラフィックステパイスインターフェイス (GDI) 多くの MS-DOS プログラムは、ビデオメモリとプリンタポートに直接書き込みを行なっていた。 この手法の欠点は、すべてのディスプレイカードとすべての形式のプリンタ用のドライパソフトウェ アを提供しなければならないということである。 Windows はグラフィックスデバイスインターフェ イス (GDI) と呼ばれる抽象的な層を導入した。 Windows がディスプレイとプリンタのドライバを 提供するので、プログラムはシステムに装着されているディスプレイカードやプリンタの形式を知 る必要はない。プログラムは、ハードウェアをアクセスする代わりに、デバイスコンテキストと呼 ばれるデータ構造を参照する GDI ファンクションを呼び出す。 Windows はデバイスコンテキスト 構造体を物理デバイスにマップし、適切な入出力命令を発行する。 GDI は直接的なビデオアクセス とほとんど同し速さであり、さらに Windows 用に書かれた異なるアプリケーションがディスプレ イを共有することを可能にしている。 28
12 章メニューとキーポードアクセラレータ 両方のクラスに持っている場合を考えてみよう。ビューはコマンドルート中で上位なので、ビュー のコマンドハンドラ関数のみが呼び出されることになる。 コマンドハンドラ関数をインストールするためにはどうすればいいか ? 必要なものは、今まで 見てきたウインドウメッセージハンドラのものに似ている。関数の本体、対応するメッセージマッ プエントリ、関数のプロトタイプが必要である。ビュークラスでハンドルしたい [ ズーム ] ( 対応する ID として / D 財ー / 00 財を持っ ) というメニュー項目を持っていると考えて欲しい。最初に、ビュー ある。たとえばアプリケーションが [ 編集 ] メニュー中に [ すべてを消去 ] 項目を持っていた場合、ク リアするものが何もないときは、この項目をディスエープルしたいだろう。読者は間違いなくこの ような淡色化されたメニュー項目を Windows べースのアプリケーションで見たことがあるだろう。 の実装ファイルに以下のコードを追加する。 BEGIN_MESSAGE_MAP (CMyView , CView) ON_COMMAND (IDM_ZOOM, 0 Ⅱ Zoom ) END_MESSAGE_MAP ( ) void CMyView: : 0 Ⅱ Zoom ( ) / / コマンドメッセージの処理コード そして CM ) , 防 e 肥クラスのヘッダファイルに以下の関数のプロトタイプを追加する。 afx—msg void 0 Ⅱ Zoom ( ) ; もちろん、 CIassWizard はウインドウメッセージハンドラの挿入を簡単にしたのと同様に ンドメッセージハンドラの挿入処理を自動化している。 0 派生クラス中のコマンドメッセージハンドリング コマ コマンドルーティングシステムはコマンドメッセージハンドリングのひとつ目の次元である。ク ラスの階層化はふたつ目の次元である。クラスライプラリのクラスのソースコードを見れば、たく さんの ON-COMMAND メッセージマップエントリを見つけるだろう。これらのべースクラスの ひとつ、たとえば CView を派生させたとき、派生クラスはすべての C 防夜メッセージマップ関数 を継承し、これにはコマンドメッセージ関数も含まれている。べースクラスのメッセージマップ関 数をオーバーライドするためには、関数とメッセージマップエントリの両方を派生クラスに追加し たぶんメニュー項目の隣のチェックマークも見たことがあるだろう。 アプリケーションの内部状態に合わせて、メニ 0 更新コマンドメッセージ なければならない。 223 コ - 一項目の表示の仕方を変更する必要がしばしば
20 章状況依存のヘルプ C ル切カカの 0 〃 e ゆ関数は、もっとも外側のフレームウインドウに WM-COMMANDHELP メッセージを送信する。 SDI アプリケーションでは、このメッセージはメインフレームのべースクラス の関数、 C. ん ap 〃 e ル〃の 0 Co 襯襯〃″ゆでハンドルされ、コンテキスト〃 / D 一盟 / F 盟 E を伴って WINHELP を呼び出すことになる。メインフレームウインドウは最上位ウインドウであり、 そしてこれはディジーチェインされた WM_COMMANDHELP メッセージ処理の開始位置である。 ビューウインドウ、あるいは別の子ウインドウ用のヘルプを表示する必要がある場合、派生フレー ムクラス中で WM_COMMANDHELP をマップしなければならない。新たな 0 〃 Co 襯襯〃ゆ 関数は、 WM ー COMMANDHELP メッセージを下位のアクテイプなビューウインドウに送ること になる。ビューウインドウがメッセージを受けたとき、それは適切なヘルプコンテキスト ID を伴っ て WINHELP を呼び出す。 MDI アプリケーションにおいて、 WM_COMMANDHELP メッセージは C 財 D / E 耀襯 e ル〃ク ラスと C 財 D. / C 厖ルクラスの両方でマップされる。 MDI の子がない場合、フレームウインドウ はコンテキストを〃 / 〃一盟 / F. 財 E に設定する。ひとつ以上の子がある場合は、フレームウィ ンドウはメッセージをアクテイプな子ウインドウに送り、その結果ドキュメント用のヘルプコンテキス トが設定される。ビュー用のヘルプが必要な場合は、クラスを CMD / C ルから派生させ、その 派生クラス中で 0 Co 襯襯 4 〃〃 e ゆ関数をマップする。この関数はさらに WM_COMMANDHELP メッセージを下位のビューに送る。 FI の WM_COMMANDHELP 処理は常にトップダウンの順で処理されることを覚えておくこ と。アプリケーションは最初に上位のウインドウにメッセージを送る。これはメッセージを子ウイン ドウに与えるという付加機能を持つ。このルーティングは普通のコマンドルーティングとは異なる。 AShi - FI 処理 ューザーが Shift-F1 を押すか [ 状況依存のヘルフ。 ] ツールバーボタンをクリックした場合には、マッ プされたメニューコマンドメッセージが、 C ルカカの関数 0 Co 厩〃召ゆに送られる。ューザー がマウスカーソルの位置決めをした後で、再びマウスをクリックしたとき、 WM_HELPHITTEST メッセージが、マウスのクリックが検出されたもっとも内部のウインドウに送られる。メッセージが そのウインドウのクラス内でマップされていない場合、ひとっ外側のウインドウがその機会を得る。 SDI アプリケーションでは、 WM_HELPHITTEST は CF, 襯 e ルクラスのメンバ関数 0 ″召ゆ〃″にマップされており、これはヘルプコンテキストを〃 / D 一 M / F. E に設定す る。 MDI アプリケーションでは、メッセージは C 盟〃 / C ルと C D. / F, 襯 e ルの両方のク ラスでマップされている。マウスカーソルが子ウインドウ内にある場合は、ドキュメントのヘルプ コンテキストが設定される。それ以外なら、コンテキストは〃 / D. 一財 / ル F AME に設定される。 ビュー固有のヘルプコンテキストを望む場合には、単にビュークラス中で WM_HELPHITTEST をマップし、メッセージをフレームに渡さないようにすればいい。 0 〃〃ゆ″″の〃耀襯パラ メータは、マウス座標をウインドウのクライアント領域の左上からの相対のデバイス単位で収めて 405
PART 3 ドキュメントーピューアーキテクチャ しない場合は、原書に記述されている「 & 」が使用できる。 ) Windows はキーストロークをメニュー項目にリンクするもうひとつの方法を提供している。キー ポードアクセラレータリソースは、キーの組み合わせと対応するコマンド ID の表から構成されて いる。たとえば [ 編集 ] メニューの [ コピー ] 項目 ( / D. ー ED. / た CO. 召必というコマンド ID を持っ ) は、 キーポードアクセラレータェントリを介して、キーの組み合わせ Ctrl-C にリンクされている。キー ポードアクセラレータのエントリに、メニュー項目が割り当てられている必要はない。 [ 編集 ] メ ニューの [ コピー ] 項目がなくても、キーの組み合わせ Ctr ト C は / D. ー ED. / た CO. Y コマンドを起動 させる。 第 2 章で指摘したように、アプリケーションフレームワークはコマンドメッセージのために洗練 アクセラレータキーもディスエープルされる。 注意キーポードアクセラレータがメュー項目に関連付けられている場合、メニュ 目がディスエープルされたときは、 コマンド処理 とき、以下に示されるどちらかの順で、メッセージハンドラを探し始める。 ができる。アプリケーションフレームワークがフレームウインドウコマンドメッセージを見つけた となる。しかしコマンドルーティングにより、はとんどどの場所でメッセージをハンドルすること こがメッセージハンドラを置く位置 アプリケーションフレームワークを使っていない場合には、 ほとんどのコマンドメッセージはアプリケーションのフレームウインドウ内から発信されるので、 収めている。 ID を持っている。プロジェクトの RESOURCE. H ファイルはアプリケーションのユニークな ID を フレームワークは、 ID_FILE_PRINT 、 ID_FILE_OPEN といった独自の内部コマンドメッセージ セージは AppStudio で割り当てられる # 怩定数で識別される場合が多い。アプリケーション のコマンドメッセージは C ルの & M ぉ s 〃 ge 関数の呼び出しにより送ることもできる。各メッ ラレータ、ツールバー、ダイアログのボタンのクリックにより発信されるものである。さらに されたルーティングシステムを提供する。これらのメッセージはメニュー選択、キーポードアクセ SDI アプリケーション ビュー アプリケーション SDI メインフレーム ドキュメント MDI アプリケーション アプリケーション MDI メインフレーム MDI 子フレーム ドキュメント ビュ ほとんどのアプリケーションでは、個々のコマンドハンドラは特定のクラス内にひとつだけ置か れるが、ビューをひとつだけ持つアプリケーションが、等価なハンドラをビューとドキュメントの 222
PART 2 クラスライプラリピュークラス 0 メッセージマップ ビューウインドウ中でユーザーがマウスの左ボタンをクリックしたとき、 Windows はそのウィ 72 リケーションでは、ドキュメントがアプリケーションの状態を保持するが、本書はまだその時点に 描画し、ユーザー動作によってこの状態を変えることができる。完成されたクラスライプラリアプ バックを行ないたいだろう。ビューの 0 〃〃耀関数はビューの現在の「状態」を元にしてイメージを プログラムがユーサー入力を受け取るのであれば、ユーサーに対して何らかの視覚的なフィ 0 ビュー状態のセープーーークラステータメンバ メッセージマップ関数のコーディングを自動化している。 マの唯一の選択肢であった。幸いにして、 VisuaI C 十十はツール、 CIassWizard を提供しており、 手で書くこともできる。実際、これは Microsoft 基本クラスライプラリバージョン 1.0 のプログラ ジと対応するメンバ関数のプロトタイプを示す表を収めている。メッセージハンドリング関数は、 付録 B ( そしてクラスライプラリのオンラインヘルプファイル ) は、 Windows の全標準メッセー それぞれの Windows メッセージについてどの関数が実行されるかをどのように知るのだろうか ? DECLARE_MESSAGE_MAP ( ) 加えて、クラスへッダファイルに以下の文が必要である。 END_MESSAGE_MAP ( ) / / メッセージマップ用のその他のエントリ ON WM_LBUTTONDOWN ( ) / / OnLButtonDown 処理用のエントリ BEGIN_MESSAGE_MAP (CMyView , CView) 接続するためのメッセージマッブマクロをコードファイルに入れなければならない。 ことを示している。最後に、読者の 0 んお″〃 0 関数をアプリケーションフレームワークに 斤ー襯記法は「何も行なわない」もので、これがメッセージマップ関数用のプロトタイプである afx—msg void OnLButtonDown(UINT nFlags , CP0int point) ; さらに、クラスへッダファイルは対応するプロトタイプを持たなければならない。 / / イベント処理コード入る void CMyView : : OnLButtonDown(UINT nFlags , CP0int point) 関数を持たなければならない。 WM ー LBUTTONDOWN に応答して動作する必要があるなら、ビュークラスは次のようなメンバ ンドウにメッセージ 具体的には WM_LBUTTONDOWN である一一を送る。プログラムが
PART 2 クラスライプラリピュークラス SetScroIISizes 関数 90 ウの制御などを含む、たくさんのメッセージハンドリングの例を以降の章で見ることになる。さし そしてさらに、独自のメッセージを定義することができる。メニュー項目のハンドラ、子ウインド クラスライプラリは約 130 の Windows のメッセージハンドリング関数を直接サポートしている。 その他の Windows のメッセージ ロールの例は、次章の EX05A を参 分での変換はいかなるものでも試みないほうがいい。別のマッピングモードを使用する完全なスク EX04C は入門的な CS げ 0 〃防夜の例である。座標変換はべースクラス内で行なわれるので、自 座標変換ーーこれはまだ 呼び出す。行のサイズは 0 C 尾 4 内で呼び出される S S げ 0 〃 s た es 関数で設定される。 ドレ K. ーこ卍を持ち、この場合「 1 行スクロールアップ」を指定するパラメータを持って 0 〃 S げ 0 〃を る。こで必要なのは、 0 S げ 0 〃関数の直接的な呼び出しである。たとえば、上の方向キーはコー 作も望むなら、スクロールメッセージをシミュレートするために 0 〃 K D 佩関数を使うことにな ラスがこの作業を行なうので何もコードを書く必要はない。しかしキーポードによるスクロール動 の 0 〃 S げ 0 〃仮想メンバ関数を呼び出す。もしマウスによるスクロールのみを望むなら、べースク ROLL と WM_VSCROLL メッセージを送る。これらのメッセージ用のハンドラは、 CS げ 0 〃防夜 0 CS げ 0 〃怖 0 ウインドウでは、スクロールバーはユーザーのマウス操作の結果として、 WM-HSC スクロールキーの CSc 「 0 〃 V / e Ⅳへの接続 しない。 メッセージを生成する。方向キーは ASCII 文字を生成しないので、こでは WM-CHAR を使用 通常の ASCII 文字を表現するキーストロークは、変換された ASCII 文字を送る WM-CHAR は、このメッセージを C 加 % パラメータで制御される s ″文を使用して操作する。 は、押されたキーの変換されていない正確なコードを与える。 0 〃 K Do メッセージマップ関数 たまに、生のキーストロークを処理する必要がある。 Windows の WM-KEYDOWN メッセージ ″怖 ) クラスを介してキーポード入力を取得する。これらはすべて以降の章で説明される。しかし 多くの場合、 Windows はエディットコントロール、キーボードアクセラレータ、あるいは CEd キーストロークのハンドリング 位が 1 ピクセルに一致する。 ングのページと行のサイズを設定する。財財ー TEXT マッピングモードでは、デバイス座標の 1 単 び出されなければならない。この関数はマッピングモード、全体のウインドウサイズ、スクローリ S S げ 0 / トたいは CS げ 0 〃怖 0 のメンバ関数で、スクローリングウインドウの初期化中に必す呼