Ich kann nichts konstruktives beitragen, nur anmerken, dass mir das auch schon öfter passiert ist: Abarbeiten irgendwelcher Timer-Messages während des Herunterfahrens, wenn schon formularmäßig so gut wie alles zerstört ist...
Nach dem Freigeben der Form (genauer nach dem Freigeben des TTimer und dessen interne MessageOnlyForm) sollte eigentlich nichts mehr eintreffen.
Das Window, an welches das WM_TIMER geschickt wird, ist dann weg.
Wenn Fenster freigegeben werden, werden deren Messages aus der Queue entfernt, aber selbst wenn nicht, dann existiert das Fenster nicht mehr, welches diese Message empfangen und verarbeiten kann.
Die Queue wird in TApplication.ProcessMessage verarbeitet, welches durch Application.Run, Application.HandleMessage und Application.ProcessMessages behandelt wird.
In der
VCL also immer wenn Application.ProcessMessages aufgerufen wird, bzw. zwischen den anderen
VCL-Ereignissen (Messages wie Button-Klicks, Timer-Events usw.), welche über/in/durch ProcessMessage ausgeführt werden.