我正在看Putty的源代码,已经用VC2003编译运行成功
于是单步跟踪,从Winmain开始用F10一步步进入
但是我发现程序运行到下面这个地方时就循环不出来了
   /*
     * Main message loop.
     */
    while (GetMessage(&msg, NULL, 0, 0) == 1) {
if (!(IsWindow(keylist) && IsDialogMessage(keylist, &msg)) &&
    !(IsWindow(aboutbox) && IsDialogMessage(aboutbox, &msg))) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
    }该怎么办呢?
下面是这段代码周围的代码帮助分析的:
[code]
if (!prev) {
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = inst;
wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));
wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM);
wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = APPNAME; RegisterClass(&wndclass);
    }    keylist = NULL;    hwnd = CreateWindow(APPNAME, APPNAME,
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
100, 100, NULL, NULL, inst, NULL);    /* Set up a system tray icon */
    AddTrayIcon(hwnd);    /* Accelerators used: nsvkxa */
    systray_menu = CreatePopupMenu();
    if (putty_path) {
session_menu = CreateMenu();
AppendMenu(systray_menu, MF_ENABLED, IDM_PUTTY, "&New Session");
AppendMenu(systray_menu, MF_POPUP | MF_ENABLED,
   (UINT) session_menu, "&Saved Sessions");
AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
    }
    AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS,
   "&View Keys");
    AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key");
    AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
    if (has_help())
AppendMenu(systray_menu, MF_ENABLED, IDM_HELP, "&Help");
    AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About");
    AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
    AppendMenu(systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit");
    initial_menuitems_count = GetMenuItemCount(session_menu);    /* Set the default menu item. */
    SetMenuDefaultItem(systray_menu, IDM_VIEWKEYS, FALSE);    ShowWindow(hwnd, SW_HIDE);    /*
     * Main message loop.
     */
    while (GetMessage(&msg, NULL, 0, 0) == 1) {
if (!(IsWindow(keylist) && IsDialogMessage(keylist, &msg)) &&
    !(IsWindow(aboutbox) && IsDialogMessage(aboutbox, &msg))) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
    }    /* Clean up the system tray icon */
    {
NOTIFYICONDATA tnid; tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = hwnd;
tnid.uID = 1; Shell_NotifyIcon(NIM_DELETE, &tnid); DestroyMenu(systray_menu);
    }    if (keypath) filereq_free(keypath);    if (advapi)
FreeLibrary(advapi);    cleanup_exit(msg.wParam);
    return msg.wParam;        /* just in case optimiser complains */
}
[/code]

解决方案 »

  1.   

    [code]
    int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
    {
        WNDCLASS wndclass;
        MSG msg;
        HMODULE advapi;
        char *command = NULL;
        int added_keys = 0;
        int argc, i;
        char **argv, **argstart;    hinst = inst;
        hwnd = NULL;    /*
         * Determine whether we're an NT system (should have security
         * APIs) or a non-NT system (don't do security).
         */
        if (!init_winver())
        {
    modalfatalbox("Windows refuses to report a version");
        }
        if (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) {
    has_security = TRUE;
        } else
    has_security = FALSE;    if (has_security) {
    #ifndef NO_SECURITY
    /*
     * Attempt to get the security API we need.
     */
    advapi = LoadLibrary("ADVAPI32.DLL");
    getsecurityinfo =
        (gsi_fn_t) GetProcAddress(advapi, "GetSecurityInfo");
    if (!getsecurityinfo) {
        MessageBox(NULL,
           "Unable to access security APIs. Pageant will\n"
           "not run, in case it causes a security breach.",
           "Pageant Fatal Error", MB_ICONERROR | MB_OK);
        return 1;
    }
    #else
    MessageBox(NULL,
       "This program has been compiled for Win9X and will\n"
       "not run on NT, in case it causes a security breach.",
       "Pageant Fatal Error", MB_ICONERROR | MB_OK);
    return 1;
    #endif
        } else
    advapi = NULL;    /*
         * See if we can find our Help file.
         */
        init_help();    /*
         * Look for the PuTTY binary (we will enable the saved session
         * submenu if we find it).
         */
        {
            char b[2048], *p, *q, *r;
            FILE *fp;
            GetModuleFileName(NULL, b, sizeof(b) - 1);
            r = b;
            p = strrchr(b, '\\');
            if (p && p >= r) r = p+1;
            q = strrchr(b, ':');
            if (q && q >= r) r = q+1;
            strcpy(r, "putty.exe");
            if ( (fp = fopen(b, "r")) != NULL) {
                putty_path = dupstr(b);
                fclose(fp);
            } else
                putty_path = NULL;
        }    /*
         * Find out if Pageant is already running.
         */
        already_running = agent_exists();    /*
         * Initialise storage for RSA keys.
         */
        if (!already_running) {
    rsakeys = newtree234(cmpkeys_rsa);
    ssh2keys = newtree234(cmpkeys_ssh2);
        }    /*
         * Initialise storage for short-term passphrase cache.
         */
        passphrases = newtree234(NULL);    /*
         * Process the command line and add keys as listed on it.
         */
        split_into_argv(cmdline, &argc, &argv, &argstart);
        for (i = 0; i < argc; i++) {
    if (!strcmp(argv[i], "-pgpfp")) {
        pgp_fingerprints();
        if (advapi)
    FreeLibrary(advapi);
        return 1;
    } else if (!strcmp(argv[i], "-c")) {
        /*
         * If we see `-c', then the rest of the
         * command line should be treated as a
         * command to be spawned.
         */
        if (i < argc-1)
    command = argstart[i+1];
        else
    command = "";
        break;
    } else {
        add_keyfile(filename_from_str(argv[i]));
        added_keys = TRUE;
    }
        }    /*
         * Forget any passphrase that we retained while going over
         * command line keyfiles.
         */
        forget_passphrases();    if (command) {
    char *args;
    if (command[0] == '"')
        args = strchr(++command, '"');
    else
        args = strchr(command, ' ');
    if (args) {
        *args++ = 0;
        while(*args && isspace(*args)) args++;
    }
    spawn_cmd(command, args, show);
        }    /*
         * If Pageant was already running, we leave now. If we haven't
         * even taken any auxiliary action (spawned a command or added
         * keys), complain.
         */
        if (already_running) {
    if (!command && !added_keys) {
        MessageBox(NULL, "Pageant is already running", "Pageant Error",
           MB_ICONERROR | MB_OK);
    }
    if (advapi)
        FreeLibrary(advapi);
    return 0;
        }    if (!prev) {
    wndclass.style = 0;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = inst;
    wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));
    wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM);
    wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = APPNAME; RegisterClass(&wndclass);
        }    keylist = NULL;    hwnd = CreateWindow(APPNAME, APPNAME,
    WS_OVERLAPPEDWINDOW | WS_VSCROLL,
    CW_USEDEFAULT, CW_USEDEFAULT,
    100, 100, NULL, NULL, inst, NULL);    /* Set up a system tray icon */
        AddTrayIcon(hwnd);    /* Accelerators used: nsvkxa */
        systray_menu = CreatePopupMenu();
        if (putty_path) {
    session_menu = CreateMenu();
    AppendMenu(systray_menu, MF_ENABLED, IDM_PUTTY, "&New Session");
    AppendMenu(systray_menu, MF_POPUP | MF_ENABLED,
       (UINT) session_menu, "&Saved Sessions");
    AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
        }
        AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS,
       "&View Keys");
        AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key");
        AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
        if (has_help())
    AppendMenu(systray_menu, MF_ENABLED, IDM_HELP, "&Help");
        AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About");
        AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
        AppendMenu(systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit");
        initial_menuitems_count = GetMenuItemCount(session_menu);    /* Set the default menu item. */
        SetMenuDefaultItem(systray_menu, IDM_VIEWKEYS, FALSE);    ShowWindow(hwnd, SW_HIDE);    /*
         * Main message loop.
         */
        while (GetMessage(&msg, NULL, 0, 0) == 1) {
    if (!(IsWindow(keylist) && IsDialogMessage(keylist, &msg)) &&
        !(IsWindow(aboutbox) && IsDialogMessage(aboutbox, &msg))) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
        }    /* Clean up the system tray icon */
        {
    NOTIFYICONDATA tnid; tnid.cbSize = sizeof(NOTIFYICONDATA);
    tnid.hWnd = hwnd;
    tnid.uID = 1; Shell_NotifyIcon(NIM_DELETE, &tnid); DestroyMenu(systray_menu);
        }    if (keypath) filereq_free(keypath);    if (advapi)
    FreeLibrary(advapi);    cleanup_exit(msg.wParam);
        return msg.wParam;        /* just in case optimiser complains */
    }
    [/code]
      

  2.   

    int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
    {
        WNDCLASS wndclass;
        MSG msg;
        HMODULE advapi;
        char *command = NULL;
        int added_keys = 0;
        int argc, i;
        char **argv, **argstart;    hinst = inst;
        hwnd = NULL;    /*
         * Determine whether we're an NT system (should have security
         * APIs) or a non-NT system (don't do security).
         */
        if (!init_winver())
        {
    modalfatalbox("Windows refuses to report a version");
        }
        if (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) {
    has_security = TRUE;
        } else
    has_security = FALSE;    if (has_security) {
    #ifndef NO_SECURITY
    /*
     * Attempt to get the security API we need.
     */
    advapi = LoadLibrary("ADVAPI32.DLL");
    getsecurityinfo =
        (gsi_fn_t) GetProcAddress(advapi, "GetSecurityInfo");
    if (!getsecurityinfo) {
        MessageBox(NULL,
           "Unable to access security APIs. Pageant will\n"
           "not run, in case it causes a security breach.",
           "Pageant Fatal Error", MB_ICONERROR | MB_OK);
        return 1;
    }
    #else
    MessageBox(NULL,
       "This program has been compiled for Win9X and will\n"
       "not run on NT, in case it causes a security breach.",
       "Pageant Fatal Error", MB_ICONERROR | MB_OK);
    return 1;
    #endif
        } else
    advapi = NULL;    /*
         * See if we can find our Help file.
         */
        init_help();    /*
         * Look for the PuTTY binary (we will enable the saved session
         * submenu if we find it).
         */
        {
            char b[2048], *p, *q, *r;
            FILE *fp;
            GetModuleFileName(NULL, b, sizeof(b) - 1);
            r = b;
            p = strrchr(b, '\\');
            if (p && p >= r) r = p+1;
            q = strrchr(b, ':');
            if (q && q >= r) r = q+1;
            strcpy(r, "putty.exe");
            if ( (fp = fopen(b, "r")) != NULL) {
                putty_path = dupstr(b);
                fclose(fp);
            } else
                putty_path = NULL;
        }    /*
         * Find out if Pageant is already running.
         */
        already_running = agent_exists();    /*
         * Initialise storage for RSA keys.
         */
        if (!already_running) {
    rsakeys = newtree234(cmpkeys_rsa);
    ssh2keys = newtree234(cmpkeys_ssh2);
        }    /*
         * Initialise storage for short-term passphrase cache.
         */
        passphrases = newtree234(NULL);    /*
         * Process the command line and add keys as listed on it.
         */
        split_into_argv(cmdline, &argc, &argv, &argstart);
        for (i = 0; i < argc; i++) {
    if (!strcmp(argv[i], "-pgpfp")) {
        pgp_fingerprints();
        if (advapi)
    FreeLibrary(advapi);
        return 1;
    } else if (!strcmp(argv[i], "-c")) {
        /*
         * If we see `-c', then the rest of the
         * command line should be treated as a
         * command to be spawned.
         */
        if (i < argc-1)
    command = argstart[i+1];
        else
    command = "";
        break;
    } else {
        add_keyfile(filename_from_str(argv[i]));
        added_keys = TRUE;
    }
        }    /*
         * Forget any passphrase that we retained while going over
         * command line keyfiles.
         */
        forget_passphrases();    if (command) {
    char *args;
    if (command[0] == '"')
        args = strchr(++command, '"');
    else
        args = strchr(command, ' ');
    if (args) {
        *args++ = 0;
        while(*args && isspace(*args)) args++;
    }
    spawn_cmd(command, args, show);
        }    /*
         * If Pageant was already running, we leave now. If we haven't
         * even taken any auxiliary action (spawned a command or added
         * keys), complain.
         */
        if (already_running) {
    if (!command && !added_keys) {
        MessageBox(NULL, "Pageant is already running", "Pageant Error",
           MB_ICONERROR | MB_OK);
    }
    if (advapi)
        FreeLibrary(advapi);
    return 0;
        }    if (!prev) {
    wndclass.style = 0;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = inst;
    wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));
    wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM);
    wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = APPNAME; RegisterClass(&wndclass);
        }    keylist = NULL;    hwnd = CreateWindow(APPNAME, APPNAME,
    WS_OVERLAPPEDWINDOW | WS_VSCROLL,
    CW_USEDEFAULT, CW_USEDEFAULT,
    100, 100, NULL, NULL, inst, NULL);    /* Set up a system tray icon */
        AddTrayIcon(hwnd);    /* Accelerators used: nsvkxa */
        systray_menu = CreatePopupMenu();
        if (putty_path) {
    session_menu = CreateMenu();
    AppendMenu(systray_menu, MF_ENABLED, IDM_PUTTY, "&New Session");
    AppendMenu(systray_menu, MF_POPUP | MF_ENABLED,
       (UINT) session_menu, "&Saved Sessions");
    AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
        }
        AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS,
       "&View Keys");
        AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key");
        AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
        if (has_help())
    AppendMenu(systray_menu, MF_ENABLED, IDM_HELP, "&Help");
        AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About");
        AppendMenu(systray_menu, MF_SEPARATOR, 0, 0);
        AppendMenu(systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit");
        initial_menuitems_count = GetMenuItemCount(session_menu);    /* Set the default menu item. */
        SetMenuDefaultItem(systray_menu, IDM_VIEWKEYS, FALSE);    ShowWindow(hwnd, SW_HIDE);    /*
         * Main message loop.
         */
        while (GetMessage(&msg, NULL, 0, 0) == 1) {
    if (!(IsWindow(keylist) && IsDialogMessage(keylist, &msg)) &&
        !(IsWindow(aboutbox) && IsDialogMessage(aboutbox, &msg))) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
        }    /* Clean up the system tray icon */
        {
    NOTIFYICONDATA tnid; tnid.cbSize = sizeof(NOTIFYICONDATA);
    tnid.hWnd = hwnd;
    tnid.uID = 1; Shell_NotifyIcon(NIM_DELETE, &tnid); DestroyMenu(systray_menu);
        }    if (keypath) filereq_free(keypath);    if (advapi)
    FreeLibrary(advapi);    cleanup_exit(msg.wParam);
        return msg.wParam;        /* just in case optimiser complains */
    }
      

  3.   

    这不是你的错,
    是你根本还没理解WINDOWS程序的基本结构......