25 章オプジェクトのリンクと埋め込み (OLE) オプジェクト数 ( フルサーバー ) オプジェクト数 ( ミ クラス数 クラス型 ドキュメント 複数 アイテム ひとつのサーバータイプ、ひとつのインスタンスーー DGROUP メモリの制約が ・ M 引サーバー 複数インスタンスサーバーを不可能にする場合、あるいはフルサーバーをスタンドアローンモー ーを使 ドで動作させるときに MDI にしたい場合に、 MDI サーバーが必要になる。実際にサー 用する各クライアントには、それぞれひとつのドキュメントオプジェクトが割り当てられる。 バーの場合は、ドキュメントあたりひとつのアイテムのままである。 クラス数オプジェクト数 ( ミニサーバー ) オプジェクト数 ( フルサーバー ) クラス型 複数 ドキュメント 複数 アイテム 複数 複数 複数のサーバータイプ、ひとつのインスタンス この型のアーキテクチャの例 ・ M 引サーバー は Microsoft ExceI で、チャートとスプレッドシートの両方をサポートする。こではミニサー ーには意味はない。なぜなら単に別々のミニサーバーをふたっ書けばよいからだ。その場合、 各サーバークラスはひとつのドキュメントクラスを持ち、そして各サーバーオプジェクトはひと ーはリンクをサポートするので、ドキュメン つのドキュメントオプジェクトを持つ。フルサー トは複数のアイテムオプジェクトを持っことができ、各ドキュメントクラスは複数のアイテムク ラスを持っことができる。 オプジェクト数 ( フルサー クラス数 クラス型 / ヾ 複数 複数 ドキュメント 複数 複数 アイテム 複数 複数 0 クライアント - サーバーの OLE オプジェクトの関係 サーバーの OLE アイテムはクライアントの OLE アイテムに対応するが、サーバーのドキュメン トとクライアントのドキュメントは対応しない。 Figure25-6 はこの種の典型的なシナリオを示した こでクライアントアプリケーションは、ふたつのアクテイプな埋め込まれた OLE アイ ものだ。 テムと、ふたつのアクテイプなリンクされた OLE アイテムを持っている。リンクされたアイテム ープログラムを使用する。 は両方とも同し型なので、同しサー ーインスタンスがロードされている。これらは普通は同しプログラムだが、そ 3 つの SDI サー 1 1 11 11 1 1 ー亠 1 1 亠 1 1 11 11 、ー亠 537
PART 3 ドキュメントーピューアーキテクチャ うふたつは派生クラス中から呼び出すことになるべースクラスの非仮想関数である。これらの関数 を一度に見てみよう。 UCView の GetDocument 関数 すっ呼び出す必要がある。 Ge の 0 襯 e 厩関数の方が G 厩ル砒 / 怖 e より頻繁に使用される。 トは複数のビューを持っことができるので、このメンバ関数は、ループ中で各ビューについて 1 回 CDo 襯 e 厩の G ルー怖 ) 関数は、ドキュメントからビューへの誘導を行なうが、ドキュメン ができる。 メントクラスのメンバ関数、あるいはパプリックデータメンバにアクセスするために使用すること ことを伝えなければならない。 Ge の 0 襯 e 厩関数はドキュメントボインタを提供し、これをドキュ が取得したと考えてみる。ビューはドキュメントオプジェクトに、対応する内部データを更新する が新しいデータをエディットコントロール中で入力したというメッセージを、ビューオプジェクト 関数は、ビューからそのドキュメントへ、アプリケーションを誘導することを可能にする。ューザー ビューオプジェクトは、関連するただひとつのドキュメントオプジェクトを持つ。 Ge の 0 襯 e 厩 return (CMyDoc*) m—pDocument ; CMyDoc* GetDocument ( ) インライン関数で、以下のようなものである。 へのポインタを返す「型に関して安全な」バージョンの Ge の 0 襯 e 厩関数を生成する。 AppWizard は派生 CView クラスを生成するとき、 C. 〃 0 襯 e 厩ポインタではなく、派生クラス この関数は 274 ラスのメンバ関数から呼び出された場合は、以下のようにカ S 虎に現在のビューが設定される。 呼び出された場合、最初のパラメータカ & 虎 % は U んんである。こゆス〃怖 e s が派生ビューク するために通知されなければならない。派生ドキュメントクラスのメンバ関数からこゆ〃怖麒 ) s が 何らかの理由でドキュメントのデータが変更された場合、すべてのビューはそのデータの表現を更新 0 CDocument の UpdateAIIViews 関数 ンタが返されてしまう。 はべースクラスの G の 0 襯 e 厩関数を呼び出すことになり、 C. 〃 0 襯召厩オプジェクトへのポイ pView—>GetDocument ( ) ; / / pView は CView* として宣言されている 下のような文 トクラス用にキャストする必要はない。 C 防 e の Ge の 0 襯厩関数は仮想関数ではないので、以 バージョンではなく、派生クラスパージョンを使用するので、返されたポインタを派生ドキュメン コンパイラが派生クラスコード中で Ge の 0 襯 e 厩の呼び出しに行き当たったとき、 CDo 翩襯召厩
ドキュメントの読み込みと書き込み 16 章 SDI 0 ドキュメントテンプレートリソース D 襯が 4 ルの最初のパラメータは / D 一財ス / ル F. ス財 E 、つまり文字列テープルリソース の識別子である。以下はこれに関して AppWizard がアプリケーションの RC ファイル中に生成す る文字列の例である。 工 DR_MAINFRAME "Windows アプリケーシ アプリケーションウインドウのキャプション MYAPP\n" ン ヨ "Myapp\n" デフォルトのドキュメント名の先頭部分 "MYAPP ドキュメント \ n " ドキュメントタイプ名 "MYAPP ファイル (* . xyz)\n" ドキュメントタイプと拡張子フィルタの指示 ・ xyz " このドキュメントタイプの拡張子 ( 注 : リソースコンパイラは上記のような文字列の連結を受理しない。実際に EX16A. RC ファイ ルを調べれば、ひとつの大きな文字列にまとめられたサプ文字列を見ることになる。 ) / のー / F. ME は \ n でサプ文字列に分けられるひとつの文字列を指定する。サプ文字列 はアプリケーションの実行に際して各所に現われる。文字列 2 は AppWizard が指定する、デフォ ルトのドキュメントファイル拡張子である。 ID / D 一 / F 盟 E はさらにアプリケーションの文字列の指定、アプリケーションのアイコ ビットマップ、メニューの識別を行なう。 AppWizard はこれらのリソースを生成 ン、ツーーノレノヾー し、 App Studio が保守する。 こまでイ D 襯が厩 e の呼び出しが、どのようにすべてのアプリケーション要素を共に結 び付けるかを見てきた。しかし、まだウインドウはまったく作成されておらす、それゆえ画面には 何も現われないということに気付くこと。 0 複数のドキュメントタイプ SDI アプリケーションはただひとつのドキュメントしかサポートしないが、複数のドキュメン トタイプをサポートすることは可能である。その場合、単に各ドキュメントクラス用に別々に Ad イ Do じ襯が 4 を呼び出すことになる。ューザーがプログラムを起動したとき、あるいは [ ファイ ル ] メニューから [ 新規作成 ] を選択したときに、アプリケーションフレームワークはドキュメント タイプをリストボックスから選択するように問いかける。恐らくそれぞれのドキュメントタイプ用 にドキュメントテンプレートリソース文字列とメニュー項目を分けたくなるだろう。シリアライズ 処理は、ドキュメントのタイプをファイル名の拡張子から識別する。 OSD ドキュメントの複数のビュー SDI アプリケーションにおける複数ビューの提供は多少複雑だ。単にユーザーにビューを選択さ せるメニュー項目を提供することもできるし、あるいはスプリッタウインドウ中で複数のビューを 午すことも可能だ。第 19 章では、どのようにスプリッタウインドウを使うかを示している。 一三ロ 323
PART 3 ドキュメントーピューアーキテクチャ 0 [ ファイル ] の [ 上書き保存 ] と [ 名前を付けて保存 ] をシリアライズコードに接続する AppWizard がアプリケーションを生成するとき、 [ ファイル ] メニューの [ 上書き保存 ] 項目は C 〃 0 襯 e 厩クラスの 0 F 立怩メンバ関数にマップされる。 0 〃 F S 〃怩は C 〃 0 翩襯 e 厩の 0 立怩 Do 襯 e 厩関数を呼び出し、これは次にストアに設定されたアーカイブオプジェクトを伴って、 ドキュメントの & ⅲ / た召関数を呼び出す。 [ ファイル ] の [ 名前を付けて保存 ] メニュー項目も同様の 方法で扱われる。これは CDo 襯 / の 0 F 泥立怩 s 関数にマップされ、 0 Sa 怩〃 0 襯 e 厩を 呼び出す。アプリケーションフレームワークは、こではドキュメントをディスクにセープするた めに必要なファイル管理をすべて行なう。 注意 [ ファイル ] の [ 新規作成 ] と [ 開く ] のメニュー選択はアプリケーションクラスのメ ンバ関数にマップされるが、 [ ファイル ] の [ 上書き保存 ] と [ 名前を付けて保存 ] はドキュ メントクラスのメンバ関数にマップされるという事実を知っておこう。 [ ファイル ] の [ 新 規作成 ] は 0 F ルルにマップされる。 SDI バージョンの″加 s 化も 0 F ル 0 を 呼び出す。アプリケーションフレームワークがル″ル s / 〃加 e を呼び出す時点では、ドキュ メントオプジェクトはまだ存在していないので、 0 F 〃召ル e は CDo 襯召厩のメンバ関 数となることはできない。しかしドキュメントがセープされる時点では、ドキュメントオ プジェクトはすでに存在している。 0 ドキュメントの lsModified フラグ 多くの Windows 用のドキュメント指向のアプリケーションは、ユーサーによるドキュメントの修 正を記憶している。ューザーがドキュメントをクローズ、あるいはプログラムを終了しようとすると、 メッセージボックスが現われ、ユーザーにドキュメントのセープを希望するかどうかを聞いてくる。 クラスライプラリアプリケーションフレームワークは C の 0 襯 e 厩のデータメンバ襯ーわ 0 ed により、この動作を直接サポートする。この論理値変数は、ドキュメントが修正されている場合は TRUE 、それ以外は FA ん SE になっている。 プロテクトされた襯ーわ盟 0 e フラグには、 CDo 襯 e 厩のメンバ関数 S 財 0 F / ag とム 盟 0 召を介してアクセスできる。ドキュメントオプジェクトのフラグは、ドキュメントが作成さ れたとき、ディスクから読み込まれたとき、あるいはディスクにセープされたときに FALSE に設 定される。ドキュメントのデータが変更された時は、プログラマは S Mo 記 F / 〃 g 関数を使って、 フラグを T UE に設定しなければならない。 VisuaI Workbench では、 [ ファイル ] メニューの [ 上書き保存 ] 項目に対応するツールバーのディ スクボタンは、現在選択されているドキュメントが修正されていない場合はディスエープルされて いる。例 EX16A では、 1 行の更新コマンド関数を使って、ム Mo によってどのようにディス クボタンと対応するメニュー項目を制御するかを見る。 326
24 章 Microsoft ODBC による テータベース管理 481 * 1 英語版 Ver. 1.5 では標準添付 だとしても、プログラムを実行するたびに全データの読み込み、書き込みを行なう必要はない。 キュメントをシリアライズできないのは明らかである。またドキュメントがメモリに収まる大きさ は、すべてのデータはディスクに書き戻されなければならない。使用可能な仮想記憶より大きなド タはメモリに読み込まれなければならず、そして更新されたドキュメントがクローズされるときに イルを結び付けるものだった。ドキュメントがオープンされるときには、すべてのドキュメントデー 第 16 章、第 17 章で導入されたシリアライズ処理は、ドキュメントオプジェクトとディスクファ テータベース管理対シリアライズ を収めていて、行指向のデータベース項目のスクロール表示を管理している。 ンのシャットダウンシーケンスの制御の取得方法を示す。例は便利な行表示ビューのべースクラス ションを見ていく。例ではまた、クラスライプラリダイアログバーも導入し、さらにアプリケーショ たものだ。データベース問い合わせツールとして便利な機能クラスライプラリと ODBC アプリケー 本章のアプリケーション例は、 ODBC と SQL をいかにデータベースの環境に組み込むかを示し 提供される * 1 ODBC プログラマーズリファレンスを含む ODBC ソフトウェア開発キットは Microsoft から別途 VisuaIC 十十は、データベースアプリケーションの作成に必要な ODBC ツールを含んでいない。 ファイルにさえアクセスすることができるのだ。 (Structured Query Language) データベースアクセス言語の両方の利点を享受できる。 dBASE プリケーションを作成する手段を提供する。プログラマはオプジェクト指向プログラミングと SQL ア規格は、 Microsoft 基本クラスライプラリプログラマに、 Windows 用の強力なデータベースア dBASE/Xbase 言語が中心だった。 Microsoft Open Database Connectivity (ODBC) ソフトウェ を必要としている。今までほとんどのマイクロコンピュータ用のデータベースプログラミングは、 多くのビジネスアプリケーションは、巨大なデータベース内の個々のレコードへの高速アクセス
PART 3 ドキュメントーピューアーキテクチャ 0 空のドキュメントの作成ーー C Ⅳ / n pp の OnFileNew 関数 アプリケーションクラスのル″ル s 〃化関数が D 襯が 4 ルを呼び出した後で、 C ー怖ス第第 の別の重要なメンバ関数、 0 〃 F N 麒 ) が呼び出される。 0 〃 F N 麒 ) は C ル切カカの別の関数の e 〃 Do 川泥の呼び出しを介して、相互に接続されたクラス名のネットワークを割り振り、そし て以下を実行する。 1. 2. 3. 4. 5. 6. 7. ドキュメントオプジェクトを生成する。しかし、ディスクからのデータ読み込みは試みない。 ( C 財〃切 E 耀襯 e クラスの ) メインフレームオプジェクトを生成する。また、メインフレームウイン ドウも作成するが、表示はしない。メインフレームウインドウは / D 一 M. / F. E メニュー ツールバー、ステータスパーを含んでいる。 ビューオプジェクトを生成する。また、ビューウインドウも作成するが、表示はしない。 ドキュメント、メインフレーム、ビューオプジェクト間の接続を確立する。これらのオプジェク トの接続を、イイ D 襯が 4 の呼び出しで確立されるクラス間の接続と混同しないこと。 ドキュメントオプジェクト用に仮想メンバ関数 0 麒の 0 翩襯 e 厩を呼び出す。これはさらに仮 想関数 D ん Co 厩 e 厩 s を呼び出す。 ビューオプジェクト用に仮想メンバ関数 0 〃ル〃尾ゆを呼び出す。 フレームオプジェクト用に仮想関数ス c 〃 F % のを呼び出し、メニュー コントローーノレノヾ ーと共にメインフレームウインドウを表示する。 ビューウインドウ、 注意上記に示した関数うちいくつかはの Do 翩襯 e 厩 F により直接呼び出されず、ア プリケーションフレームワークを介して間接的に呼び出される。 324 メントの初期化はすべてドキュメントクラスのコンストラクタ中で行なうことができるからだ。し メントオプジェクトを再使用しないのであれば、 0 ル麒の 0 襯 e 厩は必要ない。なぜなら、ドキュ 0 ル麒の 0 襯 e 厩メンバ関数はまだ紹介していなかった。 SDI アプリケーションがもし同しドキュ 第 15 章でビュークラスの 0 加″ / メンバ関数を見てきたが、ドキュメントクラスの 0 ドキュメントクラスの〇 n Ⅳ e Ⅳ Docume 関数 すことに注意。 ステップを実行する。 0 F ル麒 , はドキュメントを空にするために常にの召ん Co 厩なを呼び出 はできない。代わりに既存のドキュメントオプジェクトを再使用し、上記のリストの最後の 3 つの キュメント、フレーム、ビューオプジェクトはすでに生成されているので、これらを生成すること ド しても呼び出される。この場合、 0 F 麒 ) は少しばかり異なる動作をしなければならない。 ル″ル s 化により呼び出される。これはまた、 [ ファイル ] メニューの [ 新規作成 ] 項目への応答と 1 回しか作成されす、そしてプログラムの寿命の間、存続する。 C ルカ第の 0 〃んル e 肥関数は SDI アプリケーションでは、ドキュメント、メインフレームウインドウ、ビューオプジェクトは
PART 4 上級的なトピックス 呼び出す。〃 0 佐のパラメータはひとつで、 0 がプライマリ Verb 、 1 がセカンタ、、リ Verb と続く。 Verb が起動されたときにサーバープログラムがロードされていない場合、 OLE システムはサー アイテムのシリアライズ クタがすべての面倒を見る。必要な場合、サー ープログラムは終了させられる。 この作業は簡単である。単純に CO C 〃盟召襯オプジェクトを削除すればよい。仮想デストラ アイテムの削除 をロードし、必要なデータを送る。 526 が、独自の CO ん C 〃盟召川ポインタをドキュメント内に保持する必要がある場合は、 OLE アイテ る。これは CO ん C のの仮想関数 D な朝〃厩 s 中で扱われる。しかしドキュメント構造体 CO ん C 〃のの内部アイテムリストを使用する場合、 OLE アイテムの削除は自動で行なわれ ドキュメントのクリーンアップ コールバックを引き起こさせる。すべての範囲指定は MM ー HIMETRIC 論理単位を仮定している。 ーに 0 立昭 0 ″〃の に頼むことがときどきある。 CO ん C 〃盟 e 襯の & 鵬〃関数は、サー クライアントから、よりクライアントの必要にかなう矩形中にデータを再描画することをサー はない。 ズの矩形でサーバーのアイコンを描画するその他のクライアントは、 G イ召の呼び出しの必要 テムのサイズを設定するためにこの関数を呼び出す。例題プログラム EX25A といった、固定サイ の G 召鵬〃赤関数を呼び出すことができる。 Windows のライトは、ドキュメント中の OLE アイ クライアントアプリケーションが OLE アイテムのサイズを知る必要がある場合、 CO C 厩 / 襯 OLE アイテムの大きさの取得と設定 いけない。派生ドキュメントクラス中のシリアライズの制御は読者が行なう。 べースクラスのドキュメントクラスがこれらのアイテムをシリアライズすると仮定しては 注意クライアントドキュメントは独自のクライアントアイテムのリストを持っているが、 に送る必要のある適当な動作が行なわれるまで保持することになる。 クライアントはデータを読み込んだ後、ユーザーが Verb を起動するといった、データをサー タをメモリ中に持っているので、単純にデータをディスクに書き込むだけである。ロードの場合、 呼び出すことになる。ストアの場合、クライアントはすでに必要なネーテイプフォーマットのデー キュメント用に用意する。この関数は最終的には CO C 厩 / 襯べースクラスの S 夜〃託関数を して、各ドキュメントをシリアライズするという動作を行なう S の〃記関数を、クライアントド ンフレームワークが OLE のシリアライズを簡単にしている。ドキュメントアイテムリストを走査 トに関して何も知ることなく、ロードとストアを行なわなければならない。実際にはアプリケーショ OLE のシリアライズというと難しそうに聞こえる。クライアントはサーバーデータのフォーマッ
16 章 0 ドキュメントテンプレートクラス 派生アプリケーションクラス用に AppWizard が生成したル″ル s 召関数を見ると、特に目立 つ以下の文がある。 ドキュメントの読み込みと書き込み SDI AddDocTemp1ate (new CSingIeDocTemp1ate (IDR-MAINFRAME, RUNTIME_CLASS (CMyDoc) , RUNTIME_CLASS (CMainFrame) , RUNTIME_CLASS (CMyView) ) ) ; / / 主 SDI フレームウインドウ スプリッタウインドウと複数ビューを持っという変わった状況で起動しない限り、これは読者が実 際にドキュメントテンプレートオプジェクトを見る唯一の機会である。この場合、これは CSingle 〃 00 襯が 4 厖クラスのオプジェクトであり、 CD 襯が厩 e から派生している。 CS 切 g D 襯力 は SDI アプリケーションにのみ適用される。なぜなら、 SDI アプリケーションはひとつのドキュメ ントオプジェクトに制限されているからである。 D “襯が厩 e は C ル切ス加クラスのメンバ 関数である。 ドキュメントテンプレートコンストラクタの呼び出しを伴う D 川が〃の呼び出しは、ク ラス間、つまりアプリケーションクラス、ドキュメントクラス、ビューウインドウクラス、メイン フレームウインドウクラスの相互関係を確立する。もちろんアプリケーションオプジェクトはテン プレートの生成前に存在しているが、この時点ではドキュメント、ビュー、フレームオプジェクト は生成されていない。アプリケーションフレームワークは、後でこれらのオプジェクトが必要なと きに、動的に生成する。 この動的な生成は、 C 十十言語の洗練された使用法である。クラス宣言と実装ファイル中の DE CLARE-DYNCREATE と / 財 P- ん EME た D 必 C E. 7 マクロの使用により、クラスライプラ リは、指定されたクラスのオプジェクトの生成を動的に行なうことができる。この動的な生成機能 が存在しなければ、アプリケーションのクラス間の相互関係をさらにたくさんハードコーディング しなければならない。たとえばアプリケーションクラスを派生させる場合、個々の派生クラスのド キュメント、ビュー、フレームオプジェクトの生成のためのコードが必要になる。これは、プログ ラムのオプジェクト指向性と相容れない。 テンプレートシステムに関して、アプリケーションクラス中で重要なのは RUNTIME- CLASS マクロの使用であり、これはクラス名をクラスライプラリの実行時メカニズムが処理できる特別な ポインタに変換するというものだ。このマクロを機能させるためには、ターゲットクラスの宣言が インクルードされていなければならない点に注意。 Figure16 ー 2 は各種クラス間の相互関係を示し、次の Figure16 ー 3 はオプジェクトの相互関係を示 321 インフレームウインドウオプジェクトのみが許される。 できるが、 SDI プログラムの実行中は、ただひとつのドキュメントオプジェクトとただひとつのメ している。アプリケーションは複数のテンプレート ( そして関連するクラスグループ ) を持っことが
16 章ドキュメントの読み込みと書き込みーーー SDI ・コンテナオプジェクトがコレクションへのポインタを収めている場合、新しいコレクションオプ ジェクトは、抜き出し演算子がアーカイプからデータをロードしたときに生成される。新しいコレ クションへのポインタは、コンテナオプジェクトのポインタデータメンバ中に格納される。アー カイプのロードの前に、古いコレクションオプジェクトを ( 空にした後で ) 削除する必要があるだ ・ CO ゲ e ポインタのコレクションがアーカイプからロードされる場合、コレクション中の各オプ ジェクト用に以下の処理ステップが行なわれる。 〇オプジェクトのクラスが識別される。 〇ヒープ記憶領域がオプジェクト用に割り当てられる。 〇オプジェクトのデータが新しく割り当てられた記憶領域にロードされる。 〇新しいオプジェクトへのポインタがコレクション中に格納される。 例 EX16A では埋め込まれた CO ⅳコレクションのシリアライズを示す。 0 シリアライズ関数とアプリケーションフレームワーク さて、シリアライズ関数の書き方と、それらの関数呼び出しはネストできるということがわかった。 だが読者は、シリアライズ処理を始めるために最初の & 厖〃〃託が呼び出されるのがどの時点なのか を知っているだろうか ? アプリケーションフレームワークでは、すべてはドキュメント ( CDo 襯 e 厩 から派生させたクラスのオプジェクト ) にキー付けされている。 [ ファイル ] メニューから [ 開く ] 、 あるいは [ 上書き保存 ] を選択した時、アプリケーションフレームワークは C. 尾ん / 怩オプジェクト ( そしてその下位にある CFile オプジェクト ) を生成し、次にドキュメントクラスの & 厖〃〃託関数 を呼び出し、 C 尾怩オプジェクトへの参照を渡す。そして派生ドキュメントクラスの S げ〃託 関数は、一時的なものでない各データメンバをシリアライズする。 注意 AppWizard が生成した任意のドキュメントクラスを見れば、クラスが DECLARE_ SE. カ 4 んと / P. ん E 盟 E. T. ー SE. カ 4 んマクロの代わりに、 DECLARE_DYNCREATE と / I? ん EMENT. ー D ) ' NC. E TE マクロを含んでいることに気がつくだろう。ドキュメン トオプジェクトは C. 尾怩抜き出し演算子と関係して使用されること、あるいはコレク ションに含まれることは決してないので、 SE. / 鳳んマクロは必要ない。アプリケーション フレームワークは、ドキュメントの & 〃託関数を直接呼び出す。それ以外のすべてのシ リアライズするクラスでは、 DEC ん E ー SE カ 4 んと / 財召ん E 盟 E. T. ー SE / んマクロを 収めることになる。 S 団アプリケーション こまでひとつのドキュメントクラスとひとつのビュークラスを持っ SDI アプリケーションを数 多く見てきた。本章ではまだひとつのビュークラスに留まっているが、アプリケーションオプジェ 319
16 章ドキュメントの読み込みと書き込み 注意 Microsoft 基本クラスライプラリバージョン 2.0 の SDI アプリケーションの動作は、 SDI メモ帳やペイントプラシといった Windows の SDI アプリケーションとひとつの点で異 なっている。以下に典型的なイベントの順を示す。 1. ューザーはドキュメントを作成し、それを TEST. DAT といった名前でディスクにセー プする。 2. ューサーがドキュメントを修正する。 3. ューサーが [ ファイル ] の [ 開く ] を選択し、 TEST. DAT を指定する。 ューザーが [ ファイル ] の [ 開く ] を選択したとき、メモ帳、ペイントプラシのどちらも、ド キュメントに対して行なわれた変更を保存するかどうかをユーザーに問い合わせる ( 上記の ステップ 2 ) 。ューザーが [ いいえ ] を選択した場合、プログラムはディスクから TEST. DAT を再読み込みする。一方 Microsoft 基本クラスライプラリバージョン 2.0 のアプリケーショ ンは、修正は恒久的なものと仮定し、ファイルの再読み込みを行なわない。 EXI 6A ーーシリアライズを持つ S 団の例 この例は例 EX15B に似ている。生徒のダイアログとビットマップ、ビュークラスは同しである。 そしてこれには [ ファイル ] の [ 上書き保存 ] 用の更新コマンド関数と、シリアライズ機能が追加され ている。ビュークラスとドキュメントクラス用のヘッダと実装ファイルは、次の章の例 EX17A で も再使用される。 こでは AppWizard が生成したコードと ClassWizard のコードに対して、追加、変更する部 分を太字にして、すべての新しいコード (EX15B と異なるコード ) をわかるようにしている。 例 EX16A 中のファイルとクラスのリストを以下に示す。 ヘッダファイル EX16A. H MAINFRM. H STUDOC. H STUVIEW. H STUDENT. H STDAFX. H ソースコードファイルクラス EX16A. CPP MAINFRM. CPP STUDOC ℃ PP STUVIEW ℃ PP STUDENT ℃ PP STDAFX. CPP CEx16aApp CAb outDlg CMainFrame CStudentDoc CStudentView CStudent 解説 プリコンパイル済みへッダ 生徒のレコード 生徒のフォームピュー (EX15B より ) 生徒のドキュメント SDI メインフレーム バージョン情報ダイアログ アプリケーションクラス (AppWizard が生成 ) CStudent 327 されている。 の実装ファイル STUDENT ℃ PP には、以下の List16 一 1 に示すように S げ〃記メンバ関数が追加 イルを元に、 List16 ー 1 に示すように S げ〃記関数のプロトタイプを含めたものである。 CS 厩 EX16A の STUDENT. H ファイルは、 EX15A プロジェクト ( 281 ページのリストを参照 ) 中のファ