用VC MFC/DLL编程时通常Debug版需要将测试信息通过控制台输出,而编译成Release版时需要将这些输出调试信息的代码给注释掉,通常这些代码较多操作比较麻烦。这个程序的作用就是为了程序员在进行MFC/DLL软件开发时Debug版可以在一个单独的控制台窗口进行调试程序的输出,而做成Release版时不必手工将这些代码注释掉,由此程序自动完成。注意:在一个进程之内只存在一个控制台窗口,对于多个可能同时调试的DLL请用颜色识别。
废话少说,请看源码,头文件定义:
#ifndef _DBWINDOW_
#define _DBWINDOW_
#include <windows.h>
//控制台输出时的文本颜色
#define WDS_T_RED FOREGROUND_RED
#define WDS_T_GREEN FOREGROUND_GREEN
#define WDS_T_BLUE FOREGROUND_BLUE
//控制台输出时的文本背景颜色
#define WDS_BG_RED BACKGROUND_RED
#define WDS_BG_GREEN BACKGROUND_GREEN
#define WDS_BG_BLUE BACKGROUND_BLUE
#ifdef _DEBUG
//设置控制台输出窗口标题
BOOL DBWindowTile(LPCTSTR tile);
//格式化文本输出
BOOL DBWindowWrite(LPCTSTR fmt, ...);
//带颜色格式化文本输出
BOOL DBWindowWrite(WORD Attrs, LPCTSTR fmt, ...);
#else
#define DBWindowTile
#define DBWindowWrite
#endif
#endif
源码实现:
#include "stdafx.h"
#include "DBWindow.h"
#ifdef _DEBUG
#include <tchar.h>
#include <stdio.h>
#include <stdarg.h>
#define CONSOLE_TILE _T("DBWindow Ver 2.2")
class ConsoleWindow
{
public:
ConsoleWindow();
virtual ~ConsoleWindow();
BOOL SetTile(LPCTSTR lpTile);
BOOL WriteString(LPCTSTR lpString);
BOOL WriteString(WORD Attrs, LPCTSTR lpString);
private:
HANDLE m_hConsole;
BOOL m_bCreate;
BOOL m_bAttrs;
WORD m_OldColorAttrs;
CRITICAL_SECTION m_csAttrs;
};
ConsoleWindow::ConsoleWindow()
{
InitializeCriticalSection(&m_csAttrs);
m_hConsole = NULL;
m_bCreate = FALSE;
if(AllocConsole())
{
m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTitle(CONSOLE_TILE);
SetConsoleMode(m_hConsole, ENABLE_PROCESSED_OUTPUT);
m_bCreate = TRUE;
}
else
{
m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if(m_hConsole == INVALID_HANDLE_VALUE)
m_hConsole = NULL;
}
if(m_hConsole)
{
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
if(GetConsoleScreenBufferInfo(m_hConsole, &csbiInfo))
{
m_bAttrs = TRUE;
m_OldColorAttrs = csbiInfo.wAttributes;
}
else
{
m_bAttrs = FALSE;
m_OldColorAttrs = 0;
}
}
}
ConsoleWindow::~ConsoleWindow()
{
if(m_bCreate)
FreeConsole();
LeaveCriticalSection(&m_csAttrs);
}
BOOL ConsoleWindow::SetTile(LPCTSTR lpTile)
{
return SetConsoleTitle(lpTile);
}
BOOL ConsoleWindow::WriteString(LPCTSTR lpString)
{
BOOL ret = FALSE;
if(m_hConsole)
{
DWORD dwWritten;
EnterCriticalSection(&m_csAttrs);
ret = WriteConsole(m_hConsole, lpString, _tcslen(lpString), &dwWritten, NULL);
LeaveCriticalSection(&m_csAttrs);
}
return ret;
}
BOOL ConsoleWindow::WriteString(WORD Attrs, LPCTSTR lpString)
{
BOOL ret = FALSE;
if(m_hConsole)
{
DWORD dwWritten;
EnterCriticalSection(&m_csAttrs);
if(m_bAttrs)SetConsoleTextAttribute(m_hConsole, Attrs);
ret = WriteConsole(m_hConsole, lpString, _tcslen(lpString), &dwWritten, NULL);
if(m_bAttrs)SetConsoleTextAttribute(m_hConsole, m_OldColorAttrs);
LeaveCriticalSection(&m_csAttrs);
}
return ret;
}
ConsoleWindow ConWindow;
#define MAX_BUF_LEN 4096
BOOL DBWindowTile(LPCTSTR tile)
{
return ConWindow.SetTile(tile);
}
BOOL DBWindowWrite(LPCTSTR fmt, ...)
{
TCHAR message[MAX_BUF_LEN];
va_list cur_arg;
va_start(cur_arg, fmt);
_vsntprintf(message, MAX_BUF_LEN, fmt, cur_arg);
va_end(cur_arg);
return ConWindow.WriteString(message);
}
BOOL DBWindowWrite(WORD Attrs, LPCTSTR fmt, ...)
{
TCHAR message[MAX_BUF_LEN];
va_list cur_arg;
va_start(cur_arg, fmt);
_vsntprintf(message, MAX_BUF_LEN, fmt, cur_arg);
va_end(cur_arg);
return ConWindow.WriteString(Attrs, message);
}
#endif
至此,一个完整的控制台调试信息输出窗口就完成了。