winapi - Find vindue tæt uden for wndproc?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg arbejder i øjeblikket på en win32 GUI app, der gør det meste af sit arbejde i vinduet tråd.

Denne tråd kan nogle gange blokeres, da den kører en scriptmotor, der kan suspenderes af en ekstern script debugger (en anden proces). Dette er ikke et problem mesteparten af ​​tiden, da det er forventet adfærd.

Men hvis brugeren forsøger at lukke vinduet, bliver appen naturligvis ikke reagerende, og du får dialogboksen 'Denne applikation svarer ikke ...'.

Min plan var at jævnligt ringe tilbage fra 'suspender kode' til appen og få det til at gøre PeekMessage til WM\_CLOSE, og i så fald afbryde debuggeren. Desværre, fra hvad jeg kan forstå, sendte WM\_CLOSE det direkte til wndproc.


Er der en anden måde, at jeg kunne opdage, at brugeren ønsker at lukke vinduet, ikke om at omkonstruere appen, som ikke er en mulighed?

Er der for eksempel en anden besked, der kan kontrolleres med PeekMessage?

Bedste reference


Hvad med det her: Spor regelmæssigt en meddelelsessløjfe for at sende eventuelle meddelelser i meddelelseskøen (det vil medføre, at mus/input-meddelelser håndteres, som vil generere WM\_CLOSE). I din apps hovedvindue sættes et flag, når WM\_CLOSE modtages og kontrollér, at flag efter spinding af sløjfen.


Det enkleste tilfælde at spinde en meddelelsessløkke for at skylle eventuelle ventende meddelelser ville være:


while (PeekMessage(&msg, NULL, 0, 0, PM\_REMOVE))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}


selvom dit appramme-arbejde måske allerede har funktioner til at gøre dette. Håber dette hjælper.

Andre referencer 1


Vil du overveje at tilføje en anden tråd omplanlægning af ansøgningen? Det ville helt sikkert gøre dit liv meget lettere! Bare lad Gui gøre alle Gui ting og køre det s budskab og gøre alt det hårde arbejde i en anden tråd. Hvis brugeren ønsker at afslutte programmet, præsentere ham en god OK/Annuller besked og suspendere/afbryde 'arbejderen tråd 'i overensstemmelse hermed. Håndtering af to separate opgaver i denne ene tråd - med alle de løsninger - vil gøre tingene mere messianere end det skal være. Held og lykke!

Andre referencer 2


Jeg antager, at du kan fortsætte med at håndtere din WM\_ CLOSE-meddelelse i wndproc, og når du modtager den, kalder du PostQuitMessage () , som igen vil generere en WM\_ QUIT-besked, der igen læses af GetMessage () / PeekMessage () .


Hvis din vinduetråd er helt blokeret, er du ude af lykke. Du har nogle få muligheder. Tråden skal kunne udføre PeekMessage (), mens du er i 'script engine mode'.


while (IsScripting()) {
    ScriptEngineTimeSlice();
    while (PeekMessage( .. )) {
        TranslateMessage( .. );
        DispatchMessage( .. ); // <-- wnd procedure will be called
        // ..
    }
}


Dette er sandsynligvis gamle nyheder for dig, da du allerede er opmærksom på dette. Men hvis du på en eller anden måde ikke kan give brugergrænsefladen en pause, kan du ikke løse dette. Hvis tråden er blokeret, er den blokeret.

Andre referencer 3


Hvis du fejler, ville det ikke sige, at brugeren fejler? Hvorfor ville de blive overrasket over, at appen så 'ikke reagerede'? I hvert fald har du kontrol over vinduesproceduren for vinduet, så hvorfor ikke bare se efter WM\_CLOSE besked derinde? Det er dit vindue?