IRunnableObject
COM公式ドキュメント
コンテナーが埋め込みオブジェクトの実行を制御できるようにします。
メソッド 5
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
実行中のオブジェクトの CLSID を取得します。
| lpClsid | GUID* | out | オブジェクトのクラス識別子へのポインター。 |
戻り値
このメソッドは、標準の戻り値 E_INVALIDARG、E_UNEXPECTED、および S_OK を返すことができます。
解説(Remarks)
埋め込みドキュメントが、ユーザーのコンピューターで利用できないアプリケーションによって作成された場合、そのドキュメントは CoTreatAsClass の呼び出しにより、ユーザーのマシンでサポートされるクラスをエミュレートして、編集用に自身を表示できることがあります。この場合、IRunnableObject::GetRunningClass の呼び出しによって返される CLSID は、ドキュメントのネイティブクラスではなく、エミュレートされるクラスのものになります。
オブジェクトを強制的に実行させます。
| pbc | IBindCtx* | in | 実行操作のバインドコンテキストへのポインター。IBindCtx を参照してください。このパラメーターには NULL を指定できます。 |
戻り値
このメソッドは、標準の戻り値 E_INVALIDARG、E_UNEXPECTED、および S_OK を返すことができます。
解説(Remarks)
コンテナーは、オブジェクトを実行状態に移行させるために IRunnableObject::Run を呼び出します。オブジェクトがまだ実行されていない場合、Run の呼び出しは数秒程度を要する負荷の高い操作になることがあります。オブジェクトが既に実行中の場合、このメソッドはオブジェクトに影響を与えません。
呼び出し元への注意
リンクが前回アクティブ化されて以降に新しいクラスへ変換されたリンクオブジェクトに対して呼び出された場合、IRunnableObject::Run は OLE_E_CLASSDIFF を返すことがあります。この場合、クライアントは IOleLink::BindToSource を呼び出す必要があります。OleRun は、IRunnableObject::Run が提供する機能を便利にまとめたヘルパー関数です。OLE 2.01 のリリースに伴い、OleRun の実装は変更され、QueryInterface を呼び出して IRunnableObject を要求し、その後 IRunnableObject::Run を呼び出すようになりました。つまり、インターフェイスとヘルパー関数は相互に置き換えて使用できます。
実装者への注意
オブジェクトにモニカーが割り当てられている場合、オブジェクトは実行中オブジェクトテーブルに登録する必要があります。オブジェクトは自身に対して強いロックを保持してはならず、代わりに不安定でロックされていない状態を維持する必要があります。オブジェクトは、最初の外部接続が行われたときにロックされる必要があります。埋め込みオブジェクトは、実行状態にある間、その埋め込み先コンテナーに対してロックを保持しなければなりません。OLE 2 が提供する既定のハンドラーは、EXE オブジェクトアプリケーションによって実装されたオブジェクトに代わって、埋め込み先コンテナーのロックを処理します。DLL オブジェクトアプリケーションによって実装されたオブジェクトは、埋め込み先コンテナーに明示的にロックを設定する必要があります。これは、まず IOleClientSite::GetContainer を呼び出してコンテナーへのポインターを取得し、次に IOleContainer::LockContainer を呼び出して実際にロックを設定することで行います。このロックは、IOleObject::Close が呼び出されたときに解放する必要があります。
オブジェクトが現在実行状態にあるかどうかを判定します。
戻り値
オブジェクトが実行状態にある場合、戻り値は TRUE です。それ以外の場合は FALSE です。
解説(Remarks)
コンテナーアプリケーションは、サーバーが即座に利用可能かどうかを知る必要があるときに IRunnableObject::IsRunning を呼び出すことができます。たとえば、コンテナーによる IOleItemContainer::GetObject メソッドの実装は、サーバーが実行されておらず、bindspeed パラメーターに BINDSPEED_IMMEDIATE が指定されている場合にエラーを返します。
オブジェクトハンドラーは、実行中のサーバーとの競合を避けたい場合や、実行中のサーバーがより新しい情報を持っている可能性がある場合に IRunnableObject::IsRunning を呼び出すことができます。たとえば、ハンドラーによる IOleObject::GetExtent の実装は、オブジェクトサーバーが実行中であればそちらに処理を委譲します。サーバーの情報の方が、ハンドラーのキャッシュ内の情報よりも新しい可能性があるためです。
OleIsRunning は、IRunnableObject::IsRunning が提供する機能を便利にまとめたヘルパー関数です。OLE 2.01 のリリースに伴い、OleIsRunning の実装は変更され、QueryInterface を呼び出して IRunnableObject を要求し、その後 IRunnableObject::IsRunning を呼び出すようになりました。つまり、インターフェイスとヘルパー関数は相互に置き換えて使用できます。
既に実行中のオブジェクトを実行状態にロックするか、実行状態からロック解除します。(IRunnableObject.LockRunning)
| fLock | BOOL | in | TRUE はオブジェクトを実行状態にロックします。FALSE はオブジェクトを実行状態からロック解除します。 |
| fLastUnlockCloses | BOOL | in | TRUE は、解放される接続がオブジェクトに対する最後の外部ロックである場合に、オブジェクトを閉じるよう指定します。FALSE は、ユーザーまたは別のプロセスによって閉じられるまでオブジェクトを開いたままにするよう指定します。 |
戻り値
このメソッドは、標準の戻り値 E_INVALIDARG、E_OUTOFMEMORY、E_UNEXPECTED、E_FAIL、および S_OK を返すことができます。
解説(Remarks)
IRunnableObject::LockRunning のほとんどの実装は CoLockObjectExternal を呼び出します。
OleLockRunning は、IRunnableObject::LockRunning が提供する機能を便利にまとめたヘルパー関数です。OLE 2.01 のリリースに伴い、OleLockRunning の実装は、QueryInterface を呼び出して IRunnableObject を要求し、その後 IRunnableObject::LockRunning を呼び出すように変更されました。つまり、インターフェイスとヘルパー関数は相互に置き換えて使用できます。
オブジェクトが OLE コンテナーに埋め込まれていることを通知します。これにより、埋め込みオブジェクトへのリンクをサポートするコンテナーで参照カウントが正しく行われるようになります。(IRunnableObject.SetContainedObject)
| fContained | BOOL | in | TRUE は、オブジェクトが OLE コンテナーに格納されていることを指定します。FALSE は、格納されていないことを示します。 |
戻り値
このメソッドは、標準の戻り値 E_INVALIDARG、E_OUTOFMEMORY、E_UNEXPECTED、および S_OK を返すことができます。
解説(Remarks)
SetContainedObject メソッドを使用すると、コンテナーはオブジェクトハンドラーに対して、リンクとして機能するのではなくコンテナーに埋め込まれていることを通知できます。この呼び出しにより、オブジェクトに対するコンテナーの参照が、外部接続の既定である強参照から弱参照へ変更されます。オブジェクトが可視状態で実行されている場合、エンドユーザーがオブジェクトに対してロックを保持しているため、このメソッドの重要性はほとんどありません。しかし、埋め込みリンクソースのサイレント更新中には、リンクが切断された後もコンテナーがオブジェクトを実行状態に保持できてはなりません。このため、オブジェクトに対するコンテナーの参照は弱参照でなければなりません。
呼び出し元への注意
コンテナーアプリケーションが埋め込みオブジェクトへのリンクをサポートする場合、SetContainedObject を呼び出す必要があります。通常、OleLoad または OleCreate を呼び出した直後にこの呼び出しを行い、閉じる前であってもそれ以降このメソッドを呼び出すことはありません。さらに、コンテナーはほとんどの場合、fContained を TRUE に設定してこのメソッドを呼び出します。fContained を FALSE に設定してこのメソッドを使用することはまれです。SetContainedObject の呼び出しが任意となるのは、埋め込みオブジェクトがコンテナー以外のクライアントから参照されないことがわかっている場合のみです。コンテナーアプリケーションが埋め込みオブジェクトへのリンクをサポートしない場合は、SetContainedObject を呼び出すことが望ましいものの、必須ではありません。
OleSetContainedObject は、SetContainedObject が提供する機能を便利にまとめたヘルパー関数です。OLE 2.01 のリリースに伴い、OleSetContainedObject の実装は、QueryInterface を呼び出して IRunnableObject を要求し、その後 IRunnableObject::SetContainedObject を呼び出すように変更されました。つまり、インターフェイスとヘルパー関数は相互に置き換えて使用できます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IRunnableObject "{00000126-0000-0000-C000-000000000046}" #usecom global IRunnableObject IID_IRunnableObject "{}" #comfunc global IRunnableObject_GetRunningClass 3 var #comfunc global IRunnableObject_Run 4 sptr #comfunc global IRunnableObject_IsRunning 5 #comfunc global IRunnableObject_LockRunning 6 int,int #comfunc global IRunnableObject_SetContainedObject 7 int ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IRunnableObject "{00000126-0000-0000-C000-000000000046}" #usecom global IRunnableObject IID_IRunnableObject "{}" #comfunc global IRunnableObject_GetRunningClass 3 sptr #comfunc global IRunnableObject_Run 4 sptr #comfunc global IRunnableObject_IsRunning 5 #comfunc global IRunnableObject_LockRunning 6 int,int #comfunc global IRunnableObject_SetContainedObject 7 int ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。