FORMTRCK.H
//+--------------------------------------------------------------------------- 
// 
//  Microsoft Windows 
//  Copyright (C) 1992, Microsoft Corporation. 
// 
//  File:       formtrck.hxx 
// 
//  Contents:   This file defines facilities for a standard implementation 
//              of reference-counted objects, incorporating mechanisms for 
//              tracking the usage history of the objects. 
// 
//  Classes:    ObjectTracker 
// 
//  History:    6-Apr-92       MikeSe  Created 
//              08-Aug-94      DonCl   copied from cinc, and renamed to formtrck.hxx 
// 
//---------------------------------------------------------------------------- 
 
#ifndef __FORMTRCK_HXX__ 
#define __FORMTRCK_HXX__ 
 
#include <windows.h> 
 
//+------------------------------------------------------------------------- 
// 
//  Class:      ObjectTracker (otr) 
// 
//  Purpose:    Provides basis for tracking (OLE) objects (aka interface handles) 
// 
//  History:    6-Apr-92 MikeSe         Created 
// 
//  Notes:      Access to this class is only indirect, through the macros 
//              defined later. 
// 
//-------------------------------------------------------------------------- 
 
class ObjectTracker 
{ 
protected: 
 
                     ObjectTracker (); 
 
//# if DBG == 1 
#if 0 
                    ~ObjectTracker(); 
    ULONG            StdAddRef ( void ); 
    ULONG            StdRelease ( void ); 
    void             TrackClassName ( char * pszName ); 
    unsigned long    GetRefCount ( void ) {return _ulRefs;}; 
 
private: 
 
    BOOL             IsClassTracking( char * pszName ); 
 
    struct TrackLink *  _tl; 
    static  BOOL        _TrackAll; 
 
public: 
        // dumps information on all outstanding objects 
    static void        DumpTrackingInfo ( int fDeleteNode = 0 ); 
    static void        TrackClass(BOOL, char * pszName ); 
 
# endif // DBG == 1 
 
protected: 
    unsigned long      _ulRefs; 
}; 
 
//+------------------------------------------------------------------------- 
// 
//  The following macros encapsulate use of the above 
// 
//  INHERIT_TRACKING: 
// 
//      For any class which implements a Cairo interface, add this macro 
//      in the class declaration, eg: 
// 
//              class CMyFoo: INHERIT_TRACKING, IFoo 
// 
//      Do not repeat this in any subclass. If both INHERIT_UNWIND and 
//      INHERIT_TRACKING are used, the former should appear first. 
 
# define INHERIT_TRACKING       protected ObjectTracker 
 
        // The following declarations are for non-retail builds 
 
//# if DBG == 1 
#if 0 
// 
// DECLARE_STD_REFCOUNTING: 
// 
//      To make use of standard refcounting code, place the above 
//      in the class declaration, in the public method section. This 
//      macro defines the AddRef and Release methods for the class. 
// 
 
#  define DECLARE_STD_REFCOUNTING                                       \ 
        STDMETHOD_(ULONG, AddRef) ()                                    \ 
                {                                                       \ 
                    return StdAddRef();                                 \ 
                };                                                      \ 
        STDMETHOD_(ULONG, Release) ()                                   \ 
                {                                                       \ 
                    ULONG ul = StdRelease();                            \ 
                    if ( ul==0 ) delete this;                           \ 
                    return ul;                                          \ 
                }; 
 
// 
//  ENLIST_TRACKING(class name) 
// 
//      Place an invocation of this in each constructor, at any appropriate 
//      point (generally immediately before returning from the constructor). 
// 
//              ENLIST_TRACKING(CMyFoo) 
// 
 
#  define ENLIST_TRACKING(cls)  TrackClassName( #cls ) 
 
// 
// NB:  In a subclass of a class which has INHERIT_TRACKING, do not 
//      use INHERIT_TRACKING again. However, do use ENLIST_TRACKING in 
//      in the constructor of the derived class, and use TRACK_ADDREF 
//      and TRACK_RELEASE if the subclass overrides the AddRef and Release 
//      methods. 
 
// 
//  TRACK_CLASS(fTrack, pszClassName) 
// 
//      Use this to add or remove a class in the list of tracked classes. 
//      You can turn tracking of all classes on or off by using a NULL 
//      pszClassName.  If fTrack is TRUE, the class will be tracked, if FALSE, 
//      the class will no longer be tracked.  The default configuration is 
//      that all classes are tracked. 
// 
//      NOTE: this affects only objects created after this macro is executed. 
// 
 
#  define TRACK_CLASS(fTrack, cls) \ 
                      ObjectTracker::TrackClass( fTrack, cls ) 
 
// 
//  DUMP_TRACKING_INFO() 
// 
//      Place this anywhere it would be useful to dump out the object 
//      tracking database. By default, this is always issued at program 
//      termination. 
// 
 
#  define DUMP_TRACKING_INFO()        DUMP_TRACKING_INFO_KEEP() 
#  define DUMP_TRACKING_INFO_KEEP()   ObjectTracker::DumpTrackingInfo(0) 
#  define DUMP_TRACKING_INFO_DELETE() ObjectTracker::DumpTrackingInfo(1) 
 
//      Output from this is controlled by setting the following mask values 
//      in OtInfoLevel 
 
#  define DEB_OT_OBJECTS        0x00000001L 
        // display object addresses, reference count and name (Default) 
 
#  define DEB_OT_CALLERS        0x80000000L 
        // display call history 
 
// In addition, set the following values to cause debug output during 
// operation: 
 
#  define DEB_OT_ERRORS         0x00000002L 
        // report errors during tracking operations (Default) 
 
#  define DEB_OT_ACTIONS        0x40000000L 
        // report each create, addref and release 
 
#  define DEB_OT_DELETE         0x20000000L 
        // display call history at object delete 
 
# else // DBG == 0 
 
inline ObjectTracker::ObjectTracker():_ulRefs(1) {}; 
 
#  define DECLARE_STD_REFCOUNTING                                       \ 
        STDMETHOD_(ULONG, AddRef) ()                                    \ 
                {                                                       \ 
                    InterlockedIncrement((long*)&_ulRefs);         \ 
                    return _ulRefs;                                \ 
                };                                                      \ 
        STDMETHOD_(ULONG, Release) ()                                   \ 
                {                                                          \ 
                    if ( InterlockedDecrement((long*)&_ulRefs) == 0 ) \ 
                    {                                                      \ 
                        delete this;                                       \ 
                        return 0;                                          \ 
                    }                                                      \ 
                    else                                                   \ 
                        return  _ulRefs;                              \ 
                }; 
 
#  define ENLIST_TRACKING(cls) 
 
#  define DUMP_TRACKING_INFO() 
 
#  define TRACK_CLASS(fTrack, cls) 
 
# endif // DBG == 0 
 
#endif  // of ifndef __OTRACK_HXX__