summaryrefslogtreecommitdiff
path: root/zen/com_util.h
diff options
context:
space:
mode:
Diffstat (limited to 'zen/com_util.h')
-rw-r--r--zen/com_util.h121
1 files changed, 121 insertions, 0 deletions
diff --git a/zen/com_util.h b/zen/com_util.h
new file mode 100644
index 00000000..db51404b
--- /dev/null
+++ b/zen/com_util.h
@@ -0,0 +1,121 @@
+// **************************************************************************
+// * 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 <string>
+#include <cassert>
+
+namespace zen
+{
+//get an enumeration interface as a std::vector of bound(!) ComPtr(s)
+template <class T, class U>
+std::vector<ComPtr<T> > convertEnum(const ComPtr<U>& 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 <class T, class MemFun>
+std::wstring getText(ComPtr<T> 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 <class T, class U> inline
+std::vector<ComPtr<T> > convertEnum(const ComPtr<U>& enumObj)
+{
+ std::vector<ComPtr<T> > output;
+
+ if (enumObj)
+ {
+ ComPtr<IUnknown> unknown;
+ enumObj->get__NewEnum(unknown.init());
+ ComPtr<IEnumUnknown> enumUnknown = com_dynamic_cast<IEnumUnknown>(unknown);
+
+ assert(enumUnknown); //IEnumUnknown must be supported!
+ if (enumUnknown)
+ {
+ ComPtr<IUnknown> itemTmp;
+ while (enumUnknown->Next(1, itemTmp.init(), NULL) == S_OK) //returns S_FALSE == 1 when finished! Don't use SUCCEEDED()!!!
+ {
+ ComPtr<T> itemNew = com_dynamic_cast<T>(itemTmp);
+ if (itemNew)
+ output.push_back(itemNew);
+ }
+ }
+ }
+
+ return output;
+}
+
+
+template <class T, class MemFun> inline
+std::wstring getText(ComPtr<T> 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 \ No newline at end of file
bgstack15