【编程基础】Win32窗口下调试输出

在Win32的console下,我们可以用基本的printf,来输出调试信息,这个很方便。不过要是在非console的窗口模式应用程序里面,就不能使用printf来输出,很多朋友遇到过这个问题,非常不方面。

其实在窗口模式下,windows提供了一个函数OutputDebugString,用于向开发环境的debug窗口输出信息,结合C语言的可变参数,就能实现跟printf一样的功能了,下面就是一个简单的采用OutputDebugString封装的调试输出函数,用法跟printf一样:

#include <windows.h> #include <stdarg.h> 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); }

另外,在编写windows应用程序时,不管是console还是窗口程序,都会经常使用GetLastError函数获取出错信息,但是这个获取到的仅仅是一个错误号,需要查询MSDN才能得知是什么意思?这样相当不方便。

既然问题抛出来了,读者大概猜到有解决方案了?没错,我们可以通过FormatMessage函数,将错误号转化为相应的错误描述,这个函数对于寻找错误原因非常有用。在console下,用这个函数格式化后直接用printf输出,在窗口程序下结合上面的OutputDebugString函数,也能方面的知道错误描述了,完整的函数如下:

#include <windows.h> #include <strsafe.h> void PrintError(DWORD dwErrcode) { LPVOID lpMsgBuf; LPVOID lpDisplayBuf;

FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwErrcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );

lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf)+40)*sizeof(TCHAR)); StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf), TEXT("err code: %d, %s"), dwErrcode, lpMsgBuf); OutputDebugString((LPCWSTR)lpDisplayBuf);

LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); }

如果你是在Windows平台下编写程序,以上部分就可以直接使用了,非常简单方便。

原文发布于微信公众号 - 程序员互动联盟(coder_online)

原文发表时间:2015-07-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Keegan小钢

Android项目重构之路:实现篇(一)

前两篇文章《Android项目重构之路:架构篇》和《Android项目重构之路:界面篇》已经讲了我的项目开始搭建时的架构设计和界面设计,这篇就讲讲具体怎么实现的...

1393
来自专栏Hongten

spring开发_Spring+Struts2

http://www.cnblogs.com/hongten/gallery/image/112920.html

952
来自专栏友弟技术工作室

python-MySQLdb的二三事

追寻 介绍 mysqldb是python操作mysql数据库的一个库.mysql的几乎所有的操作都可以实现,另外,mysqldb的一些比较的option让数据...

1.2K12
来自专栏林德熙的博客

win10 uwp 依赖属性

本文告诉大家如何使用依赖属性,包括在 UWP 和 WPF 如何使用。 本文不会告诉大家依赖属性的好处,只是简单告诉大家如何使用。

1012
来自专栏Golang语言社区

【投稿专区】crc校验码的计算

在Modbus或环保212协议中,数据的校检码(CRC-16)由两个字节16位构成。而一般电气、自动化仪表的crc16校验,多项式码选用16进制A001。 CR...

4638
来自专栏岑玉海

hbase源码系列(十二)Get、Scan在服务端是如何处理?

继上一篇讲了Put和Delete之后,这一篇我们讲Get和Scan, 因为我发现这两个操作几乎是一样的过程,就像之前的Put和Delete一样,上一篇我本来只打...

56010
来自专栏JMCui

再学习之MyBatis.

一、框架基本介绍 1、概念 支持普通SQL查询、存储过程和高级映射,简化和实现了Java 数据持久化层的的开源框架,主要流行的原因在于他的简单性和易使用性。 2...

4908
来自专栏Keegan小钢

Android项目重构之路:实现篇(二)

核心层处于接口层和界面层之间,向下调用Api,向上提供Action,它的核心任务就是处理复杂的业务逻辑。先看看我对Action的定义:

1302
来自专栏python学习指南

Elasticsearch多索引

 在Elasticsearch中,一般的查询都支持多索引。 只有文档API或者别名API等不支持多索引操作,因此本篇就翻译一下多索引相关的内容。 首先,先...

5466
来自专栏二进制文集

Netty 之入门应用

系列文章:http://www.jianshu.com/p/594441fb9c9e

1713

扫码关注云+社区

领取腾讯云代金券