原因是该书使用的Platform SDK库比VC6还要新. 解决办法就是将程序中用到的新的API或者宏替换成旧版(VC6使用)的即可... 我试着搞了一下该书中的第一个例子01-ErrorShow,编译出错信息如下: --------------------Configuration: 01 ErrorShow - Win32 Debug-------------------- Compiling... ErrorShow.cpp You are not using the latest Platform SDK header/library files. This may prevent the project from building correctly. g:\cmnhdr.h(212) : error C2065: 'GetWindowLongPtr' : undeclared identifier g:\cmnhdr.h(212) : error C2065: 'GWLP_HINSTANCE' : undeclared identifier g:\01-errorshow\errorshow.cpp(83) : error C2065: 'PCTSTR' : undeclared identifier g:\01-errorshow\errorshow.cpp(83) : error C2146: syntax error : missing ')' before identifier 'LocalLock' g:\01-errorshow\errorshow.cpp(83) : error C2059: syntax error : ')' g:\01-errorshow\errorshow.cpp(125) : error C2664: 'DialogBoxParamA' : cannot convert parameter 4 from 'long (struct HWND__ *,unsigned int,unsigned int,long)' to 'int (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long)' None of the functions with this name in scope match the target type Error executing cl.exe. Creating browse info file...01 ErrorShow.exe - 6 error(s), 0 warning(s) 修改了相应的几个地方后,就可以了,且运行成功 --------------------Configuration: 01 ErrorShow - Win32 Debug-------------------- Compiling... ErrorShow.cpp You are not using the latest Platform SDK header/library files. This may prevent the project from building correctly. Linking... Creating browse info file...01 ErrorShow.exe - 0 error(s), 0 warning(s)下面把修改后的代码贴出来,你可以通过查找JOKE100关键字来找出修改的地方. /****************************************************************************** Module: CmnHdr.h Notices: Copyright (c) 2000 Jeffrey Richter Purpose: Common header file containing handy macros and definitions used throughout all the applications in the book. See Appendix A. ******************************************************************************/ #pragma once // Include this header file once per compilation unit //////////////////////// Windows Version Build Option ///////////////////////// #define _WIN32_WINNT 0x0500 //#define WINVER 0x0500 //////////////////////////// Unicode Build Option ///////////////////////////// // If we are not compiling for an x86 CPU, we always compile using Unicode. #ifndef _M_IX86 #define UNICODE #endif// To compile using Unicode on the x86 CPU, uncomment the line below. //#define UNICODE// When using Unicode Windows functions, use Unicode C-Runtime functions too. #ifdef UNICODE #define _UNICODE #endif ///////////////////////// Include Windows Definitions ///////////////////////// #pragma warning(push, 3) #include <Windows.h> #pragma warning(pop) #pragma warning(push, 4) ///////////// Verify that the proper header files are being used ////////////// #ifndef WT_EXECUTEINPERSISTENTIOTHREAD #pragma message("You are not using the latest Platform SDK header/library ") #pragma message("files. This may prevent the project from building correctly.") #endif ////////////// Allow code to compile cleanly at warning level 4 /////////////// /* nonstandard extension 'single line comment' was used */ #pragma warning(disable:4001)// unreferenced formal parameter #pragma warning(disable:4100)// Note: Creating precompiled header #pragma warning(disable:4699)// function not inlined #pragma warning(disable:4710)// unreferenced inline function has been removed #pragma warning(disable:4514)// assignment operator could not be generated #pragma warning(disable:4512) ///////////////////////// Pragma message helper macro ///////////////////////// /* When the compiler sees a line like this: #pragma chMSG(Fix this later)it outputs a line like this: c:\CD\CmnHdr.h(82):Fix this laterYou can easily jump directly to this line and examine the surrounding code. */#define chSTR2(x) #x #define chSTR(x) chSTR2(x) #define chMSG(desc) message(__FILE__ "(" chSTR(__LINE__) "):" #desc) ////////////////////////////// chINRANGE Macro //////////////////////////////// // This macro returns TRUE if a number is between two others #define chINRANGE(low, Num, High) (((low) <= (Num)) && ((Num) <= (High))) //////////////////////////////// chDIMOF Macro //////////////////////////////// // This macro evaluates to the number of elements in an array. #define chDIMOF(Array) (sizeof(Array) / sizeof(Array[0])) ///////////////////////////// chBEGINTHREADEX Macro /////////////////////////// // This macro function calls the C runtime's _beginthreadex function. // The C runtime library doesn't want to have any reliance on Windows' data // types such as HANDLE. This means that a Windows programmer needs to cast // values when using _beginthreadex. Since this is terribly inconvenient, // I created this macro to perform the casting. typedef unsigned (__stdcall *PTHREAD_START) (void *);#define chBEGINTHREADEX(psa, cbStack, pfnStartAddr, pvParam, fdwCreate, pdwThreadId) ((HANDLE)_beginthreadex( (void *) (psa), (unsigned) (cbStack), (PTHREAD_START) (pfnStartAddr), (void *) (pvParam), (unsigned) (fdwCreate), (unsigned *) (pdwThreadId))) ////////////////// DebugBreak Improvement for x86 platforms /////////////////// #ifdef _X86_ #define DebugBreak() _asm { int 3 } #endif /////////////////////////// Software Exception Macro ////////////////////////// // Useful macro for creating your own software exception codes #define MAKESOFTWAREEXCEPTION(Severity, Facility, Exception) ((DWORD) ( /* Severity code */ (Severity ) | /* MS(0) or Cust(1) */ (1 << 29) | /* Reserved(0) */ (0 << 28) | /* Facility code */ (Facility << 16) | /* Exception code */ (Exception << 0))) /////////////////////////// Quick MessageBox Macro //////////////////////////// inline void chMB(PCSTR s) { char szTMP[128]; GetModuleFileNameA(NULL, szTMP, chDIMOF(szTMP)); MessageBoxA(GetActiveWindow(), s, szTMP, MB_OK); } //////////////////////////// Assert/Verify Macros ///////////////////////////// inline void chFAIL(PSTR szMsg) { chMB(szMsg); DebugBreak(); } // Put up an assertion failure message box. inline void chASSERTFAIL(LPCSTR file, int line, PCSTR expr) { char sz[128]; wsprintfA(sz, "File %s, line %d : %s", file, line, expr); chFAIL(sz); } // Put up a message box if an assertion fails in a debug build. #ifdef _DEBUG #define chASSERT(x) if (!(x)) chASSERTFAIL(__FILE__, __LINE__, #x) #else #define chASSERT(x) #endif // Assert in debug builds, but don't remove the code in retail builds. #ifdef _DEBUG #define chVERIFY(x) chASSERT(x) #else #define chVERIFY(x) (x) #endif /////////////////////////// chHANDLE_DLGMSG Macro ///////////////////////////// // The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog // boxes because DlgProc return a BOOL instead of an LRESULT (like // WndProcs). 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)))) //////////////////////// Dialog Box Icon Setting Macro //////////////////////// // Sets the dialog box icons inline void chSETDLGICONS(HWND hwnd, int idi) { SendMessage(hwnd, WM_SETICON, TRUE, (LPARAM) LoadIcon((HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), MAKEINTRESOURCE(idi))); SendMessage(hwnd, WM_SETICON, FALSE, (LPARAM) LoadIcon((HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), MAKEINTRESOURCE(idi))); // [原来的代码,REMARKED BY JOKE100] /* inline void chSETDLGICONS(HWND hwnd, int idi) { SendMessage(hwnd, WM_SETICON, TRUE, (LPARAM) LoadIcon((HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi))); SendMessage(hwnd, WM_SETICON, FALSE, (LPARAM) LoadIcon((HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi))); */ // [END BY JOKE100] } /////////////////////////// OS Version Check Macros /////////////////////////// inline void chWindows9xNotAllowed() { OSVERSIONINFO vi = { sizeof(vi) }; GetVersionEx(&vi); if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { chMB("This application requires features not present in Windows 9x."); ExitProcess(0); } } inline void chWindows2000Required() { OSVERSIONINFO vi = { sizeof(vi) }; GetVersionEx(&vi); if ((vi.dwPlatformId != VER_PLATFORM_WIN32_NT) && (vi.dwMajorVersion < 5)) { chMB("This application requires features present in Windows 2000."); ExitProcess(0); } } ///////////////////////////// UNICODE Check Macro ///////////////////////////// // Since Windows 98 does not support Unicode, issue an error and terminate // the process if this is a native Unicode build running on Windows 98// This is accomplished by creating a global C++ object. Its constructor is // executed before WinMain.#ifdef UNICODEclass CUnicodeSupported { public: CUnicodeSupported() { if (GetWindowsDirectoryW(NULL, 0) <= 0) { chMB("This application requires an OS that supports Unicode."); ExitProcess(0); } } };// "static" stops the linker from complaining that multiple instances of the // object exist when a single project contains multiple source files. static CUnicodeSupported g_UnicodeSupported;#endif /////////////////////////// Force Windows subsystem /////////////////////////// #pragma comment(linker, "/subsystem:Windows") ///////////////////////////////// End of File //////////////////////////////////****************************************************************************** Module: ErrorShow.cpp Notices: Copyright (c) 2000 Jeffrey Richter ******************************************************************************/ //#include "..\CmnHdr.h" /* See Appendix A. */ #include "CmnHdr.h" /* See Appendix A. */ #include <Windowsx.h> #include <tchar.h> #include "Resource.h" /////////////////////////////////////////////////////////////////////////////// #define ESM_POKECODEANDLOOKUP (WM_USER + 100) const TCHAR g_szAppName[] = TEXT("Error Show"); /////////////////////////////////////////////////////////////////////////////// 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 // Get the error code's textual description BOOL fOk = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (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) { FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM, hDll, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (PTSTR) &hlocal, 0, NULL); FreeLibrary(hDll); } } if (hlocal != NULL) { // SetDlgItemText(hwnd, IDC_ERRORTEXT, (PCTSTR) LocalLock(hlocal)); SetDlgItemText(hwnd, IDC_ERRORTEXT, (LPCTSTR) LocalLock(hlocal)); LocalFree(hlocal); } else { SetDlgItemText(hwnd, IDC_ERRORTEXT, TEXT("Error number not found.")); } 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); SetForegroundWindow(hwnd); break; } return(FALSE); } /////////////////////////////////////////////////////////////////////////////// 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), // [REVISED BY JOKE100] // NULL, Dlg_Proc, _ttoi(pszCmdLine)); NULL, (DLGPROC)Dlg_Proc, _ttoi(pszCmdLine)); // [END BY JOKE100] } return(0); } //////////////////////////////// End of File //////////////////////////////////
补充:我经过以上修改后,程序可以运行,但是并不能正确显示错误代码的文本描述, 经查看 FormatMessage 函数的定义,发现参数 dwLanguageId 的说明如下: Specifies the 32-bit language identifier for the requested message.This parameter is ignored if dwFlags includes FORMAT_MESSAGE_FROM_STRING. If you pass a specific LANGID in this parameter, FormatMessage will return a message for that LANGID only.If the function cannot find a message for that LANGID, it returns ERROR_RESOURCE_LANG_NOT_FOUND. If you pass in zero, FormatMessage looks for a message for LANGIDs in the following order: 1.Language neutral 2.Thread LANGID, based on the thread's locale value 3.User default LANGID, based on the user's default locale value 4.System default LANGID, based on the system default locale value 5.US English If FormatMessage doesn't find a message for any of the preceding LANGIDs, it returns any language message string that is present. If that fails, it returns ERROR_RESOURCE_LANG_NOT_FOUND. 该参数为要求的消息指定32位语言识别符。将其改为'0'编译后运行程序,效果和 Visual Studio自带的Error Lookup运行结果一样。系统配置:Win98+VC++6.0(均为简体中文版)
解决办法就是将程序中用到的新的API或者宏替换成旧版(VC6使用)的即可...
我试着搞了一下该书中的第一个例子01-ErrorShow,编译出错信息如下:
--------------------Configuration: 01 ErrorShow - Win32 Debug--------------------
Compiling...
ErrorShow.cpp
You are not using the latest Platform SDK header/library
files. This may prevent the project from building correctly.
g:\cmnhdr.h(212) : error C2065: 'GetWindowLongPtr' : undeclared identifier
g:\cmnhdr.h(212) : error C2065: 'GWLP_HINSTANCE' : undeclared identifier
g:\01-errorshow\errorshow.cpp(83) : error C2065: 'PCTSTR' : undeclared identifier
g:\01-errorshow\errorshow.cpp(83) : error C2146: syntax error : missing ')' before identifier 'LocalLock'
g:\01-errorshow\errorshow.cpp(83) : error C2059: syntax error : ')'
g:\01-errorshow\errorshow.cpp(125) : error C2664: 'DialogBoxParamA' : cannot convert parameter 4 from 'long (struct HWND__ *,unsigned int,unsigned int,long)' to 'int (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long)'
None of the functions with this name in scope match the target type
Error executing cl.exe.
Creating browse info file...01 ErrorShow.exe - 6 error(s), 0 warning(s)
修改了相应的几个地方后,就可以了,且运行成功
--------------------Configuration: 01 ErrorShow - Win32 Debug--------------------
Compiling...
ErrorShow.cpp
You are not using the latest Platform SDK header/library
files. This may prevent the project from building correctly.
Linking...
Creating browse info file...01 ErrorShow.exe - 0 error(s), 0 warning(s)下面把修改后的代码贴出来,你可以通过查找JOKE100关键字来找出修改的地方.
/******************************************************************************
Module: CmnHdr.h
Notices: Copyright (c) 2000 Jeffrey Richter
Purpose: Common header file containing handy macros and definitions
used throughout all the applications in the book.
See Appendix A.
******************************************************************************/
#pragma once // Include this header file once per compilation unit
//////////////////////// Windows Version Build Option /////////////////////////
#define _WIN32_WINNT 0x0500
//#define WINVER 0x0500
//////////////////////////// Unicode Build Option /////////////////////////////
// If we are not compiling for an x86 CPU, we always compile using Unicode.
#ifndef _M_IX86
#define UNICODE
#endif// To compile using Unicode on the x86 CPU, uncomment the line below.
//#define UNICODE// When using Unicode Windows functions, use Unicode C-Runtime functions too.
#ifdef UNICODE
#define _UNICODE
#endif
///////////////////////// Include Windows Definitions /////////////////////////
#pragma warning(push, 3)
#include <Windows.h>
#pragma warning(pop)
#pragma warning(push, 4)
///////////// Verify that the proper header files are being used //////////////
#ifndef WT_EXECUTEINPERSISTENTIOTHREAD
#pragma message("You are not using the latest Platform SDK header/library ")
#pragma message("files. This may prevent the project from building correctly.")
#endif
////////////// Allow code to compile cleanly at warning level 4 ///////////////
/* nonstandard extension 'single line comment' was used */
#pragma warning(disable:4001)// unreferenced formal parameter
#pragma warning(disable:4100)// Note: Creating precompiled header
#pragma warning(disable:4699)// function not inlined
#pragma warning(disable:4710)// unreferenced inline function has been removed
#pragma warning(disable:4514)// assignment operator could not be generated
#pragma warning(disable:4512)
///////////////////////// Pragma message helper macro /////////////////////////
/*
When the compiler sees a line like this:
#pragma chMSG(Fix this later)it outputs a line like this: c:\CD\CmnHdr.h(82):Fix this laterYou can easily jump directly to this line and examine the surrounding code.
*/#define chSTR2(x) #x
#define chSTR(x) chSTR2(x)
#define chMSG(desc) message(__FILE__ "(" chSTR(__LINE__) "):" #desc)
////////////////////////////// chINRANGE Macro ////////////////////////////////
// This macro returns TRUE if a number is between two others
#define chINRANGE(low, Num, High) (((low) <= (Num)) && ((Num) <= (High)))
//////////////////////////////// chDIMOF Macro ////////////////////////////////
// This macro evaluates to the number of elements in an array.
#define chDIMOF(Array) (sizeof(Array) / sizeof(Array[0]))
///////////////////////////// chBEGINTHREADEX Macro ///////////////////////////
// This macro function calls the C runtime's _beginthreadex function.
// The C runtime library doesn't want to have any reliance on Windows' data
// types such as HANDLE. This means that a Windows programmer needs to cast
// values when using _beginthreadex. Since this is terribly inconvenient,
// I created this macro to perform the casting.
typedef unsigned (__stdcall *PTHREAD_START) (void *);#define chBEGINTHREADEX(psa, cbStack, pfnStartAddr, pvParam, fdwCreate, pdwThreadId) ((HANDLE)_beginthreadex( (void *) (psa), (unsigned) (cbStack), (PTHREAD_START) (pfnStartAddr), (void *) (pvParam), (unsigned) (fdwCreate), (unsigned *) (pdwThreadId)))
////////////////// DebugBreak Improvement for x86 platforms ///////////////////
#ifdef _X86_
#define DebugBreak() _asm { int 3 }
#endif
/////////////////////////// Software Exception Macro //////////////////////////
// Useful macro for creating your own software exception codes
#define MAKESOFTWAREEXCEPTION(Severity, Facility, Exception) ((DWORD) ( /* Severity code */ (Severity ) | /* MS(0) or Cust(1) */ (1 << 29) | /* Reserved(0) */ (0 << 28) | /* Facility code */ (Facility << 16) | /* Exception code */ (Exception << 0)))
/////////////////////////// Quick MessageBox Macro ////////////////////////////
inline void chMB(PCSTR s) {
char szTMP[128];
GetModuleFileNameA(NULL, szTMP, chDIMOF(szTMP));
MessageBoxA(GetActiveWindow(), s, szTMP, MB_OK);
}
//////////////////////////// Assert/Verify Macros /////////////////////////////
inline void chFAIL(PSTR szMsg) {
chMB(szMsg);
DebugBreak();
}
// Put up an assertion failure message box.
inline void chASSERTFAIL(LPCSTR file, int line, PCSTR expr) {
char sz[128];
wsprintfA(sz, "File %s, line %d : %s", file, line, expr);
chFAIL(sz);
}
// Put up a message box if an assertion fails in a debug build.
#ifdef _DEBUG
#define chASSERT(x) if (!(x)) chASSERTFAIL(__FILE__, __LINE__, #x)
#else
#define chASSERT(x)
#endif
// Assert in debug builds, but don't remove the code in retail builds.
#ifdef _DEBUG
#define chVERIFY(x) chASSERT(x)
#else
#define chVERIFY(x) (x)
#endif
/////////////////////////// chHANDLE_DLGMSG Macro /////////////////////////////
// The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog
// boxes because DlgProc return a BOOL instead of an LRESULT (like
// WndProcs). 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))))
//////////////////////// Dialog Box Icon Setting Macro ////////////////////////
// Sets the dialog box icons
inline void chSETDLGICONS(HWND hwnd, int idi) {
SendMessage(hwnd, WM_SETICON, TRUE, (LPARAM)
LoadIcon((HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
MAKEINTRESOURCE(idi)));
SendMessage(hwnd, WM_SETICON, FALSE, (LPARAM)
LoadIcon((HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
MAKEINTRESOURCE(idi)));
// [原来的代码,REMARKED BY JOKE100]
/*
inline void chSETDLGICONS(HWND hwnd, int idi) {
SendMessage(hwnd, WM_SETICON, TRUE, (LPARAM)
LoadIcon((HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
MAKEINTRESOURCE(idi)));
SendMessage(hwnd, WM_SETICON, FALSE, (LPARAM)
LoadIcon((HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
MAKEINTRESOURCE(idi)));
*/
// [END BY JOKE100]
}
/////////////////////////// OS Version Check Macros ///////////////////////////
inline void chWindows9xNotAllowed() {
OSVERSIONINFO vi = { sizeof(vi) };
GetVersionEx(&vi);
if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
chMB("This application requires features not present in Windows 9x.");
ExitProcess(0);
}
}
inline void chWindows2000Required() {
OSVERSIONINFO vi = { sizeof(vi) };
GetVersionEx(&vi);
if ((vi.dwPlatformId != VER_PLATFORM_WIN32_NT) && (vi.dwMajorVersion < 5)) {
chMB("This application requires features present in Windows 2000.");
ExitProcess(0);
}
}
///////////////////////////// UNICODE Check Macro /////////////////////////////
// Since Windows 98 does not support Unicode, issue an error and terminate
// the process if this is a native Unicode build running on Windows 98// This is accomplished by creating a global C++ object. Its constructor is
// executed before WinMain.#ifdef UNICODEclass CUnicodeSupported {
public:
CUnicodeSupported() {
if (GetWindowsDirectoryW(NULL, 0) <= 0) {
chMB("This application requires an OS that supports Unicode.");
ExitProcess(0);
}
}
};// "static" stops the linker from complaining that multiple instances of the
// object exist when a single project contains multiple source files.
static CUnicodeSupported g_UnicodeSupported;#endif
/////////////////////////// Force Windows subsystem ///////////////////////////
#pragma comment(linker, "/subsystem:Windows")
///////////////////////////////// End of File //////////////////////////////////******************************************************************************
Module: ErrorShow.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
//#include "..\CmnHdr.h" /* See Appendix A. */
#include "CmnHdr.h" /* See Appendix A. */
#include <Windowsx.h>
#include <tchar.h>
#include "Resource.h"
///////////////////////////////////////////////////////////////////////////////
#define ESM_POKECODEANDLOOKUP (WM_USER + 100)
const TCHAR g_szAppName[] = TEXT("Error Show");
///////////////////////////////////////////////////////////////////////////////
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 // Get the error code's textual description
BOOL fOk = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(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) {
FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM,
hDll, dwError, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(PTSTR) &hlocal, 0, NULL);
FreeLibrary(hDll);
}
} if (hlocal != NULL) {
// SetDlgItemText(hwnd, IDC_ERRORTEXT, (PCTSTR) LocalLock(hlocal));
SetDlgItemText(hwnd, IDC_ERRORTEXT, (LPCTSTR) LocalLock(hlocal));
LocalFree(hlocal);
} else {
SetDlgItemText(hwnd, IDC_ERRORTEXT, TEXT("Error number not found."));
}
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);
SetForegroundWindow(hwnd);
break;
} return(FALSE);
}
///////////////////////////////////////////////////////////////////////////////
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),
// [REVISED BY JOKE100]
// NULL, Dlg_Proc, _ttoi(pszCmdLine));
NULL, (DLGPROC)Dlg_Proc, _ttoi(pszCmdLine));
// [END BY JOKE100]
}
return(0);
}
//////////////////////////////// End of File //////////////////////////////////
为过请问什么地方可以更新我的SDK?
LoadIcon((HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
MAKEINTRESOURCE(idi)));
// SendMessage(hwnd, WM_SETICON, TRUE, (LPARAM)
// LoadIcon((HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
// MAKEINTRESOURCE(idi)));
DialogBoxParam(hinstExe, MAKEINTRESOURCE(IDD_ERRORSHOW),
NULL, (DLGPROC)Dlg_Proc, _ttoi(pszCmdLine));
// NULL, Dlg_Proc, _ttoi(pszCmdLine));
tp://ftp.microsoft.com/developr/platformsdk/feb2001/
去下载,很大。
经查看 FormatMessage 函数的定义,发现参数 dwLanguageId 的说明如下: Specifies the 32-bit language identifier for the requested message.This
parameter is ignored if dwFlags includes FORMAT_MESSAGE_FROM_STRING. If
you pass a specific LANGID in this parameter, FormatMessage will return
a message for that LANGID only.If the function cannot find a message for
that LANGID, it returns ERROR_RESOURCE_LANG_NOT_FOUND. If you pass in zero, FormatMessage looks for a message for LANGIDs in the
following order: 1.Language neutral
2.Thread LANGID, based on the thread's locale value
3.User default LANGID, based on the user's default locale value
4.System default LANGID, based on the system default locale value
5.US English If FormatMessage doesn't find a message for any of the preceding LANGIDs,
it returns any language message string that is present. If that fails, it
returns ERROR_RESOURCE_LANG_NOT_FOUND. 该参数为要求的消息指定32位语言识别符。将其改为'0'编译后运行程序,效果和
Visual Studio自带的Error Lookup运行结果一样。系统配置:Win98+VC++6.0(均为简体中文版)