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.
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 network • my 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
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?
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 network • my 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
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.
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' .
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?
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:
if(GetKeyState(VK_NUMLOCK)and1=1)then// Wenn Numlock aktiviert ist...
(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 network • my 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
Mein keypressedfunktion siehr wenn ich mich richtig erinnere etwa so aus:
Code:
function KeyPressed(keycode:Word):boolean;
begin
result:=GetKeyState(keycode)and128<>0;
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,
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?
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:
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 network • my 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
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?
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
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.