This has the added benefit of making your program look like OWL code.
If a TClass is used anywhere, the compiler generates the whole shebang, so CMDLEARN.EXE actually contains a half-dozen or so classes, exactly as if I'd written them by hand. With all that generated code, it's a good idea to keep the templates as small as possible, so the template classes all call a global CMsgTracer object called theTracer to actually do the tracing. CTracer writes messages to TRACE.OUT, keeping track of call levels to indent the diagnostics all nice and pretty.
Before you marvel at how clever I am and run to graft my tracing code onto your own app, there are a few disgusting aspects you should be aware of. First of all, the template classes are not part of the MFC class hierarchy because the DECLARE/IMPLEMENT_DYNAMIC macros have a major brain hemorrhage when you pass them template names. So MFC doesn't know these classes exist. MFC thinks CApp is derived from CWinApp even though TrCmdTarget<WinApp> sits between. Likewise, the message map base pointers skip the template classes. So, for example, the base class message map pointer for CFileView points to CView's message map, not TrWnd<CView>. That's why I call the template classes "phantom classes." (Also because it sounds cool.) Fortunately, their ghostliness is harmless for most purposes.
Another problem is that if any "real" app class overrides WindowProc, OnCommand, or OnCmdMsg, and returns before calling its base class (TrWnd<Base>), the call won't be traced.
Finally, my tracing mechanism has a major drawback as a debugging tool: it requires that you modify your source code. You must derive all your clases from the TClasses instead of the normal MFC classes. Nevertheless, if you're experiencing especially difficult command routing woes, it might be worth your while. If so, you can compile your app with TRACEMSG.CPP. Its output is in some ways better than Spy's: you get symbolic names for MFC messages and command IDs, tracing for OnCommand and OnCmdMsg (OnNotify would be easy to add), and you can trace nonwindow objects like documents and your app.
Of course, it only works with the 32-bit Visual C++ compiler. That's the only one from Microsoft that supports templates.
|