Slik behandler WM_ENDSESSION etcContributor: HALLVARD Vassbotn {I en tidligere post med emnet "[Delphi] Serios bug når closingwindows ???" [email protected] (Per Bakkendorff) skriver: > Når du har en Delphi program er i gang, og du er nedleggelse vinduer, > (ikke lukke appen først), er ingen av dine destructors kalt !!!! først trodde jeg problemet var programmererens kode, men så innså jeg at det virkelig er en bug eller i det minste en veldig lat "funksjon" sikret problem synes å være at når du lukker ned Windows, vil det først sende en WM_QueryEndSession melding til alle kjørende vinduer på øverste nivå. Dette håndteres og behandles på riktig måte ved TForm objektet i VCL.Then forutsatt at alle søknader indikerte at det var ok å stenge, Windows vil sende WM_EndSession meldinger til alle vinduer. Denne meldingen er ikke håndteres av VCL. Søknaden er rett og slett brakt ned med en bang.No vinduer er lukket, ingen destructor ringte og ingen exit prosedyrer called.The løsningen er å håndtere WM_EndSession meldingen selv. Det er flere måter å håndtere meldinger i Delphi, men den eneste pålitelige måten å håndtere WM_ENDSESSION er å bruke HookWindow metode for Application.In meldingen handler, sjekk for å se om meldingen er en WM_ENDSESSION. I så fall bør vi legge ned programmet. Vi kunne ha kalt Lukk metoden i hovedvinduet, men API dokumentasjon Windows sier at systemet kan gå ned når som helst etter retur fra WM_ENDSESSION og postet WM_QUIT melding kanskje aldri kommer til application.The løsningen er å bare ringe Halt i stedet. Dette vil ringe alle registrert exit prosedyrer, inkludert de i kontroller og DB enheter. Disse vil frigjøre søknaden og skjermobjekter og ta BDE ned correctly.A enkelt eksempel slik:} enhet Tst2u; interfaceuses SysUtils, WinTypes, WinProcs, Meldinger, Klasser, grafikk, kontroller, skjemaer, Dialoger, Rister, DBGrids, DB, DBTables; skriver TForm1 = klasse (TForm) DataSource1: TDataSource; Tabell 1: TTable; DBGrid1: TDBGrid; Prosedyren FormCreate (Sender: TObject); private {felleserklæringer} funksjon HookProc (var Melding: TMessage): boolean; offentlige {offentlige erklæringer} end; Var Form1: TForm1, gjennomføring {$ R * .DFM} konst FlagFileName = 'C: \\ Flag.Fil'; prosedyre CreateFlagFile, Div F: System.Text, begynne System.Assign (F, FlagFileName ); System.Rewrite (F); Writeln (F, 'Dette er en dummy flagg fil'); System.Close (F), slutten, prosedyre KillFlagFile, Div F: File, begynner System.Assign (F, FlagFileName); System.Erase (F); end; prosedyre MyExitProc; langt, begynner KillFlagFile; ende; prosedyre TForm1.FormCreate (Sender: TObject), begynner Application.HookMainWindow (HookProc); end; funksjon TForm1.HookProc (var Melding: TMessage): boolean, begynner Resultat: = false; hvis Message.Msg = WM_EndSession begynne så hvis WordBool (Message.wParam) da begynne {Windows avsluttes ned - rydde opp !! } {Dette bør utføre alle ExitProcs, lukke vinduer og call destructors ...} Halt; {Dette fungerer! } {Dette bør lukke ting ned på riktig måte, men har vi nok tid til å håndtere eventuelle postet meldinger før Windows er allerede nede ?? Dette vil resultere i en PostQuitMessage som kanskje aldri kommer} {Lukk;} {Dette fungerer ikke alltid - unngå det} end!; end, end, initialisering CreateFlagFile; AddExitProc (MyExitProc); end.This enhet viser at utgangs prosedyrene kalles når du lukker programmet som normalt og når du lukker ned Windows og bruke HookMainWindow. Uten HookMainWindow samtale, vil avkjørselen proc ikke bli kalt. Dette er spesielt viktig for DB-programmer. Uten Halt, vil LCK filene ikke bli slettet, buffere kan ikke skylles, endringer postet og så videre.
Windows avsluttes down
Previous:Ross data Compression
Next Page:Readstring bekker linje ved line