Rekursiva anrop till fönstret manager funktioner kan oväntat misslyckas

Gäller för: Windows

Symptom


Rekursiva anrop till fönstret manager funktioner som exporteras av USER32. DLL kan returnera utan att utföra den begärda åtgärden och utan att ange en felkod. Detta inträffar vanligen i program med en djupt kapslade fönstret hierarki. Bland problem som kan uppstå:
  • Program med ett djupt kapslade fönstret hierarki inte underordnade fönster ändra storlek på korrekt när ram-fönstrets storlek. Windows flyttas eller storleksändras genom att anropa MoveWindow, SetWindowPos eller DeferWindowPos.
  • Fönstermeddelanden sprids inte till windows överordnade eller underordnade fönster som förväntat. DefWindowProc kan inte lyckas sprida meddelanden till fönstret överordnade eller underordnade fönster i fönstret tar emot meddelandet.
  • Fönstret meddelanden skickas till ett fönster genom att anropa SendMessage, SendMessageTimeout eller SendMessageCallback inte tas emot av angivet fönster.
Dessutom kan program som annars fungerar normalt också inträffa ovan om WH_CALLWNDPROC eller WH_CALLWNDPROCRET hook är inställda på trådar i programmet som äger windows. Hook kan ställas in på en specifik tråd eller alla UI trådar genom att anropa funktionen SetWindowsHookEx.

Orsak


Detta är ett resultat av Windows att det inte går att växa kernel-stacken för anropande tråd för att utföra den begärda åtgärden. På grund av ytterligare kernel-stacken hantering av förfaranden som krävs i x64 Windows-miljö, kernel-stacken kan förbrukas i en snabbare takt än i en Windows-miljö när gör Rekursiva anrop till funktioner för fönstret exporteras x86 av USER32. DLL. även om symptomen som beskrivs i denna artikel är mer sannolikt att uppstå i x64 Windows-plattformar, är det möjligt för rekursiva anrop att förbruka kernel-stacken för en tråd på x86 Windows-plattformar.

Lösning


Följande lösningar som kan användas för att undvika det här problemet
  1. Ändra storlek på underordnade fönster vid hantering av WM_WINDOWPOSCHANGED-fönstermeddelanden i stället skicka meddelandet till DefWindowProc.
  2. Ändra storlek underfönster asynkront när det överordnade fönstret ändrar storlek i stället för att ändra storlek på underordnade fönster under bearbetning av WM_WINDOWPOSCHANGED eller WM_SIZE fönster visas.
  3. Konstruera programmet UI att minska djupet kapslade fönster.

Mer information


Delar av delsystemet Win32 implementeras i en drivrutin för kernel-läge (WIN32K. SYS). Anrop till funktioner som exporteras av USER32. DLL-fil för att ändra status för ett fönster, inklusive dess storlek och placering, ringer till WIN32K. SYS för att utföra den begärda åtgärden. Funktioner som ändrar status för ett fönster brukar resultera i fönstret meddelanden som skickas till fönstret ändras, där WIN32K. SYS är en bildtext för användarläge anropa fönstret procedur i fönstret ändras. Till exempel WIN32K. SYS skickar ett fönster meddelandet WM_WINDOWPOSCHANGING fönster och ett WM_WINDOWPOSCHANGED fönster meddelande när storlek och position i fönstret ändras genom att anropa funktionen SetWindowPos. DefWindowProc skickar angivet fönster ett WM_SIZE meddelande när funktionen anropas med ett WM_WINDOWPOSCHANGED-meddelande och Selektionspanelens storlek har ändrats. Program storlek vanligtvis underordnade fönster när det överordnade fönstret får ett WM_WINDOWPOSCHANGED eller WM_SIZE fönstret meddelande, vilket leder till att göra Rekursiva anrop till WIN32K. SYS för fönstret djupt kapslade hierarkier. Program som annars fungerar normalt kan också uppstå problem som beskrivs i denna artikel när WH_CALLWNDPROC eller WH_CALLWNDPROCRET krokar på trådar i processen. Detta beror på ytterligare kernel-stackutrymme som förbrukas när WIN32K. SYS hanterar anropar hook-procedurer. Ringer SendMessage om du vill skicka ett meddelande i fönstret till ett fönster som ägs av den anropande tråden anropar vanligtvis hur fönstret i fönstret tar emot meddelandet utan att anropa WIN32K. SYS. SendMessage kommer dock anropar WIN32K. SYS, om det finns WH_CALLWNDPROC krokar eller WH_CALLWNDPROCRET skapar hookar uppsättning anropande tråd som WIN32K. SYS hanterar krokar och handtag som anropar hook-procedurer. Som nämnts ovan DefWindowProc skickar angivet fönster ett WM_SIZE meddelande när funktionen anropas med ett WM_WINDOWPOSCHANGED-meddelande och Selektionspanelens storlek har ändrats. En WH_CALLWNDPROC krok eller en WH_CALLWNDPROCRET kommer anropet SendMessage DefWindowProc gör att övergå i kernel-läge för att anropa procedurer i luren. Storleksändring underordnade fönster när du hanterar WM_WINDOWPOSCHANGED fönstermeddelanden i stället för WM_SIZE fönstermeddelanden minska användning av kernel-stacken genom att eliminera behovet av SendMessage att övergå i kernel-läge i ordning anropa procedurer i luren. Utvecklare av Windows Forms-program som uppstår det här problemet ska hänvisa till KB artikel 953934för ytterligare information.