栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Win32程序添加控制台日志输出以及卡死问题的解决

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Win32程序添加控制台日志输出以及卡死问题的解决

在使用c/c++学习Win32编程的过程中,有时候需要对程序运行情况进行观察与调试。使用传统的控制台进行输出日志就是很方便的一种方法。下面给出添加日志控制台的一个函数。
输入参数hWnd为窗口句柄,用来生成消息框,作为消息框的所有者窗口的句柄。

BOOL addConsole(HWND hWnd) {
	HANDLE hStdin;
	DWORD mode;
	
	if (AllocConsole() == 0) {
		MessageBox(hWnd, _T("AllocConsole failed!"), NULL, MB_OK);
		return false;
	}
	hStdin = GetStdHandle(STD_INPUT_HANDLE);
	GetConsoleMode(hStdin, &mode);
	mode &= ~ENABLE_QUICK_EDIT_MODE;
	mode &= ~ENABLE_INSERT_MODE;
	mode &= ~ENABLE_MOUSE_INPUT;
	SetConsoleMode(hStdin, mode);

	if (freopen("conout$", "w", stdout) == NULL) {
		MessageBox(hWnd, _T("freopen stdout failed!"), NULL, MB_OK);
		return false;
	}
	if (freopen("conin$", "r", stdin) == NULL) {
		MessageBox(hWnd, _T("freopen stdin failed!"), NULL, MB_OK);
		return false;
	}
	if (freopen("conerr$", "w", stderr) == NULL) {
		MessageBox(hWnd, _T("freopen stderr failed!"), NULL, MB_OK);
		return false;
	}

	printf("添加控制台成功!n");
	return true;
}
  • AllocConsole()函数
    为当前线程分配一个控制台窗口,一般来说一个线程只能分配一个控制台窗口,多次分配会失败并返回0。windows系统用特殊的文件名:conout$,conin$ 以及conerr$ 来标识控制台输入、输出以及错误输出缓冲区。当使用AllocConsole()分配成功(或线程成功挂载到一个控制台)时,上述三个描述符变得有效,否则使用这些描述符会使程序报错。
  • freopen()函数
    c语言标准库函数,用来重定向输入输出流,包含于stdio.h头文件之中。当我们使用printf()与scanf()函数的时候,会默认调用stdout与stdin的输入输出流。如果我们创建的是控制台项目,那么stdout与stdin会默认使用控制台作为输入输出文件。但是Win32 GUI程序初始不带有控制台窗口,因此在分配了控制台后如果要使用它,还需要将stdin与stdout重定向到指定的控制台窗口。
    第一个参数是重定向到的文件。如果重定向到硬盘内的路径,则会打开(或创建)这个文件,用以输出或输入数据。特殊地,conout$,conin$ 以及conerr$ 文件名指示输出输入到控制台中。
  • 控制台卡死
    在使用控制台的时候,如果鼠标选中或尝试输入内容,线程会被堵塞导致程序卡死,只有输入回车将控制台缓冲清空时程序才会恢复正常。这个时候可以右键控制台窗口的标题栏,设置属性,将快速编辑模式和插入模式移除。更方便地,可以使用SetConsoleMode()函数移除这些模式。这个时候,控制台充当了仅可读临时日志的功能,而且不能选中文字内容。

本文参考了@小七爱淘气的文章。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1033455.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号