In-Context フック機能の注意事項
パフォーマンス上の理由から、クライアント開発者はコンテキスト内フック関数を登録します。 ただし、これらのフック関数はサーバーのアドレス空間にマップされるため、クライアントとサーバーの開発者は、イベント処理が円滑に行われるように予防措置を講じる必要があります。
クライアント開発者向けの注意事項
クライアント開発者は、次の問題に注意する必要があります。
- サーバー アプリケーションを続行する前にフック関数が戻る必要があるため、コンテキスト内フック関数はプロセッサ時間をあまり使用しないでください。
- イベントがトリガーされた後、フック関数が呼び出された時点までに、イベントに関連付けられたウィンドウが存在しなくなった可能性があります。 クライアントは、イベントに関連する他のアクションを実行する前に、イベントに関連付けられているウィンドウがまだ存在することを確認する必要があります。 ウィンドウがまだ存在することを確認するために、クライアントは Microsoft Win32 IsWindow 関数を使用します。
- フック関数が定義されている DLL が別の DLL にリンクしている場合、クライアント開発者はシステムが他の DLL を読み込む必要があります。 暗黙的にリンクする場合 (.def ファイルとインポートを使用)、追加の DLL は Windows ディレクトリ、または Windows\System、Windows\System32、Windows\SysWOW64 などのシステム ディレクトリのいずれかに存在する必要があります。 明示的にリンクする場合 (LoadLibraryを使用)、LoadLibrary の呼び出しで、追加の DLL が存在するディレクトリへの完全なパス指定する必要があります。
- コンテキスト内フック関数は、フック関数を含む DLL が 16 ビット アプリケーションに読み込まれるときにスタック オーバーフローを引き起こす可能性があります。 この問題は、16 ビット アプリケーションで、フック関数の呼び出しにつながるシステム関数呼び出しのチェーンに対応するのに十分な大きさではない固定スタック サイズが使用されるために発生します。
サーバー開発者向けの注意事項
サーバー開発者は、クライアント アプリケーションがコンテキスト内フック関数を登録する可能性があることに注意する必要があります。 サーバーが NotifyWinEvent呼び出すときは、WM_GETOBJECT およびその他の IAccessible メソッドを処理するように準備する必要があります。
インターフェイス ポインターが無効です
クライアントがコンテキスト内フック関数内 AccessibleObjectFromEvent を呼び出すと、返される IAccessible インターフェイス ポインターは、サーバーのアドレス空間内のコードを直接指します。 クライアントがこのポインターを使用してインターフェイス プロパティを呼び出した場合、コンポーネント オブジェクト モデル (COM) ライブラリはマーシャリング (プロセス境界を越えたインターフェイス パラメーターのパッケージ化と送信) やマーシャリング解除 (プロセス境界を越えて送信されたパラメーターのアンパック) には関係せず、オブジェクトが破棄されたかどうかを検出しません。
クライアントが破棄されたオブジェクトに対してインターフェイス プロパティを呼び出した場合、無効なインターフェイス ポインターにより、サーバーがこの状況を検出しない限り、サーバーのアドレス空間に一般保護エラーが発生します。
無効なインターフェイス ポインターから保護するために、サーバー 、アクセス可能なオブジェクトをラップし、アクセス可能なオブジェクトの有効期間を監視するプロキシ オブジェクトを作成。 たとえば、クライアントが IAccessible プロパティを呼び出してオブジェクトに関する情報を取得すると、プロキシはアクセス可能なオブジェクトがまだ使用可能かどうかを確認し、使用できる場合は、アクセス可能なオブジェクトにクライアントの要求を転送します。 アクセス可能なオブジェクトが破棄された場合、プロキシはクライアントにエラーを返します。