Jak: vytvoření a použití instance CComQIPtr a CComPtr
V klasické Windows programování, knihovny často implementován, objekty COM (nebo přesněji, jako servery COM).Mnoho součástí operačního systému Windows jsou implementovány jako servery COM a počet přispěvovatelů poskytují knihovny v tomto formuláři.Informace o základy COM Component Object Model (COM).
Jestliže konkretizujete objekt modelu COM (Component Object), uložit inteligentní ukazatel COM, který provádí referenční počítání pomocí volání ukazatele rozhraní AddRef a Release v se objekt.Pokud používáte aktivní šabloně knihovny (ATL) nebo Microsoft Foundation třídy knihovny MFC (), použijte CComPtr inteligentní ukazatel.Pokud nepoužíváte ATL nebo MFC, použijte _com_ptr_t.Protože neexistuje žádný COM rovnocenné std::unique_ptr, jediným vlastníkem a vlastník více scénářů použití těchto ukazatelů inteligentní.I CComPtr a ComQIPtr přesunout podporu operací, které mají rvalue odkazy.
Příklad
Následující příklad ukazuje použití 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 namí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án v comip.h.Kompilátor vytvoří specializace z _com_ptr_t při generuje tříd obálky pro knihovny typů.
Poskytuje také ATL CComQIPtr, který má jednodušší syntaxi pro dotaz na objekt COM načíst další rozhraní.Doporučujeme však CComPtr neboť vše, CComQIPtr lze provést a sémanticky více konzistentní s raw ukazatele rozhraní COM.Používáte-li CComPtr dotaz rozhraní nové ukazatele rozhraní umístěn do výstupní parametr.Pokud selže volání, je vrácen popisovač HRESULT je typické COM vzorek.S CComQIPtr, vrácená hodnota je ukazatel sám a pokud hovor, vnitřní vrácená hodnota HRESULT není přístupný.Následující dva řádky zobrazit jak při zpracování mechanismy 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*/ }
CComPtrposkytuje specializace IDispatch umožňující ukládání ukazatele komponent modelu COM, automatizace a vyvolání metod rozhraní pomocí pozdní vazba.CComDispatchDriverje definice typedef pro CComQIPtr<IDispatch, &IIDIDispatch>, který je implicitně převést na CComPtr<IDispatch>.Proto když všechny tyto tři názvy se zobrazí v kódu, je ekvivalentní CComPtr<IDispatch>.Následující příklad ukazuje, jak lze získat pomocí ukazatele k objektovému modelu aplikace Microsoft Word 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
Inteligentní ukazatelů (Příručka programování moderních C++)