本文转自:http://blog.csdn.net/pkueecser/article/details/7469761

在MFC程序中输出调试信息的方法有两种,一种是使用TRACE宏,可以向Output窗口输出调试信息;另一种是用MessageBox,弹出消息框来输出调试信息,但会影响程序的运行。
其实有一种方法可以更为方便的输出调试信息,就是输出到控制台(Console)中,即不影响程序运行,又便于查看调试信息。方法如下:

1.  使用时略显麻烦。需要建立全局的instance,使用时需要p->print.  不能格式输出,不太方便。 推荐指数:★★★

在MFC中用控制台显示输出内容


在写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。

//.h
class CConsolePrinter
{
public:void print(const char* str);static void Destroy();static CConsolePrinter* Instance();virtual ~CConsolePrinter();protected:CConsolePrinter();private:static CConsolePrinter* _instance;FILE *file;};
//.cpp
CConsolePrinter* CConsolePrinter::_instance = 0;CConsolePrinter::CConsolePrinter()
{// create a new console to the processAllocConsole();int hCrun;    hCrun = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);file  = _fdopen(hCrun, "w");// use default stream buffersetvbuf(file, NULL, _IONBF, 0);*stdout = *file;std::cout << "Ready!\n";
}CConsolePrinter::~CConsolePrinter()
{FreeConsole();fclose(file);}CConsolePrinter* CConsolePrinter::Instance()
{if (_instance == 0){_instance = new CConsolePrinter;}return _instance;
}void CConsolePrinter::Destroy()
{if (_instance){delete _instance;}_instance = 0;
}void CConsolePrinter::print(const char *str)
{std::cout << str << std::endl;
}使用方法也很简单。首先在应用程序类的InitInstance()函数中添加CConsolePrinter::Instance();,例如:
BOOL CMfcWithConsoleApp::InitInstance()
{// details omitted// allocate a console
#ifdef _DEBUGCConsolePrinter::Instance();
#endif// details omitted// The one and only window has been initialized, so show and update it.m_pMainWnd->ShowWindow(SW_SHOW);m_pMainWnd->UpdateWindow();return TRUE;
}第二步在应用程序类的ExitInstance()函数中添加CConsolePrinter::Destroy();,例如:
int CMfcWithConsoleApp::ExitInstance()
{// TODO: Add your specialized code here and/or call the base class#ifdef _DEBUGCConsolePrinter::Destroy();
#endifreturn CWinApp::ExitInstance();
}然后就是在需要输出字符串信息的地方调用CConsolePrinter::Instance()->print();函数。
void CMfcWithConsoleDoc::OnEditCopy()
{   // TODO: Add your command handler code here
#ifdef _DEBUGCConsolePrinter::Instance()->print("CMfcWithConsoleDoc::OnEditCopy() ");
#endif
}需要注意的是,如果关闭控制台窗口会导致主程序退出。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

2. MFC/DLL  编程时用独立的控制台窗口显示用户自定义调试信息     推荐指数:★★★★

支持格式输出!只需在待输出文件include "DBWindow.h",用DBWindowWrite 代替printf

 不好的地方是程序开始时就会弹出console,显得不太高级~

我将这个功能封装为两个文件,请将此文本内容下载到本地,保存为正确的文件名后使用。在不改变源代码的情况下实现,Debug版显示调试信息窗口,在Release版下不现实调试窗口且不增加程序负担。

###############DBWindow.h##################

/********************************************************************
 创建日期: 2004/09/02
 文件名称: DBWindow.h
  
      作者: 刘磊(vietor)
      版本: 2.0
      邮箱: liuleilover@163.com

创建目的:
      用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
      邮箱: liuleilover@163.com

创建目的:
      用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.

VC2010 MFC中实现printf调试功能,即MFC程序利用控制台输出调试信息 (2011-10-17 16:00)   推荐指数:★★★★★
1、在项目自动生成的stdafx.h文件中添加下面头文件
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
2、把下面的函数加到你初始化的地方,然后你就可以使用printf函数了
void InitConsoleWindow()
{
    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();
CString str;
 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();
 printf( "str   =   %s\n ",   "debug");
调用此函数后会弹出一个CONSOLE,然后printf的东西就会出现在上面。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

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>

void CTestDebugConsoleDlg::OnBnClickedButton6()
{
// 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 的 “实现一个通用的调试控制台”。

GUI程序中添加控制台调试相关推荐

  1. MFC应用程序中添加控制台窗口

    在MFC程序中输出调试信息的方法有两种,一种是使用TRACE宏,可以向Output窗口输出调试信息:另一种是用MessageBox,弹出消息框来输出调试信息,但会影响程序的运行. 其实有一种方法可以更 ...

  2. MFC应用程序中添加控制台窗口---debug输出窗口

    在MFC程序中输出调试信息的方法有两种,一种是使用TRACE宏,可以向Output窗口输出调试信息:另一种是用MessageBox,弹出消息框来输出调试信息,但会影响程序的运行. 其实有一种方法可以更 ...

  3. GUI程序中的Matplotlib绘图

    1.示例程序和运行效果 一般的书上介绍Matplotlib的绘图功能都主要是介绍matplotlib.pyplot模块中的指令式绘图功能,因为这种方式与MATLAB很相似,使用过MATLAB的人转而使 ...

  4. java怎么加定时器_JAVA WEB程序中添加定时器

    JAVA WEB程序中添加定时器 //这是我的定时器类,用来定时执行某段任务: package com.my.time; import java.text.ParseException; import ...

  5. 如何在RCP程序中添加一个banner栏

    前言:这段时间还算比较空闲,我准备把过去做过的有些形形色色,甚至有些奇怪的研究总结一下,也许刚好有人用的着也不一定,不枉为之抓耳挠腮的时光和浪费的电力.以前有个客户提出要在RCP程序中添加一个bann ...

  6. 在Spring MVC Web应用程序中添加社交登录:集成测试

    我已经写了关于为使用Spring Social 1.1.0的应用程序编写单元测试的挑战,并为此提供了一种解决方案 . 尽管单元测试很有价值,但是它并不能真正告诉我们我们的应用程序是否正常运行. 这就是 ...

  7. 在Spring MVC Web应用程序中添加社交登录:单元测试

    Spring Social 1.0具有spring-social-test模块,该模块为测试Connect实现和API绑定提供支持. 该模块已从Spring Social 1.1.0中删除,并由 Sp ...

  8. MFC对话框程序中添加工具栏及工具栏上的Button响应UPDATE_COMMAND_UI消息

    对话框中添加工具栏及工具栏上的Button响应UPDATE_COMMAND_UI消息 在对话框程序中添加工具栏其实很简单,网上能找到很多的例子.一般的步骤就是:1.在资源中添加工 具栏资源:2.在对话 ...

  9. 对类HelloWorld程序中添加一个MessageBox弹窗

    对类HelloWorld程序中添加一个MessageBox弹窗 分析: 任一程序运行的时候都会加载kernel32.dll的,但MessageBoxA()这个API却是在user32.dll中的.所以 ...

最新文章

  1. linux检查是否有D进程,Linux内核调试技术——进程D状态死锁检测
  2. php 接收 oc 图片上传,php yii2接口中图片上传
  3. 对于58同城自动登陆的补充【主要是代码】
  4. [28期] lamp兄弟连28期学员手册,请大家务必看一下
  5. 清除重复记录只保留一条
  6. 10分钟教会你Apache Shiro
  7. Java Stream flatMap()
  8. VS2022编译项目出现““csc.exe”已退出,代码为 -1073741819”的错误解决办法
  9. Hibernate中的HQL语言
  10. laravel mysql 悲观锁_Laravel中悲观锁 乐观锁的使用
  11. 关于软件开发的那些事(三):聊聊软件项目管理及成本核算
  12. iOS面试题:Socket原理
  13. ad中那个快捷键是重复上一部_7个高手常用的快捷键,你应该收藏!
  14. JAVA代码实现计算器功能
  15. php strict warning,PHP Warning: Unsupported declare 'strict_types' in ...
  16. 输入框添加Emoje表情demo
  17. java生成二维码,全过程,不要积分
  18. ab测试工具 linux,超实用压力测试工具-ab工具
  19. 百科:产品生命周期理论
  20. 计算机终端通讯380023,华为发布首款5G手机Mate20X,通讯服务商标注册属于第几类?...

热门文章

  1. Android备份到电脑,用 TWRP「一键 Ghost」你的 Android 手机,还能备份到电脑
  2. widget中文技术文档
  3. Anlin-chat多功能聊天室php源码下载,极速安装
  4. 硬盘变成RAW 修复
  5. 如何使用ReadProcessMemory读取多重指针
  6. linux如何启动一个进程而不阻塞,当你在 Linux 上启动一个进程时会发生什么? | Linux 中国...
  7. html上上上级目录,html如何表示上级目录
  8. python 代码转程序_如何用pyinstaller把自己编写的python源代码转换成可执行程序?...
  9. javax.net.ssl.SSLHandshakeException: Unacceptable certificate: CN=GeoTrust SSL C
  10. Java利用Ant包进行解压缩文件