Поделиться через


Функция 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

Ссылка на IID интерфейса, извлекаемого через ppv.

[out] ppv

Тип: void**

При успешном возвращении этого метода содержит указатель интерфейса, запрошенный в riid.

Возвращаемое значение

Тип: HRESULT

Возвращает S_OK, был ли запрошен интерфейс найден в таблице или если запрошенный интерфейс был IUnknown. Возвращает E_NOINTERFACE, если запрошенный интерфейс не найден.

Комментарии

Примечание До Windows Vista QISearch не экспортировался по имени и не объявлялся в общедоступном файле заголовка. Чтобы использовать его в таких случаях, необходимо использовать GetProcAddress и запросить порядковый номер 219 из Shlwapi.dll, чтобы получить указатель функции. В Windows Vista QISearch включен в Shlwapi.h, и в этом нет необходимости.
 
Если запрошенным интерфейсом является IUnknown, то QISearch использует первую запись указанного массива структур QITAB . В противном случае QISearch выполняет поиск в таблице до тех пор, пока она не найдет соответствующее ЗНАЧЕНИЕ IID или не достигнет конца таблицы. При обнаружении соответствующего IID функция перемещает связанный указатель интерфейса на количество байтов, указанное членом dwOffset структуры QITAB интерфейса и переосмысляется как указатель COM. Этот указатель назначается параметру ppv функции QISearch. Метод также вызывает IUnknown::AddRef для увеличения числа ссылок интерфейса.

Если QISearch достигает конца таблицы без поиска интерфейса, он возвращает E_NOINTERFACE и устанавливает для ppvзначение NULL.

Важно включить в таблицу все применимые интерфейсы. Например, если объект реализует производный интерфейс, необходимо также включить базовый интерфейс в таблицу.

Мы рекомендуем использовать макрос IID_PPV_ARGS , определенный в Objbase.h, для упаковки параметров riid и ppv . Этот макрос предоставляет правильный КОД на основе интерфейса, на который указывает значение в ppv, что исключает возможность ошибки кодирования в riid , которая может привести к непредвиденным результатам.

Примечание Библиотека активных шаблонов (ATL) предоставляет значительно лучшую версию реализации QueryInterface на основе таблиц.
 

Примеры

В следующем примере показано, как использовать QISearch для реализации QueryInterface. Он использует макрос offsetofclass из ATL для вычисления смещения от основания объекта CSample к указанному интерфейсу.

Этот объект поддерживает два интерфейса, кроме IUnknown, поэтому в таблице QITAB есть две записи, отличные от NULL. Запись для каждого интерфейса указывает указатель на связанный IID (IID_IPersist или IID_IPersistFolder) и смещение указателя интерфейса относительно базового указателя класса. В примере для определения смещения используется макрос offsetofclass из ATL.

Примечание Забыв включить все базовые классы, в том числе косвенные, является распространенной ошибкой. Обратите внимание, что существует запись для интерфейса IPersist . Этот интерфейс является косвенным базовым классом для CSample, наследуемым через IPersistFolder.
 

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
Header shlwapi.h
Библиотека Shlwapi.lib
DLL Shlwapi.dll (версия 5.0 или более поздняя)