QISearch 関数 (shlwapi.h)

IUnknown::QueryInterface メソッドのテーブル駆動型実装。

構文

HRESULT QISearch(
  [in]  void     *that,
  [in]  LPCQITAB pqit,
  [in]  REFIID   riid,
  [out] void     **ppv
);

パラメーター

[in] that

型: void*

COM オブジェクトのベースへのポインター。

[in] pqit

種類: LPCQITAB

QITAB 構造体の配列。 配列内の最後の構造体には、 piid メンバーを NULL に設定し、 その dwOffset メンバーを 0 に設定する必要があります。

[in] riid

型: REFIID

ppv を介して取得するインターフェイスの IID への参照。

[out] ppv

型: void**

このメソッドが正常に返されると、 riid で要求されたインターフェイス ポインターが含まれます。

戻り値

型: HRESULT

要求されたインターフェイスがテーブルで見つかった場合、または要求されたインターフェイスが IUnknown であった場合は、S_OKを返します。 要求されたインターフェイスが見つからなかった場合は、E_NOINTERFACEを返します。

注釈

メモ Windows Vista より前のバージョンでは、 QISearch は名前でエクスポートされなかったか、パブリック ヘッダー ファイルで宣言されていませんでした。 このような場合に使用するには、 GetProcAddress を 使用し、Shlwapi.dll から序数 219 を要求して関数ポインターを取得する必要があります。 Windows Vista では、SHlwapi.h に QISearch が含まれており、これは必要ありません。
 
要求されたインターフェイスが IUnknown の場合、 QISearch は、指定された QITAB 構造体の配列の最初のエントリを使用します。 それ以外の場合、 QISearch は、一致する IID が見つかるか、テーブルの末尾に達するまでテーブルを検索します。 一致する IID が見つかった場合、関数は、インターフェイスの QITAB 構造体の dwOffset メンバーによって指定されたバイト数だけ関連付けられたインターフェイス ポインターを進め、COM ポインターとして再解釈します。 そのポインターは、 QISearch 関数の ppv パラメーターに割り当てられます。 また、 メソッドは IUnknown::AddRef を呼び出して、インターフェイスの参照カウントをインクリメントします。

QISearch がインターフェイスを見つけずにテーブルの末尾に達すると、E_NOINTERFACEが返され、ppvNULL に設定されます。

テーブルには、該当するすべてのインターフェイスを含める必要があります。 たとえば、オブジェクトが派生インターフェイスを実装する場合は、基本インターフェイスもテーブルに含める必要があります。

riid パラメーターと ppv パラメーターをパッケージ化するには、Objbase.h で定義されているIID_PPV_ARGS マクロを使用することをお勧めします。 このマクロは 、ppv の値によって指されるインターフェイスに基づいて正しい IID を提供します。これにより、 riid でコーディング エラーが発生し、予期しない結果が発生する可能性がなくなります。

メモ Active Template Library (ATL) では、QueryInterface のテーブル駆動型実装のバージョンが大幅に向上しています。
 

次の例は、 QISearch を使用して QueryInterface を実装する方法を示しています。 ATL の offsetofclass マクロを使用して、CSample オブジェクトのベースから指定したインターフェイスへのオフセットを計算します。

このオブジェクトは IUnknown 以外の 2 つのインターフェイスをサポートしているため、QITAB テーブルには NULL 以外のエントリが 2 つあります。 各インターフェイスのエントリは、関連付けられた IID (IID_IPersist または IID_IPersistFolder) へのポインターと、クラスの基本ポインターに対するインターフェイス ポインターのオフセットを指定します。 このサンプルでは、ATL の offsetofclass マクロを使用して、そのオフセットを決定します。

メモ 間接クラスを含むすべての基底クラスを含めるのを忘れることは、一般的なエラーです。 IPersist インターフェイスのエントリがあることに注意してください。 このインターフェイスは、 IPersistFolder を介して継承される CSample の間接基底クラスです。
 

class CSample : public IPersistFolder
{
  public:
    CSample() { /* other construction goes here */ }
    
    STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();
  
    // *** IPersist ***
    STDMETHODIMP GetClassID(CLSID *pClassID);
    
    // *** IPersistFolder ***
    STDMETHODIMP Initialize(LPCITEMIDLIST pidl);
  
  private:
  // private members go here
};

HRESULT CSample::QueryInterface(REFIID riid, void **ppv)
{
    static QITAB rgqit[] = 
    {   
        QITABENT(CSample, IPersist),
        QITABENT(CSample, IPersistFolder)
        { 0 },
    };

    return QISearch(this, rgqit, IID_PPV_ARGS(&ppv));
}

要件

要件
サポートされている最小のクライアント Windows 2000 Professional、Windows XP [デスクトップ アプリのみ]
サポートされている最小のサーバー Windows 2000 Server、Windows Server 2003 [デスクトップ アプリのみ]
対象プラットフォーム Windows
ヘッダー shlwapi.h
Library Shlwapi.lib
[DLL] Shlwapi.dll (バージョン 5.0 以降)