Recursieve aanroepen van functies van venster manager mislukken onverwacht

Van toepassing: Windows

Symptomen


Venster beheer functies uitgevoerd door USER32 recursieve aanroepen. DLL-bestand mogelijk zonder de aangevraagde bewerking uit te voeren en het instellen van een foutcode geretourneerd. Dit gebeurt meestal in toepassingen met een venster diep geneste hiërarchie. Tussen de symptomen kunnen optreden:
  • Toepassingen met een venster diep geneste hiërarchie niet correct subvensters formaat als u het formaat van het framevenster. Windows worden verplaatst en/of de afmetingen van het aanroepen van MoveWindow, SetWindowPos of DeferWindowPos.
  • Vensterberichten worden niet doorgegeven aan windows bovenliggende of onderliggende vensters zoals verwacht. DefWindowProc kunnen berichten naar het bovenliggende venster of onderliggende vensters van het venster het bericht niet is doorgegeven.
  • Venster berichten naar een venster door de aanroepende SendMessage, SendMessageTimeout of SendMessageCallback worden niet ontvangen door het opgegeven venster.
Ook kunnen toepassingen die anders normaal werken ook de symptomen hierboven beschreven als WH_CALLWNDPROC of WH_CALLWNDPROCRET venster haken zijn ingesteld op threads die eigenaar zijn van de vensters in de toepassing. Venster haken kunnen worden ingesteld op een bepaalde thread of op alle UI-threads door het aanroepen van de functie SetWindowsHookEx.

Oorzaak


Dit probleem is het resultaat van Windows niet kunnen groeien de kernelstack van de thread om de gevraagde bewerking niet uitvoeren. Door extra kernelstack afhandeling van procedures die nodig zijn in de x64 Windows-omgeving, de kernelstack sneller dan in een Windows-omgeving bij het maken van recursieve aanroepen naar venster beheer functies geëxporteerd x86 kan worden gebruikt door USER32. DLL. Hoewel de symptomen die in dit artikel worden beschreven zijn vaker voor in de x64 Windows-platforms, is het mogelijk voor recursieve aanroepen verbruiken kernelstack van een thread op x86 Windows-platforms.

Oplossing


De volgende oplossingen kunnen worden gebruikt om dit probleem te omzeilen
  1. Het formaat van onderliggende vensters bij het verwerken van WM_WINDOWPOSCHANGED vensterberichten in plaats daarvan doorgegeven aan DefWindowProc.
  2. Asynchroon de grootte van onderliggende vensters wanneer het bovenliggende venster aangepast in plaats van onderliggende vensters vergroten/verkleinen tijdens het verwerken van de WM_WINDOWPOSCHANGED of het WM_SIZE-venster weergegeven.
  3. De toepassing UI te verminderen, de diepte van de geneste venster ontwerpen.

Meer informatie


Delen van het Win32-subsysteem worden geïmplementeerd in kernel-modus-apparaatstuurprogramma (WIN32K. SYS). Aanroepen van functies door USER32 geëxporteerd. DLL-bestand te wijzigen van de status van een venster, met inbegrip van de grootte en positie, belt in WIN32K. SYS de aangevraagde bewerking uit te voeren. Functies die normaal gesproken de status van een venster wijzigen in het vensterberichten die worden verzonden naar het venster wordt gewijzigd, waarbij resulteren WIN32K. SYS is een toelichting gebruikersmodus met de procedure van het venster van het venster wordt gewijzigd. Bijvoorbeeld WIN32K. SYS stuurt een venster een WM_WINDOWPOSCHANGING venster en een WM_WINDOWPOSCHANGED venster als u de grootte en/of de positie van het venster door de functie SetWindowPos aanroept. DefWindowProc wordt het opgegeven venster een WM_SIZE bericht verzonden wanneer aangeroepen met een WM_WINDOWPOSCHANGED-bericht en de grootte van het venster is gewijzigd. Toepassingen meestal de grootte van onderliggende vensters wanneer het bovenliggende venster WM_WINDOWPOSCHANGED of WM_SIZE-venster bericht, die leidt ontvangt tot een recursieve aanroepen in WIN32K. SYS voor diep geneste venster hiërarchieën. Toepassingen die anders normaal werken kunnen ook de symptomen in dit artikel wordt beschreven als WH_CALLWNDPROC of WH_CALLWNDPROCRET haken zijn ingesteld op threads in het proces. Dit komt door de kernel meer stackruimte verbruikt wanneer WIN32K. SYS verwerkt het haakje-procedures aanroepen. SendMessage een venster om bericht te verzenden naar een venster dat eigendom is van de thread roepen roept de procedure van het venster van het venster bericht ontvangen zonder u aan te roepen in WIN32K meestal. SYS. SendMessage roept echter in WIN32K. SYS als WH_CALLWNDPROC haken of WH_CALLWNDPROCRET aangehaakt als WIN32K instellen op de thread. SYS beheert de haken en grepen haakje procedures aanroepen. Zoals eerder vermeld, DefWindowProc wordt het opgegeven venster een WM_SIZE bericht verzonden wanneer aangeroepen met een WM_WINDOWPOSCHANGED-bericht en de grootte van het venster is gewijzigd. Een haak WH_CALLWNDPROC of een WH_CALLWNDPROCRET, zal de SendMessage-aanroep DefWindowProc maakt de overgang in kernel-modus om het haakje-procedures aanroepen. Formaat onderliggende vensters wanneer kernel stack-gebruik WM_WINDOWPOSCHANGED vensterberichten in plaats van WM_SIZE vensterberichten verwerken beperkt door hoeft u de SendMessage overgang in de kernelmodus in volgorde hook-procedures aanroepen. Ontwikkelaars van Windows Forms-toepassingen die dit probleem ondervindt, KB-artikel 953934voor meer informatie raadplegen.