Simptomi
Rekursīva izsauc logu pārvaldnieka funkcijas eksportēto USER32. DLL var atgriezt bez veiktu pieprasīto darbību un kurā kļūdas kods. Tas parasti notiek ļoti ligzdotu logu hierarhijas programmām. Starp simptomi var rasties:
-
Lietojumprogrammas, kurās ir ļoti ligzdotu logu hierarhijas nespēj mainīt bērna windows pareizi, ir mainīti loga rāmis. Windows tiek pārvietota un/vai mainīti, zvanot pa tālruni MoveWindow, SetWindowPos vai DeferWindowPos.
-
Ziņojumu logs netiek ieviesti vecāku windows vai bērna windows, kā paredzēts. DefWindowProc veiksmīgi nevar izplatīt ziņojumu logā vai bērna windows saņem ziņojumu logā.
-
Ziņojumi logā nosūtīts logu, zvanot SendMessage SendMessageTimeout vai SendMessageCallback netiek saņemti norādītajā window.
Turklāt lietojumprogrammām, kas citādi darboties normāli var rasties iepriekš iestatot WH_CALLWNDPROC vai WH_CALLWNDPROCRET logu aizķeres uz savu windows lietojumprogrammu pavedienus simptomi. Loga aizķeres, izsaucot funkciju SetWindowsHookEx var iestatīt konkrētu pavedienu vai visu UI pavedienu.
Cēlonis
Šī darbība ir radusies Windows nespēj kļūst kodola grupas zvanu pavedienu, lai veiktu pieprasīto darbību. Jo papildu kodola steka apstrādes procedūras, kas nepieciešamas x64 Windows vidē kodola grupas var patērēt ātrāk nekā ar x86 Windows vidē, veicot rekursīva izsauc logu pārvaldnieka funkcijas eksportēt, USER32. DLL. kaut arī šajā rakstā aprakstītie simptomi biežāk sastopami x64 Windows platformas, ir iespējams rekursīva zvaniem patērēt kodola Pavediena steks uz x86 Windows platformām.
Risinājums
Šo risinājumu var izmantot, lai novērstu šo problēmu
-
Apstrādājot WM_WINDOWPOSCHANGED ziņojumi logā vietā iet ziņojumu DefWindowProc mainīt bērna windows.
-
Asinhroni mainīt bērna windows, galvenā loga izmēri nevis izmēru bērnu windows WM_WINDOWPOSCHANGED vai WM_SIZE logu ziņojumu apstrādes laikā.
-
Pārveidot lietojumprogrammu UI samazina dziļums ligzdotu logu.
Papildinformācija
Fragmentu Win32 apakšsistēmā ir ieviests kodola režīma draiveris (WIN32K. SYS). Zvanu funkcijas eksportēto USER32. DLL mainīt valsts logu, tā lielumu un atrašanās vietu, tostarp aicinās uz WIN32K. Sistēmas, lai veiktu pieprasīto darbību. Funkcijas, kas parasti modificē loga stāvokli izraisa logu ziņojumus logā tiek modificēts, kur WIN32K. SYS padara lietotāja režīma remarka zvanīt modificē loga loga procedūru. Piemēram, WIN32K. SYS nosūtīs logu WM_WINDOWPOSCHANGING logu ziņojumu un ziņojumu WM_WINDOWPOSCHANGED logu, lielumu un/vai loga atrašanās vietas ir modificēti, izsaucot funkciju SetWindowPos. DefWindowProc nosūtīs norādītajā window WM_SIZE ziņojums, izsaucot WM_WINDOWPOSCHANGED ziņojumu un mainīts loga lielumu. Programmas parasti izmēru bērnu windows galvenā loga saņemot WM_WINDOWPOSCHANGED vai WM_SIZE logu ziņojumu, kas izraisa rekursīva zvanīšana uz WIN32K. SYS ļoti ligzdotu logu hierarhijas. Iestatot WH_CALLWNDPROC vai WH_CALLWNDPROCRET aizķeres procesa pavedieni par šajā rakstā aprakstītie simptomi var rasties arī programmas, kas citādi darboties normāli. Tas ir tāpēc, ka papildu kodola steka vietas ir patērēt, kad WIN32K. SYS apstrādā izsaucot aizķeres procedūras. Izsaucot SendMessage nosūtīt ziņojumu loga loga zvanot pavedienu pieder parasti zvanu logu procedūru loga ziņojuma saņemšana bez piezvana uz WIN32K. SYS. Tomēr SendMessage aicinās uz WIN32K. Ja WH_CALLWNDPROC aizķeres. SYS vai WH_CALLWNDPROCRET āķi kopa zvanot pavediens, kā WIN32K. SYS pārvalda aizķeres, un tas apstrādā izsaucot aizķeres procedūras. Kā jau tika minēts, DefWindowProc nosūtīt norādīto loga WM_SIZE ziņojums, izsaucot WM_WINDOWPOSCHANGED ziņojumu un mainīts loga lielumu. WH_CALLWNDPROC aizķeres vai WH_CALLWNDPROCRET izraisīs SendMessage izsaukumu DefWindowProc padara pāreju par kodola režīma lai zvanu aizķeres procedūras. Izmēru maiņas bērnu windows laikā, neliekot SendMessage pāreja uz kodola režīma pasūtījuma apstrādes WM_WINDOWPOSCHANGED ziņojumi logā, nevis WM_SIZE ziņojumi logā samazinās kodola steka lietojuma izsauc aizķeres procedūras. Šī problēma rodas Windows Forms lietojumprogrammu izstrādātājiem attiecas zināšanu bāzes rakstā 953934papildinformāciju.