windows核心编程第一章:ErrorShow.cpp
windows核心编程第一章:ErrorShow.cpp
前言
本章对错误信息的处理
DWORD GetLastError();
VOID SetLastError(DWORD dwErrCode):
如果我在自己写的程序中检测到一个错误,我可能希望向用户显示文本描述,而不是显示个干巴巴的错误编号。Windows提供了一个函数,可以将错误代码转换为相应的文本描述此函数名为FormatMessage,如下所示:
```cpp
DWORD FormatMessage
(
DWORD dwFlags,
LPCVOID pSource
DWORD dwMessageld
DWORD dwLanguageId
PTSTR pszBuffer.
DWORD nSize
va list *Arguments
)
FormatMessage的功能实际相当丰富,为了构造要向用户显示的字符串,它是首选的一种方式。之所以说它好用,一个原因是它能轻松地支持多种语言(译注:这里的语言是自然语言,比如汉语、英语等等,而不是计算机编程语言)。它能获取一个语言标识符作为参数,并返回那种语言的文本。当然,你首先必须翻译好字符串,并将翻译好的消息表(message table)资源嵌入自己的.exe 或 DLL 模块中。但在此之后,这个函数就能自动选择正确的字符串。ErrorShow 示例程序(参见后文)演示了如何调用这个函数将Microsoft 定义的错误代码编号转换为相应的文本描述。
自定义错误信息
定义的时候需要符合相关的规定,规定如下
ErrorShow.cpp
/******************************************************************************
01_ErrorShow.cpp
windows核心编程(2024)
windoesx.h头文件
展示了如何获取错误代码的文本描述的方法
(c)by zhangYongJiang
******************************************************************************/
#include "..\CommonFiles\CmnHdr.h" /* 编译配置头文件 */
#include <Windowsx.h> //消息处理宏
#include <tchar.h> //通用类型
#include <winerror.h> //错误代码定义文件
#include "Resource.h"
///
//自定义消息
#define ESM_POKECODEANDLOOKUP (WM_USER + 100)
//const TCHAR g_szAppName[] = TEXT("Error Show");
///
INT_PTR WINAPI Dlg_Proc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam);
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
///
//增加一个函数入口
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {
HWND hwnd = FindWindow(TEXT("#32770"), TEXT("Error Show"));
//预防多开的代码
if (IsWindow(hwnd)) {
// An instance is already running, activate it and send it the new #
//如果在运行,就激活并发送自定义的消息
SendMessage(hwnd, ESM_POKECODEANDLOOKUP, _ttoi(pszCmdLine), 0);
}
else {
DialogBoxParam(hinstExe, MAKEINTRESOURCE(IDD_ERRORSHOW),
NULL, Dlg_Proc, _ttoi(pszCmdLine));
}
return(0);
}
///
INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
//定义消息处理函数(宏)
chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
case ESM_POKECODEANDLOOKUP:
SetDlgItemInt(hwnd, IDC_ERRORCODE, (UINT)wParam, FALSE);
FORWARD_WM_COMMAND(hwnd, IDOK, GetDlgItem(hwnd, IDOK), BN_CLICKED,
PostMessage);//获取控件消息,送入消息队列中去
SetForegroundWindow(hwnd);//将创建指定窗口的现场带到前台并激活窗口
break;
}
return(FALSE);
}
//查阅windowsx.h定义FORWARD_WM_INITDIALOG
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {
chSETDLGICONS(hwnd, IDI_ERRORSHOW);//添加图标
// Don't accept error codes more than 5 digits long
Edit_LimitText(GetDlgItem(hwnd, IDC_ERRORCODE), 5);//显示可以输入到编辑器中的数字长度
//查看命令行传递的错误码
// Look up the command-line passed error number
SendMessage(hwnd, ESM_POKECODEANDLOOKUP, lParam, 0);
return(TRUE);
}
///
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {
switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
break;
case IDC_ALWAYSONTOP:
//将窗口设置为最顶层
SetWindowPos(hwnd, IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP)
? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
break;
case IDC_ERRORCODE:
//启用或禁用窗口或空间的鼠标和键盘输入
EnableWindow(GetDlgItem(hwnd, IDOK), Edit_GetTextLength(hwndCtl) > 0);
break;
case IDOK:
// Get the error code
//获取错误代码
DWORD dwError = GetDlgItemInt(hwnd, IDC_ERRORCODE, NULL, FALSE);
HLOCAL hlocal = NULL; // Buffer that gets the error message string
//使用错误的系统语言环境,参数系统默认的语言
// Use the default system locale since we look for Windows messages.
// Note: this MAKELANGID combination has 0 as value
//注意:这个MAKELANGID组合的置为0
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
//获取错误代码的文本描述,返回存储在输出缓冲区中的TCHAR数
// Get the error code's textual description
BOOL fOk = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwError, systemLocale,
(PTSTR)&hlocal, 0, NULL);
if (!fOk) {
//是否网络相关的错误
// Is it a network-related error?
HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL,
DONT_RESOLVE_DLL_REFERENCES);
if (hDll != NULL) {
fOk = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
hDll, dwError, systemLocale,
(PTSTR)&hlocal, 0, NULL);
FreeLibrary(hDll);
}
}
if (fOk && (hlocal != NULL)) {
//显示错误信息
SetDlgItemText(hwnd, IDC_ERRORTEXT, (PCTSTR)LocalLock(hlocal));
LocalFree(hlocal);
}
else {
SetDlgItemText(hwnd, IDC_ERRORTEXT,
TEXT("No text found for this error number."));
}
break;
}
}
End of File //