Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Windows 是不是(有条件地)限制了递归调用的次数?

7 views
Skip to first unread message

Cen

unread,
Oct 18, 2009, 10:18:52 AM10/18/09
to
���뽹��ʹ��ڼ���Ĺ�ϵ, ��Դ��[2,3]�ͺ�������.

��DlgWindowProc�����DefWindowProc�������޵ݹ�, ��ΪDlg��ע��WndProc��DefDlgProc,
DefDlgProc��call DlgWindowProc, ���Լ�������Ϣ, ��call DefWindowProc, û�еݹ��ϵ.
��DlgWindowProc�����DefDlgProc�����޵ݹ�, һ˲��ջ���Stack overflow - code c00000fd.

����Tab���л�Focus, SetFocus����WM_KILLFOCUS, ���ǵݹ����,
���ǵݹ鵽38��ʱ, SetFocusû����WM_KILLFOCUS, ���ǵݹ���ֹ.
���Դ�뿴������Ϊʲô, ������XP��Щ�ı�, Ҫ�����ں˲�֪��, ����ͷ�ĵڶ�̨��ʾ������, û����windbg˫�����.

����һ����ֵĵط�, ����A�ʹ���B��SetFocus/WM_KILLFOCUS�ǶԳƵ�,
��WM_SETFOCUSȴֻ����A��,����Bһ��WM_SETFOCUSҲû��.
���Ӧ����������[3], ����Aԭ����Focus, ����xxxSendFocusMessages����WM_SETFOCUS, ����Bԭ��û��Focus, �Ͳ�������.

SetFocus����ΪUSER32!NtUserSetFocus[1], ����kernel mode��xxxSetFocus[2], xxxSendFocusMessages[3].
��ЩԴ���ϴεİ�����, ����VS�����, ������ֻժ¼��صIJ���.

[1] win2k\private\ntos\w32\ntuser\kernel\ntstubs.c
HWND NtUserSetFocus(
IN HWND hwnd)
{
retval = (HWND)xxxSetFocus(pwnd);
}

[2] win2k\private\ntos\w32\ntuser\kernel\focusact.c
PWND xxxSetFocus(
PWND pwnd)
{
/*
* Save current pwndFocus since we must return this.
*/
pwndTemp = ptiCurrent->pq->spwndFocus;
/*
* Change the global pwndFocus and send the WM_{SET/KILL}FOCUS
* messages.
*/
xxxSendFocusMessages(ptiCurrent, pwnd);
hwndTemp = HW(pwndTemp);
/*
* Return the pwnd of the window that lost the focus.
* Return the validated hwndTemp: since we locked/unlocked pwndTemp,
* it may be gone.
*/
return RevalidateHwnd(hwndTemp);
}

[3] win2k\private\ntos\w32\ntuser\kernel\focusact.c
void xxxSendFocusMessages(
PTHREADINFO pti,
PWND pwndReceive)
{
if (pwndReceive == NULL) {
} else {
if (pwndLose != NULL) {
xxxSendMessage(pwndLose, WM_KILLFOCUS, (WPARAM)HWq(pwndReceive), 0);
}
/*
* Send the WM_SETFOCUS message, but only if the window we're
* setting the focus to still has the focus! This allows apps
* to prevent themselves from losing the focus by catching
* the WM_NCACTIVATE message and returning FALSE or by calling
* SetFocus() inside their WM_KILLFOCUS handler.
*/
if (pwndReceive == pti->pq->spwndFocus) {
/*
* We have to do this BEFORE sending the WM_SETFOCUS message.
* The app, upon receiving it, very well may turn around and
* SetFocus() to a child window.
*/
if (FWINABLE()) {
xxxWindowEvent(EVENT_OBJECT_FOCUS, pwndReceive, OBJID_CLIENT,
INDEXID_OBJECT, 0);
}
xxxSendMessage(pwndReceive, WM_SETFOCUS, (WPARAM)HW(pwndLose), 0);
}
}
}

"acc" <jo...@sina.com> wrote:
> ��buzzard����û�г��ʹ����⵱����һЩ�����Ȩ�⣬����д�����ˣ�
>
> ������ָ���̽��㡢���뽹�㣩
>
> ���촴����һ�����ڣ��������Ӵ��ڣ��Ӵ��ڴ�������һ��ġ������Ӵ������յ�����ʱ��ִ�� SetFocus()������ WM_KILLFOCUS ����д�£�
>
> LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
> {
> case WM_KILLFOCUS:
> _tprintf(TEXT("%x\n"), GetFocus());
> SetFocus(hWnd);
> break;
> }
>
> ���ֲ�û�а���Ԥ�Ƶ�����������޵ݹ顣��������������֮������� 20 �Σ����䵽��ԭ���Ĵ����ϡ����ս���û�б仯����һ���Ǹ���Ľ��
>
> ��Ҳû��ô����ʵ�飬ֻ�����룬�Dz��� Windows ���ijЩ���ܵ����޵ݹ飬���˷�����
>
> ��Լ�ǵ� msdn ����˵����Ҫ�ڶԻ���������� DefWindowProc������ᵼ�����޵ݹ顣��Ҳû�ԣ���֪���Ƿ�Ҳ�����ƣ������� Windows �����ܲ����Էֱ��һ���Ի����̵��� DefWindowProc ����ĵݹ飿
>
> �������û��ʲôȷ�е����ʣ����ڼ��̵�һ����ļ���û��ͷ����������ġ�

"acc" <jo...@sina.com> wrote:
> �ǵ� msdn ����˵����������ڣ������һϵ�С�����Ч�������������뽹�㣬����ڡ�����ͨ�� API �ı���������Ч��Ҳ���˾������Ǹ������ˡ�

0 new messages