DumontEXE 0.0.1
cmcApi.h
00001 /* ***************************************************************************
00002 **
00003 ** Copyright (C) 2007 Lorimark Solutions, LLC. All rights reserved.
00004 **
00005 ** This file is part of the DumontEXE Scripting Extension Kit
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://dumont.showoff-db.org/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://dumont.showoff-db.org/licensing.html 
00017 ** or contact the sales department at sales@lorimarksolutions.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ** author: Mark Petryk ~ Lorimark Solutions, LLC
00023 ** **************************************************************************/
00024 
00025 #ifndef CDA_API_H_422FD07F_0597_4cbb_A034_9AE85166472E
00026 #define CDA_API_H_422FD07F_0597_4cbb_A034_9AE85166472E
00027 
00028 class cmcApplication;
00029 
00030 #include "cmcObject.h"
00031 
00032 #include "rpc.h"
00033 #include "rpcndr.h"
00034 
00035 namespace cmcDatabaseApi {
00036 
00037 /*!
00038 ** \brief Commence COM Interface
00039 **
00040 ** This is the primary object used to interface to anything within the Commence
00041 **  executable.  This interface occurs through the COM API.  All of the calls are
00042 **  marshalled through the Invoke() method after the parameters have been initialized
00043 **  and whatnot.  Included is a series of convenience functions such as GetServerLong(),
00044 **  GetServerBool(), GetServerString() and so on.
00045 **
00046 ** Let me make a note here on reference counting - a fun subject!  When you call a COM
00047 **  invoke function on a server, and that server returns to you a new IDispatch pointer,
00048 **  that IDispatch pointer usually points to another server object.  When the server fetched for
00049 **  you that new server object, it incremented the reference count on that new server
00050 **  object.  You asked for a pointer to an object, the server manufactured it for you, 
00051 **  and before it returned it to you it incremented it reference count so that the object 
00052 **  the pointer was pointing to wouldn't inadvertently get destroyed before you got your 
00053 **  hands on it.
00054 **
00055 ** Therefore, you now have an IDispatch pointer that is properly reference counted.  
00056 **  Before you can throw that pointer away, you *must* release it.  If you do not, then 
00057 **  the server will still think there is a reference counted pointer hanging around 
00058 **  somewhere.
00059 **
00060 ** In this Dumont project, we wrap these pointers inside of our Commence objects, since
00061 **  that's what the objects are for - interfacing to Commence.  Our wrappers take care
00062 **  of all the messy interface details.  However, when we construct a new wrapper, we
00063 **  pass along this IDispatch pointer we received earlier.  According to policy, when
00064 **  we pass that pointer along to another function or wrapper, we must increment its 
00065 **  reference count, since, there are now two objects that are holding a copy of that 
00066 **  pointer.  This is no problem because when our server wrapper gets created, with a 
00067 **  reference to this dispatch pointer, it increments the reference count on that IDispatch
00068 **  pointer.  And when our wrapper object gets destroyed, it decrements the reference 
00069 **  count.  All is good.
00070 **
00071 ** Until...
00072 **
00073 ** ...we forget that we still have that initial IDispatch pointer we received from our
00074 **  initial invoke request on the server.  As long as we remember to release the 
00075 **  reference count on that pointer then everything is ok.
00076 **
00077 ** So, check out the code on the cmcApplication::database() routine for instance.
00078 **  You will see that first a IDispatch pointer is obtained from Invoke (AddRef(), 
00079 **  that's one).  Then we pass that interface pointer along to our new object wrapper 
00080 **  (AddRef() again, that's two).  Now, since we're done with the first IDispatch pointer
00081 **  we need to release it before we terminate this routine, otherwise we'll have that
00082 **  dangling pointer lying around that we don't want.  The object that we created, still
00083 **  has a reference counted pointer to the object, and once eventually that object gets
00084 **  destroyed (sometime later), then the final count on that reference counted IDispatch 
00085 **  pointer will be freed and the server will (probably) release that object from memory.
00086 **
00087 ** This is a very important concept to understand for vbScript, since it opens and 
00088 **  releases objects constantly.  Dumont is tailored very carefully to insure that 
00089 **  objects that are referenced by some other part of the system are not inadvertently
00090 **  destroyed before vbScript is through with it.
00091 **
00092 */
00093 class cmcApi:
00094   public cmcObject
00095 {
00096   Q_OBJECT
00097   public:
00098 
00099     /*!
00100     ** \brief Copy Constructor
00101     **
00102     */
00103     cmcApi( const cmcApi & copy );
00104 
00105     /*!
00106     ** \brief Primary Constructor
00107     **
00108     ** This constructor is used by any one of the super classes.  It requires a pointer
00109     **  to the dispatch interface, and also requires a reference to the application object
00110     **  itself.
00111     **
00112     */
00113     cmcApi( const QString & objectName, IDispatch * dispatch, cmcApplication * application, QObject * parent = NULL );
00114 
00115     /*!
00116     ** \brief Primary Destructor
00117     **
00118     ** This destructor handles cleanup of the object.
00119     **
00120     */
00121     virtual ~cmcApi()
00122     {
00123       Release();
00124       m_dispatch = 0;
00125     }
00126 
00127     /*!
00128     ** \brief Server QueryInterface Call
00129     **
00130     ** This makes the call to the server QueryInterface.
00131     **
00132     */
00133     inline virtual HRESULT QueryInterface
00134     (
00135       /* [in]          */ REFIID                      riid,
00136       /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR * ppvObject
00137     )
00138     {
00139       if( m_dispatch )
00140       {
00141         return( m_dispatch->QueryInterface( riid, ppvObject ) );
00142       }
00143       return E_NOINTERFACE;
00144     }
00145     
00146     /*!
00147     ** \brief Server AddRef call
00148     **
00149     ** This makes the call to the server AddRef.
00150     **
00151     **
00152     */
00153     inline virtual ULONG AddRef(void)
00154     {
00155       ULONG retVal = 0;
00156       if( m_dispatch ) retVal = m_dispatch->AddRef(); 
00157 //      qDebug( "AddRef(%s::%s)=%lu", metaObject()-> className(), name().toAscii().data(), retVal );
00158       return( retVal );
00159     }
00160 
00161     /*!
00162     ** \brief Server Release call
00163     **
00164     ** This makes the call to the server Release.
00165     **
00166     */
00167     inline virtual ULONG Release(void)
00168     {
00169       ULONG retVal = 0;
00170       if( m_dispatch ) retVal = m_dispatch->Release();
00171 //      qDebug( "Release(%s::%s)=%lu", metaObject()-> className(), name().toAscii().data(), retVal );
00172       return( retVal );
00173     }
00174 
00175 
00176     inline virtual HRESULT GetTypeInfoCount
00177     (
00178       /* [out] */ UINT * pctinfo
00179     )
00180     {
00181       HRESULT retVal = E_NOINTERFACE;
00182       if( m_dispatch ) retVal = m_dispatch-> GetTypeInfoCount( pctinfo );
00183       return( retVal );
00184     }
00185     
00186     inline virtual HRESULT GetTypeInfo
00187     (
00188       /* [in]  */ UINT         iTInfo,
00189       /* [in]  */ LCID         lcid,
00190       /* [out] */ ITypeInfo ** ppTInfo
00191     )
00192     {
00193       HRESULT retVal = E_NOINTERFACE;
00194       if( m_dispatch ) retVal = m_dispatch-> GetTypeInfo( iTInfo, lcid, ppTInfo );
00195       return( retVal );
00196     }
00197 
00198     inline virtual HRESULT GetIDsOfNames
00199     (
00200       /* [in]           */ REFIID     riid,
00201       /* [size_is][in]  */ LPOLESTR * rgszNames,
00202       /* [in]           */ UINT       cNames,
00203       /* [in]           */ LCID       lcid,
00204       /* [size_is][out] */ DISPID   * rgDispId
00205     )
00206     {
00207       HRESULT retVal = E_NOINTERFACE;
00208       if( m_dispatch ) retVal = m_dispatch-> GetIDsOfNames( riid, rgszNames, cNames, lcid, rgDispId );
00209       return( retVal );
00210     }
00211 
00212     inline virtual HRESULT Invoke
00213     (
00214       /* [in]      */ DISPID        dispIdMember,
00215       /* [in]      */ REFIID        riid,
00216       /* [in]      */ LCID          lcid,
00217       /* [in]      */ WORD          wFlags,
00218       /* [out][in] */ DISPPARAMS  * pDispParams,
00219       /* [out]     */ VARIANT     * pVarResult,
00220       /* [out]     */ EXCEPINFO   * pExcepInfo,
00221       /* [out]     */ UINT        * puArgErr
00222     )
00223     {
00224       HRESULT retVal = E_NOINTERFACE;
00225       if( m_dispatch )
00226       {
00227 //        qDebug( "Invoke dispid=%lx", dispIdMember );
00228         retVal = m_dispatch->Invoke
00229         (
00230           dispIdMember, 
00231           riid, 
00232           lcid, 
00233           wFlags, 
00234           pDispParams, 
00235           pVarResult, 
00236           pExcepInfo, 
00237           puArgErr 
00238         );
00239       }
00240       return( retVal );
00241     }
00242 
00243     inline virtual HRESULT Invoke
00244     (
00245       /* [in]      */ const char * dispIdMember,
00246       /* [in]      */ REFIID       riid,
00247       /* [in]      */ LCID         lcid,
00248       /* [in]      */ WORD         wFlags,
00249       /* [out][in] */ DISPPARAMS * pDispParams,
00250       /* [out]     */ VARIANT    * pVarResult,
00251       /* [out]     */ EXCEPINFO  * pExcepInfo,
00252       /* [out]     */ UINT       * puArgErr
00253     )
00254     {
00255       HRESULT retVal = E_NOINTERFACE;
00256       if( m_dispatch )
00257       {
00258 //        qDebug( "Invoke dispid=%s", dispIdMember );
00259         retVal = m_dispatch-> Invoke
00260         (
00261           GetIDofName(dispIdMember), 
00262           riid, 
00263           lcid, 
00264           wFlags, 
00265           pDispParams, 
00266           pVarResult, 
00267           pExcepInfo, 
00268           puArgErr 
00269         );
00270       }
00271 
00272       return( retVal );
00273     }
00274 
00275     inline virtual DISPID  GetIDofName( const char * cmdName )
00276     {
00277       QString x = cmdName;
00278       return( GetIDofName( x ) );
00279     }
00280 
00281     virtual DISPID  GetIDofName( QString & cmdName );
00282 
00283     virtual IDispatch * GetServerObject( const QString & name, const QString & topic, const char * dispid, WORD wFlags = DISPATCH_PROPERTYGET, HRESULT * hr = NULL );
00284     virtual IDispatch * GetServerObject( const long mode, const QString & name, const long flags, const char * dispid, WORD wFlags = DISPATCH_PROPERTYGET, HRESULT * hr = NULL );
00285     virtual IDispatch * GetServerObject( const long mode, const QString & name, const long flags, const long dispid, WORD wFlags = DISPATCH_PROPERTYGET, HRESULT * hr = NULL );
00286     virtual IDispatch * GetServerObject( DISPID dispid, WORD wFlags = DISPATCH_PROPERTYGET, HRESULT * hr = NULL );
00287     virtual IDispatch * GetServerObject( const char * dispid, WORD wFlags = DISPATCH_PROPERTYGET , HRESULT * hr = NULL );
00288 
00289     virtual long GetServerLong(   DISPID       dispid,  WORD wFlags = DISPATCH_PROPERTYGET  );
00290     virtual long GetServerLong(   const char * dispid,  WORD wFlags = DISPATCH_PROPERTYGET  );
00291     virtual bool GetServerBool(   DISPID       dispid,  WORD wFlags = DISPATCH_PROPERTYGET  );
00292     virtual bool GetServerBool(   const char * dispid,  WORD wFlags = DISPATCH_PROPERTYGET  );
00293 
00294     virtual QString GetServerString( DISPID       dispid,  WORD wFlags = DISPATCH_PROPERTYGET , HRESULT * hr = NULL );
00295     virtual QString GetServerString( DISPID       dispid, const QString & req, WORD wFlags = DISPATCH_PROPERTYGET , HRESULT * hr = NULL );
00296     virtual QString GetServerString( const char * dispid,  WORD wFlags = DISPATCH_PROPERTYGET, HRESULT * hr = NULL );
00297     virtual QString GetServerString( const char * dispid, const QString & req, WORD wFlags = DISPATCH_PROPERTYGET, HRESULT * hr = NULL );
00298 
00299     virtual void    PutServerString( DISPID       dispid, QString newValue, WORD wFlags = DISPATCH_PROPERTYPUT );
00300     virtual void    PutServerString( const char * dispid, QString newValue, WORD wFlags = DISPATCH_PROPERTYPUT );
00301     virtual void    PutServerLong(   DISPID       dispid, long    newValue, WORD wFlags = DISPATCH_PROPERTYPUT );
00302     virtual void    PutServerLong(   const char * dispid, long    newValue, WORD wFlags = DISPATCH_PROPERTYPUT );
00303 
00304     virtual bool    SetServerString( DISPID dispid,       const QString & newValue, long flags = 0 );
00305     virtual bool    SetServerString( const char * dispid, const QString & newValue, long flags = 0 );
00306 
00307   public slots:
00308 
00309     void dumpInterface( IDispatch * dispatch = NULL );
00310 
00311   signals:
00312 
00313   protected:
00314 
00315     IDispatch * m_dispatch;
00316 
00317   private:
00318 
00319 }; // endclass cmcApi
00320 
00321 } // namespace cmcDatabaseApi
00322 
00323 #endif // #ifndef CDA_API_H
00324 
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties




~ ~ ~ ~ ~ ~
Source Code without Comments is like a Cranberry Garland
without the berries. Comment your Code!
 
Commence Database User Support Group Forum
http://newsgroup.showoff-db.org/
~ ~ ~ ~ ~ ~
Author: Mark Petryk
Lorimark Solutions, LLC
mark@lorimarksolutions.com