У меня есть следующий вывод из Spy ++:
<00227> 001F1732 P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:-43 yPos:28
<00228> 001F1732 S WM_SIZING fwSide:WMSZ_LEFT lprc:0012F410
<00229> 001F1732 R WM_SIZING fProcessed:False
<00230> 001F1732 S WM_WINDOWPOSCHANGING lpwp:0012F404
<00231> 001F1732 S WM_GETMINMAXINFO lpmmi:0012EEF4
<00232> 001F1732 R WM_GETMINMAXINFO lpmmi:0012EEF4
<00233> 001F1732 R WM_WINDOWPOSCHANGING
<00234> 001F1732 S WM_NCCALCSIZE fCalcValidRects:True lpncsp:0012F3D8
<00235> 001F1732 R WM_NCCALCSIZE fuValidRect:0000 lpncsp:0012F3D8
<00236> 001F1732 S WM_NCPAINT hrgn:00000001
<00237> 001F1732 R WM_NCPAINT
<00238> 001F1732 S WM_ERASEBKGND hdc:09012308
<00239> 001F1732 R WM_ERASEBKGND fErased:True
<00240> 001F1732 S WM_WINDOWPOSCHANGED lpwp:0012F404
<00241> 001F1732 S WM_MOVE xPos:950 yPos:404
<00242> 001F1732 R WM_MOVE
<00243> 001F1732 S WM_SIZE fwSizeType:SIZE_RESTORED nWidth:282 nHeight:79
<00244> 001F1732 R WM_SIZE
<00245> 001F1732 S WM_WINDOWPOSCHANGING lpwp:0012F064
<00246> 001F1732 R WM_WINDOWPOSCHANGING
<00247> 001F1732 S WM_NCCALCSIZE fCalcValidRects:True lpncsp:0012F038
<00248> 001F1732 R WM_NCCALCSIZE fuValidRect:0000 lpncsp:0012F038
<00249> 001F1732 S WM_NCPAINT hrgn:00000001
<00250> 001F1732 R WM_NCPAINT
<00251> 001F1732 S WM_ERASEBKGND hdc:16011DB5
<00252> 001F1732 R WM_ERASEBKGND fErased:True
<00253> 001F1732 S WM_WINDOWPOSCHANGED lpwp:0012F064
<00254> 001F1732 R WM_WINDOWPOSCHANGED
<00255> 001F1732 R WM_WINDOWPOSCHANGED
<00256> 001F1732 S WM_PAINT hdc:00000000
<00257> 001F1732 R WM_PAINT
<00258> 001F1732 P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:-9 yPos:28
Отступы в строках с 241 по 254 были добавлены мной, чтобы сделать более очевидным, что эти сообщения являются вложенными. То есть они были отправлены с помощью сообщения WM_WINDOWPOSCHANGED в строке 240.
Вот связанный WndProc (это все из проекта по умолчанию, созданного Visual Studio 2005, за исключением случаев, когда он помечен для отображения кода, который я добавил):
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
LRESULT lReturnValue = 0; //---added by me
static int lcount = 0; //---added by me
switch (message)
{
//---added by me from here vvvv
case WM_WINDOWPOSCHANGED:
++lcount;
lReturnValue = DefWindowProc(hWnd, message, wParam, lParam);
//--lcount;
return lReturnValue;
case WM_ERASEBKGND:
case WM_NCPAINT:
{
wchar_t a[20];
_itow(lcount, &a[0], 10);
OutputDebugString(a);
OutputDebugString(L"\n");
}
return DefWindowProc(hWnd, message, wParam, lParam);
//---added by me to here ^^^^
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Если я запускаю это, в окне вывода VS есть следующее:
0
0
1
1
1
1
2
2
2
2
etc
Если я раскомментирую
//--lcount;
строка, которую я получаю:
0
0
0
0
0
0
0
0
etc
Я не понимаю, почему? Я ожидаю получить:
0
0
1
1
0
0
1
1
etc
, где 1 представляют вызовы WM_ERASEBKGND и WM_NCPAINT изнутри WM_WINDOWPOSCHANGED (как показано в выходных данных Spy ++). Очевидно, с моей стороны есть какое-то фундаментальное недоразумение, и я не могу этого понять! Любые идеи / предложения, чтобы попытаться с благодарностью приняты ...
Если вы согласны с тем, что я назвал своим ожидаемым поведением для этого кода, я также был бы признателен за комментарий. Таким образом, я знаю, что не смотрю на это совершенно неправильно. :)
Редактировать: Я думаю, что Spy ++ лжет! Я добавил вызов OutputDebugString в верхней части WndProc, чтобы вывести число каждые сообщения, полученные окном и получившие:
[WM_MOUSEMOVE] // not received
WM_SIZING
WM_WINDOWPOSCHANGING
WM_GETMINMAXINFO
WM_NCCALCSIZE
WM_NCPAINT
WM_ERASEBKGND
WM_WINDOWPOSCHANGED
WM_MOVE
WM_SIZE
[WM_WINDOWPOSCHANGING] // not received
WM_NCCALCSIZE
WM_NCPAINT
WM_ERASEBKGND
[WM_WINDOWPOSCHANGED] // not received
WM_PAINT
[WM_MOUSEMOVE] // not received
где строки «не получены» - это msgs. Spy ++ сообщает, что окно открывается, но оно никогда не появляется в WndProc! Более того, если я ставлю точку останова в самом начале WndProc, а другую - на вызов DefWindowProc в WM_WINDOWPOSCHANGED, то при переходе через вызов DefWindowProc точка останова в начале WndProc не срабатывает ... это означает, что no msg получает WndProc в результате вызова DefWindowProc в WM_WINDOWPOSCHANGED. Если кто-то не видит что-то, что мне не хватает, Spy ++ не точно отображает сообщения, которые получает ваше окно, а скорее их искаженную версию, как я покажу выше!