我正在看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]
于是单步跟踪,从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]
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]
{
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 */
}
是你根本还没理解WINDOWS程序的基本结构......