QCosDumontDLL Class Reference

#include <QCosDumontDLL.h>

Inheritance diagram for QCosDumontDLL:

Inheritance graph

List of all members.

Public Member Functions

 QCosDumontDLL ()
 QCosDumontDLL (IUnknown *pUnknownOuter, QObject *server=NULL, ITypeInfo *i_ITypeInfo=NULL)
virtual ~QCosDumontDLL ()
virtual HRESULT Init ()
virtual HRESULT __stdcall get_isValid (VARIANT_BOOL *)
virtual HRESULT __stdcall InterfaceSupportsErrorInfo (const IID &riid)

Static Public Member Functions

static HRESULT CreateInstance (IUnknown *pUnknownOuter, QCosUnknown **ppNewComponent)

Public Attributes

QPointer< QObject > d

Private Member Functions

HRESULT __stdcall 
NondelegatingQueryInterface (const IID &iid, void **ppv)
virtual HRESULT __stdcall GetTypeInfoCount (UINT *pCountTypeInfo)
virtual HRESULT __stdcall GetTypeInfo (UINT iTypeInfo, LCID, ITypeInfo **ppITypeInfo)
virtual HRESULT __stdcall GetIDsOfNames (const IID &iid, OLECHAR **arrayNames, UINT countNames, LCID, DISPID *arrayDispIDs)
virtual HRESULT __stdcall Invoke (DISPID dispidMember, const IID &iid, LCID, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pvarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr)
 This is a server invoke.

Private Attributes

ITypeLib * m_ITypeLib
ITypeInfo * m_ITypeInfo

Detailed Description

Definition at line 42 of file QCosDumontDLL.h.

Constructor & Destructor Documentation

QCosDumontDLL::QCosDumontDLL (  )  [inline]

Definition at line 62 of file QCosDumontDLL.h.

QCosDumontDLL::QCosDumontDLL ( IUnknown *  pUnknownOuter,
QObject *  server = NULL,
ITypeInfo *  i_ITypeInfo = NULL 

Definition at line 69 of file QCosDumontDLL.cpp.

QCosDumontDLL::~QCosDumontDLL (  )  [virtual]

Definition at line 101 of file QCosDumontDLL.cpp.

Member Function Documentation

HRESULT QCosDumontDLL::CreateInstance ( IUnknown *  pUnknownOuter,
QCosUnknown **  ppNewComponent 
) [static]

Definition at line 263 of file QCosDumontDLL.cpp.

HRESULT __stdcall QCosDumontDLL::get_isValid ( VARIANT_BOOL *  retVal  )  [virtual]

Definition at line 1320 of file QCosDumontDLL.cpp.

virtual HRESULT __stdcall QCosDumontDLL::GetIDsOfNames ( const IID iid,
OLECHAR **  arrayNames,
UINT  countNames,
DISPID *  arrayDispIDs 
) [private, virtual]

HRESULT __stdcall QCosDumontDLL::GetTypeInfo ( UINT  iTypeInfo,
ITypeInfo **  ppITypeInfo 
) [private, virtual]

Definition at line 293 of file QCosDumontDLL.cpp.

HRESULT __stdcall QCosDumontDLL::GetTypeInfoCount ( UINT *  pCountTypeInfo  )  [private, virtual]

Definition at line 283 of file QCosDumontDLL.cpp.

HRESULT QCosDumontDLL::Init (  )  [virtual]

todo make typelib load from disk properly. (done?)

Reimplemented from QCosUnknown.

Definition at line 155 of file QCosDumontDLL.cpp.

virtual HRESULT __stdcall QCosDumontDLL::InterfaceSupportsErrorInfo ( const IID riid  )  [inline, virtual]

Definition at line 85 of file QCosDumontDLL.h.

HRESULT __stdcall QCosDumontDLL::Invoke ( DISPID  dispidMember,
const IID iid,
LCID  lcid,
WORD  wFlags,
DISPPARAMS *  pDispParams,
VARIANT *  pvr,
EXCEPINFO *  pExcepInfo,
UINT *  pArgErr 
) [private, virtual]

This is a server invoke.

This function handles the invoke for our server component. This takes method invoke requests from the client (usually vbScript) and breaks them all down into their components and builds a Qt compatible method invoke call. It then passes control to the Qt object which performs the action and returns some result. That result too is then pulled apart and forced into the COM variant result (pvr). This whole function is the key to exposing any standard Qt object to COM.

And now a little dissertation on this COM interface
The interface from vbScript begins with a call to GetIDsFromNames. This call is initiated when a vb call is made to the initiated object. A typical call interface looks like this:

  dim dumont: set dumont = CreateObject("DumontDLL")

That preceeding code begins with a call to GetIDsFromNames with only one value in the arrayNames array. This value is a text equivalent of "test". Note, however, that the value can be either "test", "Test", "TEST", TeSt" in other words - no case sensitivity! Also, this call to GetIDsFromNames does NOT include any parameter information - and here is where the trouble begins.

The first for GetIDsFromNames is to find a matching function for the text. This is accomplished with a case-insensitive search of all the metaObject() method() names (for the time-being, we're only searching the method names). If a matching method name is found, then its INDEX number is returned to the caller (in this case, the vbScript host). It must be noted that this index number does not necessarily represent the index number of the method we're actually going to call. Here's why:

Let's say the QObject we are exposing has four functions, all with different signatures. Take for example:

 class myObject : public QObject
    public slots:

      void test(void);
      void test(QString message);
      void test(QString message, double number);
      long test(double input, int fraction);

 }; // endclass myObject

Obviously, due to C++ polymorphism, these are four distinct functions distinguished only by their parameter types. Also, note that we have "exposed" these functions in the "public slots" section of the object definition. This exposure is what causes these functions to be made available to to the metaObject() system of the Qt library. And, as stated earlier, only methods (public slots) are available to this COM automation library interface.

Since these four methods are exposed to the metaObject() system, each one of them has a unique ID (or index number). Since they are defined sequentially in the object definition, they will be numbered sequentially. The Qt meta-object- compiler (moc) takes care of assigning these interface ID numbers. You're advised to read through that documentation yourself, but note that the ID numbers assigned are a composite of all the ID numbers of all the super-objects to this object. So, in the example above, if QObject has 4 methods and properties that it exposes, our first method ID number will be the 5th number in sequence (or 4 in value). What this means is that ANY method that ANY of the objects expose in our object tree are automatically available to this single interface! That's pretty powerful, when you think about it.

In the call to GetIDsFromNames, then, the ID number that gets returned is a function of two things: 1, the ID number assigned by the moc, and 2, which function got found by the search routine. Since the list of method names is searched sequentially then the search function usually finds the first method defined.

If vbScript calls for dumont.test, then the ID number will be the first function in our definition, because this is the first matching function. If vbScript calls for dumont.test "message text", 3.4 then the call to GetIDsFromNames will still only return the first ID number because it's only matching on the function name and not the parameter list. It is this ID number that is returned back to vbScript.

The next call the vbScript makes to complete this funciton call is the call to Invoke(). This function call receives the function ID number that was found on the earlier call to GetIDsFromNames, and a bonus - the parameter list! Here's the caviat, though. The member ID number that we receive does not necessarily represent the ID number of the function we want to call, because, remember, when we went searching for that ID number we didn't have the parameter list available to us. Therefore, the ID number only represents the first funciton in our list of matching function names.

What we do here is we first assemble the parameter list handed to us by vbScript into a form that's Qt compatible. What this means is we extract all the parameters from vb into a set of parameters for the Qt invoke function, making translations as we go. This is the 'date-input-translation' function of the task. It is important to note here that Qt can only accept ten parameters to it's slots - if you have more you're out of luck, and I'd suggest reformatting your function interface.

Once we have this parameter list assembled we can go back to our function 'name', which we have because we have 'a' function ID, and assemble what is called a a method signature. This method signature consists of the method name followed by a complete method parameter type list. Once we have a complete method signature we can then perform another 'method search' to get the REAL method ID number.

Once we have the REAL method ID number we can then use that to get the method return value (referred to as the 'methodType' in this library). Once we have all these things, the method name, the method parameter list, the method return type, can can then finally perform the actual Qt invoke function.

dispidMember This dispidMember (dispatch ID member) was generated in the GetIDsOfNames call whereby the qt object in question (the one being wrapped by us) was queried for a matching function name. This dispidMember number includes a code to indicate if this is a Qt Method, Property, or Enum, and it includes the actual ID number of the MPE (method/property/enum) in question. Keep in mind that the ACTUAL method (by id) that gets called may be different than the actual dispidMember value provided here, because when the call to GetIDsOfNames was made, we didn't have the parameters that was going to get passed in. Therefore, we matched only on the methodName and not on the full methodSignature. Not to worry, though. We are only using this dispidMember number to get back to the methodName, and when we finally invoke the method, Qt is going to take care of matching the method name and parameter list making sure we call the correct function.
iid Interface IDentifier
This should always be IID_NULL.
lcid Localization Identifier
Localization is not supported
wFlags wFlags - type of invoke requested.
The Invoke function can be called a number of different ways. How it is called depends (I suppose) largely on how the expression is presented in vbScript (or whatever the hosting calling language is). The following is listed here for information purposes only - we don't actually use this value in our Invoke procedure:

  case DISPATCH_METHOD        :
pDispParams Dispatch Parameters
This is a parameter header. It carries information about how many parameters are provided and pointers to arrays of where those parameters can be accessed.
pvr Dispatch Result
This is the variant result. It should be checked to point to something other than zero before it is loaded with anything.
pExcepInfo Exception Info
This is exception info, and I don't know how to use it yet.
pArgErr Argument Errors
This is arguments error information - and I'm not sure what to do about it either.

Definition at line 806 of file QCosDumontDLL.cpp.

HRESULT __stdcall QCosDumontDLL::NondelegatingQueryInterface ( const IID iid,
void **  ppv 
) [private, virtual]

Reimplemented from QCosUnknown.

Definition at line 127 of file QCosDumontDLL.cpp.

Member Data Documentation

QPointer<QObject> QCosDumontDLL::d

Definition at line 52 of file QCosDumontDLL.h.

ITypeInfo* QCosDumontDLL::m_ITypeInfo [private]

Definition at line 94 of file QCosDumontDLL.h.

ITypeLib* QCosDumontDLL::m_ITypeLib [private]

Definition at line 93 of file QCosDumontDLL.h.

The documentation for this class was generated from the following files:

~ ~ ~ ~ ~ ~
Source Code without Comments is like a Cranberry Garland
without the berries. Comment your Code!
Commence Database User Support Group Forum
~ ~ ~ ~ ~ ~
Author: Mark Petryk
Lorimark Solutions, LLC