Entwickler-Ecke

Windows API - MessageBox nach Prozedur automatisch schließen


Ulixes - Fr 30.01.09 14:01
Titel: MessageBox nach Prozedur automatisch schließen
Hey!

Mein Problem liegt dabei, dass ich Daten einlese und deshalb das Programm ein längere Zeit (unbekannt) nicht "ansprechbar" ist.

Wenn ich User wäre, schlösse ich das Programm, was nicht der Sinn sein kann. Also möchte ich am Anfang der Prozedur sagen, dass es etwas länger dauern

kann. Am Ende der Prozedur soll dann die Messagebox automatisch geschlossen werden (ein Pipston wäre schön :D ).


Wie kann ich die Messagebox automatisch schließen, obwohl die Zeit unbekannt ist??


Ich habe dazu nichts brauchbares im Internet gefunden.

Vielen Dank im Vorraus!


nagel - Fr 30.01.09 14:05

Einfache Lösung wäre: Hinweisfenster selbst bauen anstatt MessageBox zu verwenden und dann am Ende der Verarbeitung Form.Close. Da die Zeit vermutlich nicht vollkommen zufällig ist ;), kannst du da auch noch eine Fortschrittsanzeige einbauen.


Ulixes - Fr 30.01.09 14:09

Ja stimmt...daran habe ich gar nicht gedacht... :D

VIELEN DANK


jaenicke - Fr 30.01.09 14:10

Und wenn das Programm wirklich gar nicht mehr antwortet, dann machst du auch etwas falsch. Wie wäre es, wenn du mal ein Application.ProcessMessages dazwischenwirfst? Dann wird das Programm gar nicht erst als abgestürzt dargestellt.


Delete - Fr 30.01.09 14:26

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Und wenn das Programm wirklich gar nicht mehr antwortet, dann machst du auch etwas falsch. Wie wäre es, wenn du mal ein Application.ProcessMessages dazwischenwirfst? Dann wird das Programm gar nicht erst als abgestürzt dargestellt.

Aber unnütz ausgebremst. Für Nebenläufigkeit nimmt man besser Threads.


jaenicke - Fr 30.01.09 15:19

Das wäre natürlich die beste Lösung, ist aber auch mit etwas mehr Aufwand verbunden.

Die einfachste, wenn auch nicht so schöne, Lösung wäre erstmal die mit Application.ProcessMessages. Denn das Problem ist, dass die MessageBox ja zum selben Thread gehört und dementsprechend auch nicht mehr reagiert.


Delete - Fr 30.01.09 15:20

Schwerer dürfte wiegen, dass eine Messagebox modal angezeigt wird und somit den ganzen Thread anhält.


jaenicke - Fr 30.01.09 15:23

Ich meinte die selbstgebastelte MessageBox als eigenes Formular, die dann natürlich mit Show angezeigt werden muss. Aber diese wird eben trotzdem ebenfalls als nicht mehr reagierend angezeigt.


Ulixes - Fr 30.01.09 16:58

Vielen Dank für die weiteren Antworten.


Bei mir funktioniert die Funktion "Application.ProcessMessages" super. Ich brauche das ganze nur für eine Präsentation,

bei der keiner in mein Quelltext schaut :D ...soll nur schön aussehen...wenn ich berechnen möchte, nehme ich die alte

Methode.


JayEff - Fr 30.01.09 17:04

user profile iconUlixes hat folgendes geschrieben Zum zitierten Posting springen:
Bei mir funktioniert die Funktion "Application.ProcessMessages" super.
Gut dass das klappt, nun noch eines: bei größeren Schleifen sollte man diese Prozedur nicht bei jedem Durchlauf aufrufen, da das die Berechnung unnötig langsam macht. Beispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
for i := 0 to VeryLargeNumber do // VeryLargeNumber ist eine sehr große Zahl! :D 
begin
  //Berechnung
  //Vielleicht noch ein Fortschritsbalken
  if (i mod 1000) = 0 then //nur bei jedem 1000sten Durchlauf
    Application.ProcessMessages;
end;

Das reicht im Normalfall auch :)


delfiphan - Sa 31.01.09 15:00

Von Application.ProcessMessages kann ich (zu mindest bei einigermassen komplexen Programmen) nur abraten. Vor allem dann, wenn der entsprechende Code nur ein Teil des ganzen Programmes darstellt.

Man darf das Application.ProcessMessages nicht einfach nur als "de-freeze" sehen. Denn in Application.ProcessMessages werden offene Ereignisse (bzw. Messages) abgearbeitet und in einem ereignisorientierten Programm kann das so ziemlich alles sein.

Wenn du in einem OnClick ein Application.ProcessMessages machst, dann gibst du dem System die Möglichkeit, das OnClick-Ereignis während dem Application.ProcessMessages gleich nochmals auszulösen. Das Programm gewinnt plötzlich enorm an Komplexität, weil man plötzlich alle nicht-erwünschten Ereignisse unterbinden muss, oder das Ergebnis eines dazwischen ausgeführten Ereignisses mitberücksichtigen muss.

Ausserdem kann eine Funktion, die Application.ProcessMessage aufruft, nicht mehr überall eingesetzt werden, weil dieser Fall (in bestehendem Code) wohl keiner wirklich berücksichtigt.

Für deine Präsentation mag das okay sein. Aber allgemein würde ich mit Threads arbeiten, wobei das leider auch eine sehr heikle und komplexe Angelegenheit werden kann.