在MFC程序中輸出調試信息的方法有兩種,一種是使用TRACE宏,可以向Output窗口輸出調試信息;另一種是用MessageBox,彈出消息框來輸出調試信息,但會影響程序的運行。
其實有一種方法可以更爲方便的輸出調試信息,就是輸出到控制檯(Console)中,即不影響程序運行,又便於查看調試信息。方法如下:
1. 使用時略顯麻煩。需要建立全局的instance,使用時需要p->print. 不能格式輸出,不太方便。 推薦指數:★★★
在寫MFC這個是一種調試的方法。
代碼下載
++++++++++++++++++++++
MFC程序利用控制檯輸出調試信息
近日研究師兄的一個MFC程序,見其會生成一個控制檯窗口輸出信息,就如同ANSYS的Output窗口,覺得這個功能實在有用。
於是研究了一下他的代碼,不過因爲其爲DLL工程,又可憐我的VC6打不開他的VS2005的Test工程,原先的工程沒有辦法編通過。
於是想把實現此功能的類拆出來,仔細研究之後,做了個Test工程,居然不好用,不知道哪裏出了問題。
於是google之,有幾個結果可供參考:
(1)Creating
a console for your MFC app's debug output[http://www.codeproject.com/KB/debug/mfcconsole.aspx?df=100&forumid=822&exp=0&select=2656]
(2)MFC 利用控制檯輸出調試信息 http://blog.csdn.net/wang23432/article/details/5747897
(3) MFC/DLL 編程時用獨立的控制檯窗口顯示用戶自定義調試信息[這篇文章因爲被轉載多次,找不到出處,google標題即可找到]
(4) GUI程序也能使用控制檯窗口[http://bbs.51cto.com/thread-396954-1-1.html]
綜合一下,其實現的方法基本一致。
1)調用AllocConsole()
函數,創建一個Console;
2)調用_cprintf()
函數,輸出字符串;
或者,重定向輸出流(詳見下文);
3)調用FreeConsole()
函數,釋放Console。
爲了使用方便,參考了師兄使用的“單例模式”,寫了下面的class。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2. MFC/DLL
編程時用獨立的控制檯窗口顯示用戶自定義調試信息 推薦指數:★★★★
支持格式輸出!只需在待輸出文件include "DBWindow.h",用DBWindowWrite 代替printf
不好的地方是程序開始時就會彈出console,顯得不太高級~
我將這個功能封裝爲兩個文件,請將此文本內容下載到本地,保存爲正確的文件名後使用。在不改變源代碼的情況下實現,Debug版顯示調試信息窗口,在Release版下不現實調試窗口且不增加程序負擔。
###############DBWindow.h##################
/********************************************************************
創建日期: 2004/09/02
文件名稱: DBWindow.h
作者: 劉磊(vietor)
版本: 2.0
郵箱: [email protected]
創建目的:
用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
###############DBWindow.cpp################
/********************************************************************
創建日期: 2004/09/02
文件名稱: DBWindow.cpp
作者: 劉磊(vietor)
版本: 2.0
郵箱: [email protected]
創建目的:
用VC MFC/DLL編程時通常Debug版需要將測試信息通過控制檯輸出,而
編譯成Release版時需要將這些輸出調試信息的代碼給註釋掉,通
常這些代碼較多操作比較麻煩。
這個程序的作用就是爲了程序員在進行MFC/DLL軟件開發時Debug版可以
在一個單獨的控制檯窗口進行調試程序的輸出,而做成Release版時
不必手工將這些代碼註釋掉,由此程序自動完成。
注意:在一個進程之內只存在一個控制檯窗口,對於多個可能同時調試的DLL
請用顏色識別。
版權聲明:
您可以隨意拷貝和使用這個程序的副本,但請保證所有文件的完整和
不被修改,如果您有修改意見,請與作者聯繫。
*********************************************************************/
#include "stdafx.h"
#include "DBWindow.h"
#ifdef _DEBUG
#include <tchar.h>
#include <stdio.h>
#include <stdarg.h>
#define CONSOLE_TILE _T("DBWindow Ver 2.0 by LiuLei")
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;
};
ConsoleWindow::ConsoleWindow()
{
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();
}
BOOL ConsoleWindow::SetTile(LPCTSTR lpTile)
{
return SetConsoleTitle(lpTile);
}
BOOL ConsoleWindow::WriteString(LPCTSTR lpString)
{
BOOL ret=FALSE;
if(m_hConsole)
{
ret=WriteConsole(m_hConsole,lpString,_tcslen(lpString),NULL,NULL);
}
return ret;
}
BOOL ConsoleWindow::WriteString(WORD Attrs,LPCTSTR lpString)
{
BOOL ret=FALSE;
if(m_hConsole)
{
if(m_bAttrs)SetConsoleTextAttribute(m_hConsole,Attrs);
ret=WriteConsole(m_hConsole,lpString,_tcslen(lpString),NULL,NULL);
if(m_bAttrs)SetConsoleTextAttribute(m_hConsole,m_OldColorAttrs);
}
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
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3.
#include <fcntl.h>
#include <stdio.h>
{
int nCrt = 0;
FILE* fp;
AllocConsole();
nCrt = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
fp = _fdopen(nCrt, "w");
*stdout = *fp;
setvbuf(stdout, NULL, _IONBF, 0);
}
BOOL CSerialPortptestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
int Index;
HKEY hKey;
LONG ret;
OSVERSIONINFO osvi;
BOOL bOsVersionInfoEx;
char keyinfo[100],comm_name[200],ValueName[200];
int i;
DWORD sType,Reserved,cbData,cbValueName;
// 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動
// 執行此操作
SetIcon(m_hIcon, TRUE); // 設置大圖標
SetIcon(m_hIcon, FALSE); // 設置小圖標
InitConsoleWindow();
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4. MFC 利用控制檯輸出調試信息 推薦指數:★★★★★★
WINDOWS爲你提供了一系列的API來完成這個功能,例如:ReadConsole,WriteConsole等,具體參見MSDN。
1、首先調用AllocConsole函數來爲你進程創建一個Console,該API是將當前進程Attache到一個新創建的 Console 上。你還可以通過調用SetConsoleTitle(tstrName)來設置Console的Title。
2、使用WriteConsoleOutput來將信息輸出到Console上;在輸出之前,先要得到Console的HANDLE,這通過 GetStdHandle(STD_OUTPUT_HANDLE)來得到,然後將信息組織成Console的格式,然後輸出。
3、關閉CONSOLE。當不需要這個CONSOLE的時候,調用FreeConsole來將當前進程從Console中Detach中。
4、通過創建一個進程來爲監視你的CONSOLE輸入和輸出;你可以創建一個線程然後來,在線程中取得標準輸入和輸出CONSOLE的HANDLE,然後循環監視其事件,再對不同的事件進行處理。
第二種方案:
在 Project | Setting 中,選項 Post-builder step 裏新建command,輸入:
editbin /SUBSYSTEM:CONSOLE $(OUTDIR)/filename.exe
(其中 filename 爲可執行文件名)
則可以使用 printf 或者 std::cout在控制檯中輸出了。
例如你的可執行文件名爲 HelloWorld.exe,則你新建的 command 就爲
editbin /SUBSYSTEM:CONSOLE $(OUTDIR)/HelloWorld.exe
需注意空格問題,eg: editbin /SUBSYSTEM:CONSOLE C:/Users/.../Documents/"Visual Studio 2008"/Projects/HelloMFC2/Debug/HelloMFC2.exe
清理工程後重新編譯。 我用了第二種方案,比較快捷而且簡單。
第三種方案:
就用TRACE,然後編譯debug的工程,直接運行你的可執行文件,可以用Dbgview來獲得輸出
第四種方案:
http://community.csdn.net/Expert/FAQ/FAQ_Index.asp id=186174
第五種方案:
就是將你的調試信息輸出到文件,如 *.txt 文件
+++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++
其餘參考:
1. 沒看懂: http://blog.csdn.net/zhuqinglu/article/details/2454524
2.
MFC窗體程序中添加調試控制檯
在編寫複雜程序的過程中,我們經常需要將一些信息輸出到文件或者屏幕上。較控制檯應用程序,MFC窗體程序要顯得麻煩一些!
下面有2種方法來實現爲MFC窗體程序添加調試控制檯,方便程序員調試程序和了解當前程序的運行狀態。
重要Windows API:AllocConsole(); //創建Console窗口
FreeConsole(); //銷燬Console窗口
(1)啓動控制檯窗口
需要包含的頭文件
#include <io.h>
#include <cstdio>
#include <FCNTL.H>
{
// start debugconsole
AllocConsole();
intptr_t handle= (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE);
int hCrt = _open_osfhandle(handle,_O_TEXT);
FILE * hf = _fdopen( hCrt, "w" );
*stdout =*hf;
char title[1024] ={0};
sprintf_s(title, 1024, "DebugCosole[%u]", (unsigned long)(this->GetSafeHwnd()));
SetConsoleTitle(title);
SetConsoleTextAttribute((HANDLE)handle, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
HWND hwnd=NULL;
while(NULL==hwnd) hwnd=::FindWindow(NULL,(LPCTSTR)title);
HMENU hmenu = ::GetSystemMenu ( hwnd, FALSE );
DeleteMenu ( hmenu, SC_CLOSE, MF_BYCOMMAND );
}
MFC窗體測試程序:
Console信息顯示:
代碼下載(VS2008):http://files.cnblogs.com/kekec/DebugConsole.rar
(2)設計另外一個MFC窗體程序
關於這種方法請詳見 Azure Product 的 “實現一個通用的調試控制檯”。