![]() |
ReadLn() für Fensterprogramme?
Hallo :)
Ich habe ein Problem welches vielleicht nicht ganz dem normalen Windows-Konzept entspricht und ich bin mir nicht sicher, ob es lösbar ist. Also ich schreibe gerade eine Art Konsolenprogramm, welches aber eigentlich ein normales Windowsprogramm ist mit einem TImage was mir als Anzeige dient (d.h. Ich schreibe den Text welcher ich anzeigen will dort drauf) Nun möchte ich so etwas wie einen WaitForUserInput Befehl implementieren, welcher solange alle Tastendrücke in einen String speichert, bis die Entertaste gedrückt wurde. Die Benutzung würde folgendermassen aussehen:
Delphi-Quellcode:
AskServerOrClient soll erst dann ausgeführt werden, wenn bei der Eingabe die Entertaste gedrückt wurde und WaitForUserInput den eingegebenen String zurückliefert. Also ziemlich ähnliche Funktionsweise wie der ReadLn() Befehl bei Konsolenprogrammen.
Drawer.AddToWriteBuffer('What''s your name? ');
Nickname := WaitForUserInput; AskServerOrClient; Ich habe mich schon an einer Lösung mittels While Schleife versucht, welche aber logischerweise alle Messages blockierte, so dass nicht mal mehr das Fenster überhaupt angezeigt wurde und dies in einer Endlosschleife endete. Die Tasten habe ich dort über FormKeyPress abgefragt und in einer Variable gespeichert welche dann von WaitForUserInput ausgelesen wurde, was mir nicht sehr sinnvoll und umständlich erscheint... Vielleicht wisst ihr auch da eine bessere Variante? Ich nehme mal an ich müsste dies über einen Thread lösen (damit habe ich bereits Erfahrungen gesammelt :wink:) Aber ich wüsste nicht wie das realisieren soll :( Ich möchte anmerken, dass ich keinen vollständigen Code brauche ;) Denkanstösse / Konzepte reichen mir völlig :-D Danke fürs Durchlesen meines Romans :mrgreen: Cu Kill0r |
Re: ReadLn() für Fensterprogramme?
Hi,
Versuch mal deine while-Methode. Aber schreib noch folgendes in die Schleife:
Delphi-Quellcode:
while not EntertasteGedrueckt do
begin Application.ProcessMessages; end; |
Re: ReadLn() für Fensterprogramme?
Und deklariere noch eine Zählvariable und führe das am besten nur alle 50-100 (oder 5-10 je nach dem) aus
Für Alle 50 mal schreibst du ins While
Delphi-Quellcode:
if Zaehlvariable mod 50 = 0 then Application.ProcessMessages;
|
Re: ReadLn() für Fensterprogramme?
Oder:
Delphi-Quellcode:
while not EntertasteGedrueckt do
begin Sleep(50); Application.ProcessMessages; end; |
Re: ReadLn() für Fensterprogramme?
Delphi-Quellcode:
find ich schon zu viel - ein
Sleep(50);
Delphi-Quellcode:
reicht bei mir schon vollkommen aus um zumindest die CPU-Auslastung auf < 1% zu setzen.
Sleep(1);
|
Re: ReadLn() für Fensterprogramme?
Hey :wink:
Danke für eure Bemühungen, aber ich glaube nicht, dass mir das wirklich weiterhelfen wird. Meine aktuelle Prozedur (mit eingefügtem Application.ProcessMessages) sieht so aus:
Delphi-Quellcode:
Hatte Application.ProcessMessages schon mal drin, aber dann rattert er einfach durch (führt AskServerOrClient bereits aus) und bleibt nicht stehen. Ausserdem scheint mir das nicht die optimale Lösung. :(
function TUser.WaitForUserInput: String;
begin InputString := ''; NextKey := ''; EnableInput; while InputEnabled do begin Application.ProcessMessages; if NextKey = #8 then begin SetLength(InputString, Length(InputString)-1); DrawInput; NextKey := ''; end else if not (NextKey = '') then begin InputString := InputString + NextKey; DrawInput; NextKey := ''; end; end; Result := InputString; end; Hier noch die FormKeyPress Prozedur:
Delphi-Quellcode:
Und noch die User.CheckKey Prozedur:
procedure TfrmChat.FormKeyPress(Sender: TObject; var Key: Char);
begin User.CheckKey(Key); end;
Delphi-Quellcode:
Ich nehme mir mal das Problem mit dem Durchlaufen vor, zumindest das sollte ja nicht passieren. :shock:
procedure TUser.CheckKey(Key: Char);
begin if InputEnabled then begin if Key = #13 then begin User.DisableInput; end else begin NextKey := Key; end; end; end; Solltet ihr noch irgendwelchen Code brauchen, sagt Bescheid. Dies ist zumindest meiner Ansicht nach der wichtigste Teil. :) Ausserdem: Gibt es vielleicht eine Art getch(); Befehl um eine Taste abzufragen für Delphi? Bin bei meiner Google Suche darauf gestossen, leider gibts den Befehl anscheinend nur in C++. GetAsyncKeyState bringt mich nicht wirklich weiter, alle Tasten per Polling abzufragen ist nicht gerade besser :lol: Dann hätte ich eben eine Idee um das Problem mit einem Thread zu lösen. Cu Kill0r |
Re: ReadLn() für Fensterprogramme?
Zitat:
ein ganz anderer Lösungsansatz: du zeigst den auszugebenden Text z.B. in einem TMemo an (TImage geht auch, wenn es dafür einen Grund gibt). Für die Eingabe von Kommandos legst du jeweils ein Editfenster mit gleicher Breite und 1 Zeile Höhe an die entsprechende Stelle über das TMemo. Bei gleichem Hintergrund und fehlendem Rand ist das Editfenster unsichtbar. Wird die Eingabe mit Enter abgeschlossen, wird das Editfenster gelöscht, die Anzeige 1 Zeile nach oben geschoben und der eingebene Text als nächste Zeile darunter geschrieben. Damit entfallen alle Probleme mit ProcessMessages oder Threads oder blockierter Anwendung. Es gibt ganz windowskonform ein Eingabecontrol und ein Ausgabecontrol. Die Verwendung unsichtbarer Editfenster zur Dateneingabe ist eine bewährte Methode, die ich z.B. in TStringGrids verwende. Gruss Reinhard |
Re: ReadLn() für Fensterprogramme?
Hi :-D
Ich weiss nicht ob ich lachen oder weinen soll :shock: (Absolut nicht böse gemeint :mrgreen:) Ziemlich ähnlich wie du es beschrieben hast (einfach alles in einem TMemo) habe ich es in einer früheren Version von dem Programm gelöst. Ich bin eben gerade daran eine Total Revision des Programms durchzuführen, welches schon 2 Jahre auf dem Buckel hat seit der letzten Version. Deswegen will ich auch alles möglichst sauber und ohne grosse Bastelei (nur dort wo es wegen der ungewöhnlichen Bedienung notwendig ist ;)) machen. Da es mit der alten Lösung diverse Probleme wegen dem TMemo gab (Flackern, Scrollen funktionierte nicht richtig, Parsen der Eingabe gestaltete sich schwierig, wenig Gestaltungsfreiheiten usw.) bin ich auf TImage umgestiegen und verwalte die Zeilenumbrüche und was alles dazu gehört selber. Die Anzeige selber funktioniert auch bestens nur eben die Eingabe bereitet mir Sorgen... :? Siehe Beiträge bezüglich der alten Version: ![]() ![]() Danke für euere Bemühungen :-D Cu Kill0r |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:52 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