Oh well, here we go again: I wrote my own COM pointer automation class. Here it goes the full code of it, which I now share with the world:
#pragma once #include <Windows.h> #include <ObjBase.h> template<typename T> class ComPtr { public: ComPtr() : _ptr(NULL) { } ComPtr(const ComPtr& other) : _ptr(NULL) { operator=(other); } ~ComPtr() { this->release(); } ComPtr& operator=(const ComPtr& other) { if(this != &other) { this->~ComPtr(); _ptr = other._ptr; if(_ptr) _ptr->AddRef(); } return *this; } void release() { if(_ptr) { _ptr->Release(); _ptr = NULL; } } bool coCreateInstance(REFCLSID rclsid) { return _ptr ? false : SUCCEEDED(::CoCreateInstance(rclsid, 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&_ptr))); } bool coCreateInstance(REFCLSID rclsid, REFIID riid) { return _ptr ? false : SUCCEEDED(::CoCreateInstance(rclsid, 0, CLSCTX_INPROC_SERVER, riid, (void**)&_ptr)); } template<typename COM_INTERFACE> bool queryInterface(REFIID riid, COM_INTERFACE **comPtr) { return !_ptr ? false : SUCCEEDED(_ptr->QueryInterface(riid, (void**)comPtr)); } bool isNull() const { return _ptr == NULL; } T& operator*() { return *_ptr; } T* operator->() { return _ptr; } T** operator&() { return &_ptr; } operator T*() const { return _ptr; } private: T *_ptr; };Basically, by using this class I don’t have to worry about calling the Release method. Most interestingly, I added two shorhand methods to ease my life,
coCreateInstance
and queryInterface
. Here are an example illustrating the use of the ComPtr class, along with the cited methods:{ ComPtr<IGraphBuilder> graph; if(!graph.coCreateInstance(CLSID_FilterGraph)) OutputDebugString(L"Failed!"); ComPtr<IMediaControl> mediaCtrl; if(!graph.queryInterface(IID_IMediaControl, &mediaCtrl)) OutputDebugString(L"Failed!"); graph->RenderFile(L"foo.avi", NULL); // sweet! }If you’re wondering about the usefulness of this ComPtr class, try to write the code above without it.
No comments:
Post a Comment