注:源码为学习《Windows核心编程》的一些尝试,非原创。若能有助于一二访客,幸甚。
/*******************************************************************************
* File: ErrorShow.cpp
* Author: [email protected]
* Time: 2013-04-15
* 描述: 修改试验原书同名程序
*******************************************************************************/
#include
#include
#include
#include "Resource.h"
/* SetDlgMsgResult This macro maps to the SetWindowLong function.
* SetWindowLong changes an attribute of the specified window, also sets a 32-bit (LONG)
* value at the specified offset into the extra window memory of a window.
* The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog
* boxes because DlgProc returns a BOOL instead of an LRESULT (likeWndProcs).
* This chHANDLE_DLGMSG macro corrects the problem.
*/
#define chHANDLE_DLGMSG(hWnd, message, fn) \
case (message): return (SetDlgMsgResult(hWnd, uMsg, \
HANDLE_##message((hWnd), (wParam), (lParam), (fn))))
// Sets the dialog box icons
inline void chSETDLGICONS(HWND hWnd, int idi)
{
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)
LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi)));
SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)
LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi)));
}
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
chSETDLGICONS(hwnd, IDI_ERRORSHOW);
return(TRUE);
}
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
break;
}
}
// 对话框过程函数
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);
}
return FALSE;
}
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int)
{
DialogBoxParam(hinstExe, MAKEINTRESOURCE(IDD_ERRORSHOW), NULL, Dlg_Proc, _ttoi(pszCmdLine));
return 0;
}
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);
return(TRUE);
}
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
break;
case IDOK:
// Get the error code
DWORD dwError = GetDlgItemInt(hwnd, IDC_ERRORCODE, NULL, FALSE);
// 定义缓存存储错误码转换成的文本
TCHAR chErrorText[6];
_itot_s(dwError, chErrorText, 6, 10);
// 显示文本
SetDlgItemText(hwnd, IDC_ERRORTEXT, chErrorText);
break;
}
}
Handle to a local memory block. This type is declared in WinDef.h as follows:
typedef HANDLE HLOCAL;
FormatMessage:
This function formats a message string.
DWORD FormatMessage(
DWORD dwFlags, LPCVOID
LPCVOID lpSource, DWORD
DWORD dwMessageId, DWORD
DWORD dwLanguageId, LPTSTR
LPTSTR lpBuffer, DWORD
DWORD nSize, va_list*
va_list* Arguments
);
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
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
// LANG_NEUTRAL, SUBLANG_NEUTRAL为两个特定的常量,用来生成语言标识符
// 这两个常量联合到一起讲生成一个0值,即操作系统的默认语言
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
// FORMAT_MESSAGE_FROM_SYSTEM告诉FormatMessage我们希望获得一个系统定义的错误码对应的字符串
// FORMAT_MESSAGE_ALLOCATE_BUFFER要求该函数分配一块足以容纳错误文本的内存,该块内存在hlocal中返回
// FORMAT_MESSAGE_IGNORE_INSERTS允许我们获得含有%占位符的消息,以提供更多上下文相关信息
// 第二个参数Pointer to the location of the message definition.
// 第三个参数指出想要查找的错误代码
// 第四个参数指出要用什么语言来显示文本描述
// 第五个参数Pointer to a buffer for the formatted (and null-terminated) message
// 第六个参数If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies
// the maximum number of characters that can be stored in the output buffer.
// If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies the minimum number of
// bytes or characters to allocate for an output buffer.
// 第七个参数Pointer to an array of 32-bit values that are used as insert values in the formatted message.
// A %1 in the format string indicates the first value in the Arguments array;
// a %2 indicates the second argument; and so on.
BOOL fOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwError, systemLocale, (PTSTR)&hlocal, 0, NULL);
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;
}
}
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
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
// LANG_NEUTRAL, SUBLANG_NEUTRAL为两个特定的常量,用来生成语言标识符
// 这两个常量联合到一起讲生成一个0值,即操作系统的默认语言
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
// FORMAT_MESSAGE_FROM_SYSTEM告诉FormatMessage我们希望获得一个系统定义的错误码对应的字符串
// FORMAT_MESSAGE_ALLOCATE_BUFFER要求该函数分配一块足以容纳错误文本的内存,该块内存在hlocal中返回
// FORMAT_MESSAGE_IGNORE_INSERTS允许我们获得含有%占位符的消息,以提供更多上下文相关信息
// 第二个参数Pointer to the location of the message definition.
// 第三个参数指出想要查找的错误代码
// 第四个参数指出要用什么语言来显示文本描述
// 第五个参数Pointer to a buffer for the formatted (and null-terminated) message
// 第六个参数If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies
// the maximum number of characters that can be stored in the output buffer.
// If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies the minimum number of
// bytes or characters to allocate for an output buffer.
// 第七个参数Pointer to an array of 32-bit values that are used as insert values in the formatted message.
// A %1 in the format string indicates the first value in the Arguments array;
// a %2 indicates the second argument; and so on.
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;
}
}
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
break;
case IDC_ERRORCODE:
EnableWindow(GetDlgItem(hwnd, IDOK), Edit_GetTextLength(hwndCtl) > 0);
break;
#define ESM_POKECODEANDLOOKUP (WM_USER + 100)
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);
}
// 对话框过程函数
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);
// This function puts the thread that created the specified window into the foreground and activates the window.
SetForegroundWindow(hwnd);
break;
}
return FALSE;
}
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
break;
case IDC_ERRORCODE:
EnableWindow(GetDlgItem(hwnd, IDOK), Edit_GetTextLength(hwndCtl) > 0);
break;
case IDC_ONTOP:
//Sets the size, position, and Z order of the control site.
SetWindowPos(hwnd, IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP) ? HWND_TOPMOST : HWND_NOTOPMOST,
0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
break;
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int)
{
HWND hwnd = FindWindow(TEXT("#32770"), TEXT("错误代码文本描述"));
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;
}
The FindWindow function retrieves a handle to the top-level window whose class name and window name match the specified strings. This function does not search child windows. This function does not perform a case-sensitive search.
/*******************************************************************************
* File: ErrorShow.cpp
* Author: [email protected]
* Time: 2013-04-15
* 描述: 修改试验原书同名程序
*******************************************************************************/
#include
#include
#include
#include "Resource.h"
// Always compiler using Unicode.
#ifndef UNICODE
#define UNICODE
#endif
#define ESM_POKECODEANDLOOKUP (WM_USER + 100)
/* SetDlgMsgResult This macro maps to the SetWindowLong function.
* SetWindowLong changes an attribute of the specified window, also sets a 32-bit (LONG)
* value at the specified offset into the extra window memory of a window.
* The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog
* boxes because DlgProc returns a BOOL instead of an LRESULT (likeWndProcs).
* This chHANDLE_DLGMSG macro corrects the problem.
*/
#define chHANDLE_DLGMSG(hWnd, message, fn) \
case (message): return (SetDlgMsgResult(hWnd, uMsg, \
HANDLE_##message((hWnd), (wParam), (lParam), (fn))))
// Sets the dialog box icons
inline void chSETDLGICONS(HWND hWnd, int idi)
{
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)
LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi)));
SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)
LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi)));
}
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_ERRORCODE:
EnableWindow(GetDlgItem(hwnd, IDOK), Edit_GetTextLength(hwndCtl) > 0);
break;
case IDC_ONTOP:
//Sets the size, position, and Z order of the control site.
SetWindowPos(hwnd, IsDlgButtonChecked(hwnd, IDC_ONTOP) ? HWND_TOPMOST : HWND_NOTOPMOST,
0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
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
// LANG_NEUTRAL, SUBLANG_NEUTRAL为两个特定的常量,用来生成语言标识符
// 这两个常量联合到一起讲生成一个0值,即操作系统的默认语言
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
// FORMAT_MESSAGE_FROM_SYSTEM告诉FormatMessage我们希望获得一个系统定义的错误码对应的字符串
// FORMAT_MESSAGE_ALLOCATE_BUFFER要求该函数分配一块足以容纳错误文本的内存,该块内存在hlocal中返回
// FORMAT_MESSAGE_IGNORE_INSERTS允许我们获得含有%占位符的消息,以提供更多上下文相关信息
// 第二个参数Pointer to the location of the message definition.
// 第三个参数指出想要查找的错误代码
// 第四个参数指出要用什么语言来显示文本描述
// 第五个参数Pointer to a buffer for the formatted (and null-terminated) message
// 第六个参数If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies
// the maximum number of characters that can be stored in the output buffer.
// If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies the minimum number of
// bytes or characters to allocate for an output buffer.
// 第七个参数Pointer to an array of 32-bit values that are used as insert values in the formatted message.
// A %1 in the format string indicates the first value in the Arguments array;
// a %2 indicates the second argument; and so on.
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("没有发现该错误码的消息文本"));
}
break;
}
}
// 对话框过程函数
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);
// This function puts the thread that created the specified window into the foreground and activates the window.
SetForegroundWindow(hwnd);
break;
}
return FALSE;
}
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int)
{
HWND hwnd = FindWindow(TEXT("#32770"), TEXT("错误代码文本描述"));
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;
}