accessible/src/windows/msaa/IUnknownImpl.h

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:abf6b531cb47
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. *
6 */
7
8 #ifndef mozilla_a11y_IUnknownImpl_h_
9 #define mozilla_a11y_IUnknownImpl_h_
10
11 #include <windows.h>
12 #undef CreateEvent // thank you windows you're such a helper
13 #include "nsError.h"
14
15 // Avoid warning C4509 like "nonstandard extension used:
16 // 'AccessibleWrap::[acc_getName]' uses SEH and 'name' has destructor.
17 // At this point we're catching a crash which is of much greater
18 // importance than the missing dereference for the nsCOMPtr<>
19 #ifdef _MSC_VER
20 #pragma warning( disable : 4509 )
21 #endif
22
23 namespace mozilla {
24 namespace a11y {
25
26 class AutoRefCnt
27 {
28 public:
29 AutoRefCnt() : mValue(0) {}
30
31 ULONG operator++() { return ++mValue; }
32 ULONG operator--() { return --mValue; }
33 ULONG operator++(int) { return ++mValue; }
34 ULONG operator--(int) { return --mValue; }
35
36 operator ULONG() const { return mValue; }
37
38 private:
39 ULONG mValue;
40 };
41
42 } // namespace a11y
43 } // namespace mozilla
44
45 #define DECL_IUNKNOWN \
46 public: \
47 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**); \
48 virtual ULONG STDMETHODCALLTYPE AddRef() MOZ_FINAL \
49 { \
50 MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); \
51 ++mRefCnt; \
52 return mRefCnt; \
53 } \
54 virtual ULONG STDMETHODCALLTYPE Release() MOZ_FINAL \
55 { \
56 MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release"); \
57 --mRefCnt; \
58 if (mRefCnt) \
59 return mRefCnt; \
60 \
61 delete this; \
62 return 0; \
63 } \
64 private: \
65 mozilla::a11y::AutoRefCnt mRefCnt; \
66 public:
67
68 #define DECL_IUNKNOWN_INHERITED \
69 public: \
70 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**); \
71
72 #define IMPL_IUNKNOWN_QUERY_HEAD(Class) \
73 STDMETHODIMP \
74 Class::QueryInterface(REFIID aIID, void** aInstancePtr) \
75 { \
76 A11Y_TRYBLOCK_BEGIN \
77 if (!aInstancePtr) \
78 return E_INVALIDARG; \
79 *aInstancePtr = nullptr; \
80 \
81 HRESULT hr = E_NOINTERFACE;
82
83 #define IMPL_IUNKNOWN_QUERY_TAIL \
84 return hr; \
85 A11Y_TRYBLOCK_END \
86 }
87
88 #define IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(Member) \
89 return Member->QueryInterface(aIID, aInstancePtr); \
90 A11Y_TRYBLOCK_END \
91 }
92
93 #define IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(BaseClass) \
94 return BaseClass::QueryInterface(aIID, aInstancePtr); \
95 A11Y_TRYBLOCK_END \
96 }
97
98 #define IMPL_IUNKNOWN_QUERY_IFACE(Iface) \
99 if (aIID == IID_##Iface) { \
100 *aInstancePtr = static_cast<Iface*>(this); \
101 AddRef(); \
102 return S_OK; \
103 }
104
105 #define IMPL_IUNKNOWN_QUERY_IFACE_AMBIGIOUS(Iface, aResolveIface) \
106 if (aIID == IID_##Iface) { \
107 *aInstancePtr = static_cast<Iface*>(static_cast<aResolveIface*>(this)); \
108 AddRef(); \
109 return S_OK; \
110 }
111
112 #define IMPL_IUNKNOWN_QUERY_CLASS(Class) \
113 hr = Class::QueryInterface(aIID, aInstancePtr); \
114 if (SUCCEEDED(hr)) \
115 return hr;
116
117 #define IMPL_IUNKNOWN_QUERY_CLASS_COND(Class, Cond) \
118 if (Cond) { \
119 hr = Class::QueryInterface(aIID, aInstancePtr); \
120 if (SUCCEEDED(hr)) \
121 return hr; \
122 }
123
124 #define IMPL_IUNKNOWN_QUERY_AGGR_COND(Member, Cond) \
125 if (Cond) { \
126 hr = Member->QueryInterface(aIID, aInstancePtr); \
127 if (SUCCEEDED(hr)) \
128 return hr; \
129 }
130
131 #define IMPL_IUNKNOWN1(Class, I1) \
132 IMPL_IUNKNOWN_QUERY_HEAD(Class) \
133 IMPL_IUNKNOWN_QUERY_IFACE(I1); \
134 IMPL_IUNKNOWN_QUERY_IFACE(IUnknown); \
135 IMPL_IUNKNOWN_QUERY_TAIL \
136
137 #define IMPL_IUNKNOWN2(Class, I1, I2) \
138 IMPL_IUNKNOWN_QUERY_HEAD(Class) \
139 IMPL_IUNKNOWN_QUERY_IFACE(I1); \
140 IMPL_IUNKNOWN_QUERY_IFACE(I2); \
141 IMPL_IUNKNOWN_QUERY_IFACE_AMBIGIOUS(IUnknown, I1); \
142 IMPL_IUNKNOWN_QUERY_TAIL \
143
144 #define IMPL_IUNKNOWN_INHERITED1(Class, Super0, Super1) \
145 IMPL_IUNKNOWN_QUERY_HEAD(Class) \
146 IMPL_IUNKNOWN_QUERY_CLASS(Super1); \
147 IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(Super0)
148
149 #define IMPL_IUNKNOWN_INHERITED2(Class, Super0, Super1, Super2) \
150 IMPL_IUNKNOWN_QUERY_HEAD(Class) \
151 IMPL_IUNKNOWN_QUERY_CLASS(Super1); \
152 IMPL_IUNKNOWN_QUERY_CLASS(Super2); \
153 IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(Super0)
154
155
156 /**
157 * Wrap every method body by these macroses to pass exception to the crash
158 * reporter.
159 */
160 #define A11Y_TRYBLOCK_BEGIN \
161 MOZ_SEH_TRY {
162
163 #define A11Y_TRYBLOCK_END \
164 } MOZ_SEH_EXCEPT(mozilla::a11y::FilterExceptions(::GetExceptionCode(), \
165 GetExceptionInformation())) \
166 { } \
167 return E_FAIL;
168
169
170 namespace mozilla {
171 namespace a11y {
172
173 /**
174 * Converts nsresult to HRESULT.
175 */
176 HRESULT GetHRESULT(nsresult aResult);
177
178 /**
179 * Used to pass an exception to the crash reporter.
180 */
181 int FilterExceptions(unsigned int aCode, EXCEPTION_POINTERS* aExceptionInfo);
182
183 } // namespace a11y;
184 } //namespace mozilla;
185
186 #endif

mercurial