xref: /aoo4110/main/sal/inc/systools/win32/comtools.hxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski #pragma once
25*b1cdbd2cSJim Jagielski 
26*b1cdbd2cSJim Jagielski #include <string>
27*b1cdbd2cSJim Jagielski #include <stdexcept>
28*b1cdbd2cSJim Jagielski #if defined _MSC_VER
29*b1cdbd2cSJim Jagielski #pragma warning(push,1)
30*b1cdbd2cSJim Jagielski #endif
31*b1cdbd2cSJim Jagielski #include <objbase.h>
32*b1cdbd2cSJim Jagielski #if defined _MSC_VER
33*b1cdbd2cSJim Jagielski #pragma warning(pop)
34*b1cdbd2cSJim Jagielski #endif
35*b1cdbd2cSJim Jagielski 
36*b1cdbd2cSJim Jagielski namespace sal
37*b1cdbd2cSJim Jagielski {
38*b1cdbd2cSJim Jagielski namespace systools
39*b1cdbd2cSJim Jagielski {
40*b1cdbd2cSJim Jagielski     typedef int HRESULT;
41*b1cdbd2cSJim Jagielski 
42*b1cdbd2cSJim Jagielski     /* Simple exception class for propagating COM errors */
43*b1cdbd2cSJim Jagielski     class ComError : public std::runtime_error
44*b1cdbd2cSJim Jagielski     {
45*b1cdbd2cSJim Jagielski     public:
ComError(const std::string & message,HRESULT hr)46*b1cdbd2cSJim Jagielski         ComError(const std::string& message, HRESULT hr) :
47*b1cdbd2cSJim Jagielski             std::runtime_error(message),
48*b1cdbd2cSJim Jagielski             hr_(hr)
49*b1cdbd2cSJim Jagielski         {}
50*b1cdbd2cSJim Jagielski 
GetHresult() const51*b1cdbd2cSJim Jagielski         HRESULT GetHresult() const
52*b1cdbd2cSJim Jagielski         {
53*b1cdbd2cSJim Jagielski             return hr_;
54*b1cdbd2cSJim Jagielski         }
55*b1cdbd2cSJim Jagielski 
56*b1cdbd2cSJim Jagielski     private:
57*b1cdbd2cSJim Jagielski         HRESULT hr_;
58*b1cdbd2cSJim Jagielski     };
59*b1cdbd2cSJim Jagielski 
60*b1cdbd2cSJim Jagielski     /* A simple COM smart pointer template */
61*b1cdbd2cSJim Jagielski     template <typename T>
62*b1cdbd2cSJim Jagielski     class COMReference
63*b1cdbd2cSJim Jagielski     {
64*b1cdbd2cSJim Jagielski     public:
COMReference()65*b1cdbd2cSJim Jagielski         COMReference() :
66*b1cdbd2cSJim Jagielski             com_ptr_(NULL)
67*b1cdbd2cSJim Jagielski         {
68*b1cdbd2cSJim Jagielski         }
69*b1cdbd2cSJim Jagielski 
COMReference(T * comptr)70*b1cdbd2cSJim Jagielski         explicit COMReference(T* comptr) :
71*b1cdbd2cSJim Jagielski             com_ptr_(comptr)
72*b1cdbd2cSJim Jagielski         {
73*b1cdbd2cSJim Jagielski             addRef();
74*b1cdbd2cSJim Jagielski         }
75*b1cdbd2cSJim Jagielski 
76*b1cdbd2cSJim Jagielski         /* Explicitly controllable whether AddRef will be called or not */
COMReference(T * comptr,bool bAddRef)77*b1cdbd2cSJim Jagielski         COMReference(T* comptr, bool bAddRef) :
78*b1cdbd2cSJim Jagielski             com_ptr_(comptr)
79*b1cdbd2cSJim Jagielski         {
80*b1cdbd2cSJim Jagielski             if (bAddRef)
81*b1cdbd2cSJim Jagielski                 addRef();
82*b1cdbd2cSJim Jagielski         }
83*b1cdbd2cSJim Jagielski 
COMReference(const COMReference<T> & other)84*b1cdbd2cSJim Jagielski         COMReference(const COMReference<T>& other) :
85*b1cdbd2cSJim Jagielski             com_ptr_(other.com_ptr_)
86*b1cdbd2cSJim Jagielski         {
87*b1cdbd2cSJim Jagielski             addRef();
88*b1cdbd2cSJim Jagielski         }
89*b1cdbd2cSJim Jagielski 
operator =(const COMReference<T> & other)90*b1cdbd2cSJim Jagielski         COMReference<T>& operator=(const COMReference<T>& other)
91*b1cdbd2cSJim Jagielski         {
92*b1cdbd2cSJim Jagielski             if (other.com_ptr_)
93*b1cdbd2cSJim Jagielski                 other.com_ptr_->AddRef();
94*b1cdbd2cSJim Jagielski             release();
95*b1cdbd2cSJim Jagielski             com_ptr_ = other.com_ptr_;
96*b1cdbd2cSJim Jagielski             return *this;
97*b1cdbd2cSJim Jagielski         }
98*b1cdbd2cSJim Jagielski 
operator =(T * comptr)99*b1cdbd2cSJim Jagielski         COMReference<T>& operator=(T* comptr)
100*b1cdbd2cSJim Jagielski         {
101*b1cdbd2cSJim Jagielski             release();
102*b1cdbd2cSJim Jagielski             com_ptr_ = comptr;
103*b1cdbd2cSJim Jagielski             addRef();
104*b1cdbd2cSJim Jagielski             return *this;
105*b1cdbd2cSJim Jagielski         }
106*b1cdbd2cSJim Jagielski 
~COMReference()107*b1cdbd2cSJim Jagielski         ~COMReference()
108*b1cdbd2cSJim Jagielski         {
109*b1cdbd2cSJim Jagielski             release();
110*b1cdbd2cSJim Jagielski         }
111*b1cdbd2cSJim Jagielski 
112*b1cdbd2cSJim Jagielski         template<typename InterfaceType>
QueryInterface(REFIID iid)113*b1cdbd2cSJim Jagielski         COMReference<InterfaceType> QueryInterface(REFIID iid)
114*b1cdbd2cSJim Jagielski         {
115*b1cdbd2cSJim Jagielski             COMReference<InterfaceType> ip;
116*b1cdbd2cSJim Jagielski             HRESULT hr = E_FAIL;
117*b1cdbd2cSJim Jagielski             if (com_ptr_)
118*b1cdbd2cSJim Jagielski                 hr = com_ptr_->QueryInterface(iid, reinterpret_cast<LPVOID*>(&ip));
119*b1cdbd2cSJim Jagielski 
120*b1cdbd2cSJim Jagielski             if (FAILED(hr))
121*b1cdbd2cSJim Jagielski                 throw ComError("QueryInterface failed: Interface not supported!", hr);
122*b1cdbd2cSJim Jagielski 
123*b1cdbd2cSJim Jagielski             return ip;
124*b1cdbd2cSJim Jagielski         }
125*b1cdbd2cSJim Jagielski 
operator ->() const126*b1cdbd2cSJim Jagielski         T* operator->() const
127*b1cdbd2cSJim Jagielski         {
128*b1cdbd2cSJim Jagielski             return com_ptr_;
129*b1cdbd2cSJim Jagielski         }
130*b1cdbd2cSJim Jagielski 
operator *() const131*b1cdbd2cSJim Jagielski         T& operator*() const
132*b1cdbd2cSJim Jagielski         {
133*b1cdbd2cSJim Jagielski             return *com_ptr_;
134*b1cdbd2cSJim Jagielski         }
135*b1cdbd2cSJim Jagielski 
136*b1cdbd2cSJim Jagielski         /* Necessary for assigning com_ptr_ from functions like
137*b1cdbd2cSJim Jagielski            CoCreateInstance which require a 'void**' */
operator &()138*b1cdbd2cSJim Jagielski         T** operator&()
139*b1cdbd2cSJim Jagielski         {
140*b1cdbd2cSJim Jagielski             release();
141*b1cdbd2cSJim Jagielski             com_ptr_ = NULL;
142*b1cdbd2cSJim Jagielski             return &com_ptr_;
143*b1cdbd2cSJim Jagielski         }
144*b1cdbd2cSJim Jagielski 
get() const145*b1cdbd2cSJim Jagielski         T* get() const
146*b1cdbd2cSJim Jagielski         {
147*b1cdbd2cSJim Jagielski             return com_ptr_;
148*b1cdbd2cSJim Jagielski         }
149*b1cdbd2cSJim Jagielski 
clear()150*b1cdbd2cSJim Jagielski         COMReference<T>& clear()
151*b1cdbd2cSJim Jagielski         {
152*b1cdbd2cSJim Jagielski             release();
153*b1cdbd2cSJim Jagielski             com_ptr_ = NULL;
154*b1cdbd2cSJim Jagielski             return *this;
155*b1cdbd2cSJim Jagielski         }
156*b1cdbd2cSJim Jagielski 
is() const157*b1cdbd2cSJim Jagielski         bool is() const
158*b1cdbd2cSJim Jagielski         {
159*b1cdbd2cSJim Jagielski             return (com_ptr_ != NULL);
160*b1cdbd2cSJim Jagielski         }
161*b1cdbd2cSJim Jagielski 
162*b1cdbd2cSJim Jagielski     private:
addRef()163*b1cdbd2cSJim Jagielski         ULONG addRef()
164*b1cdbd2cSJim Jagielski         {
165*b1cdbd2cSJim Jagielski             ULONG cnt = 0;
166*b1cdbd2cSJim Jagielski             if (com_ptr_)
167*b1cdbd2cSJim Jagielski                 cnt = com_ptr_->AddRef();
168*b1cdbd2cSJim Jagielski             return cnt;
169*b1cdbd2cSJim Jagielski         }
170*b1cdbd2cSJim Jagielski 
release()171*b1cdbd2cSJim Jagielski         ULONG release()
172*b1cdbd2cSJim Jagielski         {
173*b1cdbd2cSJim Jagielski             ULONG cnt = 0;
174*b1cdbd2cSJim Jagielski             if (com_ptr_)
175*b1cdbd2cSJim Jagielski                 cnt = com_ptr_->Release();
176*b1cdbd2cSJim Jagielski             return cnt;
177*b1cdbd2cSJim Jagielski         }
178*b1cdbd2cSJim Jagielski 
179*b1cdbd2cSJim Jagielski     private:
180*b1cdbd2cSJim Jagielski         T* com_ptr_;
181*b1cdbd2cSJim Jagielski     };
182*b1cdbd2cSJim Jagielski 
183*b1cdbd2cSJim Jagielski } // systools
184*b1cdbd2cSJim Jagielski } // sal
185*b1cdbd2cSJim Jagielski 
186*b1cdbd2cSJim Jagielski /* Typedefs for some popular COM interfaces */
187*b1cdbd2cSJim Jagielski typedef sal::systools::COMReference<IDataObject> IDataObjectPtr;
188*b1cdbd2cSJim Jagielski typedef sal::systools::COMReference<IStream> IStreamPtr;
189*b1cdbd2cSJim Jagielski typedef sal::systools::COMReference<IEnumFORMATETC> IEnumFORMATETCPtr;
190*b1cdbd2cSJim Jagielski 
191