前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【答疑释惑第三十六讲】Windows下如何调试?

【答疑释惑第三十六讲】Windows下如何调试?

作者头像
程序员互动联盟
发布2018-03-15 16:57:10
8650
发布2018-03-15 16:57:10
举报
疑惑一

Windows窗口程序到底能不能用printf?

很多小伙伴在控制台下写程序时,要打印或者调试很方便,用printf就可以直接打印输出,方便看结果,但是在编写窗口程序时,由于窗口程序的子系统是Windows,而不是控制台的子系统console,因此非字符模式是不能用printf来输出的,那么到底在窗口模式下能不能用printf呢?

答案是肯定的,但是需要我们自己创建一个控制台终端,可以用Windows提供的API函数AllocConsole来创建一个控制台,以后的输出都是在这个控制台里操作。当然只创建了控制台还不行,还得重定向输入、输出和错误输出口,重定向有几种方式:

最简单的就是用freopen函数绑定新的标准输入输出,方法如下: AllocConsole(); freopen("CONIN$", "r", stdin); freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr);

如果只是想把printf的结束输入文件,可以直接把文件句柄赋给标准输入: FILE * fpin = fopen ("c://in.txt" ,"r" ); *stdin = *fpin;

最后一种就比较麻烦,就不多说了,下面的函数实现重定向: void RedirectConsole(void) { DWORD hdl = (DWORD)GetStdHandle(STD_OUTPUT_HANDLE); int hConHandle = _open_osfhandle(hdl, _O_TEXT); _iobuf *fp = _tfdopen(hConHandle, TEXT("w")); *stdout = *fp; setvbuf(stdout, NULL, _IONBF, 0);

输入关键printf获取相关资料,不懂得可以后台继续问。

疑惑二

Windows窗口不用控制台能不能打印调试信息

在窗口程序模式下,要在终端打印只有按上面的方法进行输出,其实只是调试看打印,可以用Windows提供的API函数实现信息打印功能,只要在debug窗口下都可以看到,而不需要像上面那样分配一个控制台窗口。这个API就是OutputDebugString,该函数的参数是一个字符串,他能把一个字符串输出到调试窗口中,可能用的伙伴就说了,只能输入文本串多没意思,要是能想printf那样输出任意类型的格式多好。其实只要我们简单改装一下就能到达跟printf函数一样的结果,下面就是一个改装好的函数参考:

void OutputDbgInfo(const TCHAR *format, ...) { TCHAR szData[512] = {0}; va_list arg; va_start(arg, format); _vsntprintf(szData, sizeof(szData)-1, format, arg); va_end(arg); OutputDebugString(szData); }

大家从函数参数上也能看出来,实际上跟printf参数一样,能实现可变参数的任意格式了。

至于查看窗口,VS就自带debug窗口,有人说要是编译好后脱离了VS环境怎么办?刚才说了,只要是debug窗口就可以,有不是只有VS才带有debug窗口,比如有Dbgview这个小程序(网上可以下载)就可以接收并显示调试信息,你可以启动它来查看。

疑惑三

WM_CLOSE,WM_DESTROY,WM_QUIT有什么区别

WM_CLOSE消息:

该消息是在关闭应用程序窗口时触发,典型的就是当你点击应用程序右上角的叉号时就会走到该消息处,该消息是关闭应用程序时最先接收到,因此这时可以阻止窗口关闭和退出应用程序,还可以用于提示保存、自动保存等操作。如果要退出应用程序,一般会调用DestroyWindow这个函数,Windows默认处理就是直接调用这个函数,该函数在关闭窗口后发送WM_DESTROY消息给应用程序。

WM_DESTROY消息:

该消息接收到时已经将窗口从屏幕上关闭了,视觉上已经看不到窗口,虽然这个时候还能阻止应用程序彻底退出,但是对于一个窗口应用程序在主窗口都已经关闭的情况下再不退出,已经没有实际意义了。一般这个时候主要是卸载一些全局句柄、释放内存和对象等操作。该消息最后一般会调用PostQuitMessage这个函数,该函数简单的投递WM_QUIT消息对消息队列中。

WM_QUIT消息:

GetMessage在获取其他任何消息,返回值都不是0,唯独这个消息,获取该消息后返回0,于是退出消息循环,最终WinMain主线程函数退出,结束程序运行。


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-01-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员互动联盟 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档