Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version
Go to top

Internet Explorer AdBlock

, 17 Jan 2008
Internet Explorer AdBlock Add-on
ieadblock_src.zip
IE AdBlockPS
IE AdBlockps.def
IE AdBlock
AdBlockBand.rgs
AdBlockBHO.rgs
bin
XListCtrlSSDU.lib
XListCtrlSSRU.lib
IE AdBlock.def
IE AdBlock.rgs
res
bmpToolbar.bmp
checkboxes.bmp
icoSettings.ico
XListCtrl
checkboxes.bmp
// XTrace.h  Version 1.1
//
// Author:       Paul Mclachlan
//
// Modified by:  Hans Dietrich
//               hdietrich2@hotmail.com
//
// Version 1.1:  added Unicode support
//               added optional thread id to output string
//               added option to enable/disable full path
//               added TRACERECT macro
//               changed name to avoid conflicts with Paul's class.
//
// This code was taken from article by Paul Mclachlan, "Getting around 
// the need for a vararg #define just to automatically use __FILE__ and 
// __LINE__ in a TRACE macro".  For original article, see
//     http://www.codeproject.com/useritems/location_trace.asp
//
// XTrace.h is a drop-in replacement for MFC's TRACE facility.  It has no
// dependency on MFC.  It is thread-safe and uses no globals or statics.
//
// It optionally adds source module/line number and thread id to each line 
// of TRACE output.  To control these features, use the following defines:
//
//     XTRACE_SHOW_FULLPATH
//     XTRACE_SHOW_THREAD_ID
//
// XTrace.h also provides the TRACERECT macro, which outputs the contents
// of a RECT struct.  In Release builds, no output will be produced.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef XTRACE_H
#define XTRACE_H

#include <stdarg.h>
#include <stdio.h>
#include <windows.h>
#include <tchar.h>

#pragma warning(push)
#pragma warning(disable : 4127)			// conditional expression is constant

#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif

#define XTRACE_SHOW_FULLPATH	FALSE	// FALSE = only show base name of file
#define XTRACE_SHOW_THREAD_ID	TRUE	// TRUE = include thread id in output
#define XTRACE_FILE				FALSE	// TRUE = output to file

class xtracing_output_debug_string
{
public:
	xtracing_output_debug_string(LPCTSTR lpszFile, int line) :
		m_file(lpszFile),
		m_line(line)
	{
	}

	void operator() (LPCTSTR lpszFormat, ...)
	{
		va_list va;
		va_start(va, lpszFormat);

		TCHAR buf1[BUFFER_SIZE];
		TCHAR buf2[BUFFER_SIZE];

		// add the __FILE__ and __LINE__ to the front
		TCHAR *cp = (LPTSTR) m_file;
		
		if (!XTRACE_SHOW_FULLPATH)
		{
			cp = (TCHAR *)_tcsrchr(m_file, _T('\\'));
			if (cp)
				cp++;
		}

		if (XTRACE_SHOW_THREAD_ID)
		{
			if (_sntprintf(buf1, BUFFER_SIZE-1, _T("%s(%d) : [%X] %s"), 
						cp, m_line, GetCurrentThreadId(), lpszFormat) < 0)
				buf1[BUFFER_SIZE-1] = _T('\0');
		}
		else
		{
			if (_sntprintf(buf1, BUFFER_SIZE-1, _T("%s(%d) : %s"), 
						cp, m_line, lpszFormat) < 0)
				buf1[BUFFER_SIZE-1] = _T('\0');
		}

		// format the message as requested
		if (_vsntprintf(buf2, BUFFER_SIZE-1, buf1, va) < 0)
			buf2[BUFFER_SIZE-1] = _T('\0');

		va_end(va);

		if (XTRACE_FILE)
		{
			TCHAR szPathName[MAX_PATH*2] = { 0 };

			::GetModuleFileName(NULL, szPathName, sizeof(szPathName)/sizeof(TCHAR)-2);

			TCHAR *cp = _tcsrchr(szPathName, _T('\\'));
			if (cp != NULL)
				*(cp+1) = _T('\0');
			_tcscat(szPathName, _T("\\_trace.log"));
			HANDLE hFile = ::CreateFile(szPathName, GENERIC_WRITE, FILE_SHARE_WRITE,
								NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
			if (hFile != INVALID_HANDLE_VALUE)
			{
				DWORD dwRC = ::SetFilePointer(hFile,		// handle to file
											  0,			// bytes to move pointer
											  NULL,			// bytes to move pointer
											  FILE_END);	// starting point

				if (dwRC != INVALID_SET_FILE_POINTER)
				{
					DWORD dwWritten = 0;
					::WriteFile(hFile,							// handle to file
								buf2,							// data buffer
								_tcslen(buf2)*sizeof(TCHAR),	// number of bytes to write
								&dwWritten,						// number of bytes written
								NULL);							// overlapped buffer
				}

				::CloseHandle(hFile);
			}
		}
		else
		{
			// write it out
			OutputDebugString(buf2);
		}
	}

private:
	LPCTSTR m_file;
	int     m_line;
	enum    { BUFFER_SIZE = 4096 };
};

class xtracing_entry_output_debug_string
{
public:
	xtracing_entry_output_debug_string(LPCTSTR lpszFile, int line) :
		m_file(lpszFile),
		m_line(line)
	{
	}

	~xtracing_entry_output_debug_string()
	{
		TCHAR buf3[BUFFER_SIZE*3];
		_stprintf(buf3, _T("======  exiting scope:  %s"), buf2);
		OutputDebugString(buf3);
	}

	void operator() (LPCTSTR lpszFormat, ...)
	{
		va_list va;
		va_start(va, lpszFormat);

		TCHAR buf1[BUFFER_SIZE];

		// add the __FILE__ and __LINE__ to the front
		TCHAR *cp = (LPTSTR) m_file;
		
		if (!XTRACE_SHOW_FULLPATH)
		{
			cp = (TCHAR *)_tcsrchr(m_file, _T('\\'));
			if (cp)
				cp++;
		}

		if (XTRACE_SHOW_THREAD_ID)
		{
			if (_sntprintf(buf1, BUFFER_SIZE-1, _T("%s(%d) : [%X] ======  %s"), 
						cp, m_line, GetCurrentThreadId(), lpszFormat) < 0)
				buf1[BUFFER_SIZE-1] = _T('\0');
		}
		else
		{
			if (_sntprintf(buf1, BUFFER_SIZE-1, _T("%s(%d) : ======  %s"), 
						cp, m_line, lpszFormat) < 0)
				buf1[BUFFER_SIZE-1] = _T('\0');
		}

		// format the message as requested
		if (_vsntprintf(buf2, BUFFER_SIZE-1, buf1, va) < 0)
			buf2[BUFFER_SIZE-1] = _T('\0');

		va_end(va);

		if (XTRACE_FILE)
		{
			TCHAR szPathName[MAX_PATH*2] = { 0 };

			::GetModuleFileName(NULL, szPathName, sizeof(szPathName)/sizeof(TCHAR)-2);

			TCHAR *cp = _tcsrchr(szPathName, _T('\\'));
			if (cp != NULL)
				*(cp+1) = _T('\0');
			_tcscat(szPathName, _T("\\_trace.log"));
			HANDLE hFile = ::CreateFile(szPathName, GENERIC_WRITE, FILE_SHARE_WRITE,
								NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
			if (hFile != INVALID_HANDLE_VALUE)
			{
				DWORD dwRC = ::SetFilePointer(hFile,		// handle to file
											  0,			// bytes to move pointer
											  NULL,			// bytes to move pointer
											  FILE_END);	// starting point

				if (dwRC != INVALID_SET_FILE_POINTER)
				{
					DWORD dwWritten = 0;
					::WriteFile(hFile,							// handle to file
								buf2,							// data buffer
								_tcslen(buf2)*sizeof(TCHAR),	// number of bytes to write
								&dwWritten,						// number of bytes written
								NULL);							// overlapped buffer
				}

				::CloseHandle(hFile);
			}
		}
		else
		{
			// write it out
			OutputDebugString(buf2);
		}
	}

private:
	LPCTSTR m_file;
	int     m_line;
	enum    { BUFFER_SIZE = 4096 };
	TCHAR buf2[BUFFER_SIZE*2];
};

#undef TRACE
#undef TRACE0
#undef TRACE1
#undef TRACE2

#define  _DEBUGnow

#ifdef _DEBUG

#define TRACE (xtracing_output_debug_string(_T(__FILE__), __LINE__ ))
#define TRACEENTRY (xtracing_output_debug_string(_T(__FILE__), __LINE__ ))
#define TRACEERROR (xtracing_output_debug_string(_T(__FILE__), __LINE__ ))
#define TRACE0 TRACE
#define TRACE1 TRACE
#define TRACE2 TRACE

#else

#ifndef __noop
#if _MSC_VER < 1300
#define __noop ((void)0)
#endif
#endif

#define TRACE		__noop
#define TRACEERROR	__noop
#define TRACE0		__noop
#define TRACE1		__noop
#define TRACE2		__noop

#endif	//_DEBUG

#define TRACEHILO(d) \
			WORD ___hi = HIWORD(d); WORD ___lo = LOWORD(d); \
			TRACE(_T(#d) _T(":  HIWORD = %u  LOWORD = %u\n"), ___hi, ___lo)

#define TRACESIZE(s) TRACE(_T(#s) _T(":  cx = %d  cy = %d\n"), \
                           (s).cx, (s).cy)

#define TRACEPOINT(p) TRACE(_T(#p) _T(":  x = %d  y = %d\n"), \
                           (p).x, (p).y)

#define TRACERECT(r) TRACE(_T(#r) _T(":  left = %d  top = %d  right = %d  bottom = %d\n"), \
                           (r).left, (r).top, (r).right, (r).bottom)

#pragma warning(pop)

#endif //XTRACE_H

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

Geert van Horrik
Software Developer CatenaLogic
Netherlands Netherlands
I am Geert van Horrik, and I have studied Computer Science in the Netherlands.
 
I love to write software using .NET (especially the combination of WPF and C#). I am also the lead developer of Catel, an open-source application development framework for WPF, Silverlight, WP7 and WinRT with the focus on MVVM.
 
I have my own company since January 1st 2007, called CatenaLogic. This company develops commercial and non-commercial software.
 
To download (or buy) applications I have written, visit my website: http://www.catenalogic.com
Follow on   Twitter

| Advertise | Privacy | Mobile
Web04 | 2.8.140921.1 | Last Updated 17 Jan 2008
Article Copyright 2008 by Geert van Horrik
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid