// ************************************************************************** // * This file is part of the FreeFileSync project. It is distributed under * // * GNU General Public License: http://www.gnu.org/licenses/gpl.html * // * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) * // ************************************************************************** #ifndef COM_UTILITY_HEADER #define COM_UTILITY_HEADER #include "com_ptr.h" #include #include namespace zen { //get an enumeration interface as a std::vector of bound(!) ComPtr(s) template std::vector > convertEnum(const ComPtr& enumObj); //enumObj: must have the "_NewEnum" property that supports the IEnumUnknown interface /* extract text from com object member function returning a single BSTR: HRESULT ComInterface::MemFun([out] BSTR *pbstr); Example: ComPtr<...> comObj =...; std::wstring description = getText(comObj, &IUPnPDevice::get_Description); */ template std::wstring getText(ComPtr comObj, MemFun memFun); //RAII class handling BSTR class Bstring { public: Bstring(const std::wstring& str) { str_ = ::SysAllocStringLen(str.data(), str.length()); } //string::data() returns unmodified string potentially containing 0-values ~Bstring() { if (str_) ::SysFreeString(str_); } const BSTR get() const { return str_; } private: Bstring(const Bstring&); //not implemented Bstring& operator=(const Bstring&); // BSTR str_; }; //############################ inline implemenatation ################################## template inline std::vector > convertEnum(const ComPtr& enumObj) { std::vector > output; if (enumObj) { ComPtr unknown; enumObj->get__NewEnum(unknown.init()); ComPtr enumUnknown = com_dynamic_cast(unknown); assert(enumUnknown); //IEnumUnknown must be supported! if (enumUnknown) { ComPtr itemTmp; while (enumUnknown->Next(1, itemTmp.init(), NULL) == S_OK) //returns S_FALSE == 1 when finished! Don't use SUCCEEDED()!!! { ComPtr itemNew = com_dynamic_cast(itemTmp); if (itemNew) output.push_back(itemNew); } } } return output; } template inline std::wstring getText(ComPtr comObj, MemFun memFun) { std::wstring text; { if (!comObj) return std::wstring(); BSTR bstr = NULL; if (FAILED((comObj.get()->*memFun)(&bstr))) return std::wstring(); if (bstr) //NULL means "no text" { text = std::wstring(bstr, ::SysStringLen(bstr)); //correctly copy 0-characters ::SysFreeString(bstr); } } return text; } } #endif //COM_UTILITY_HEADER