IPersistFile
COM公式ドキュメント
ストレージオブジェクトやストリームではなく、ディスク上のファイルからオブジェクトを読み込んだり、ファイルへ保存したりできるようにします。
メソッド 5
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
オブジェクトが、現在のファイルに最後に保存されてから変更されたかどうかを判定します。
戻り値
解説(Remarks)
このメソッドは、オブジェクトを閉じる前に保存すべきかどうかを判定するために使用します。オブジェクトのダーティフラグは、IPersistFile::Save メソッド内で条件付きでクリアされます。
呼び出し側への注意
OLE は IsDirty を呼び出しません。アプリケーションは、オブジェクトをファイルに保存する場合を除き、このメソッドを呼び出しません。エラーの戻りコードは、オブジェクトが変更されたことを示すものとして扱ってください。このメソッドが明示的に S_FALSE を返さない限り、オブジェクトは保存する必要があると想定してください。
実装者への注意
内包オブジェクトを持たないオブジェクトは、単純に自身のダーティフラグをチェックして適切な結果を返します。1 つ以上の内包オブジェクトを持つコンテナーは、いずれかの内包オブジェクトが最後に保存されてから変更された場合に設定される、内部ダーティフラグを保持する必要があります。これを行うには、コンテナーは IAdviseSink インターフェイスを実装してアドバイズシンクを保持します。次に、コンテナーは IDataObject::DAdvise を呼び出して、各リンクまたは埋め込みをデータ変更通知に登録できます。そして、IAdviseSink::OnDataChange 通知を受け取ったときに、内部ダーティフラグを設定できます。コンテナーがデータ変更通知に登録しない場合、IPersistFile::IsDirty の実装は、各内包オブジェクトが変更されたかどうかを判定するために、それぞれについて IPersistStorage::IsDirty を呼び出すことになります。
コンテナーは、保存後にオブジェクトの保存先ファイルが現在の作業ファイルとなる限り、保存されるたびにダーティフラグをクリアできます。したがって、ダーティフラグは Save または Save As 操作が成功した後にはクリアされますが、Save A Copy As . . . 操作の後にはクリアされません。
指定されたファイルを開き、そのファイルの内容からオブジェクトを初期化します。
| pszFileName | LPWSTR | in | 開くファイルの絶対パス。 |
| dwMode | STGM | in | ファイルを開く際に使用するアクセスモード。指定できる値は STGM 列挙型から取られます。このメソッドはこの値を推奨値として扱い、必要に応じてより制限の厳しい権限を追加してもかまいません。dwMode が 0 の場合、実装はユーザーがファイルを開くときに使用される既定の権限でファイルを開く必要があります。 |
戻り値
このメソッドは、次の値を返すことがあります。
| 戻りコード | 説明 |
|---|---|
| メソッドが正常に完了しました。 | |
| メモリ不足のため、オブジェクトを読み込めませんでした。 | |
| メモリ不足以外の何らかの理由で、オブジェクトを読み込めませんでした。 |
解説(Remarks)
IPersistFile::Load は、指定されたファイルからオブジェクトを読み込みます。このメソッドは初期化のためだけのものであり、オブジェクトをエンドユーザーに表示するわけではありません。ユーザーが ファイルを開く コマンドを選択したときに発生する処理と同等ではありません。
呼び出し側への注意
ファイルモニカーの BindToObject メソッドは、モニカーのバインド操作中(リンクされたオブジェクトが実行されるとき)にオブジェクトを読み込むために、このメソッドを呼び出します。通常、アプリケーションがこのメソッドを直接呼び出すことはありません。実装者への注意
ファイルを開くために必要な情報はアプリケーションごとに大きく異なるため、このメソッドを実装するオブジェクト自身が、pszFileName パラメーターで指定されたファイルを開く必要もあります。これは、呼び出し側がストレージまたはストリームを開き、開いたストレージまたはストリームへのポインターを読み込み対象のオブジェクトに渡す IPersistStorage::Load や IPersistStream::Load とは異なります。通常 OLE 複合ファイルを使用するアプリケーションでは、IPersistFile::Load の実装は、指定されたファイル内のストレージオブジェクトを開くために StgOpenStorage 関数を呼び出すだけで済みます。その後、通常の初期化処理を続行できます。ストレージオブジェクトを使用しないアプリケーションは、通常のファイルオープン手順を実行できます。
オブジェクトの読み込みが完了したら、実装はそのオブジェクトを実行中オブジェクトテーブルに登録する必要があります(IRunningObjectTable::Register を参照)。
オブジェクトのコピーを指定されたファイルに保存します。
| pszFileName | LPWSTR | in | オブジェクトの保存先となるファイルの絶対パス。pszFileName が NULL の場合、オブジェクトは現在のファイルがあれば、そこにデータを保存する必要があります。 |
| fRemember | BOOL | in | pszFileName パラメーターを現在の作業ファイルとして使用するかどうかを示します。TRUE の場合、pszFileName が現在のファイルとなり、オブジェクトは保存後にダーティフラグをクリアする必要があります。FALSE の場合、この保存操作は Save A Copy As ... 操作です。この場合、現在のファイルは変更されず、オブジェクトはダーティフラグをクリアしてはいけません。pszFileName が NULL の場合、実装は fRemember フラグを無視する必要があります。 |
戻り値
解説(Remarks)
このメソッドは、次の 3 つのいずれかの方法でオブジェクトを指定されたファイルに保存するために呼び出すことができます。
実装側は、呼び出し側がどの種類の保存操作を要求しているかを判別する必要があります。pszFileName パラメーターが NULL の場合は Save が要求されています。pszFileName パラメーターが NULL でない場合は、fRemember パラメーターの値を使用して Save As と Save a Copy As を区別します。
Save または Save As 操作では、IPersistFile::Save は保存後に内部ダーティフラグをクリアし、すべてのアドバイザリ接続に IAdviseSink::OnSave 通知を送信します(IOleAdviseHolder::SendOnSave も参照)。また、これらの操作では、オブジェクトは IPersistFile::SaveCompleted の呼び出しを受け取るまで NoScribble モードになります。NoScribble モードでは、オブジェクトはファイルに書き込んではいけません。
Save As のシナリオでは、実装はすべてのアドバイザリ接続に IAdviseSink::OnRename 通知も送信する必要があります(IOleAdviseHolder::SendOnRename も参照)。
Save a Copy As のシナリオでは、実装は保存後に内部ダーティフラグをクリアしません。
呼び出し側への注意
OLE は IPersistFile::Save を呼び出しません。通常、アプリケーションは、オブジェクトを直接ファイルに保存する場合を除き、このメソッドを呼び出しません。その保存操作は、一般にエンドユーザーに委ねられます。オブジェクトが自身のファイルに書き込めるようになったことを、オブジェクトに通知します。
| pszFileName | LPWSTR | in | オブジェクトが先ほど保存されたファイルの絶対パス。 |
戻り値
このメソッドは常に S_OK を返します。
解説(Remarks)
SaveCompleted は、IPersistFile::Save の呼び出しが完了し、保存されたファイルが現在の作業ファイルになったとき(Save または Save As 操作で保存された場合)に呼び出されます。Save の呼び出しはオブジェクトを NoScribble モードにするため、オブジェクトは自身のファイルに書き込めません。SaveCompleted が呼び出されると、オブジェクトは Normal モードに戻り、自身のファイルへ自由に書き込めるようになります。
呼び出し側への注意
OLE は SaveCompleted メソッドを呼び出しません。通常、アプリケーションは、オブジェクトを直接ファイルに保存する場合を除き、このメソッドを呼び出しません。その操作は、一般にエンドユーザーに委ねられます。オブジェクトに関連付けられているファイルの現在の名前を取得します。現在の作業ファイルがない場合、このメソッドはオブジェクトの既定の保存プロンプトを取得します。
| ppszFileName | LPWSTR* | out | 現在のファイルのパス、または既定のファイル名プロンプト(*.txt など)。エラーが発生した場合、ppszFileName には NULL が設定されます。 |
戻り値
このメソッドは、次の値を返すことがあります。
| 戻りコード | 説明 |
|---|---|
| 有効な絶対パスが正常に返されました。 | |
| 既定の保存プロンプトが返されました。 | |
| メモリ不足のため、操作が失敗しました。 | |
| メモリ不足以外の何らかの理由で、操作が失敗しました。 |
解説(Remarks)
このメソッドは、ppszFileName パラメーターで返される文字列のメモリを IMalloc::Alloc メソッドを使用して割り当てます。その文字列を解放するために IMalloc::Free メソッドを呼び出す責任は、呼び出し側にあります。呼び出し側とこのメソッドはいずれも、CoGetMalloc の呼び出しによって提供される OLE タスクアロケーターを使用します。
ppszFileName で返されるファイル名は、ドキュメントが読み込まれたときに IPersistFile::Load の呼び出しで指定された名前、またはドキュメントが別のファイルに保存された場合は IPersistFile::SaveCompleted で指定された名前です。
オブジェクトに現在の作業ファイルがない場合は、Save As ダイアログボックスに表示するであろう既定のプロンプトを提供する必要があります。たとえば、ワードプロセッサーオブジェクトの既定の保存プロンプトは次のようになります。
"*.txt"。
呼び出し側への注意
OLE は GetCurFile メソッドを呼び出しません。アプリケーションは、このインターフェイスの保存メソッドも呼び出す場合を除き、このメソッドを呼び出しません。オブジェクトを保存する際には、IPersistFile::Save を呼び出す前にこのメソッドを呼び出して、オブジェクトに関連付けられたファイルがあるかどうかを判定できます。このメソッドが S_OK を返した場合は、IPersistFile::Save をファイル名 NULL と fRemember パラメーターの値 TRUE で呼び出すことで、オブジェクトに自身を現在のファイルへ保存するよう指示できます。このメソッドが S_FALSE を返した場合は、ppszFileName パラメーターで返された保存プロンプトを使用して、エンドユーザーにファイル名の入力を求めることができます。その後、ユーザーが入力したファイル名で IPersistFile::Save を呼び出して Save As 操作を実行できます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IPersistFile "{0000010B-0000-0000-C000-000000000046}" #usecom global IPersistFile IID_IPersistFile "{}" #comfunc global IPersistFile_IsDirty 4 #comfunc global IPersistFile_Load 5 wstr,int #comfunc global IPersistFile_Save 6 wstr,int #comfunc global IPersistFile_SaveCompleted 7 wstr #comfunc global IPersistFile_GetCurFile 8 var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。#define global IID_IPersistFile "{0000010B-0000-0000-C000-000000000046}" #usecom global IPersistFile IID_IPersistFile "{}" #comfunc global IPersistFile_IsDirty 4 #comfunc global IPersistFile_Load 5 wstr,int #comfunc global IPersistFile_Save 6 wstr,int #comfunc global IPersistFile_SaveCompleted 7 wstr #comfunc global IPersistFile_GetCurFile 8 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。