![]() |
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:
Application.ProccessMessages verarbeitet aber auch Tastatur Messages.
for i:=1 to 60 do
begin if Ready(device) then Break; Sleep(100); Application.ProccessMessages; end; 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:
Damit werden aber nur Mouss Messages verarbeitet und wichtige Messages wie WM_PAINT leider nicht.
while PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) do
begin TranslateMessage(Msg); DispatchMessage (Msg); end; 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 ? |
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. |
Re: Messages vom Keyboard nicht verarbeiten
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
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:
Irgenwie müsste global für die Anwendung alle Keyboard-Events abfangen und in einer eigenen Queue zwischenspeichern.
...
ClearKeyBoardBuffer; // KEY-Messages einfach schlucken Application.ProccessMessage; [Edit] Inzwischen habe ich eine eigene Message Queue gebaut. Damit werden Key-Messages zwischengespeichert:
Delphi-Quellcode:
[/Edit]
// 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; |
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 01:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz