In ATL und MFC steckt ein ziemlich ausgeklügelter Trace-Mechanismus. Wenn man sich das MFC – ATL Trace Tool ansieht kann man zu allen möglichen Kategorien Informationen in Debug Fenster ausgeben lassen.
Alleine die MFC hat 14 verschiedene Trace Kategorien. Darunter besonders interessante wie CommandRouting, AppMsg und WinMsg. Die ATL hat weitere 27 Kategorien.
Es lohnt sich mal einen Blick in dieses Tool und die entsprechenden Ausgaben zu machen. Es gehört zu den oft unbekannten netten Helferlein, die leider mangels Bekanntheit selten benutzt werden.
Um Fehler zu finden und einzugrenzen, sind mir jedoch oft eher zu viele Ausgaben vorhanden, als zu wenige. Zudem finde ich es manchmal unhandlich mit dem Trace-Tool die Nachrichten ab einem bestimmten Moment einzuschalten und wieder auszuschalten.
Ich habe eine kleine Hilfsklasse gebaut,mit der man in jedem Szenario, jederzeit zu einem bestimmten Moment das Tracing im Code ein- und automatisch wieder ausschalten kann.
class CDebugEnableTraceForCategory
{
public:
CDebugEnableTraceForCategory(ATL::CTraceCategory &category,
PCSTR pszPrompt=NULL,
UINT uiLevel=4,
ATL::ATLTRACESTATUS eStatus=ATL::ATLTRACESTATUS_ENABLED)
: m_category(category)
, m_uiSaveLevel(category.GetLevel())
, m_eSaveStatus(category.GetStatus())
, m_strPrompt(pszPrompt)
{
if (!m_strPrompt.IsEmpty())
TRACE("%s - Tracelevel %d\n", m_strPrompt.GetString(),uiLevel);
m_category.SetLevel(uiLevel);
m_category.SetStatus(eStatus);
}
~CDebugEnableTraceForCategory()
{
m_category.SetLevel(m_uiSaveLevel);
m_category.SetStatus(m_eSaveStatus);
if (!m_strPrompt.IsEmpty())
TRACE("%s - Tracelevel %d\n", m_strPrompt.GetString(), m_uiSaveLevel);
}
private:
// Data fields
ATL::CTraceCategory &m_category;
ATL::ATLTRACESTATUS m_eSaveStatus;
UINT m_uiSaveLevel;
CStringA m_strPrompt;
// no copy operator
CDebugEnableTraceForCategory(const CDebugEnableTraceForCategory &);
CDebugEnableTraceForCategory& operator=(const CDebugEnableTraceForCategory &);
};
Mit dieser Klasse kann ich zum Beispiel alle Windows-Nachrichten an MFC Fenster bei einer bestimmen Aktion ausgeben lassen. Und wenn die Aktion fertig ist stopp auch das Tracing wieder.
Hier als Beispiel um alle Fensternachrichten in der Aktion LoadFrame zu Tracen:
void CMyApp::InitInstance()
{
...
CDebugEnableTraceForCategory trace(traceWinMsg,"messages in LoadFrame");
pMainFrame->LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW);
...
}
Weitere Infos in der MSDN findet man unter ATL::CTraceCategory und ATLTRACE2 http://msdn.microsoft.com/en-us/library/dhxsse89(VS.100).aspx