OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
autodisp.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectConnections
3// Copyright (c) 1994, 1996 by Borland International
4/// \file
5/// OLE Automation - Implementation of TDispatch, a light-weight version
6/// of IDispatch.
7/// \note See TServedObject for a richer implementation of IDispatch.
8//----------------------------------------------------------------------------
9#include <ocf/pch.h>
10#include <ocf/appdesc.h>
11#include <ocf/ocreg.h>
12#include <ocf/occtrl.h>
13
14namespace ocf {
15
16using namespace owl;
17
19
20//
21//
22//
28
29//
30//
31//
38
40DEFINE_COMBASES1 (TDispatchCOM, IDispatch)
41
42//
43//
44//
46:
47 Object(const_cast<void*>(objDesc.Object)),
48 Class(objDesc.Class)
49{
50 SetOuter(outer ? outer
51 : &objDesc.Class->Aggregate(const_cast<void*>(objDesc.Object), *this));
52 //
53 // NOTE: RefCnt = 0 on creation, will ++ in TAutoVal operator(IDispatch*)
54 //
55}
56
57// IDispatch implementation
58
60TDispatch::GetTypeInfoCount(unsigned int * pctinfo)
61{
62 *pctinfo = 0;
63 return HR_NOERROR;
64}
65
67TDispatch::GetTypeInfo(unsigned int, LCID, ITypeInfo* *)
68{
69 return HR_NOTIMPL;
70}
71
73TDispatch::GetIDsOfNames(const IID & riid, OLECHAR * * names,
74 unsigned int cNames, LCID lcid, DISPID * dispIds)
75{
76 if (riid != IID_NULL){
77 WARNX(OcfDll, riid != IID_NULL, 1, _T("TDispatch::GetIDsOfNames() riid != IID_NULL"));
79 }
80
82 TAutoSymbol* symbol;
83 for (int i = 0; i < (int)cNames; i++) {
84 dispIds[i] = -1;
85 if (i == 0) {
86 symbol = Class->Lookup(OleStr(names[0]), LANGIDFROMLCID(lcid),
88 if (!symbol)
90 }
91 else if (symbol) {
92 if (!Class->LookupArg(OleStr(names[i]), LANGIDFROMLCID(lcid), symbol, dispIds[i]))
94 }
95 }
96 return retval;
97}
98
99//
100//
101//
103TDispatch::Invoke(DISPID dispidMember, const IID& /*riid*/, LCID lcid,
104 unsigned short wFlags, DISPPARAMS* dispparams,
106 unsigned int* retArgErr)
107{
108 // Make a copy of the object in case there's this pointer adjustment
109 //
110 ObjectPtr object = Object;
111
112 // Make sure our object is still valid
113 //
114 if (!object) {
115 WARNX(OcfDll, !object, 1, _T("TDispatch::Invoke() Object == 0"));
117 }
118
119 // Build an object representing the data passed in
120 // NOTE: Here lies the difference between the 'Invoke' of TServedObject
121 // and TDispatch: the last parameter to TAutoStack's constructor.
122 //
123 TAutoStack stack(dispidMember, dispparams->rgvarg, lcid, dispparams->cArgs,
124 dispparams->cNamedArgs, dispparams->rgdispidNamedArgs, 0);
125
126 // Find the symbol we're asked to dispatch to
127 //
128 stack.Symbol = Class->FindId(dispidMember, object);
129
130 if (!stack.Symbol) {
131 // NOTE: This is a 'hack' that allows TServedObject to expose a generic method
132 // that's used for cases when the object does not provide a method
133 // that matches the dispId invoked.
134 // It is used by our container support for sinking non-standard events.
135 //
136 if ((stack.Symbol = Class->FindId(DISPID_CATCH_ALL, object)) == nullptr)
138 }
139
140 // Check the attribute bits to ensure we support the type
141 //
142 if (!stack.Symbol->TestFlag(wFlags)) {
143 TRACEX(OcfDll, 1, _T("TDispatch::Invoke() type unsupported"));
145 }
146
147 // Check if we need return result
148 // NOTE: Some servers [such as Word.Basic] seem to be very picky about
149 // the distinction between a function and procedure. They are not
150 // as flexible as we are here..
151 //
153 varResult = 0;
154
155
156 // Check that the number of arguments sent matches what we're expecting
157 //
158 // Again here we'll have to relax a little on the param count check since in the
159 // case of the DISPID_CATCH_ALL, the handler is a generic one that can handle
160 // any number of parameters.
161 //
162 if (((stack.ArgSymbolCount = Class->GetArgCount(*stack.Symbol)) +
163 ((wFlags & (DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF)) != 0) < stack.ArgCount) &&
164 (stack.Symbol->DispId != DISPID_CATCH_ALL)){
165 TRACEX(OcfDll, 1, _T("TDispatch::Invoke() BadParamCount"));
167 }
168
169
170 // Dispatch via the command object and hope we're OK
171 // NOTE: TDispatchCreator() vs. Creator of TDispatch & TServedObject
172 //
173 TDispatchCreator myDispatcher=TDispatchCreator();
174 switch(Class->Dispatch(object, myDispatcher, *this, wFlags, stack, (TAutoVal*)varResult)) {
175 case TXAuto::xNoError:
176 return HR_NOERROR;
177
178 case TXAuto::xNotIDispatch:
179 case TXAuto::xForeignIDispatch:
180 return HR_DISP_BADVARTYPE;
181
182 case TXAuto::xValidateFailure:
183 *retArgErr = stack.CurrentArg;
184 return HR_DISP_OVERFLOW;
185
186 case TXAuto::xConversionFailure:
187 case TXAuto::xTypeMismatch:
188 *retArgErr = stack.CurrentArg;
190
191 case TXAuto::xNoArgSymbol:
192 *retArgErr = stack.CurrentArg;
194
195 case TXAuto::xParameterMissing:
196 case TXAuto::xNoDefaultValue:
198
199 case TXAuto::xErrorStatus:
200 if (exceptInfo) {
201 exceptInfo->wCode = (unsigned short)stack.ErrorCode;
202 exceptInfo->wReserved = 0;
203 exceptInfo->bstrSource = 0; // cmp vs. TServedObject's support
204 exceptInfo->bstrDescription = TOleAuto::SysAllocString((const OLECHAR *)stack.ErrorMsg);
205 exceptInfo->bstrHelpFile = 0;
206 exceptInfo->pfnDeferredFillIn = 0;
207
208 // INVESTIGATE: Is there a method to relay better SCODEs ?
209 //
210 exceptInfo->scode = E_FAIL;
211 }
212 return HR_DISP_EXCEPTION;
213
214 case TXAuto::xExecutionFailure:
215 default:
216 // INVESTIGATE: Is there a better error code here ?
217 //
218 return HR_DISP_OVERFLOW;
219 }
220}
221
222
223} // OCF namespace
224
225//==============================================================================
226
TAppDescriptor - OLE application descriptor definitions.
#define DISPID_CATCH_ALL
Definition automacr.h:1045
#define WARNX(group, condition, level, message)
Definition checks.h:277
#define DIAG_DECLARE_GROUP(group)
Definition checks.h:404
#define TRACEX(group, level, message)
Definition checks.h:263
TUnknown * CreateObject(TObjectDescriptor objDesc, IUnknown *outer=0)
Definition autodisp.cpp:23
IDispatch * CreateDispatch(TObjectDescriptor objDesc, IUnknown *outer=0)
Definition autodisp.cpp:32
Standard implementation of a controlling IUnknown for an object, to be inherited with other COM inter...
Definition oleutil.h:264
static BSTR SysAllocString(const OLECHAR *)
Definition module.cpp:1256
#define _T(x)
Definition cygwin.h:51
Include for OC, gets common headers when precompiled headers are enabled.
Object Component Framework (COM encapsulation)
Definition appdesc.h:22
void * ObjectPtr
Definition autodefs.h:84
@ asAnyCommand
any command: method, property get/set, build
Definition autodefs.h:298
class _ICLASS TDispatch
Definition autodefs.h:956
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
Definition of TOcControl class - Proxy object representing a control in.
#define HR_DISP_TYPEMISMATCH
Definition defs.h:92
#define HR_DISP_UNKNOWNINTERFACE
Definition defs.h:97
#define HR_NOTIMPL
Definition defs.h:76
#define HR_DISP_BADPARAMCOUNT
Definition defs.h:89
#define HR_DISP_UNKNOWNNAME
Definition defs.h:98
#define HR_DISP_PARAMNOTOPTIONAL
Definition defs.h:94
#define HR_DISP_EXCEPTION
Definition defs.h:95
#define HR_DISP_OVERFLOW
Definition defs.h:91
#define HR_DISP_BADVARTYPE
Definition defs.h:90
#define HR_DISP_PARAMNOTFOUND
Definition defs.h:93
#define HR_NOERROR
Definition defs.h:73
#define HR_DISP_MEMBERNOTFOUND
Definition defs.h:88
OLE Registration definitions.
#define _IFUNC
Definition oleutil.h:28
#define DEFINE_QI_OLEBASE(cls, low)
Definition oleutil.h:443
#define DEFINE_COMBASES1(cls, i1)
Definition oleutil.h:428
#define OleStr(s)
Definition string.h:128
Undefined default template for dispatchers Template specialization is used to allow the compiler to l...
Definition dispatch.h:258