Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Jul 09, 2025 11:51

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 20 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Events in Konsole [gelöst]
BeitragVerfasst: Di Feb 26, 2008 18:33 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 07, 2006 13:37
Beiträge: 83
Wohnort: Partenheim
Es ist mir etwas peinlich, aber ich bekomme es einfach nicht hin, in einer simplen Konsolenanwendung eine Schleife solange laufen zu lassen, bis eine Taste gedrückt wurde. Gibt es da eine Art Key-Event, wie es SDL hat?

Conan

_________________
THE TRUTH IS NOT OUT THERE!


Zuletzt geändert von Conan am Do Feb 28, 2008 14:47, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 26, 2008 18:47 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Habe ich auch schon überlegt, aber soetwas gibt es glaube ich nicht. Dazu musst du auf betriebssystemspezifische Funktionen zurückgreifen (wie z.B. GetKeyState) um zu prüfen, ob eine Taste gedrückt wird.

Sonst gibt es noch funktionen wie ReadKey, aber die warten, bis eine Taste gedrückt wurde, daher dürfte das ungünstig sein.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 26, 2008 19:04 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 07, 2006 13:37
Beiträge: 83
Wohnort: Partenheim
Vielen Dank für die Hilfe.
Zu getKeyState finde ich leider nur das C-Interface, nichts für Delphi.
Da es sich ohnehin um eine Serveranwendung handeln wird, wäre es dann am sinnvollsten, den Server einfach durch eine bestimmte Clientnachricht zu beenden?
Wie wird das denn üblicherweise gemacht?

Conan

_________________
THE TRUTH IS NOT OUT THERE!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 26, 2008 20:04 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Hmm... Wenn es nur um das Beenden geht, würde ich mich einfach auf Strg+C verlassen, dass bei Konsolenanwendungen gewöhnlich Lethal wirkt. Was GetKeyState betrifft, das findet sich in der Unit Windows, die Wirkungsweise ist die gleiche wie in C.

Und wenn du das asynchron laufen lassen willst, solltest du bei einem Linuxserver sowieso das starten und beenden über daemons regeln.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 26, 2008 21:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Na ja. Okay. Möglichkeiten gibt es ja genügend. Es kommt immer darauf was du damit vor hast.

Eine andere Möglichkeit wäre auch ein Thread. Den startest du und wärend dessen kannst du Befehle via ReadLn von der Konsole einlesen. Wenn du diese verarbeitest kannst du den Server starten etc.

Strg+C halte ich für nicht so praktisch. Was ist mit Einstellungen die evtl. beim Beenden abgespeichert werden müssen. Hartes abschießen sollte eher nur dazu genutzt werden, wenn nichts mehr geht. Ist zu mindest meine Meinung.

Wenn der Server dauerhaft laufen soll, dann solltest du aber wohl eher über Service / Deamon nachdenken. Und diesen dann je nachdem über ein Webfrontent oder einen extra Client konfigurieren etc. Je nachdem was beliebt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 26, 2008 23:39 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 07, 2006 13:37
Beiträge: 83
Wohnort: Partenheim
Vielen Dank für die Antworten.

Wenn das mit GetKeyState funktioniert, werd' ich das gleich morgen testen, das wäre großartig. Als Alternative die Lösung mit dem Thread, die klingt ebenfalls gut.
Die STRG+C-Lösung ist leider nicht möglich, da ich beim Beenden eben noch ein paar Dinge tun muss.
Diese Daemon-Sache klingt mir noch etwas fremd, daher hoffe ich, dass eine der ersten beiden Alternativen funktioniert.

Nochmal vielen Dank, ich melde mich, wenn ich's getestet hab' :).

Conan

_________________
THE TRUTH IS NOT OUT THERE!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Feb 27, 2008 13:00 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 07, 2006 13:37
Beiträge: 83
Wohnort: Partenheim
Okay, also irgendwie scheint die GetKeyState()-Methode schonmal zu funktionieren.
Aber ich bin noch etwas hilflos mit der Handhabung des Rückgabewertes.
Die Methode gibt mir einen SmallInt, also einen 16Bit vorzeichenbehafteten, ganzzahligen Wert zurück.
In der MSDN-Hilfe steht:
Zitat:
If the high-order bit is 1, the key is down; otherwise, it is up.
If the low-order bit is 1, the key is toggled.


Also bedeutet:
(1) 1000 0000 0000 0000 // die entspr. Taste ist gedrückt
und sobald sie nochmal gedrückt wird, folgt
(2) 1000 0000 0000 0001
da sie getoggelt wurde. Lasse ich anschließend die Taste los, folgt
(3) 0000 0000 0000 0001

So in etwa sieht die Rückgabe auch aus. Wenn keine Taste gedrückt ist, habe ich, je nach Toggle-Zustand, eine 0 oder eine 1. Ist aber eine Taste gedrückt, bekomme ich für Zustand (1) eine -128 und für Zustand (2) eine -127.
Bekomme ich vielleicht doch nur einen ShortInt (also 8 Bit) zurück, denn dann passt der Wert via Zweierkomplement.
Wenn das so ist, gibt es dann eine Möglichkeit, direkt das "high-order" und das "low-order"-Bit auszulesen?

Vielen Dank schonmal,
Conan

_________________
THE TRUTH IS NOT OUT THERE!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Feb 27, 2008 13:56 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Also, wenn ich mich recht entsinne ist ein short in C 8 Bit groß (signed).
Das wiederum bedeutet, dass das High-Order-Bit das Vorzeichen angibt, d.h. wenn die Rückgabezahl < 0 ist, ist die Taste wirklich gedrückt. Um auszulesen, ob das Low-Order-Bit gesetzt wurde, wendest du einfach den and-Operator mit 1 an, also z.B.:
Code:
  1.  
  2. if (GetKeyState(VK_NUMLOCK) and 1 = 1) then // Wenn Numlock aktiviert ist...
  3.  

(Anm.: Bei Numlock und Co kannst du am Toggle-State auslesen, ob es aktiviert bzw. deaktiviert ist.)

@Lossy:
Strg+C löst soweit ich das gesehen habe einen Laufzeitfehler aus, den man definitiv abfangen kann. Das kann man z.B. am NWN-Server sehen, der beim Strg+C noch auf alle Spieler wartet, bis sie draußen sind.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Feb 27, 2008 14:11 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Mein keypressedfunktion siehr wenn ich mich richtig erinnere etwa so aus:

Code:
  1. function KeyPressed(keycode:Word):boolean;
  2. begin
  3.   result:=GetKeyState(keycode)and 128<>0;
  4. end;


Wenn du größere Mengen an Tasten in einem frame prüfen willst, kannst du dir GetKeyboardstate mal ansehen. Je nachdem was du willst könnte auch GetAsyncKeystate nützlich sein,

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Feb 27, 2008 14:21 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
@Conan: Hast du dir schon mal die MSDN Seite zu GetKeyState angesehen?

@Lord Horazont: Okay. Mag sein, dass der Ein oder Andere das so macht. Ich persönlich würde es nicht so machen, denn ein Laufzeitfehler/Exceptions ist in meinen Augen nicht dazu da um einen Status zu übergeben. In etwa so wie die Indy Komponenten die, beim erfolgreichen Beenden einer Verbindung, eine Exception auslösen. Das ist in meinen Augen ein schlechtes Design. Aber ich bin was das angeht auch ein bisschen kleinlich. ;)
Der Server von NWN ist der Windows oder Linux? Denn Windows bricht ja glaube ich die Anwendung ab, oder?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Feb 27, 2008 15:03 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 07, 2006 13:37
Beiträge: 83
Wohnort: Partenheim
Gut, es klappt, vielen Dank für die hilfreichen Antworten.

@Lossy: Ja, da hab' ich die ganzen Informationen über die Rückgabe her. Die Delphi-Hilfe sagt mir allerdings, dass ein 16Bit SmallInt zurückgegeben wird. Es ist aber definitiv ein 8Bit Wert (zumindest wird die achte Position als high-order Bit betrachtet).

@Lord Horazont & The-Winner: Danke, das war genau das, was ich wissen wollte.

Folgender Code verknüpft die Folgen bitweise mit "und", wenn also das high-order Bit gesetzt ist, ist das Ergebnis true:
Code:
  1. GetKeyState(nVirtKey) and 10000000 = 10000000


Eigentlich sehr einfach ...

Also vielen Dank nochmal,
Conan

_________________
THE TRUTH IS NOT OUT THERE!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Feb 27, 2008 17:38 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Lossy eX hat geschrieben:
Der Server von NWN ist der Windows oder Linux? Denn Windows bricht ja glaube ich die Anwendung ab, oder?


Gibts auch für Windows, aber ich rede jetzt vom Linuxserver.
Aber ich meine mich auch zu erinnern, dass ich unter Windows auch nen Laufzeitfehler bekommen habe, den ich hätte abfangen können. Und ich finde, dass das durchaus eine gute lösung ist, die es Entwicklern ermöglicht, das separat zu behandeln oder es eben einfach zu ignorieren, wenn da nichts mehr zu tun ist.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Feb 27, 2008 21:04 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Conan hat geschrieben:
Folgender Code verknüpft die Folgen bitweise mit "und", wenn also das high-order Bit gesetzt ist, ist das Ergebnis true:
Code:
  1. GetKeyState(nVirtKey) and 10000000 = 10000000


Der funktioniert so nicht, da du 10000000 im binärsystem meinst was 128 in dezimal ist.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 28, 2008 00:09 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 07, 2006 13:37
Beiträge: 83
Wohnort: Partenheim
Doch, das funktioniert so. Es handelt sich um einen 8-Bit Vorzeichentyp, daher steht das achte Bit für das Vorzeichen. Im Zweierkomplement entspricht 1000 0000 dann eigentlich -128. Das ist hier aber egal, da es ja nicht um den Zahlenwert an sich geht, sondern nur um das erste und letzte Bit. Das erste verknüpfe ich also einfach via "und" mit einer 1 und teste, ob bei meinem Ergebnis an dieser Position immer noch eine 1 steht. Delphi scheint zu merken, dass ich an dieser Stelle mit 1000 0000 einen Binärwert meine (ein "%" darf ich als Präfix nämlich nicht davor setzen).
Mir wäre es natürlich lieber, wenn ich einfach abfragen könnte, ob an der achten Stelle eine 1 steht. Geht das vielleicht mit diesen Shift-Funktionen shr und shl etwas eleganter?

Conan

_________________
THE TRUTH IS NOT OUT THERE!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 28, 2008 00:42 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Dein code funktioniert zwar, aber nicht so wie du dir das vorstellst:
der short 127 oder 128 den GetKeyState zurückliefert wird in cardinal konvertiert was $FFFFFF80 oder $FFFFFF80 ergibt.
10000000 wird zu $989680 konvertiert. Nun ist $FFFFFF8x and $989680 wieder $989680, weshalb dein code funktioniert.
Also basiert dein code darauf, dass 10000000 ein vielfaches von 128 ist.

Du kannst natürlich wenn dir das lieber ist als die direkten ANDs
GetKeyState(key) and (1 shl 7)=(1 shl 7)
oder
(GetKeyState(key)shr 7) and 1=1 nehmen
und das =128 btw =1 kannst du durch <>0 ersetzen

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 20 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 10 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 16 Queries | GZIP : On ]