M icrosoft 基本クラスライプラリ アプリケーションフレームワーク 本章では、 Microsoft 基本クラスライプラリバージョン 2.0 ( あるいは単にクラスライプラリ ) ア プリケーションフレームワークの利点を紹介する。アプリケーションフレームワークのプログラミ ングがどのようなものかを完全に理解するのを助けるために、最初に、余計な部分はすべて取り除 いてあるが完全に動作する Windows 用のクラスライプラリプログラムを示す。こでは理屈は最 小限に押さえているが、メッセージマッピングとドキュメントービューの節は、以降の章で役立つ重 要な情報を例と共に収めている。 なせアプリケ - ションフレームワークを使うのか ? Windows 用アプリケーションを開発するにあたっては、ます開発環境を選ばなければならない。 たとえば Microsoft VisuaI Basic のような対話的な環境という選択肢を除くとすると、以下の選 択肢から選ばなければならない。 ・努力して目的にたどり着く Windows SDK ( ソフトウェア開発キット ) ・新しい Micorsoft 基本クラスライプラリアプリケーションフレームワーク ・ BorIand の Object Windows Library (OWL) など、その他の Windows をベースとするアプリ んでいる。どれが楽だろうか ? WindowsSDK のプログラマであるのなら、 もし読者がゼロから始めるのであれば、 ケーションフレームワーク Microsoft Press の編集者は、本章をマーケティング資料のように公正なものにする必要はない クラスライプラリについては、その苦労は途中まで済 どの選択にしても相当な努力が必要である。すでに クラスライプラリバージョン 2.0 は C 十十 Microsoft Windows API である。 以下は筆者が見たこのクラスライプラリの利点である。 待ち続けていたアプリケーション開発環境なのである。 といってくれたが、救いにはならなかった。筆者はこの製品に熱中している。これは私が 10 年間も 39 この前提を受け入れ
26 章 VisuaI C 十十は、クラスライプラリを使って記述された、 C 言語の外部参照インターフェイスを ダイナミックリンクライプラリ (DLL) 従来の DLL と異なり、クラスライプラリ DLL は Microsoft クラスライプラリアプリケーション AMicrosoft C 十十コンバイラにより制限されるクラスライプラリ 0 乢の使用法 従来の DLL とクラスライプラリ DLL の間にはいくつかの大きな違いがある。 ジェクトを作成すること、そしてこれらをベースクラスとして使用することが可能である。ただし れたクラスは、静的にリンクされたクラスと同じように使うことができる。 DLL 内のクラスのオプ クラスライプラリ DLL には、いかなる C 十十クラスでも収容することができる。 DLL に収容さ クラスライプラリ DLL のインターフェイスを持っクラスライプラリ DLL に焦点を当てる。 の種の DLL を示したものである。本章ではこれとは異なる種類の DLL 、つまり C 十十言語と互換 る。 YMSVCYMFCYSAMPLESYDLLTRACE サプディレクトリ内のサンプルプログラムは、 ノート 11 は、ユ—Y*—DLL(-USRDLL) として知られている DLL の記述プロセスを解説してい 持つ従来型の DLL の作成をサポートしている。ヘルプファイル MFCNOTES. HLP のテクニカル えば次の関数 クセスを組み合わせた、特別な内部関数名を使っている。 MicrosoftC 十十コンパイラでは、 名、返されるデータ型、パラメータのデータ型、そしてパプリック / プロテクト / プライベー 内でのみ使用できる。なぜこの制限があるのか ? MicrosoftC 十十コンパイラは、クラス名、関数 たと Windows SDK プログラマ諸氏へ ?GetDescendantWindow@CWnd@@RFCPEV1@H@Z は、以下のようにばらばらにされ、ごてごて飾り付けられた名前に割り当てられる。 CWnd* GetDescendantWindow(int nID) const 553 付き ) では、このェクスポートは必要ない。 だろう。 この要素は忘れること。 Microsoft C / C 十十バージョン 7.0 以降 (/GA スイッチ スポート関数用に、 Windows の財〃乃っぴ加の 2 化関数を使っていたことは間違いない ( クライアント内の関数が Windows と DLL により呼び出される ) 。そしてこれらのェク るなら、恐らくエクスポートしているクライアントコールバック関数を使っていただろう 読者が SDK 環境で Windows の DLL クライアントアプリケーションを書いたことがあ
m—bContinuePrinting ・ m_bModified ・ m nIDTracking ・ m-pDisplayMemDC ・ m-pMainWnd ・ m-pszHelpFiIePath ・ m_rectBounds ・ m_rectDraw• MacApp アプリケーションフレームワーク・ ・・ 326 , 491 ・・ 245 , 346 , 349 ・・ 461 , 475 ・・ 184 , 589 ・ 102 , 103 ・・ 29 , 483 ・・ 367 ・・ 407 ・・ 472 ・・ 398 ・・ 540 ・・ 379 ・・ 27 ・・ 401 ・・ 403 ・・ 403 ・・ 553 ・・ 69 ・・ 404 ・・ 411 ・・ 421 ・・ 344 ・・ 452 MM_HIENGLISH ・ MM_HIMETRIC ・ MM_ISOTROPIC ・ MM_LOENGLISH ・・ ~ モード・ MM_LOMETRIC ・・ MM_TEXT ・ ~ マッピングモード・ ~ モード・ MM_TWIPS ・ ~ の用途・・ main と呼ばれる関数・ MakeBitmap ・ MAKEHELP ・ 処理・・ MAKEHM. EXE ・ MakeProclnstance ・・ MAK ファイル・ malloc ・ MAP セクション・ MATPLAN アプリケー MDB_CANCEL ・ MDI ・ ン・ヨ ン - ョ ン・ ModifyMenu ・・ MRU ・ MS-DOS アプリケー MSVCVARS. BAT ・・ new ・ ~ ヒープ・・ near ・ nCmdShow ・ nChild ・ NAME パラメータ・ ・・ 104 , 368 , 371 , 373 ・・ 177 ・・ 181 ・・ 613 ・・ 555 , 559 , 589 ・・ 104 , 368 , 373 ・ 104 , 526 , 540 ・・ 104 , 476 ・・ 162 , 164 ・・ 260 ・・ 452 ・・ 54 ・・ 395 ・・ 33 ・・ 325 ・・ 233 ・・ 108 ・・ 90 ・・ 472 ・・ 104 ・・ 102 ・ 104 ~ アプリケーション・ ~ クライアントウインドウ・ ~ アプリケーションクラス・ ・・ 41 , 52 , 437 ・・ 341 , 411 ~ クライアントウインドウがメインフレームウイン ドウに割り付けられる・ 子ウインドウがひとつのとき・ ~ ドキュメントテンプレートクラス・ ~ フレームウインドウと子ウインドウ・ ・・ 345 ・・ 344 ・・ 508 ・・ 446 ~ によってクライアントアプリケーションのメモリ が割り当てられる・ ・・ 556 ~ の代わりに Windows のグローノヾルメモリ割り当 M essage B OX ・ MFC200D. DLL ・ MFC200. DLL ・ MFCNOTES. HLP ・・ ~ は標準 AFX リソースを収めている・ Micorsoft 基本クラスライプラリバージョン 2.0 ・ ・・ 400 ・・ 557 ・・ 92 ・・ 43 ・・ 515 ・・ 481 ・・ 33 ・・ 483 ・・ 551 , 554 ・・ 554 , 566 て関数を使う・ N extD IgCtrI ・ NMAKE ・・ NotifyChanged ・ NotifySaved ・ 0 Microsoft Access ・ Microsoft Excel ・ Microsoft Open Database Connectivity ・ Object Linking and Embedding : OLE ・ Object Windows Library (OWL) ODBC ・・ ~ データベースアクセスプログラム・ ・・ 540 , 545 ・・ 483 , 509 , 552 Microsoft Quick C for Windows ・ Microsoft SQL Server ・・ Microsoft Visual Basic ・ ~ コントローノレ・ Microsoft Windows ・・ Microsoft Windows 3.1 プログラマーズリファレンス Microsoft Word for Windows ・ Microsoft 基本クラスライプラリ・ ~ ノヾージョン 2.0 ・ MM_ANISOTROPIC ・・ ・・ 29 , 39 , 161 ・・ 104 ・・ 39 ・・ 28 , 38 ・・ 392 , 515 ・・ 455 ・・ 34 , 41 ~ の DLL 階層・ ODBC. DLL ・・ ODBC. INI ・ ODBC. LIB ・ OLE ・ ~ アイテム・ ・・ 30 , 41 , 65 , 67 , 348 , 513 ~ アイテム対 C 十十オプジェクト・ ~ アイテムの大きさの取得と設定・・ ~ アイテムの削除・ ~ アイテムのシリアライズ・・ ・・ 183 ・・ 277 ・・ 38 ・・ 540 ・・ 30 ・・ 39 ・・ 481 ・・ 488 ・・ 483 ・・ 483 ・・ 509 ・・ 523 ・・ 515 ・・ 526 ・・ 526 ・・ 542 625
1 章 Microsoft Windows と Visual C 十十 ることができる ! 試してみるといい ( その場合 App Studi0 を別のファイルとしてコピーし、その コピーをロードしないといけない ) 。 AC / C 十十コンノヾイラ VisuaI C 十十コンパイラは、 C ソースコードと C 十十ソースコードの両方を処理することができ る。コンパイラはソースコードファイル名の拡張子を調べて言語を決定する。 C という拡張子は C ソースコードを示し、 CPP 、あるいは CXX は C 十十ソースコードを示す。コンパイラは ANSI ノ ジョン 2.1 に準拠し、さらに Microsoft の付加的な拡張がある。ただし VisuaIC 十十バージョン 1.0 では、テンプレートと例外処理の文法はサポートされていない。 VisuaI Workbench の CMicrosoft Foundation Class を使用 ] オプション ( [ オプション ] の < プロジェクトの設定 > ダイアログボック ス中 ) は、コンパイラが Microsoft 基本クラスライプラリのインクルードファイルを使用するかど うかを決定する。 0 リンカ VisuaI C 十十リンカは、 EXE ファイルを生成するために、コンパイラが生成した OBJ ファイル を処理する。 VisuaI Workbench の CMicrosoft Foundation CIass を使用 ] オプションを指定する と、リンカは適切なメモリモデル用の Microsoft 基本クラスライプラリを使用する。 0 リソースコンノヾイラ VisuaI C 十十リソースコンパイラは、コンパイルモード、あるいはバインドモードのどちらかで 動作する。コンパイルモードでは、 AppStudio で生成した ASCII のリソース ( RC ) ファイルをバ イナリの RES ファイルにコンパイルする。バインドモードでは、 RES ファイルが実行 (EXE) ファ イルにマージされる。 RES ファイルを更新したときは、再リンクすることなしに、 RES ファイル を EXE ファイルに再バインドすることができる。 0 テパッガ プログラムが最初から動作すれば、デバッガは必要ない。そうでないなら、デバッガが必要なこと がある。 VisuaI C 十十デバッガは、 Windows 上で動作する初めての C 十十のデバッグ環境である。 デバッガはプレークポイントをディスク上に確実に保存するために、 VisuaIWorkbench と共に緊 密に動作する。ツールバーのボタンでプレークポイントをオン / オフし、シングルステップ実行を 制御する。 Figure 1 ー 2 は動作中の C 十十デバッガを示したものである。派生クラスとべースクラス のすべてのデータメンバを表示するために、く口一カル > ウインドウ中で、どのようにオプジェク トボインタが展開されているかに注目すること。プログラムをデバッグするためには、コンパイラ とリンカのオプションをデバッグ情報を生成するように設定して、プログラムをビルドしなければ ならない。 35
2 章 Microsoft 基本クラスライプラリアプリケーションフレームワーク る。普通のクラスライプラリは、任意のプログラムと結合できるように設計された、独立したクラ スのセットであるが、アプリケーションフレームワークはプログラム自身の構造も定義している。 これはわすかな区別にしか聞こえないし、実際その通りである。 Microsoft 基本クラスライプラリ ノヾージョン 1.0 、 BorIandOWL 、 Micorsoft 基本クラスライプラリバージョン 2.0 といったはとん どの Windows の開発クラスライプラリは、アプリケーションフレームワークと考えられる。しか しながら、 Microsoft 基本クラスライプラリバージョン 2.0 はその他の製品以上の相当量の機能を 提供している。 0 アプリケーションフレームワークの例 一般論はこれで十分だろう。すでにいくらかのコードを見る段階にきている。擬似コードではな く、実際にコンパイルし、クラスライプラリと共に動作する本物のコードである。なんだと思う ? 古き良き「 He110 world! 」アプリケーションにちょっと手を加えたものだ ( すでにバージョン 1.0 の クラスライプラリを使っているなら、フレームウインドウのべースクラスを除いて、このコードは なじみのあるものだろう ) 。 Windows 用のクラスライプラリアプリケーションとして動作する、お およそ最低量のコードである。同等の Windows SDK アプリケーションと対比してみよう ! では各行を理解する必要はない。またこれをタイプ入力すること、テストすることで悩まなくてい い。次の章を待てば、そこでは「本物の」アプリケーションフレームワークを使い始められる。 注意規約により、クラスライプラリのクラス名は文字 C で始まる。 以下は、我らの MYAPP アプリケーション用のヘッダと実装ファイルのソースコードである。 CMyApp と CMyFrame のふたつのクラスは、それぞれクラスライプラリのべースクラスから派生 させたものだ。最初は、 MYAPP アプリケーション用のヘッダファイル MYAPP. H である。 / / アプリケーションクラス class CMyApp : public CWinApp public: virtual BOOL 工 nitlnstance ( ) ; / / フレームウインドウクラス class CMyFrame : publi c CFrameWnd public : CMyFrame ( ) ; protected : / / 'afx-msg' は、以下のふたつの関数がクラスライプラリのメッセージ / / ディスパッチシステムに組み込まれることを示している afx—msg void OnLButtonDown(UINT nF1ags , CP0int point) ; afx—msg void OnPaint ( ) ; DECLARE_MESSAGE_MAP ( ) 43
0 ■ー 0 一 PART 1 Windows 、 VisualC 十十、アプリケーションフレームワークの基本 ファイル旧編集旧しおり (M) 著作権 0 ヘルプ ( 旦 ) 目次 ( C ) ヒストリ ( T ) プラウサ (R 検索 ( s ) 戻る ( B) 階田 CView: :GetDocument CDocument* GetDocument() const; 説明 ビューのドキュメントへのポインタを取得します。これにより、ドキュメント のメンバ関数を呼び出すことができます。 戻り値 ビューに関連付けられた CDocument オブジェクトへのポインタを返します。 ヒ、ユーがドキュメントに関連付けられていなかった場合は、 NULL を返します FigureI-3 Visual C 十十ヘルプのウインドウ ÄWindows 診断ツール プロフェッショナルエディションの Visual C 十十には、別製品である Windows SDK に含まれ るものと同じ診断ツールが収められている。 Windows メッセージを観察する SPY 、メモリを調べ る HEAPWALK 、ヘルプファイルをコンパイルする HC31 、使用可能メモリを作為的に制限する STRESS 、コード中のボトルネックとなる部分を警告するプロファイラブログラムなどである。 VisuaI C 十十のスタンダードエディションとプロフェッショナルエディションはどちらも、診断 出力表示用の DBWIN ューティリティ、手で書かれたメイクファイルを処理する NMAKE プログ ラムを収めている。 NMAKE は非標準バージョンの Microsoft 基本クラスライプラリをビルドす るのに使用される。 0 M icrosoft 基本クラスライプラリバージョン 2.0 Microsoft 基本クラスライプラリ、バージョン 2.0 ( あるいは単にクラスライプラリ ) は、本書の 真の主題である。これは読者が詳しく知りたいであろうアプリケーションフレームワークを定義し ている。第 2 章からは、実際のコードといくつかの重要な概念を示しながら学び始める。 38
基本的なイベントハンドリング CIassWizard の使用 Microsoft 基本クラスライプラリアプリケーションフレームワークが、どのようにビュークラス の仮想関数 0 D を呼び出すかを第 3 章で見てきた ーで、クラスライプラリリファレンスを 調べてみよう。 C 防砒 , クラスと、そのべースクラス C ルのドキュメントを探せば、数百のメン ノヾ関数を見ることになる。 0 K Do 広 0 カお″″のゆといった、 0 〃で始まる名前が付けられて いる関数は、キーストローク、マウスのクリックといった各種の Windows 「イベント」への応答と して、アプリケーションフレームワークが呼び出すメンバ関数である。 これらアプリケーションフレームワークに呼び出される関数のほとんどは、 0 D のような仮 想関数ではないので、プログラムするためにはより多くの努力を必要とする。本章では、アプリケー ションフレームワークと読者の関数のコードとを結び付けるために必要な、「メッセージマップ」構 造をセットアップするために、 VisuaI C 十十の CIassWizard をどのように使うかを説明する。 こでは、実践的なメッセージマップ関数のアプリケーションを提示する。 最初のふたつの例では普通の C 怖クラスを使用している。多くの場合、読者は「スクロールす る」ビューを要望するだろう。最後の例は C 怖 e 肥べースクラスの代わりに CS げ 0 〃怖召を使ってい る。これにより、アプリケーションフレームワークはスクロールバーを挿入し、ビューを「すらす」 ことができる。 ユーサー入力の取得ーーメッセージマップ関数 第 3 章の EX03A アプリケーションは (Micorsoft Windows の標準のウインドウのサイズ変更、 クローズ以外の ) ューザー入力を受け取ることはできなかった。ウインドウはメニューとツールバーを 持っていたが、これらはビューのコードに「接続」されていなかった。メニューとツールバーはフレー ムクラスに依存しているので本書の第 3 部まで待たねばならないが、それ以外の多くの Windows の入力ソースはそれまでの間、読者を忙しくさせることだろう。しかしながら、マウスのクリック のような各種 Windows のイベントを処理できるようになる前に、クラスライプラリのメッセージ マップシステムをどのように使用するかを学ばなければならない。
TrueType is a registered trademark of Apple Computer, lnc. CASE:W is a trademark of Caseworks, lnc. TETRIS is a trademark of v/o electronorgtechnica. LaserJet is a registered trademark of Hewlett-Packard Company. Lego is a registered trademark Of Lego Systems, lnc. Microsoft is a registered trademark and Microsoft Access, Microsoft QuickBasic, Visual Basic, Visual C 十十 , Windows, and the Windows operating system 10g0 are trademarks Of Microsoft Corporation. 3M is a registered trademark and Post-it is a trademark Of 3M Corporation. Smalltalk is a registered trademark of Xerox Corporation. Copyright 1994 by Microsoft Corporation. Original English language Edition Copyright ◎ 1993 David J. Kruglinski Published by arrangement with the original publisher, Microsoft Press, a division of Microsoft Corporation, Redmond, Washington, U. S. A. Japanese language Edition published by ASCII Corporation 1994. 本書は、株式会社アスキーが米国 Microsoft 社との契約により翻訳したものです。
1. 2. 3. 4. 26 章ダイナミックリンクライプラリ (DLL) VisuaI Workbench の < プロジェクトの設定 > ダイアログ中で CMicrosoft Foundation Class を使用 ] チェックポックスのチェックをはすす。 < C/C 十十コンパイラオプション > ダイアログ中で、 [ 共通 ] ラジオボタンを押してから以下の [ ビルドオプション ] を変更する。 〇 [ メモリモデル ] : [ モデル ] を [ ラージ ] に設定する。 〇 [ プリプロセッサ ] : [ シンポルとマクロの定義 ] に「 _AFXDLL 」を追加する。 〇 CWindows の起動と終了 ] : [far 関数として生成する ] チェックポックスをチェックする。 プロジェクトのくリンカオプション > ダイアログ中で、 [ ビルドオプション ] を [ リリース用 ] に 設定し、 [ インブット ] の [ ライプラリ ] リストの先頭に MFC200 を追加する。 プロジェクトの < リンカオプション > ダイアログ中で、 [ ビルドオプション ] を [ デバッグ用 ] に 設定し、 [ インブット ] の [ ライプラリ ] リストの先頭に MFC200. 〃を追加する。 クライアントの EXE ファイルのサイズを減らしたい場合は、リソーススクリプトの冗長なリソー スを除去する。これを行なうには App Studio を起動し、 [ ファイル ] メニューから [ インクルード ファイルの設定 ] を選択する。表示された < インクルードファイルの設定 > ダイアログボックス中の [ コンパイル時に追加するファイル ] リストボックスから、標準 AFX リソースへの参照を削除し、 次に COK] をクリックする。アプリケーションフレームワークは、 MFC200. DLL リソースを検索す る前にクライアントリソースを検索するので、必要な場合は標準 AFX リソースをオーバーライド することができるということを覚えておくこと。 以上に示された変更を行なった後、 VisuaIWorkbench の [ プロジェクト ] メニューから [ リビル ド ] を選択しなければならない。 ■クラスライプラリ拡張 DLL クラスライプラリ DLL に新しいクラスを追加したい場合には、醯FC200. DLL をリビルドするの ではなく、 MFC200. DLL と共にロード可能な、独自のクラスライプラリ拡張 DLL をクライアント プログラム用に書くことになる。拡張 DLL を書く場合、明確に定義されたいくつかの規則に従わ なければならない。これは本章の最初の例中で、強調していることである。 警告 MFC200. DLL を変更すると、 Microsoft 版の DLL に依存するアプリケーションで 問題を起こすことがある。 0 クラスライプラリ DLL のメモリ使用法 クラスライプラリ拡張 DLL では、メモリはクライアントアプリケーションにより管理される。ク ラスライプラリ DLL 中で怩肥演算子を使った場合朝砒とんは DLL 用に特別にオーバーロー ドされている ) 、クライアントアプリケーションのメモリが割り当てられるということである。ク 555
VisuaI Basic コントロール 1991 年に発売された Microsoft Visual Basic は、 Microsoft Windows 用の開発システムとし て評判がよく、成功していることは疑いの余地がない。成功の一部は、その公開された仕様による ものである。 Microsoft やほかのサードバーテイソフトウェア開発元から提供される、 C で書かれ た特別なダイナミックライプラリ (DLL) 、 Visual Basic 「コントロール」を追加することで、 Basic 言語を拡張することができる。この VisuaI Basic コントロールは VisuaI C 十十でも使用すること ができ、そして App Studio はこれらを完全にサポートする。 Microsoft Visual Basic 3.0 のプロ フェッショナルエディションは、コントロール開発キット (CDK) を含んでおり、独自のカスタムコ ントロールを書くことができる。 本章では、 Visual Basic コントロールが Windows の標準コントロール、カスタムコントロール とどう違うのかを学び、そしてどのようにこれらのコントロールが Microsoft 基本クラスライプ ラリバージョン 2.0 のプログラムと統合されるのかを学ぶ。 VisuaI C 十十に含まれている VisuaI Basic の GRID コントロールを取り込んだものを例として作成し、コントロールのプロバティ、メ ソッド、イベントの使用法を示す。最終結果は、未熟だが機能するスプレッドシートプログラムで ある。 注意個々の標準 VBX イベント、標準 VBX プロバティ、 Visual Basic の GRID コント ロールに固有のプロバティ、イベントについての詳しいドキュメントは、ヘルプファイル MFCNOTES. HLP 中の MFC テクニカルノート 27 を参照。 標準 Wi 血 ws コントロールと通常のカスタムコントロール CEdit, C 召″加広 CS げ 0 〃召といったクラスで表現される標準 Windows コントロールをすで に見てきた。これらのコントロールは Windows に組み込まれ、そしてクラスライプラリはこれら を完全にサポートしている。通常のカスタムコントロール (C で書かれ、通常は DLL として実装さ れる ) もクラスライプラリで使用することができる。 App Studio を使ってダイアログ中で通常のカ スタムコントロールの位置、サイズを指定することはできるが、設計時にはコントロールがどのよ 161