Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi OnFocusLost-Event? (https://www.delphipraxis.net/129018-onfocuslost-event.html)

Carsten1234 11. Feb 2009 07:10


OnFocusLost-Event?
 
Hallo,

ich habe (in einem Projekt) eine eigenständige Unit (ohne DFM), die lediglich Kommunikationsroutinen für den Transfer Gerät <==> PC über die serielle Schnittstelle bereit stellt. Nun kann es vorkommen, dass ein Transfer zw. Gerät und PC etwas länger dauern kann und damit der Anwender nicht ratlos da steht, ob gerade was passiert, wollte ich während des Transfers einen kl. Dialog (nennen wir ihn GaugeDlg) hochkommen lassen, der (ähnl. dem Kopierfenster im Windows Explorer) eine Prozentanzeige darstellt.
Nur: Diesen GaugeDlg kann ich (von meiner Transfer-Unit) ja nicht ShowModal darstellen lassen, da dann der eigentliche Datentransfer im Hintergrund nicht mehr läuft. Lasse ich hingegen den GaugeDlg nur per Show darstellen, kann der Anwender ihn weg klicken.
Schön wäre also ein OnFocusLost-Event, der dann den Dialog wieder BringToFront 'macht'.
Hat jemand eine Idee/einen Tipp, wie man so etwas geschickt löst?
Ich möchte ungern die Kommunikationsroutinen aus der eigenständigen Unit in den GaugeDlg verlagern...

Dank vorab und Gruß, Carsten

Nachtrag: Kam mir gerade so in den Sinn. Wäre eine Lösungsmöglichkeit, den GaugeDlg in einem Thread zu starten?

Relicted 11. Feb 2009 07:20

Re: OnFocusLost-Event?
 
Moin,

geschickt wäre es deine "kommunikations" Routinen in einen Thread auszulagern. Somit kann die Mainform den Dialog Modal anzeigen und die Kommunikation im Hintergrund trotzdem weiterrattern. Dazu dann noch ein Event "OnProgress" das vom Thread gefeuert und im modalen Dialog angezeigt wird und fertig ist der Lack :-)

Gruß
Reli

SvB 11. Feb 2009 08:08

Re: OnFocusLost-Event?
 
Ja, würde ich so machen, wie Relicted beschrieben hat. Zusätzlich könntest Du den Dialog so gestalten, dass der Benutzer ihn nicht schließen kann, ihn ganz normal mit Show anzeigen und zusätzlich noch FormStyle := fsStayOnTop einstellen. Dann geht er nicht in den Hintergrund. Eventuell würde es auch ausreichen, dass man im MainForm in der StatusBar irgendwelche Informationen anzeigt.

Grüße Sven

Carsten1234 11. Feb 2009 08:24

Re: OnFocusLost-Event?
 
Es war auch schon mein Gedanke, die Kommunikationsroutinen in einen Thread auszulagern, aber
1) habe ich mit Threads noch nicht allzu viel Erfahrung
2) müsste das Ganze Threadsafe sein(?)

Speziell betrifft mein Problem ja auch nur eine einzige Kommunikationsroutine, alle anderen Routinen gehen blitzschnell. Nur wollte ich eigentlich für diese eine Routinen keinen Threadaufwand betreiben...

Gruß, Carsten

Relicted 11. Feb 2009 08:42

Re: OnFocusLost-Event?
 
Falls du die Unit rausgeben darfst paste sie doch einfach mal dann schauen wir mal drüber.
Ansich ist aber der Thread problemlos zu integrieren. Wenn du nur einen Thread hast sollte es problemlos möglich sein deine Unit auszulagern.

Carsten1234 11. Feb 2009 13:24

Re: OnFocusLost-Event?
 
Zitat:

Zitat von Relicted
Wenn du nur einen Thread hast sollte es problemlos möglich sein deine Unit auszulagern.

Nun, für die Kommunikation nutze ich ApdComPort und diese läuft ja eh schon (der Dispatcher) in einem Thread (wenn ich den Quellcode richtig verstanden habe). Das wäre dann also ein Thread im Thread...

Gruß, Carsten

sx2008 12. Feb 2009 02:20

Re: OnFocusLost-Event?
 
Es gibt da auch noch andere (sehr flexible) Möglichkeiten.
Zuerst definieren wir ein Interface:
Delphi-Quellcode:
IProgressFeedback = interface
   procedure WriteMessage(const msg:string);
   procedure SetProgressMinMax(min,max:integer);
   procedure SetProgress(value:Integer);
end;
Deine Kommunikationklasse bekommt nun dieses Interface im Konstruktor mitgeteilt:
Delphi-Quellcode:
TMyKomm = class(...)
private
  FFeedback : IProgressFeedback;
...
public
  constructor Create(feedback:IProgressFeedback);

  procedure DoWork;
end

constructor TMyKomm.Create(feedback:IProgressFeedback);
begin
  inherited;
  FFeedback := feedback; // speichern für spätere verwendung
end;

procedure TMyKomm.DoWork;
begin
   FFeedback.WriteMessage('starte Kommunikation mit Gerät...';
   FFeedback.SetProgressMinMax(0, ...);
   for i := 0 to ... do
   begin
     FFeedback.SetProgress(i); // mitteilen, wo wir gerade stehen
     ...
   end;
   FFeedback.WriteMessage('download der Daten erfolgreich.';
end;
Jetzt muss das vereinbarte Interface nur noch von irgendeiner Klasse implementiert werden.
Das kann ein eigenes Formular sein oder auch das Formular, von dem der ganze Vorgang angestossen wurde.
Delphi-Quellcode:
TForm1 = class(TForm, IProgressFeedback)
....
protected
   procedure WriteMessage(const msg:string);
   procedure SetProgressMinMax(min,max:integer);
   procedure SetProgress(value:Integer);
...
end;

procedure TForm1.SetProgress(value:Integer);
begin
  self.BringToFront; // Trick: Formular wird automatisch immer wieder nach vorne gebracht
  Progress1.Value := value; // Progressbar setzen
  Progress1.Refresh; // sicherstellen, dass neu gezeichnet wird
end;
Sollte dich diese Technik interessieren, dann sag' Bescheid; ich kann dann auch noch zeigen, wie man die laufende Operation sauber abbrechen kann, falls der Benutzer dies wünscht.

Carsten1234 12. Feb 2009 06:25

Re: OnFocusLost-Event?
 
Hallo sx2008,

Zitat:

Zitat von sx2008
Es gibt da auch noch andere (sehr flexible) Möglichkeiten.
(...)
Sollte dich diese Technik interessieren, dann sag' Bescheid; ich kann dann auch noch zeigen, wie man die laufende Operation sauber abbrechen kann, falls der Benutzer dies wünscht.

danke erstmal dafür, das sieht sehr interessant aus. Ich werde es erstmal (versuchen zu) verinnerlichen und melde mich dann ggf. nochmal. :bounce1:

Gruß, Carsten

himitsu 12. Feb 2009 08:05

Re: OnFocusLost-Event?
 
Warum willst du überhaupt dem User einen Dialog aufzwingen?
(sowas nervt mich schon bei einigen anderen Programmen öfters mal voll an)

Wenn der User es gesehn hat, was spricht dann dagegen, wenn er dieses Fenster wegklickt?

Carsten1234 13. Feb 2009 08:26

Re: OnFocusLost-Event?
 
Zitat:

Zitat von himitsu
Warum willst du überhaupt dem User einen Dialog aufzwingen?

Damit der User sieht, das sich da noch was tut und nicht denkt, dass das Programm ggf. abgestürzt ist. Nach der Übertragung verschindet er selbsständig wieder.
Wenn Du eine größere Datei via Explorer kopierst, möchtest Du doch auch eine Rückinfo, ob da noch was kopiert wird!?!?!

Gruß, Carsten


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:28 Uhr.
Seite 1 von 2  1 2      

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