Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Programm reagiert nicht - Windows-Test? (https://www.delphipraxis.net/167456-programm-reagiert-nicht-windows-test.html)

himitsu 30. Mär 2012 15:30

Programm reagiert nicht - Windows-Test?
 
Wie prüft eigentlich Windows, ob ein Programm nicht reagiert?

Wird eventuell eine Message geschickt und wenn ja welche.



Der Grund ist Folgender:

Wir haben im Programm an massig vielen Stellen ein Application.ProcessMessages, welches oftmals nur für einen grafischen Refresh zustäständig ist und damit das Programm nicht völlig einfriert.
Aber leider ist es dabei ja möglich auf irgendwelchen Buttons rumzucklicken, welches an ein paar Stellen zu Problemen führt.
Und alles irgendwie anders zu machen, ist auf die Schelle auch nicht so schnell möglich. (ist alles über Jahrzehnte historisch gewachsen)

Nun hab ich also erstmal ein eigenes ProcessDrawMessages erstellt, welches sich nur um PM_QS_PAINT und PM_QS_SENDMESSAGE kümmert. (MSDN-Library durchsuchenPeekMessage)

Nja, und jetzt müßte ich noch irgendwie Windows sagen, daß das Programm nicht "wirklich" hängt und mal sehn, welche Messages auch noch unbedingt verarbeitet werden müssen.

jfheins 30. Mär 2012 17:02

AW: Programm reagiert nicht - Windows-Test?
 
laut diesem Blog Eintrag: http://blogs.msdn.com/b/meason/archi...for-hangs.aspx
Musst du wohl zwangsläufig Eingaben verarbeiten. Und wenn du sie einfach ignorierst ;-)

Uwe Raabe 30. Mär 2012 17:09

AW: Programm reagiert nicht - Windows-Test?
 
Ich finde auch, du solltest alle Messages verarbeiten. Es könnte sonst ziemlich überraschend wirken, wenn plötzlich alle gemachten Mausklicks und Tastatureingaben quasi auf einmal verarbeitet werden, nur weil sie noch in der Message-Queue stecken.

Ich weiß, ich erzähle nichts Neues, aber du solltest das Konzept schnellstmöglich ändern, sonst wächst es noch weitere Jahrzehnte so weiter.

himitsu 30. Mär 2012 18:59

AW: Programm reagiert nicht - Windows-Test?
 
Es werden ja Messages verarbeitet.
Allerdings erstmal nur die Nicht-Benutzereingaben.
Die Maus- und TastatusMessages werden entweder später verarbeitet (sobald die Prozeduren fertig sind, mit ihrer Arbeit) oder die werden einfach gelöscht (abgerufen und nicht verarbeitet).

Zitat:

nur weil sie noch in der Message-Queue stecken.
Joar, ist uns auch eingefallen.
Eventuell die Usermessages verwerfen :gruebel:
Aber so ist es schonmal besser, da hier alles nacheinander und wenigstens nicht durcheinander verarbeitet wird. :oops:

Nja, ist halt alles nicht so einfach.
Ja, natürlich wäre es besser, alles abzusuchen und überall z.B. die Buttons zu deaktivieren, während der Arbeit, aber das dauert auch eine Weile.

Aber jetzt ist erstmal Wochenende und die Arbeit geht dann am Montag weiter.

sx2008 31. Mär 2012 11:35

AW: Programm reagiert nicht - Windows-Test?
 
Zitat:

Zitat von himitsu (Beitrag 1159475)
... es besser, alles abzusuchen und überall z.B. die Buttons zu deaktivieren...

Vielleicht ist das gar nicht so schwer wie es im ersten Moment aussieht.
Man bräuchte eine Klasse (abgeleitet von TComponent) mit 2 Methoden: FreezeUI() und UnfreezeUI().
Delphi-Quellcode:
Freezer1.IgnoreControl := ButtonStop;
Freezer1.FreezeUI;
try
  MachWasDasSehrLangeDauertUndDerBenutzerNichtUnterbrechenDarf;
finally
  Freezer1.UnfreezeUI;
end;
Beim Einfrieren werden in einer Schleife alle Komponenten des Owners (=das Formular) durchgegangen.
Dabei wird geprüft:
TButton? TSpeedButton? TToolbar? TCoolbar? TMainMenu?
Visible? Enabled?
Alle gefundenen Komponenten, die Visible und Enabled sind werden in eine ObjectList eingetragen
und anschliesend wird das Property Enabled auf False gesetzt.
Dabei macht man sich zunutze, dass Enabled und Visible ab der Klasse TControl vorhanden sind.
Sollte die Komponente gleich dem IgnoreControl sein, dann findet das aber nicht statt.

Beim Auftauen braucht man nur noch die Objectliste durchgehen und für jede Komponente das Property Enabled wieder auf True zu setzen.

Ich denke, man könnte diese Freeze-Komponente in 0,5 bis 1 Stunde programmieren und es braucht vielleicht noch 2-3 Tage mehr bis man alles entdeckt hat was ich hier vergessen habe.

Bummi 31. Mär 2012 11:51

AW: Programm reagiert nicht - Windows-Test?
 
Vielleicht auch so was
Delphi-Quellcode:
procedure TForm2.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
  if MyFlag4Ignore then
    begin
    if (Msg.message = WM_Char)
       or (Msg.message = WM_LButtonDown)
       or .....
       or ...
       then

        Handled := true;
    end;
end;

Uwe Raabe 31. Mär 2012 12:08

AW: Programm reagiert nicht - Windows-Test?
 
Vielleicht hilft auch TApplicationEvents.OnMessage

himitsu 31. Mär 2012 12:24

AW: Programm reagiert nicht - Windows-Test?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1159533)
Vielleicht hilft auch TApplicationEvents.OnMessage

siehe :angle2:
Zitat:

Zitat von Bummi (Beitrag 1159529)
Vielleicht auch so was
Delphi-Quellcode:
procedure TForm2.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);

Aber wozu das global (immer und überall) einbinden, wo ich schon eine lokale Variante hab (nur dort wo nötig). :stupid:



@Freezer: Das müßte ich auch überall manuell einbauen und wenn, dann kann ich es auch gleich richtig machen.

Mir fällt da grade was ein.
Wir haben sowieso von fast allen Komponenten eigene Ableitungen verbaut.
Da könnte ich das "Click" unserer Buttons verändern, so daß sich der Button selber enablen/disablen kann, wärend die Klickprozedur läuft.
Ich glaub das währe wohl die ideale Lösung, für die meisten Problemstellen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz