home *** CD-ROM | disk | FTP | other *** search
- ////////////////////////////////////////////////////////////////
- // TRACEMSG Copyright 1995 Microsoft Systems Journal.
- // If this program works, it was written by Paul DiLascia.
- // If not, I don't know who wrote it.
- //
- // This file defines the tracing class and "phantom" template classes that
- // shadow MFC classes, overriding WindowProc, OnCommand and OnCmdMsg.
-
- #ifndef TRACEMSG_H
- #define TRACEMSG_H
-
- #if (_MFC_VER < 0x300)
- #error Sorry, this program requires MFC Version 3.0 or later.
- #endif
-
- #ifdef _DEBUG
-
- //////////////////
- // Trace class for CCmdTarget. Overrides OnCmdMsg to log the call.
- //
- template<class BASE>
- class TrCmdTarget : public BASE {
- public:
- virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
- AFX_CMDHANDLERINFO* pHandlerInfo);
- };
-
- //////////////////
- // Trace class for CWnd. Overrides WindowProc and OnCommand.
- //
- template<class BASE>
- class TrWnd : public TrCmdTarget<BASE> {
- public:
- virtual LRESULT WindowProc(UINT msg, WPARAM wp, LPARAM lp);
- virtual BOOL OnCommand(WPARAM wp, LPARAM lp);
- };
-
- //////////////////
- // This class does the actual tracing, to keep template functions are small.
- // There's only one of these. It also implements Trace On/Off commands.
- //
- class CMsgTracer : public TrCmdTarget<CCmdTarget> {
- DECLARE_DYNAMIC(CMsgTracer)
- private:
- CMapWordToPtr m_mapMsg; // Table of WM_XXX message names
- CMapWordToPtr m_mapCmd; // Table of MFC ID_XXX command ID names
- CFile m_file; // TRACE file (TRACE.OUT)
- char m_szIndent[80]; // indent string filled with '|'
- int m_nCallDepth; // number of nested calls
-
- // Push/pop call level for pretty printing
- void PushCallLevel() {
- m_szIndent[m_nCallDepth++] = '|';
- m_szIndent[m_nCallDepth] = 0;
- }
- void PopCallLevel() {
- m_szIndent[--m_nCallDepth] = 0;
- }
-
- // Helpers
- LPCSTR GetMessageName(UINT msg); // e.g. "WM_SIZE"
- LPCSTR GetCommandName(UINT nID); // e.g. "ID_FILE_OPEN"
- LPCSTR GetCmdCodeName(int nCode); // e.g. "CN_UPDATE_COMMAND_UI"
-
- public:
- BOOL m_bTraceMsg; // message tracing on
- BOOL m_bTraceCmd; // command tracing on
-
- CMsgTracer();
- ~CMsgTracer();
-
- void Write(LPCSTR str, int len=-1); // write a string to trace file
-
- BOOL TRACE_OnCmdMsg(CCmdTarget* pTarg, UINT nID, int nCode, void* pExtra,
- AFX_CMDHANDLERINFO* pHandlerInfo);
- BOOL TRACE_WindowProc(CWnd* pWnd, UINT msg, WPARAM wp, LPARAM lp);
- BOOL TRACE_OnCommand(CWnd* pWnd, WPARAM wp, LPARAM lp);
-
- void TRACE_ReturnWindowProc(LRESULT lRet);
- void TRACE_ReturnOnCommand(BOOL bRet);
- void TRACE_ReturnOnCmdMsg(BOOL bRet);
-
- // This object "Trace" commands
- afx_msg void OnTraceMsg();
- afx_msg void OnTraceCmd();
- afx_msg void OnUpdateTraceCmd(CCmdUI* pCmdUI);
- afx_msg void OnUpdateTraceMsg(CCmdUI* pCmdUI);
- DECLARE_MESSAGE_MAP();
- };
-
- extern CMsgTracer theTracer; // the one-and-only tracing object
-
- ////////////////////////////////////////////////////////////////
- // Template class "implementations." These template functions tell the
- // compiler how to generate the real functions for the template classes.
- // Override MFC functions OnCmdMsg, WindowProc, OnCommand.
- // TRACE the call, call the base class, then TRACE the return value.
- //
- // The implementation is similar for all: call CMsgTracer first
- // to trace the call, then the return value.
-
- template<class BASE>
- BOOL TrCmdTarget<BASE>::OnCmdMsg(UINT nID, int nCode, void* pExtra,
- AFX_CMDHANDLERINFO* pHI)
- {
- BOOL bTraced = theTracer.TRACE_OnCmdMsg(this, nID, nCode, pExtra, pHI);
- BOOL bRet = BASE::OnCmdMsg(nID, nCode, pExtra, pHI);
- if (bTraced)
- theTracer.TRACE_ReturnOnCmdMsg(bRet);
- return bRet;
- }
-
- template<class BASE>
- LRESULT TrWnd<BASE>::WindowProc(UINT msg, WPARAM wp, LPARAM lp)
- {
- BOOL bTraced = theTracer.TRACE_WindowProc(this, msg, wp, lp);
- LRESULT lRet = BASE::WindowProc(msg, wp, lp);
- if (bTraced)
- theTracer.TRACE_ReturnWindowProc(lRet);
- return lRet;
- }
-
- template<class BASE>
- BOOL TrWnd<BASE>::OnCommand(WPARAM wp, LPARAM lp)
- {
- BOOL bTraced = theTracer.TRACE_OnCommand(this, wp, lp);
- BOOL bRet = BASE::OnCommand(wp, lp);
- if (bTraced)
- theTracer.TRACE_ReturnOnCommand(bRet);
- return bRet;
- }
-
- // Derive your app classes from these
- //
- #define TCmdTarget TrCmdTarget<CCmdTarget>
- #define TWinApp TrCmdTarget<CWinApp>
- #define TDocument TrCmdTarget<CDocument>
-
- #define TWnd TrWnd<CWnd>
- #define TMDIFrameWnd TrWnd<CMDIFrameWnd>
- #define TMDIChildWnd TrWnd<CMDIChildWnd>
- #define TView TrWnd<CView>
- #define TDialog TrWnd<CDialog>
- #define TStatusBar TrWnd<CStatusBar>
- #define TToolBar TrWnd<CToolBar>
-
- #else // not _DEBUG
-
- #define TWinApp CWinApp
- #define TDocument CDocument
- #define TMDIFrameWnd CMDIFrameWnd
- #define TMDIChildWnd CMDIChildWnd
- #define TView CView
- #define TDialog CDialog
- #define TWnd CWnd
- #define TStatusBar CStatusBar
- #define TToolBar CToolBar
-
- #endif // _DEBUG
-
- #endif // TRACEMSG_H
-