函数的返回值和错误码对判断函数的执行结果和失败原因有重要的价值。每个使用Windows API进行C++编程的老铁们都自己封装过FormatMessage这个函数,我用了快一年才想到自己去封装它以提高便携性。
函数MyFormatMessage打印函数执行状态及对应的提示信息。
语法
DWORD
MyFormatMessage(
TCHAR *funcName,
DWORD errCode = 0
)
{
LPVOID lpMsgBuf;
TCHAR lpDisplayBuf[1024];
DWORD dw = errCode;
if (0 == dw) {
dw = GetLastError();
}
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);
StringCchPrintf(lpDisplayBuf, 1024, _T("Function: %s Failed with %#x: %s"), funcName, dw, lpMsgBuf);
_tprintf(_T("%s"), lpDisplayBuf);
LocalFree(lpMsgBuf);
return dw;
}
参数
funcName 与函数执行无关,仅拼接在打印信息中以指示错误码发生在哪个函数的调用中
errCode 不传入该参数时,函数将使用自己调用GetLastError()取得的错误码,否则使用传入的错误码
返回值
函数的errCode参数传0时,返回函数自身调用GetLastError()取得的错误码,或者返回由errCode传入的非0错误码(将错误码再次传出的目的是为了复用)
测试用例
#include "stdafx.h"
#include <Windows.h>
#include <strsafe.h>
#include <locale.h>
#include <datetimeapi.h>
#include <shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
/*
* 这里为了节约篇幅折叠了MyFormatMessage函数的定义
*/
int main()
{
setlocale(LC_CTYPE, "chs");//设置中文语境
//判断文件是否存在
int errCode = PathFileExists(_T("C:\\Windows\\notepad.exe"));
MyFormatMessage(_T("PathFileExists"), errCode);
if (FALSE ==PathFileExists(_T("isFileExist.txt")))
{
MyFormatMessage(_T("PathFileExists"));
}
return 0;
}
结果
分析
调用该函数前应该使用 setlocale(LC_CTYPE, “chs”) 设置好语言环境,不然中文无法正确显示。
第一次调用 PathFileExists 的打印结果可能会令人疑惑,通常情况下这一次的调用都是成功的(除非你手贱删掉了该路径下的notepad.exe文件),但是errCode的值却是 1,这是为甚么呢?
其实是我先入为主地认为 PathFileExists 在成功是返回 0,而在出错时返回错误码,但是光标放到该函数上按F1来打开MSDN查看帮助手册可以知道,该函数在成功是返回 True(即1),在出错时返回 0,原因就出在这里。