Sdílet prostřednictvím


Postupy: Vytváření a používání instancí objektů CComPtr a CComQIPtr

V klasické programování v systému Windows jsou knihovny často implementovány jako objekty modelu COM (nebo přesněji, servery COM).Mnoho součástí operačního systému Windows jsou implementovány jako servery COM a knihovny v tomto formuláři zadat počet přispěvatelů.Informace o základy modelu COM naleznete v tématu Component Object Model (COM).

Když konkretizujete objekt modelu COM (Component Object), Uložit ukazatel rozhraní COM inteligentní ukazatel, který provádí referenční inventury pomocí volání AddRef a Release v destruktoru.Používáte-li aktivní šablonu knihovny (ATL) nebo Microsoft Foundation Class Library (MFC), pak použijte CComPtr inteligentní ukazatel.Pokud nepoužíváte knihovny ATL nebo knihovny MFC, použijte _com_ptr_t.Vzhledem k tomu, že je ekvivalentní žádný COM std::unique_ptr, použijte tyto chytré ukazatele jednoho vlastníka i vlastníka více scénářů.Obě CComPtr a ComQIPtr podpory přesunout operace, které mají odkazy rvalue.

Příklad

Následující příklad ukazuje, jak použít CComPtr k vytvoření instance objektu COM a získání ukazatele na jeho rozhraní.Všimněte si, že CComPtr::CoCreateInstance členské funkce se používá k vytvoření objektu COM, místo funkce Win32, který má stejný název.

void CComPtrDemo()
{

    HRESULT hr = CoInitialize(NULL);

    // Declare the smart pointer.
    CComPtr<IGraphBuilder> pGraph;

    // Use its member function CoCreateInstance to 
    // create the COM object and obtain the IGraphBuilder pointer.
    hr = pGraph.CoCreateInstance(CLSID_FilterGraph);
    if(FAILED(hr)){ /*... handle hr error*/ }

    // Use the overloaded -> operator to call the interface methods.
    hr = pGraph->RenderFile(L"C:\\Users\\Public\\Music\\Sample Music\\Sleep Away.mp3", NULL);
    if(FAILED(hr)){ /*... handle hr error*/ }

    // Declare a second smart pointer and use it to  
    // obtain another interface from the object.
    CComPtr<IMediaControl> pControl;
    hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
    if(FAILED(hr)){ /*... handle hr error*/ }

    // Obtain a third interface.
    CComPtr<IMediaEvent> pEvent;
    hr = pGraph->QueryInterface(IID_PPV_ARGS(&pEvent));
    if(FAILED(hr)){ /*... handle hr error*/ }

    // Use the second interface.
    hr = pControl->Run();
    if(FAILED(hr)){ /*... handle hr error*/ }

    // Use the third interface. 
    long evCode = 0;
    pEvent->WaitForCompletion(INFINITE, &evCode);

    CoUninitialize();

    // Let the smart pointers do all reference counting.
}

CComPtra jeho příbuzní jsou součástí knihovny ATL a jsou definovány v atlcomcli.h._com_ptr_tje deklarováno v comip.h.Kompilátor vytvoří specializace z _com_ptr_t při generuje obálkové třídy pro knihovny typů.

ATL poskytuje také CComQIPtr, která má jednodušší syntaxi pro dotaz na objekt COM načíst další rozhraní.Doporučujeme však CComPtr vzhledem k tomu, že tak činí vše, co CComQIPtr lze provést a sémanticky více konzistentní s raw ukazatele rozhraní COM.Použijete-li CComPtr na dotaz na rozhraní, nové ukazatele rozhraní se umístí do výstupní parametr.Pokud volání selže, vrátí HRESULT, což je typický vzorek COM.S CComQIPtr, vrácená hodnota je ukazatel sám a pokud selže volání, interní návratovou hodnotu HRESULT nelze získat přístup.Následující dva řádky jak při vyřizování stížností v CComPtr a CComQIPtr se liší.

// CComPtr with error handling:
CComPtr<IMediaControl> pControl;
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
if(FAILED(hr)){ /*... handle hr error*/ }

// CComQIPtr with error handling
CComQIPtr<IMediaEvent> pEvent = pControl;
if(!pEvent){ /*... handle NULL pointer error*/ }

// Use the second interface.
hr = pControl->Run();
if(FAILED(hr)){ /*... handle hr error*/ }

CComPtrspecializace poskytuje rozhraní IDispatch, což umožňuje ukládat odkazy na komponenty pro automatizaci modelu COM a volat metody na rozhraní pomocí pozdní vazba.CComDispatchDriverje definice typu pro CComQIPtr<IDispatch, &IIDIDispatch>, který je implicitně převést na CComPtr<IDispatch>.Když všechny tyto tři názvy se zobrazí v kódu, je tedy ekvivalentní CComPtr<IDispatch>.Následující příklad ukazuje, jak získat odkaz na model objektu aplikace Microsoft Word pomocí CComPtr<IDispatch>.

void COMAutomationSmartPointerDemo()
{

    CComPtr<IDispatch> pWord;
    CComQIPtr<IDispatch, &IID_IDispatch> pqi = pWord;
    CComDispatchDriver pDriver = pqi;

    HRESULT hr;
    _variant_t pOutVal;

    CoInitialize(NULL);
    hr = pWord.CoCreateInstance(L"Word.Application", NULL, CLSCTX_LOCAL_SERVER);    
    if(FAILED(hr)){ /*... handle hr error*/ }

    // Make Word visible.
    hr = pWord.PutPropertyByName(_bstr_t("Visible"),  &_variant_t(1));
    if(FAILED(hr)){ /*... handle hr error*/ }

    // Get the Documents collection and store it in new CComPtr
    hr = pWord.GetPropertyByName(_bstr_t("Documents"), &pOutVal);
    if(FAILED(hr)){ /*... handle hr error*/ }

    CComPtr<IDispatch> pDocuments = pOutVal.pdispVal; 

    // Use Documents to open a document
    hr = pDocuments.Invoke1 (_bstr_t("Open"), &_variant_t("c:\\users\\public\\documents\\sometext.txt"),&pOutVal);
    if(FAILED(hr)){ /*... handle hr error*/ }

    CoUninitialize();
}

Viz také

Koncepty

Chytré ukazatele (moderní verze jazyka C++)