在书写#include的时候.
把tlhelp32.h放在windows.h的上面,
不行,就放在下面.(究竟是上还是下,我记不情了,呵呵)
你可以试试/

解决方案 »

  1.   

    原因是该书使用的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 //////////////////////////////////
      

  2.   

    高!
    为过请问什么地方可以更新我的SDK?
      

  3.   

    哈哈!我已经搞店了!其实就是两个关键的地方:  SendMessage(hwnd, WM_SETICON, FALSE, (LPARAM) 
          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));
      
      

  4.   

    <<Windows核心编程>>中有许多是WIN2000的API,安装WIN2000 的platform SDK 即可。《Windows网络编程》有WIN2000的SDK,不过是BETA版。 最新的到:
           tp://ftp.microsoft.com/developr/platformsdk/feb2001/
     去下载,很大。
         
      

  5.   

    怎么安装2000的SDK?那不是说这个程序只能在2000下运行?
      

  6.   

        奇怪,我的win98,vc6,从来没有更新过什么sdk,该函数照样可以用。你的文件里连WINAPI,HANDLE这些最常用的宏都没有定义,是不是文件坏了?检查一下tlhelp32.h文件看看。不行在#include<tlhelp32.h>前面加个#include <windows.h>。
      

  7.   

        奇怪,我的win98,vc6,从来没有更新过什么sdk,该函数照样可以用。你的文件里连WINAPI,HANDLE这些最常用的宏都没有定义,是不是文件坏了?检查一下tlhelp32.h文件看看。不行在#include<tlhelp32.h>前面加个#include <windows.h>。
      

  8.   

    补充:我经过以上修改后,程序可以运行,但是并不能正确显示错误代码的文本描述,
    经查看 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(均为简体中文版)