WinStd
Windows Win32 API using Standard C++
Loading...
Searching...
No Matches
COM.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2024 Amebis
4 Copyright © 2016 GÉANT
5*/
6
8
9#pragma once
10
11#include "Common.h"
12#include <assert.h>
13#include <unknwn.h>
14#include <stdexcept>
15#include <string>
16
17namespace winstd
18{
21
27 class com_runtime_error : public num_runtime_error<HRESULT>
28 {
29 public:
36 com_runtime_error(_In_ error_type num, _In_ const std::string& msg) : num_runtime_error<HRESULT>(num, msg)
37 {}
38
45 com_runtime_error(_In_ error_type num, _In_opt_z_ const char *msg = nullptr) : num_runtime_error<HRESULT>(num, msg)
46 {}
47 };
48
50
53
58 {
63
69 template <class _T>
70 void operator()(_T *_Ptr) const
71 {
72 CoTaskMemFree(_Ptr);
73 }
74 };
75
81 template <class T>
82 class com_obj : public dplhandle<T*, NULL>
83 {
85
86 public:
93 _In_ REFCLSID rclsid,
94 _In_opt_ LPUNKNOWN pUnkOuter,
95 _In_ DWORD dwClsContext)
96 {
97 HRESULT hr = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (LPVOID*)&m_h);
98 if (FAILED(hr))
99 throw com_runtime_error(hr, "CoCreateInstance failed");
100 }
101
107 template <class _Other>
108 com_obj(_In_ _Other *other)
109 {
110 assert(other);
111 HRESULT hr = other->QueryInterface(__uuidof(T), (void**)&m_h);
112 if (FAILED(hr))
113 throw com_runtime_error(hr, "QueryInterface failed");
114 }
115
121 template <class _Other>
123 {
124 HRESULT hr = other->QueryInterface(__uuidof(T), (void**)&m_h);
125 if (FAILED(hr))
126 throw com_runtime_error(hr, "QueryInterface failed");
127 }
128
132 virtual ~com_obj()
133 {
134 if (m_h != invalid)
136 }
137
143 template <class _Other>
144 HRESULT query_interface(_Out_ _Other **h) const
145 {
146 assert(h);
147 assert(m_h);
148 return m_h->QueryInterface(__uuidof(_Other), (void**)h);
149 }
150
156 template <class _Other>
157 HRESULT query_interface(_Out_ com_obj<_Other> &h) const
158 {
159 assert(m_h);
160 _Other *_h;
161 HRESULT hr = m_h->QueryInterface(__uuidof(_Other), (void**)&_h);
162 if (SUCCEEDED(hr))
163 h.attach(_h);
164 return hr;
165 }
166
167 protected:
173 void free_internal() noexcept override
174 {
175 m_h->Release();
176 }
177
187 T* duplicate_internal(_In_ T* h) const override
188 {
189 h->AddRef();
190 return h;
191 }
192 };
193
197 class bstr : public dplhandle<BSTR, NULL>
198 {
199 WINSTD_DPLHANDLE_IMPL(bstr, BSTR, NULL)
200
201 public:
205 bstr(_In_opt_z_ LPCOLESTR src)
206 {
207 m_h = SysAllocString(src);
208 if (!m_h)
209 throw std::bad_alloc();
210 }
211
215 bstr(_In_reads_opt_(len) LPCOLESTR src, _In_ UINT len)
216 {
217 m_h = SysAllocStringLen(src, len);
218 if (!m_h)
219 throw std::bad_alloc();
220 }
221
225 template<class _Traits, class _Ax>
226 bstr(_In_ const std::basic_string<OLECHAR, _Traits, _Ax> &src)
227 {
228 size_t len = src.length();
229 if (len > UINT_MAX)
230 throw std::invalid_argument("string too long");
231 m_h = SysAllocStringLen(src.c_str(), static_cast<UINT>(len));
232 if (!m_h)
233 throw std::bad_alloc();
234 }
235
241 virtual ~bstr()
242 {
243 if (m_h != invalid)
245 }
246
252 UINT length() const noexcept
253 {
254 return SysStringLen(m_h);
255 }
256
257 protected:
263 void free_internal() noexcept override
264 {
265 SysFreeString(m_h);
266 }
267
278 {
279 handle_type h_new = SysAllocStringLen(h, SysStringLen(h));
280 if (h_new != invalid)
281 return h_new;
282 throw std::bad_alloc();
283 }
284 };
285
289 #pragma warning(push)
290 #pragma warning(disable: 26432) // Copy constructor and assignment operator are also present, but not detected by code analysis as they are using base type source object reference.
291 class variant : public VARIANT
292 {
293 public:
297 variant() noexcept
298 {
299 VariantInit(this);
300 }
301
305 variant(_In_ const VARIANT& varSrc)
306 {
307 vt = VT_EMPTY;
308 const HRESULT hr = VariantCopy(this, &varSrc);
309 if (FAILED(hr))
310 throw winstd::com_runtime_error(hr, "VariantCopy failed");
311 }
312
316 #pragma warning(suppress: 26495) // vt member is initialized as a result of memcpy()
317 variant(_Inout_ VARIANT&& varSrc) noexcept
318 {
319 memcpy(this, &varSrc, sizeof(VARIANT));
320 varSrc.vt = VT_EMPTY;
321 }
322
326 variant(_In_ bool bSrc) noexcept
327 {
328 vt = VT_BOOL;
329 boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
330 }
331
335 variant(_In_ char cSrc) noexcept
336 {
337 vt = VT_I1;
338 cVal = cSrc;
339 }
340
344 variant(_In_ unsigned char nSrc) noexcept
345 {
346 vt = VT_UI1;
347 bVal = nSrc;
348 }
349
353 variant(_In_ short nSrc) noexcept
354 {
355 vt = VT_I2;
356 iVal = nSrc;
357 }
358
362 variant(_In_ unsigned short nSrc) noexcept
363 {
364 vt = VT_UI2;
365 uiVal = nSrc;
366 }
367
371 variant(_In_ int nSrc, _In_ VARTYPE vtSrc = VT_I4) noexcept
372 {
373 assert(vtSrc == VT_I4 || vtSrc == VT_INT);
374 vt = vtSrc;
375 intVal = nSrc;
376 }
377
381 variant(_In_ unsigned int nSrc, _In_ VARTYPE vtSrc = VT_UI4) noexcept
382 {
383 assert(vtSrc == VT_UI4 || vtSrc == VT_UINT);
384 vt = vtSrc;
385 uintVal= nSrc;
386 }
387
391 variant(_In_ long nSrc, _In_ VARTYPE vtSrc = VT_I4) noexcept
392 {
393 assert(vtSrc == VT_I4 || vtSrc == VT_ERROR);
394 vt = vtSrc;
395 lVal = nSrc;
396 }
397
401 variant(_In_ unsigned long nSrc) noexcept
402 {
403 vt = VT_UI4;
404 ulVal = nSrc;
405 }
406
410 variant(_In_ float fltSrc) noexcept
411 {
412 vt = VT_R4;
413 fltVal = fltSrc;
414 }
415
419 variant(_In_ double dblSrc, _In_ VARTYPE vtSrc = VT_R8) noexcept
420 {
421 assert(vtSrc == VT_R8 || vtSrc == VT_DATE);
422 vt = vtSrc;
423 dblVal = dblSrc;
424 }
425
429 variant(_In_ long long nSrc) noexcept
430 {
431 vt = VT_I8;
432 llVal = nSrc;
433 }
434
438 variant(_In_ unsigned long long nSrc) noexcept
439 {
440 vt = VT_UI8;
441 ullVal = nSrc;
442 }
443
447 variant(_In_ CY cySrc) noexcept
448 {
449 vt = VT_CY;
450 cyVal.Hi = cySrc.Hi;
451 cyVal.Lo = cySrc.Lo;
452 }
453
457 variant(_In_z_ LPCOLESTR lpszSrc) noexcept
458 {
459 vt = VT_EMPTY;
460 *this = lpszSrc;
461 }
462
466 variant(_In_z_ BSTR bstr) noexcept
467 {
468 vt = VT_EMPTY;
469 *this = bstr;
470 }
471
475 variant(_In_opt_ IDispatch* pSrc)
476 {
477 vt = VT_DISPATCH;
478 pdispVal = pSrc;
479
480 if (pdispVal != NULL)
481 pdispVal->AddRef();
482 }
483
487 variant(_In_opt_ IUnknown* pSrc)
488 {
489 vt = VT_UNKNOWN;
490 punkVal = pSrc;
491
492 if (punkVal != NULL)
493 punkVal->AddRef();
494 }
495
499 variant(_In_ const SAFEARRAY *pSrc)
500 {
501 assert(pSrc != NULL);
502
503 LPSAFEARRAY pCopy;
504 const HRESULT hr = SafeArrayCopy(const_cast<LPSAFEARRAY>(pSrc), &pCopy);
505 if (FAILED(hr))
506 throw winstd::com_runtime_error(hr, "SafeArrayCopy failed");
507
508 SafeArrayGetVartype(const_cast<LPSAFEARRAY>(pSrc), &vt);
509 vt |= VT_ARRAY;
510 parray = pCopy;
511 }
512
516 virtual ~variant()
517 {
518 VariantClear(this);
519 }
520
524 variant& operator=(_In_ const VARIANT& varSrc)
525 {
526 if (this != &varSrc) {
527 const HRESULT hr = VariantCopy(this, &varSrc);
528 if (FAILED(hr))
529 throw winstd::com_runtime_error(hr, "VariantCopy failed");
530 }
531 return *this;
532 }
533
537 variant& operator=(_Inout_ VARIANT&& varSrc) noexcept
538 {
539 if (this != &varSrc) {
540 VariantClear(this);
541 memcpy(this, &varSrc, sizeof(VARIANT));
542 varSrc.vt = VT_EMPTY;
543 }
544 return *this;
545 }
546
550 variant& operator=(_In_ bool bSrc) noexcept
551 {
552 if (vt != VT_BOOL) {
553 VariantClear(this);
554 vt = VT_BOOL;
555 }
556 boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
557 return *this;
558 }
559
563 variant& operator=(_In_ char cSrc) noexcept
564 {
565 if (vt != VT_I1) {
566 VariantClear(this);
567 vt = VT_I1;
568 }
569 cVal = cSrc;
570 return *this;
571 }
572
576 variant& operator=(_In_ unsigned char nSrc) noexcept
577 {
578 if (vt != VT_UI1) {
579 VariantClear(this);
580 vt = VT_UI1;
581 }
582 bVal = nSrc;
583 return *this;
584 }
585
589 variant& operator=(_In_ short nSrc) noexcept
590 {
591 if (vt != VT_I2) {
592 VariantClear(this);
593 vt = VT_I2;
594 }
595 iVal = nSrc;
596 return *this;
597 }
598
602 variant& operator=(_In_ unsigned short nSrc) noexcept
603 {
604 if (vt != VT_UI2) {
605 VariantClear(this);
606 vt = VT_UI2;
607 }
608 uiVal = nSrc;
609 return *this;
610 }
611
615 variant& operator=(_In_ int nSrc) noexcept
616 {
617 if (vt != VT_I4) {
618 VariantClear(this);
619 vt = VT_I4;
620 }
621 intVal = nSrc;
622 return *this;
623 }
624
628 variant& operator=(_In_ unsigned int nSrc) noexcept
629 {
630 if (vt != VT_UI4) {
631 VariantClear(this);
632 vt = VT_UI4;
633 }
634 uintVal= nSrc;
635 return *this;
636 }
637
641 variant& operator=(_In_ long nSrc) noexcept
642 {
643 if (vt != VT_I4) {
644 VariantClear(this);
645 vt = VT_I4;
646 }
647 lVal = nSrc;
648 return *this;
649 }
650
654 variant& operator=(_In_ unsigned long nSrc) noexcept
655 {
656 if (vt != VT_UI4) {
657 VariantClear(this);
658 vt = VT_UI4;
659 }
660 ulVal = nSrc;
661 return *this;
662 }
663
667 variant& operator=(_In_ long long nSrc) noexcept
668 {
669 if (vt != VT_I8) {
670 VariantClear(this);
671 vt = VT_I8;
672 }
673 llVal = nSrc;
674 return *this;
675 }
676
680 variant& operator=(_In_ unsigned long long nSrc) noexcept
681 {
682 if (vt != VT_UI8) {
683 VariantClear(this);
684 vt = VT_UI8;
685 }
686 ullVal = nSrc;
687
688 return *this;
689 }
690
694 variant& operator=(_In_ float fltSrc) noexcept
695 {
696 if (vt != VT_R4) {
697 VariantClear(this);
698 vt = VT_R4;
699 }
700 fltVal = fltSrc;
701 return *this;
702 }
703
707 variant& operator=(_In_ double dblSrc) noexcept
708 {
709 if (vt != VT_R8) {
710 VariantClear(this);
711 vt = VT_R8;
712 }
713 dblVal = dblSrc;
714 return *this;
715 }
716
720 variant& operator=(_In_ CY cySrc) noexcept
721 {
722 if (vt != VT_CY) {
723 VariantClear(this);
724 vt = VT_CY;
725 }
726 cyVal.Hi = cySrc.Hi;
727 cyVal.Lo = cySrc.Lo;
728 return *this;
729 }
730
734 variant& operator=(_In_z_ LPCOLESTR lpszSrc) noexcept
735 {
736 VariantClear(this);
737 vt = VT_BSTR;
738 bstrVal = SysAllocString(lpszSrc);
739 return *this;
740 }
741
745 variant& operator=(_Inout_opt_ IDispatch* pSrc)
746 {
747 VariantClear(this);
748 vt = VT_DISPATCH;
749 pdispVal = pSrc;
750 if (pdispVal != NULL)
751 pdispVal->AddRef();
752 return *this;
753 }
754
758 variant& operator=(_Inout_opt_ IUnknown* pSrc)
759 {
760 VariantClear(this);
761 vt = VT_UNKNOWN;
762 punkVal = pSrc;
763 if (punkVal != NULL)
764 punkVal->AddRef();
765 return *this;
766 }
767
771 variant& operator=(_In_ unsigned char* pbSrc) noexcept
772 {
773 if (vt != (VT_UI1|VT_BYREF)) {
774 VariantClear(this);
775 vt = VT_UI1|VT_BYREF;
776 }
777 pbVal = pbSrc;
778 return *this;
779 }
780
784 variant& operator=(_In_ short* pnSrc) noexcept
785 {
786 if (vt != (VT_I2|VT_BYREF)) {
787 VariantClear(this);
788 vt = VT_I2|VT_BYREF;
789 }
790 piVal = pnSrc;
791 return *this;
792 }
793
797 variant& operator=(_In_ unsigned short* pnSrc) noexcept
798 {
799 if (vt != (VT_UI2|VT_BYREF)) {
800 VariantClear(this);
801 vt = VT_UI2|VT_BYREF;
802 }
803 puiVal = pnSrc;
804 return *this;
805 }
806
810 variant& operator=(_In_ int* pnSrc) noexcept
811 {
812 if (vt != (VT_I4|VT_BYREF)) {
813 VariantClear(this);
814 vt = VT_I4|VT_BYREF;
815 }
816 pintVal = pnSrc;
817 return *this;
818 }
819
823 variant& operator=(_In_ unsigned int* pnSrc) noexcept
824 {
825 if (vt != (VT_UI4|VT_BYREF)) {
826 VariantClear(this);
827 vt = VT_UI4|VT_BYREF;
828 }
829 puintVal = pnSrc;
830 return *this;
831 }
832
836 variant& operator=(_In_ long* pnSrc) noexcept
837 {
838 if (vt != (VT_I4|VT_BYREF)) {
839 VariantClear(this);
840 vt = VT_I4|VT_BYREF;
841 }
842 plVal = pnSrc;
843 return *this;
844 }
845
849 variant& operator=(_In_ unsigned long* pnSrc) noexcept
850 {
851 if (vt != (VT_UI4|VT_BYREF)) {
852 VariantClear(this);
853 vt = VT_UI4|VT_BYREF;
854 }
855 pulVal = pnSrc;
856 return *this;
857 }
858
862 variant& operator=(_In_ long long* pnSrc) noexcept
863 {
864 if (vt != (VT_I8|VT_BYREF)) {
865 VariantClear(this);
866 vt = VT_I8|VT_BYREF;
867 }
868 pllVal = pnSrc;
869 return *this;
870 }
871
875 variant& operator=(_In_ unsigned long long* pnSrc) noexcept
876 {
877 if (vt != (VT_UI8|VT_BYREF)) {
878 VariantClear(this);
879 vt = VT_UI8|VT_BYREF;
880 }
881 pullVal = pnSrc;
882 return *this;
883 }
884
888 variant& operator=(_In_ float* pfSrc) noexcept
889 {
890 if (vt != (VT_R4|VT_BYREF)) {
891 VariantClear(this);
892 vt = VT_R4|VT_BYREF;
893 }
894 pfltVal = pfSrc;
895 return *this;
896 }
897
901 variant& operator=(_In_ double* pfSrc) noexcept
902 {
903 if (vt != (VT_R8|VT_BYREF)) {
904 VariantClear(this);
905 vt = VT_R8|VT_BYREF;
906 }
907 pdblVal = pfSrc;
908 return *this;
909 }
910
914 variant& operator=(_In_ const SAFEARRAY *pSrc)
915 {
916 assert(pSrc != NULL);
917 VariantClear(this);
918
919 LPSAFEARRAY pCopy;
920 const HRESULT hr = SafeArrayCopy(const_cast<LPSAFEARRAY>(pSrc), &pCopy);
921 if (SUCCEEDED(hr)) {
922 SafeArrayGetVartype(const_cast<LPSAFEARRAY>(pSrc), &vt);
923 vt |= VT_ARRAY;
924 parray = pCopy;
925 return *this;
926 }
927 throw com_runtime_error(hr, "SafeArrayCopy failed");
928 }
929
930 public:
939 bool operator==(_In_ const VARIANT& varSrc) const noexcept
940 {
941 if (vt == VT_NULL && varSrc.vt == VT_NULL) return true;
942 if (vt != varSrc.vt) return false;
943 return compare(static_cast<const VARIANT&>(*this), varSrc, LOCALE_USER_DEFAULT, 0) == static_cast<HRESULT>(VARCMP_EQ);
944 }
945
954 bool operator!=(_In_ const VARIANT& varSrc) const noexcept
955 {
956 return !operator==(varSrc);
957 }
958
967 bool operator<(_In_ const VARIANT& varSrc) const noexcept
968 {
969 if (vt == VT_NULL && varSrc.vt == VT_NULL) return false;
970 return compare(static_cast<const VARIANT&>(*this), varSrc, LOCALE_USER_DEFAULT, 0)== static_cast<HRESULT>(VARCMP_LT);
971 }
972
981 bool operator>(_In_ const VARIANT& varSrc) const noexcept
982 {
983 if (vt == VT_NULL && varSrc.vt == VT_NULL) return false;
984 return compare(static_cast<const VARIANT&>(*this), varSrc, LOCALE_USER_DEFAULT, 0)== static_cast<HRESULT>(VARCMP_GT);
985 }
986
995 bool operator<=(_In_ const VARIANT& varSrc) const noexcept
996 {
997 return !operator>(varSrc);
998 }
999
1008 bool operator>=(_In_ const VARIANT& varSrc) const noexcept
1009 {
1010 return !operator<(varSrc);
1011 }
1012
1018 HRESULT change_type(_In_ VARTYPE _vt, _In_opt_ USHORT wFlags = 0) noexcept
1019 {
1020 return VariantChangeType(this, this, wFlags, _vt);
1021 }
1022
1023 private:
1025 HRESULT compare(_In_ const VARIANT &varLeft, _In_ const VARIANT &varRight, _In_ LCID lcid, _In_ ULONG dwFlags) const noexcept
1026 {
1027 switch(vt) {
1028 case VT_I1: return varLeft.cVal == varRight.cVal ? VARCMP_EQ : varLeft.cVal > varRight.cVal ? VARCMP_GT : VARCMP_LT;
1029 case VT_UI2: return varLeft.uiVal == varRight.uiVal ? VARCMP_EQ : varLeft.uiVal > varRight.uiVal ? VARCMP_GT : VARCMP_LT;
1030 case VT_UI4: return varLeft.uintVal == varRight.uintVal ? VARCMP_EQ : varLeft.uintVal > varRight.uintVal ? VARCMP_GT : VARCMP_LT;
1031 case VT_UI8: return varLeft.ullVal == varRight.ullVal ? VARCMP_EQ : varLeft.ullVal > varRight.ullVal ? VARCMP_GT : VARCMP_LT;
1032 default: return VarCmp(const_cast<LPVARIANT>(&varLeft), const_cast<LPVARIANT>(&varRight), lcid, dwFlags);
1033 }
1034 }
1036 };
1037 #pragma warning(pop)
1038
1042 class safearray : public dplhandle<SAFEARRAY*, NULL>
1043 {
1044 WINSTD_DPLHANDLE_IMPL(safearray, SAFEARRAY*, NULL)
1045
1046 public:
1052 virtual ~safearray()
1053 {
1054 if (m_h != invalid)
1055 free_internal();
1056 }
1057
1058 protected:
1064 void free_internal() noexcept override
1065 {
1066 SafeArrayDestroy(m_h);
1067 }
1068
1079 {
1080 handle_type h_new;
1081 HRESULT hr = SafeArrayCopy(h, &h_new);
1082 if (SUCCEEDED(hr))
1083 return h_new;
1084 throw com_runtime_error(hr, "SafeArrayCopy failed");
1085 }
1086 };
1087
1091 template <class T>
1093 {
1096
1097 public:
1103 safearray_accessor(_In_ SAFEARRAY* psa) : m_sa(psa)
1104 {
1105 HRESULT hr = SafeArrayAccessData(psa, (void HUGEP**)&m_data);
1106 if (FAILED(hr))
1107 throw com_runtime_error(hr, "SafeArrayAccessData failed");
1108 }
1109
1116 {
1117 SafeArrayUnaccessData(m_sa);
1118 }
1119
1123 T HUGEP* data() const noexcept
1124 {
1125 return m_data;
1126 }
1127
1128 protected:
1129 SAFEARRAY* m_sa;
1130 T HUGEP* m_data;
1131 };
1132
1137 {
1140
1141 public:
1147 com_initializer(_In_opt_ LPVOID pvReserved)
1148 {
1149 HRESULT hr = CoInitialize(pvReserved);
1150 if (FAILED(hr))
1151 throw com_runtime_error(hr, "CoInitialize failed");
1152 }
1153
1159 com_initializer(_In_opt_ LPVOID pvReserved, _In_ DWORD dwCoInit)
1160 {
1161 HRESULT hr = CoInitializeEx(pvReserved, dwCoInit);
1162 if (FAILED(hr))
1163 throw com_runtime_error(hr, "CoInitializeEx failed");
1164 }
1165
1172 {
1173 CoUninitialize();
1174 }
1175 };
1176
1178}
1179
1182
1188template <class T>
1189static _Check_return_ HRESULT CoCreateInstance(_In_ REFCLSID rclsid, _In_opt_ LPUNKNOWN pUnkOuter, _In_ DWORD dwClsContext, _Inout_ winstd::com_obj<T> &v)
1190{
1191 T* ppv;
1192 HRESULT hr = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (LPVOID*)&ppv);
1193 if (SUCCEEDED(hr))
1194 v.attach(ppv);
1195 return hr;
1196}
1197
1203template <class T>
1204static _Check_return_ HRESULT CoGetObject(_In_ LPCWSTR pszName, _In_opt_ BIND_OPTS* pBindOptions, _In_ REFIID riid, _Inout_ winstd::com_obj<T>& v)
1205{
1206 T* ppv;
1207 HRESULT hr = CoGetObject(pszName, pBindOptions, riid, (LPVOID*)&ppv);
1208 if (SUCCEEDED(hr))
1209 v.attach(ppv);
1210 return hr;
1211}
1212
1214
1217
1226inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ IDispatch* value)
1227{
1228 V_VT(&v) = VT_DISPATCH;
1229 V_DISPATCH(&v) = value;
1230 value->AddRef();
1231 return *(&v + 1);
1232}
1233
1242inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const CHAR value)
1243{
1244 V_VT(&v) = VT_I1;
1245 V_I1(&v) = value;
1246 return *(&v + 1);
1247}
1248
1257inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const BYTE value)
1258{
1259 V_VT(&v) = VT_UI1;
1260 V_UI1(&v) = value;
1261 return *(&v + 1);
1262}
1263
1272inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const SHORT value)
1273{
1274 V_VT(&v) = VT_I2;
1275 V_I2(&v) = value;
1276 return *(&v + 1);
1277}
1278
1287inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const USHORT value)
1288{
1289 V_VT(&v) = VT_UI2;
1290 V_UI2(&v) = value;
1291 return *(&v + 1);
1292}
1293
1302inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const LONG value)
1303{
1304 V_VT(&v) = VT_I4;
1305 V_I4(&v) = value;
1306 return *(&v + 1);
1307}
1308
1317inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const ULONG value)
1318{
1319 V_VT(&v) = VT_UI4;
1320 V_UI4(&v) = value;
1321 return *(&v + 1);
1322}
1323
1332inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const LONGLONG value)
1333{
1334 V_VT(&v) = VT_I8;
1335 V_I8(&v) = value;
1336 return *(&v + 1);
1337}
1338
1347inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const ULONGLONG value)
1348{
1349 V_VT(&v) = VT_UI8;
1350 V_UI8(&v) = value;
1351 return *(&v + 1);
1352}
1353
1362inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const FLOAT value)
1363{
1364 V_VT(&v) = VT_R4;
1365 V_R4(&v) = value;
1366 return *(&v + 1);
1367}
1368
1377inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const DOUBLE value)
1378{
1379 V_VT(&v) = VT_R8;
1380 V_R8(&v) = value;
1381 return *(&v + 1);
1382}
1383
1392inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const BOOL value)
1393{
1394 return v << (value ? VARIANT_TRUE : VARIANT_FALSE);
1395}
1396
1405inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ LPCOLESTR value)
1406{
1407 V_VT(&v) = VT_BSTR;
1408 V_BSTR(&v) = SysAllocString(value);
1409 return *(&v + 1);
1410}
1411
1420template<class _Traits, class _Ax>
1421inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const std::basic_string<OLECHAR, _Traits, _Ax>& value)
1422{
1423 if (value.size() > UINT_MAX)
1424 throw std::invalid_argument("string too long");
1425 V_VT(&v) = VT_BSTR;
1426 V_BSTR(&v) = SysAllocStringLen(value.data(), static_cast<UINT>(value.size()));
1427 return *(&v + 1);
1428}
1429
1440inline VARIANT& operator <<(_Out_ VARIANT& v, _In_ const GUID& value)
1441{
1442 OLECHAR guid_niz[38 + 1];
1443 V_VT(&v) = VT_BSTR;
1444 V_BSTR(&v) = SysAllocStringLen(guid_niz, _swprintf_s_l(
1445 guid_niz, _countof(guid_niz),
1446 L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
1447 NULL,
1448 value.Data1,
1449 value.Data2,
1450 value.Data3,
1451 value.Data4[0], value.Data4[1],
1452 value.Data4[2], value.Data4[3], value.Data4[4], value.Data4[5], value.Data4[6], value.Data4[7]));
1453 return *(&v + 1);
1454}
1455
1457
1458namespace winstd
1459{
1462
1473 inline VARIANT BuildVBARRAY(_In_ VARTYPE vt, _In_opt_ LPCVOID array, _In_ ULONG columns, _In_ ULONG rows)
1474 {
1475 LPSAFEARRAY sa;
1476 size_t n;
1477 if (columns == 1) {
1478 // Make vector when one column only.
1479 sa = SafeArrayCreateVector(VT_VARIANT, 0, rows);
1480 n = rows;
1481 }
1482 else {
1483 // Make 2-dimensional array when more columns.
1484 SAFEARRAYBOUND dim[2] = {
1485 { columns, 0 },
1486 { rows, 0 }
1487 };
1488 sa = SafeArrayCreate(VT_VARIANT, 2, dim);
1489 n = columns * rows;
1490 }
1491 if (!sa)
1492 throw std::bad_alloc();
1493 assert(array || !n);
1494
1495 // Support VARIANT types that may be used for SAFEARRAY
1496 // Source: https://learn.microsoft.com/en-us/windows/win32/api/wtypes/ne-wtypes-varenum#remarks
1497 size_t delta_src;
1498 VARIANT* v = NULL;
1499 switch (vt) {
1500 case VT_BOOL: delta_src = sizeof(V_BOOL(v)); break;
1501 case VT_BSTR: delta_src = sizeof(V_BSTR(v)); break;
1502 case VT_CY: delta_src = sizeof(V_CY(v)); break;
1503 case VT_DATE: delta_src = sizeof(V_DATE(v)); break;
1504 case VT_DECIMAL: delta_src = sizeof(V_DECIMAL(v)); break;
1505 case VT_DISPATCH: delta_src = sizeof(V_DISPATCH(v)); break;
1506 case VT_ERROR: delta_src = sizeof(V_ERROR(v)); break;
1507 case VT_I1: delta_src = sizeof(V_I1(v)); break;
1508 case VT_I2: delta_src = sizeof(V_I2(v)); break;
1509 case VT_I4: delta_src = sizeof(V_I4(v)); break;
1510 case VT_INT: delta_src = sizeof(V_INT(v)); break;
1511 case VT_R4: delta_src = sizeof(V_R4(v)); break;
1512 case VT_R8: delta_src = sizeof(V_R8(v)); break;
1513 case VT_RECORD: delta_src = sizeof(V_RECORD(v)); break;
1514 case VT_UI1: delta_src = sizeof(V_UI1(v)); break;
1515 case VT_UI2: delta_src = sizeof(V_UI2(v)); break;
1516 case VT_UI4: delta_src = sizeof(V_UI4(v)); break;
1517 case VT_UINT: delta_src = sizeof(V_UINT(v)); break;
1518 case VT_UNKNOWN: delta_src = sizeof(V_UNKNOWN(v)); break;
1519 default: throw std::invalid_argument("unsupported VARIANT type");
1520 };
1521 size_t delta_dst = SafeArrayGetElemsize(sa);
1522
1523 {
1525 LPBYTE dst = ssa.data();
1526 LPCBYTE src = reinterpret_cast<LPCBYTE>(array);
1527 for (size_t i = 0; i < n; ++i, src += delta_src, dst += delta_dst) {
1528 v = reinterpret_cast<VARIANT*>(dst);
1529
1530 // No VariantInit, since SafeArrayCreate(Vector) zero-initializes all elements.
1531 // VariantInit(v);
1532 V_VT(v) = vt;
1533 memcpy(&(v->byref), src, delta_src);
1534 }
1535 }
1536
1537 VARIANT var;
1538 V_VT(&var) = VT_ARRAY | VT_VARIANT;
1539 V_ARRAY(&var) = sa;
1540 return var;
1541 }
1542
1557 template <class T, ULONG columns = 1>
1558 VARIANT BuildVBARRAY(_In_reads_opt_(rows) const T* array, _In_ ULONG rows)
1559 {
1560 assert(array || !rows);
1561
1562 LPSAFEARRAY sa;
1563 if constexpr (columns == 1) {
1564 // Make vector when one column only.
1565 sa = SafeArrayCreateVector(VT_VARIANT, 0, rows);
1566 }
1567 else {
1568 // Make 2-dimensional array when more columns.
1569 SAFEARRAYBOUND dim[2] = {
1570 { columns, 0 },
1571 { rows, 0 }
1572 };
1573 sa = SafeArrayCreate(VT_VARIANT, _countof(dim), dim);
1574 }
1575 if (!sa)
1576 throw std::bad_alloc();
1577
1578 assert(SafeArrayGetElemsize(sa) == sizeof(VARIANT));
1579
1580 {
1582 VARIANT* dst = ssa.data();
1583 for (size_t i = 0; i < rows; ++i) {
1584 VARIANT* dst_next = &(*dst << array[i]);
1585 assert(dst + columns == dst_next);
1586 dst = dst_next;
1587 }
1588 }
1589
1590 VARIANT var;
1591 V_VT(&var) = VT_ARRAY | VT_VARIANT;
1592 V_ARRAY(&var) = sa;
1593 return var;
1594 }
1595
1604 inline VARIANT BuildVBARRAY(_In_ HDC dc, _In_ HBITMAP pic)
1605 {
1606 // Get picture parameters.
1607 BITMAP bmp;
1608 GetObject(pic, sizeof(bmp), reinterpret_cast<LPSTR>(&bmp));
1609
1610 // Estimate file parameters.
1611 BITMAPINFOHEADER bmh = { sizeof(bmh) };
1612 GetDIBits(dc, pic, 0, bmp.bmHeight, NULL, reinterpret_cast<LPBITMAPINFO>(&bmh), DIB_RGB_COLORS);
1613
1614 // Allocate.
1615 size_t pallete_size = sizeof(RGBQUAD) * bmh.biClrUsed;
1616 LPSAFEARRAY sa = SafeArrayCreateVector(VT_UI1, 0, static_cast<ULONG>(sizeof(BITMAPFILEHEADER) + sizeof(bmh) + pallete_size + bmh.biSizeImage));
1617 if (!sa)
1618 throw std::bad_alloc();
1619
1620 // Locate BITMAPFILEHEADER, BITMAPINFO and pixel map.
1622 auto header = reinterpret_cast<LPBITMAPFILEHEADER>(ssa.data());
1623 auto info = reinterpret_cast<LPBITMAPINFO>(ssa.data() + sizeof(*header));
1624 auto raster = ssa.data() + sizeof(*header) + sizeof(bmh) + pallete_size;
1625
1626 // Fill in BITMAPFILEHEADER.
1627 memset(header, 0, sizeof(*header));
1628#pragma warning(push)
1629#pragma warning(disable: 6276) // "BM" is not an UTF16 char.
1630 header->bfType = *reinterpret_cast<WORD*>("BM");
1631#pragma warning(pop)
1632 header->bfSize = static_cast<DWORD>(sizeof(*header) + sizeof(bmh) + pallete_size + bmh.biSizeImage);
1633 header->bfOffBits = static_cast<DWORD>(sizeof(*header) + sizeof(bmh) + pallete_size);
1634
1635 // Fill in BITMAPINFO.
1636 memcpy(&(info->bmiHeader), &bmh, sizeof(bmh));
1637 memset(&(info->bmiColors), 0, pallete_size);
1638
1639 // Set pallete and pixel map.
1640 GetDIBits(dc, pic, 0, bmp.bmHeight, raster, info, DIB_RGB_COLORS);
1641
1642 VARIANT var;
1643 V_VT(&var) = VT_ARRAY | VT_UI1;
1644 V_ARRAY(&var) = sa;
1645 return var;
1646 }
1647
1658 template <class T>
1659 void IDispatchInvoke(_In_ T* cp, _In_ DISPID id, _In_opt_ DISPPARAMS* param, _In_ LCID locale = LOCALE_USER_DEFAULT)
1660 {
1661 assert(cp);
1663 HRESULT hr = cp->EnumConnections(&e);
1664 if (FAILED(hr))
1665 throw com_runtime_error(hr, "IDispatch::EnumConnections failed");
1666
1667 CONNECTDATA cd;
1668 while (e->Next(1, &cd, NULL) == S_OK) {
1669 com_obj<IDispatch> d(cd.pUnk);
1670 d->Invoke(id, IID_NULL, locale, DISPATCH_METHOD, param, NULL, NULL, NULL);
1671 }
1672 }
1673
1684 template <class T>
1685 T VariantAsInteger(_In_ const VARIANT* var, _In_ T fallback = 0)
1686 {
1687 assert(var);
1688 switch (V_VT(var)) {
1689 case VT_UINT_PTR: return static_cast<T>(V_UINT_PTR(var));
1690 case VT_INT_PTR: return static_cast<T>(V_INT_PTR(var));
1691 case VT_UINT: return static_cast<T>(V_UINT(var));
1692 case VT_INT: return static_cast<T>(V_INT(var));
1693 case VT_UI4: return static_cast<T>(V_UI4(var));
1694 case VT_I4: return static_cast<T>(V_I4(var));
1695 case VT_UI2: return static_cast<T>(V_UI2(var));
1696 case VT_I2: return static_cast<T>(V_I2(var));
1697 case VT_UI1: return static_cast<T>(V_UI1(var));
1698 case VT_I1: return static_cast<T>(V_I1(var));
1699 }
1700 return fallback;
1701 }
1702
1711 inline BOOL VariantAsBoolean(_In_ const VARIANT* var, _In_ BOOL fallback = FALSE)
1712 {
1713 assert(var);
1714 switch (V_VT(var)) {
1715 case VT_BOOL: return V_BOOL(var) != VARIANT_FALSE;
1716 case VT_UI4: return V_UI4(var) != 0;
1717 case VT_I4: return V_I4(var) != 0;
1718 case VT_UI2: return V_UI2(var) != 0;
1719 case VT_I2: return V_I2(var) != 0;
1720 case VT_UI1: return V_UI1(var) != 0;
1721 case VT_I1: return V_I1(var) != 0;
1722 case VT_UINT: return V_UINT(var) != 0;
1723 case VT_INT: return V_INT(var) != 0;
1724 case VT_UINT_PTR: return V_UINT_PTR(var) != 0;
1725 case VT_INT_PTR: return V_INT_PTR(var) != 0;
1726 }
1727 return fallback;
1728 }
1729
1731}
BSTR string wrapper.
Definition COM.h:198
bstr(LPCOLESTR src)
Constructs BSTR from OLE string.
Definition COM.h:205
handle_type duplicate_internal(handle_type h) const override
Duplicates the string.
Definition COM.h:277
virtual ~bstr()
Destroys the string.
Definition COM.h:241
void free_internal() noexcept override
Destroys the string.
Definition COM.h:263
UINT length() const noexcept
Returns the length of the string.
Definition COM.h:252
bstr(LPCOLESTR src, UINT len)
Constructs BSTR from OLE string with length.
Definition COM.h:215
bstr(const std::basic_string< OLECHAR, _Traits, _Ax > &src)
Constructs BSTR from std::basic_string.
Definition COM.h:226
Context scope automatic COM (un)initialization.
Definition COM.h:1137
com_initializer(LPVOID pvReserved, DWORD dwCoInit)
Initializes the COM library for use by the calling thread, sets the thread's concurrency model,...
Definition COM.h:1159
virtual ~com_initializer()
Uninitializes COM.
Definition COM.h:1171
com_initializer(LPVOID pvReserved)
Initializes the COM library on the current thread and identifies the concurrency model as single-thre...
Definition COM.h:1147
COM object wrapper template.
Definition COM.h:83
void free_internal() noexcept override
Releases the object by decrementing reference counter.
Definition COM.h:173
com_obj(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext)
Creates a new instance of a class.
Definition COM.h:92
HRESULT query_interface(_Other **h) const
Queries the object for another interface.
Definition COM.h:144
T * duplicate_internal(T *h) const override
Duplicates the object by incrementing the reference counter.
Definition COM.h:187
HRESULT query_interface(com_obj< _Other > &h) const
Queries the object for another interface.
Definition COM.h:157
virtual ~com_obj()
Releases object.
Definition COM.h:132
com_obj(_Other *other)
Queries the object for another interface and creates new class with it.
Definition COM.h:108
com_obj(com_obj< _Other > &other)
Queries the object for another interface and creates new class with it.
Definition COM.h:122
COM runtime error.
Definition COM.h:28
com_runtime_error(error_type num, const std::string &msg)
Constructs an exception.
Definition COM.h:36
com_runtime_error(error_type num, const char *msg=nullptr)
Constructs an exception.
Definition COM.h:45
Device context wrapper class.
Definition GDI.h:84
Base abstract template class to support object handle keeping for objects that support trivial handle...
Definition Common.h:1287
handle_type m_h
Object handle.
Definition Common.h:1276
BSTR handle_type
Definition Common.h:1029
Numerical runtime error.
Definition Common.h:1481
HRESULT error_type
Definition Common.h:1483
Context scope automatic SAFEARRAY (un)access.
Definition COM.h:1093
safearray_accessor(SAFEARRAY *psa)
Increments the lock count of an array, and retrieves a pointer to the array data.
Definition COM.h:1103
T HUGEP * data() const noexcept
Return SAFEARRAY data pointer.
Definition COM.h:1123
SAFEARRAY * m_sa
SAFEARRAY.
Definition COM.h:1129
virtual ~safearray_accessor()
Decrements the lock count of an array.
Definition COM.h:1115
T HUGEP * m_data
SAFEARRAY data.
Definition COM.h:1130
SAFEARRAY string wrapper.
Definition COM.h:1043
virtual ~safearray()
Destroys the array.
Definition COM.h:1052
handle_type duplicate_internal(handle_type h) const override
Duplicates the array.
Definition COM.h:1078
void free_internal() noexcept override
Destroys the array.
Definition COM.h:1064
VARIANT struct wrapper.
Definition COM.h:292
bool operator<=(const VARIANT &varSrc) const noexcept
Is variant less than or equal to?
Definition COM.h:995
variant(bool bSrc) noexcept
Constructs VARIANT from bool.
Definition COM.h:326
variant & operator=(unsigned int nSrc) noexcept
Copy from unsigned int value.
Definition COM.h:628
variant & operator=(unsigned long nSrc) noexcept
Copy from unsigned long value.
Definition COM.h:654
variant(float fltSrc) noexcept
Constructs VARIANT from float.
Definition COM.h:410
variant(VARIANT &&varSrc) noexcept
Moves VARIANT from another.
Definition COM.h:317
variant & operator=(float fltSrc) noexcept
Copy from float value.
Definition COM.h:694
variant & operator=(float *pfSrc) noexcept
Copy from float reference.
Definition COM.h:888
variant(IDispatch *pSrc)
Constructs VARIANT from IDispatch.
Definition COM.h:475
variant(int nSrc, VARTYPE vtSrc=VT_I4) noexcept
Constructs VARIANT from integer.
Definition COM.h:371
variant(const SAFEARRAY *pSrc)
Constructs VARIANT from SAFEARRAY.
Definition COM.h:499
variant & operator=(double *pfSrc) noexcept
Copy from double reference.
Definition COM.h:901
variant & operator=(const SAFEARRAY *pSrc)
Copy from SAFEARRAY.
Definition COM.h:914
variant & operator=(int *pnSrc) noexcept
Copy from int reference.
Definition COM.h:810
bool operator>(const VARIANT &varSrc) const noexcept
Is variant greater than?
Definition COM.h:981
variant & operator=(bool bSrc) noexcept
Copy from bool value.
Definition COM.h:550
variant & operator=(long nSrc) noexcept
Copy from long value.
Definition COM.h:641
HRESULT change_type(VARTYPE _vt, USHORT wFlags=0) noexcept
Converts a variant from one type to another.
Definition COM.h:1018
variant & operator=(IUnknown *pSrc)
Copy from IUnknown.
Definition COM.h:758
variant & operator=(short nSrc) noexcept
Copy from short value.
Definition COM.h:589
variant & operator=(unsigned char *pbSrc) noexcept
Copy from unsigned char reference.
Definition COM.h:771
variant & operator=(unsigned short nSrc) noexcept
Copy from unsigned short value.
Definition COM.h:602
variant & operator=(unsigned char nSrc) noexcept
Copy from unsigned char value.
Definition COM.h:576
variant & operator=(char cSrc) noexcept
Copy from char value.
Definition COM.h:563
variant(LPCOLESTR lpszSrc) noexcept
Constructs VARIANT from OLE string.
Definition COM.h:457
virtual ~variant()
Destroys VARIANT.
Definition COM.h:516
variant(const VARIANT &varSrc)
Constructs VARIANT from another.
Definition COM.h:305
variant(unsigned char nSrc) noexcept
Constructs VARIANT from byte.
Definition COM.h:344
variant & operator=(double dblSrc) noexcept
Copy from double value.
Definition COM.h:707
bool operator!=(const VARIANT &varSrc) const noexcept
Is variant not equal to?
Definition COM.h:954
variant & operator=(int nSrc) noexcept
Copy from int value.
Definition COM.h:615
variant(unsigned long nSrc) noexcept
Constructs VARIANT from unsigned long.
Definition COM.h:401
bool operator==(const VARIANT &varSrc) const noexcept
Is variant equal to?
Definition COM.h:939
variant(IUnknown *pSrc)
Constructs VARIANT from IUnknown.
Definition COM.h:487
variant(unsigned int nSrc, VARTYPE vtSrc=VT_UI4) noexcept
Constructs VARIANT from unsigned integer.
Definition COM.h:381
variant & operator=(CY cySrc) noexcept
Copy from CY value.
Definition COM.h:720
variant & operator=(LPCOLESTR lpszSrc) noexcept
Copy from OLE string value.
Definition COM.h:734
variant(long long nSrc) noexcept
Constructs VARIANT from 64-bit integer.
Definition COM.h:429
variant & operator=(unsigned int *pnSrc) noexcept
Copy from unsigned int reference.
Definition COM.h:823
variant(long nSrc, VARTYPE vtSrc=VT_I4) noexcept
Constructs VARIANT from long.
Definition COM.h:391
variant & operator=(long *pnSrc) noexcept
Copy from long reference.
Definition COM.h:836
variant(unsigned short nSrc) noexcept
Constructs VARIANT from unsigned short.
Definition COM.h:362
bool operator>=(const VARIANT &varSrc) const noexcept
Is variant greater than or equal to?
Definition COM.h:1008
variant & operator=(short *pnSrc) noexcept
Copy from short reference.
Definition COM.h:784
variant() noexcept
Constructs blank VARIANT.
Definition COM.h:297
bool operator<(const VARIANT &varSrc) const noexcept
Is variant less than?
Definition COM.h:967
variant(unsigned long long nSrc) noexcept
Constructs VARIANT from unsigned integer.
Definition COM.h:438
variant(char cSrc) noexcept
Constructs VARIANT from character.
Definition COM.h:335
variant & operator=(unsigned short *pnSrc) noexcept
Copy from unsigned short reference.
Definition COM.h:797
variant & operator=(long long *pnSrc) noexcept
Copy from long long reference.
Definition COM.h:862
variant(BSTR bstr) noexcept
Constructs VARIANT from BSTR.
Definition COM.h:466
variant & operator=(unsigned long long *pnSrc) noexcept
Copy from unsigned long long reference.
Definition COM.h:875
variant(double dblSrc, VARTYPE vtSrc=VT_R8) noexcept
Constructs VARIANT from double or variant date.
Definition COM.h:419
variant(short nSrc) noexcept
Constructs VARIANT from short.
Definition COM.h:353
variant(CY cySrc) noexcept
Constructs VARIANT from CY (64-bit integer)
Definition COM.h:447
variant & operator=(unsigned long long nSrc) noexcept
Copy from unsigned long long value.
Definition COM.h:680
variant & operator=(VARIANT &&varSrc) noexcept
Moves from another VARIANT.
Definition COM.h:537
variant & operator=(long long nSrc) noexcept
Copy from long long value.
Definition COM.h:667
variant & operator=(IDispatch *pSrc)
Copy from IDispatch.
Definition COM.h:745
variant & operator=(unsigned long *pnSrc) noexcept
Copy from unsigned long reference.
Definition COM.h:849
variant & operator=(const VARIANT &varSrc)
Copy from another VARIANT.
Definition COM.h:524
VARIANT & operator<<(VARIANT &v, IDispatch *value)
Saves value to VARIANT.
Definition COM.h:1226
void IDispatchInvoke(T *cp, DISPID id, DISPPARAMS *param, LCID locale=LOCALE_USER_DEFAULT)
Calls IDispatch::Invoke.
Definition COM.h:1659
T VariantAsInteger(const VARIANT *var, T fallback=0)
Check VARIANT value for integer value.
Definition COM.h:1685
VARIANT BuildVBARRAY(VARTYPE vt, LPCVOID array, ULONG columns, ULONG rows)
Builds VBARRAY of uniform data.
Definition COM.h:1473
BOOL VariantAsBoolean(const VARIANT *var, BOOL fallback=FALSE)
Check VARIANT value for boolean value.
Definition COM.h:1711
static _Check_return_ HRESULT CoGetObject(LPCWSTR pszName, BIND_OPTS *pBindOptions, REFIID riid, winstd::com_obj< T > &v)
Converts a display name into a moniker that identifies the object named, and then binds to the object...
Definition COM.h:1204
static _Check_return_ HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, winstd::com_obj< T > &v)
Creates and default-initializes a single object of the class associated with a specified CLSID.
Definition COM.h:1189
#define WINSTD_NONCOPYABLE(C)
Declares a class as non-copyable.
Definition Common.h:67
#define WINSTD_NONMOVABLE(C)
Declares a class as non-movable.
Definition Common.h:75
#define WINSTD_DPLHANDLE_IMPL(C, T, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition Common.h:176
static const T invalid
Invalid handle value.
Definition Common.h:1034
Deleter for unique_ptr using CoTaskMemFree.
Definition COM.h:58
void operator()(_T *_Ptr) const
Delete a pointer.
Definition COM.h:70
CoTaskMemFree_delete() noexcept
Default constructor.
Definition COM.h:62