windows - Afbryder Win10 WM\_PAINT-behandling med nye WM\_PAINT-meddelelser?

Indlæg af Hanne Mølgaard Plasc

Problem



En run-time-fejl s stack-sporfil viser vinduesproceduren, der bliver kaldt to gange med WM\_PAINT -meddelelser. Vinduet var midt i at blive malet på grund af den første WM\_PAINT besked (efter BeginPaint]] men før EndPaint), da vinduesproceduren blev pludselig kaldet igen for at behandle en ny WM\_PAINT besked. Det skete tilsyneladende efter et opkald til SetBkColor eller SelectObject. [[[27] [28] [29] [30] [31] [32] [33]


Jeg er klar over, at dette kan ske, hvis vores ansøgning hedder UpdateWindow (eller brugt SendMessage til at sende WM\_PAINT til sig selv, men jeg tror ikke, at det nogensinde sker. Desuden UpdateWindow er en no-op, hvis opdateringsregionen er tom, hvilket skal være tilfældet siden BeginPaint validerer opdateringsregionen. [34] [35] [36] [37] [38]


Dette problem er blevet rapporteret til os af to kunder, der kører Windows 10, men ellers er det aldrig blevet set før i vores langstabile applikation. Jeg spekulerer på, om muligvis Windows 10 (eller nogle midlertidige Windows 10 auto-opdatering måske senere rettet) kunne være begyndt at SendMessage overflødige WM\_PAINT meddelelser?!? Selv om der var en god grund til at sende dem i stedet for at sende dem, forekommer det uvenligt at tvinge reentrantmaleri, mens BeginPaint er aktiv. [39] [40] [41]


Per forespørgsel, her er pseudokoden for stakken sporet:

RTS: Ubehandlet undtagelse nr. 3: Ugyldig placering

BW linje 3056 - RepaintChars

BW linje 3071 - RepaintText

BW linje 3242 - Gentag (kaldet efter BeginPaint før EndPaint)

MAIN linje 85 - WindowProcedure (håndterer WM\_PAINT her)

Kan ikke genkende modul

Kan ikke genkende modul

Kan ikke genkende modul

BW linje 3056 - RepaintChars

BW linje 3071 - RepaintText

BW linje 2976 - RepaintAround

BW linje 3253 - Gentag (kaldet efter BeginPaint før EndPaint)

MAIN linje 85 - WindowProcedure (håndterer WM\_PAINT her)

MAIN lin 145 - main [42] [43] [44] [45] [46] [47]


Uanset den muligvis ikke-relaterede 'ugyldige placering' run-time-fejl øverst, forsøger jeg at forstå bedre de nysgerrige reentrant WM\_PAINT beskeder. Det er muligt toppen af ​​stablingssporet er en illusorisk gentagelse af den nederste halvdel, men jeg tror ikke på grund af små forskelle (f.eks. ingen RepaintAround i den øverste halvdel) og hvordan hver placering peger på meningsfulde linjer, der giver et konsistent billede. [48]

Bedste reference


Baseret på kommentarer, indser jeg nu, at min WM\_PAINT -håndterer ikke kunne have været afbrudt enten eksternt eller internt ved opkald til SendMessage/GetMessage/PeekMessage, så min stakspor skal være forkert. Mit gæt er, at et kortere sporingsspor kan være lagt oven på et tidligere længere WM\_PAINT stakkespor og danner en tilsyneladende sammenhængende historie, der vildlede mig med at tro på, at reentrant WM\_PAINT budskaber var sker. [49] [50] [51] [52]


Det forekommer stadig muligt, at en subtil ændring fra nogle Win10-opdateringer muligvis har udløst denne run-time-fejl, da det skete i et rock-solid tekstvisningsværktøj, der næsten ikke ændrede sig om et årti. Min stakkesporing pegede på en linje af kode, der kunne gøres mere modstandsdygtig over for dårlige data, så forhåbentlig er det løst. Jeg sætter pris på Stack Overflow-fællesskabet, der hjælper mig med at få mit hoved lige om det!