徵狀
視窗管理員函式匯出 USER32 的遞迴呼叫。DLL 可能會傳回在不執行要求的作業及設定的錯誤代碼。這通常是發生在具有深層巢狀的視窗階層架構的應用程式。之間的徵狀,您可能會發生:
-
具有深層巢狀的視窗階層架構的應用程式無法正確地調整子視窗,框架視窗調整大小時。Windows 會移動和/或調整大小藉由呼叫 MoveWindow、 SetWindowPos 或 DeferWindowPos。
-
父視窗,或如預期般的子視窗,視窗訊息不會進行傳播。DefWindowProc 無法成功地傳播到父視窗或 [接收訊息] 視窗的子視窗的訊息。
-
視窗訊息傳送至視窗呼叫 SendMessage,由 SendMessageTimeout 或 SendMessageCallback 未收到所指定的視窗。
此外,否則能發揮正常作用的應用程式也可能會遇到的徵狀,上面所述,如果在應用程式中擁有 windows 的執行緒上設定 WH_CALLWNDPROC 或 WH_CALLWNDPROCRET 視窗勾點。視窗勾點可以在特定的執行緒上,或在所有的 UI 執行緒上設定藉由呼叫 SetWindowsHookEx 函式。
原因
這是 Windows 無法成長的呼叫執行緒的核心堆疊,才能執行要求的作業的結果。因為額外的核心堆疊處理程序必要的 x64 Windows 環境中,核心堆疊可由 USER32 使用比在 Windows 環境時進行遞迴呼叫視窗管理員函式匯出 x86 的速度。DLL。 雖然本文中所述的徵狀較可能發生在 x64 Windows 平台,則可能使用執行緒的核心堆疊在 x86 上的遞迴呼叫 Windows 平台。
解決方案
下列的解決方案可以用來解決這個問題
-
處理改為將訊息傳遞至 DefWindowProc 的 WM_WINDOWPOSCHANGED 視窗訊息時,請調整大小的子視窗。
-
父視窗調整大小時而不是處理 WM_WINDOWPOSCHANGED 或 WM_SIZE 視窗訊息時,子視窗調整大小時,以非同步方式調整大小的子視窗。
-
重新設計應用程式 UI,以減少巢狀的窗深度。
其他相關資訊
Win32 子系統的部份被實作在核心模式裝置驅動程式 (WIN32K。SYS)。USER32 所匯出的函式呼叫。若要變更的狀態視窗中,包括其大小和位置,DLL 就會呼叫 WIN32K。SYS 執行要求的作業。修改視窗的狀態通常的函式會導致視窗訊息傳送至視窗遭到修改,其中 WIN32K。SYS 使呼叫正在修改視窗的視窗程序的使用者模式圖說文字。例如,WIN32K。SYS 會傳送視窗 WM_WINDOWPOSCHANGING 視窗訊息及 WM_WINDOWPOSCHANGED 視窗訊息大小和 (或) 視窗的位置修改藉由呼叫 SetWindowPos 函式時。DefWindowProc 將傳送到 WM_SIZE 訊息呼叫 WM_WINDOWPOSCHANGED 訊息時指定的視窗和視窗的大小已變更。通常應用程式來調整大小的子視窗,當父視窗收到 WM_WINDOWPOSCHANGED 或 WM_SIZE 視窗訊息,這樣會導致發出到 WIN32K 的遞迴呼叫。SYS 深的巢狀的視窗階層。否則正常的應用程式也可能會遇到 WH_CALLWNDPROC 或 WH_CALLWNDPROCRET 的攔截程序在程序中的執行緒上設定時,本文中所述的徵狀。這是因為額外的核心堆疊空間的使用時機 WIN32K。SYS 處理呼叫攔截程序。呼叫 SendMessage,將視窗訊息傳送至呼叫的執行緒所擁有的視窗通常會呼叫視窗程序,而不必呼叫 WIN32K 接收訊息的視窗。SYS。不過,會呼叫 SendMessage,到 WIN32K。SYS,如果有 WH_CALLWNDPROC 攔截程序或 WH_CALLWNDPROCRET 攔截上呼叫的執行緒,設定為 WIN32K。SYS 管理攔截程序和呼叫攔截程序的控制代碼。如上所述,DefWindowProc 會傳送給指定的視窗 WM_SIZE 訊息呼叫 WM_WINDOWPOSCHANGED 訊息時,視窗的大小已變更。WH_CALLWNDPROC 攔截程序或 WH_CALLWNDPROCRET 將會造成 SendMessage 呼叫轉換為核心模式的 DefWindowProc 對才能呼叫勾點程序。調整大小的子視窗時處理 WM_WINDOWPOSCHANGED 視窗訊息,而不是 WM_SIZE 視窗訊息將會減少核心堆疊的使用方式免除 SendMessage 來切換至核心模式的順序呼叫攔截程序。遇到這個問題的 Windows Form 應用程式的開發人員應參閱 KB 文章如需詳細資訊。