OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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