MFC窗体程序中调用控制台输出信息

最近运行一个MFC对话框窗体程序,编译环境是VS2010,由于需要长时间测试,想像Tomcat那样打开一个控制台输出日志。查看相关资料后,发现其实也不难的,现把调用步骤总结一下。

  1. 打开控制台输出
    在程序的InitInstance()函数中添加如下代码:
#ifdef _DEBUG
	AllocConsole();
#endif

因为是调试时需要,所以这里加上_DEBUG宏,有初始化就得有关闭,善始善终嘛。在ExitInstance()函数中添加:

#ifdef _DEBUG
	FreeConsole();
#endif
	...
	return CWinApp::ExitInstance();

这样运行程序,打开对话框同时也打开了控制台终端:
打开终端
那么如何向终端输出内容呢,需要调用WriteConsole函数:

HANDLE g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
char out[20] = "测试打印内容\n";
WriteConsole(g_hOutput, out, strlen(out), NULL, NULL);
CloseHandle(g_hOutput);

打印测试内容
我这里要打印16进制的密钥,需要把字符串转16进制输出:

char buff[17];
char out[50] = "16进制:";
 int len = 8;

HANDLE g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
DES((unsigned char*)key, source, (unsigned char*)buff);

for (int i=0; i<len; i++) {
	 sprintf(out,"%s%02x", out, (unsigned char)buff[i]);
}
WriteConsole(g_hOutput, out, strlen(out), NULL, NULL);
CloseHandle(g_hOutput);

显示结果如下:
打印16进制内容
这里要注意下CloseHandle函数要在最后调用,如果打印“测试打印内容”后调用,那后面的16进制内容就输出不了了。

  1. 使用printf函数输出
    使用C的程序员都习惯用printf函数,而且格式化输出很方便,这里要想使用printf函数输出,在初始化的时候就麻烦一些了,要进行输出重定向,InitInstance()函数中修改一下:
#ifdef _DEBUG
	//AllocConsole();
	InitConsoleWindow();
#endif

InitConsoleWindow内容如下:

static int fHandle = -1;
void CDES加密测试App::InitConsoleWindow()
{
	FILE *fp;
	AllocConsole();
	fHandle = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
	if (fHandle > 0)
	{
		fp = _fdopen(fHandle, "w");
		*stdout = *fp;
		setvbuf(stdout, NULL, _IONBF, 0);
	}
}

ExitInstance()函数也修改下:

#ifdef _DEBUG
	if (fHandle > 0)
		_close(fHandle);
	FreeConsole();
#endif
	...
	return CWinApp::ExitInstance();

还要添加上头文件:

#include <io.h>
#include <fcntl.h>

接下来就可以测试使用printf函数了,在使用的地方别忘添加上头文件:

#include <stdio.h> 
...
char buff[17];
char out[50] = "16进制:";
int len = 8;

//HANDLE g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
DES((unsigned char*)key, source, (unsigned char*)buff);

for (int i=0; i<len; i++) {
	sprintf(out,"%s%02x", out, (unsigned char)buff[i]);
}
//WriteConsole(g_hOutput, out, strlen(out), NULL, NULL);
//CloseHandle(g_hOutput);
printf("%s\n", out);

运行结果跟使用WriteConsole输出是一样的,这下好用多了。

  1. 关闭问题解决
    无意间先关闭了控制台终端,程序就发生异常了:
    发生异常
    看来得监听控制台的事件信息,在对话框的WriteConsole函数中添加事件回调函数:
if (::SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE) == FALSE)
{
	return FALSE;
}

ConsoleHandler用来处理事件内容,代码如下:

BOOL WINAPI ConsoleHandler(DWORD CEvent)
{
	// 处理对应的CTRL_事件
	switch (CEvent) 
	{
	case CTRL_C_EVENT:
	case CTRL_BREAK_EVENT:
	case CTRL_CLOSE_EVENT:
	case CTRL_LOGOFF_EVENT:
	case CTRL_SHUTDOWN_EVENT:
		break;

	default:
		return FALSE;
	} 
	return TRUE;
}

该函数返回TRUE时程序退出,这里只是简单测试,如果有需要在关闭前处理的内容请编写相应代码。这次再关闭控制台窗口时,程序就不报异常了。

猜你喜欢

转载自blog.csdn.net/xinxin_2011/article/details/84890931
今日推荐