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/)
-   -   Delphi Messages vom Keyboard nicht verarbeiten (https://www.delphipraxis.net/51816-messages-vom-keyboard-nicht-verarbeiten.html)

shmia 19. Aug 2005 13:30


Messages vom Keyboard nicht verarbeiten
 
Problem:
ich schicke über die Serielle Schnittstelle einen Befehl an ein Gerät und muss max. 6 Sekunden auf Anwort warten.
Dabei soll das Programm aber nicht so aussehen, als ob es eingefroren wäre.
Deshalb sieht das Warten so aus:
Delphi-Quellcode:
for i:=1 to 60 do
begin
   if Ready(device) then
      Break;
   Sleep(100);
   Application.ProccessMessages;  
end;
Application.ProccessMessages verarbeitet aber auch Tastatur Messages.
Wenn der ungeduldige Benutzer eine Funktionstaste drückt, bevor die Daten da sind, kommt es zu einem Fehler.
Statt Application.ProccessMessages stelle ich mir nun etwas wie:
Delphi-Quellcode:
while PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) do
begin
   TranslateMessage(Msg);
   DispatchMessage (Msg);
end;
Damit werden aber nur Mouss Messages verarbeitet und wichtige Messages wie WM_PAINT leider nicht.
Was kann man statt dessen machen ?
Hätte es einen Sinn, mit PeekMessage alle Messages abzuholen und die Messages,
die einem nicht in den Kram passen (Key Messages)
mit PostMessage erneut in die Queue zu stellen ?

Robert Marquardt 19. Aug 2005 13:55

Re: Messages vom Keyboard nicht verarbeiten
 
Der Ansatz ist falsch.
Lagere das Senden in einen Thread aus und die Oberflaeche friert nicht ein.
Damit ist die Oberflaeche in einem bestimmten Zustand. Entsprechend muessen die moeglichen Aktionen begrenzt werden.
Du verstehst hier offensichtlich nicht die Trennung zwischen Messages und den daraus resultierenden Reaktionen.
Eine GUI ist immer in einem Zustand. Jeder Zustand mappt Eingaben/Messages zu Reaktionen.

Im Zustand "Thread laeuft" muessen daher die Eingaben auf passende Reaktionen gemappt werden. Dei haeufigste Reaktion duerfte hier ignorieren sein.
Das Mapping wird meist durch Komponenten/Controls erledigt. Um das Mapping zu vereinfachen gibt es die TAction-Familie.

shmia 19. Aug 2005 16:27

Re: Messages vom Keyboard nicht verarbeiten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Robert
Der Ansatz ist falsch.
Lagere das Senden in einen Thread aus und die Oberflaeche friert nicht ein.

Ich denke angestrengt darüber nach, :gruebel: aber eigener Thread hilft mir wohl auch nicht weiter.

Die Anwendung arbeitet mit ActionLists; ich könnte also die Action vorher disablen.
Allerdings arbeiten die Benutzer wie am Fliessband.
Solange der Dialog mit der ser. Schnittstelle läuft, würden der Shortcut F6 der mit der Action verbunden ist,
zu nichts führen.
Dann müsste er nochmals F6 drücken... :?
Irgendwie muss ich Keyboard Messages solange verzögern, bis mein lang dauernder Vorgang abgeschlossen ist.

Von meiner Anwendung heraus rufe ich ein VB-Script auf; dieses VB-Script startet nun den
lang dauernder Vorgang (Automatisierungschnittstelle).
Das macht die Sache noch komplizierter. :roll:

Im Moment sieht meine Warteschleife so aus:
Delphi-Quellcode:
  ...
  ClearKeyBoardBuffer; // KEY-Messages einfach schlucken
  Application.ProccessMessage;
Irgenwie müsste global für die Anwendung alle Keyboard-Events abfangen und in einer eigenen Queue zwischenspeichern.

[Edit]
Inzwischen habe ich eine eigene Message Queue gebaut.
Damit werden Key-Messages zwischengespeichert:
Delphi-Quellcode:
// Test Procedure
procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
   for i := 0 to 100 do
   begin
      // alle Messages ausser KEY-Messages verarbeiten
      ProccessMessagesNoKey;
      Sleep(100);
   end;
   // jetzt alle Key-Messages aus der Vergangenheit abspielen
   PlaybackMessageQueue;
end;
[/Edit]

Robert Marquardt 19. Aug 2005 17:22

Re: Messages vom Keyboard nicht verarbeiten
 
Natuerlich musst du F6 disablen, damit es unbenutzbar ist.
Willst du Fliessbandarbeit machen, so musst du ein Fliessband (Queue) von Auftraegen einrichten.
Sobald die Queue das erste Element bekommt, so wird der Arbeitsthread gestartet.
Der Arbeitssthread synchronisiert sich mit dem Hauptthread und holt sich einen Auftrag aus der Queue.
Das macht er solange bis kein Auftrag mehr in der Queue ist, dann beendet er sich.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:02 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