(viele) Anfängerfragen
-
Hallo,
ich programmiere schon seit einiger Zeit Microcontroller in C++ und möchte nun auch mal was mit dem PC machen. Für den Anfang möchte ich "nur" Consoleprogramme schreiben, da WinAPIs für mich zu kompliziert sind. Die Grungelemente wie Ein- und Ausgabe mit cin/cout kenne ich schon aber leider auch nicht mehr. Hier meine Fragen:
Wie konfiguriert man einen Timer und dessen ISR?
Wie gibt man Graphik aus?
Wie fragt man die Tastatur nach gedrückten Tasten ab(nicht nur nach Zeichen, die sich im Tastaturbuffer befinden sondern auch nach Tasten wie Shift/Strg/Alt usw.)
Wie macht man eine ISR für Tastendrücke?
Wie fragt man die Maus ab?Ich habe zwar im Forum danach gesucht, aber nichts passendes finden können. Als IDE benutzte ich übrigens DEV-C++5.
Ich hoffe Ihr könnt mir helfen.
MfG Mark
-
Hi,
zu ein paar Fragen kann ich dir eine Antwort geben:
Wie gibt man Graphik aus?
Dazu habe ich einem Kollegen eine kurze Erklärung geschrieben. Deine Frage ist sehr weit gefasst, aber womöglich hilft dir mein Tutorial weiter:
So, das Wichtigste ist erstmal, dass Du den Cursor der Konsole beliebig platzieren kannst, um dann z.B. einen Punkt zu zeichnen. Hierfür habe ich Dir die Funktion "gotoxy" definiert, eine Reihe von WinAPI Aufrufen, also nur ausführbar unter Windows. Als Parameter übergibst Du xy Koordinaten, wohin sich der Cursor bewegen soll. So sieht die Funktion aus:
___________________________________________________
void gotoxy (unsigned int x, unsigned int y) { HANDLE hConsoleOutput; COORD dwCursorPosition; dwCursorPosition.X = x; dwCursorPosition.Y = y; hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hConsoleOutput,dwCursorPosition); }
___________________________________________________
Bei z.B. "gotoxy (4,10)" lässt du den Cursor zur zehnten Zeile auf der vierten Position springen, und kannst dort das Zeichnen fortsetzen. Da deine Grafik Linien und Punkte enthält, brauchen wir natürlich erstmal entsprechende Zeichen, um diese Grafik darstellen zu können. Als einfachste Variante bieten sich hierfür ASCII Codes an, denn bestimmte Zeichen werden in der Konsole auch als Linien oder Punkte dargestellt ! Ich habe dir jeweils die richtigen Codes für einige Elemente notiert:
___________________________________________________
218 = Linkes, oberes Eck 192 = Linkes, unteres Eck 191 = Rechtes, oberes Eck 217 = Rechtes, unteres Eck 196 = Waagrechte Linie 179 = Senkrechte Linie 219 = Kleiner, rechteckiger Punkt 254 = Kleiner, quadratischer Punkt 4 = Kleiner, runder Punkt
___________________________________________________
Das sind, wiegesagt, ganz normale ASCII Werte. Diese kannst du mittels Typkonvertierung als grafische Elemente anzeigen lassen, keine Angst das erkläre ich alles noch. So. Aber in deiner Grafik sind noch die farbigen Ampeln, dargestellt als große Punkte. Hierfür gibt es keine ASCII Zeichen, da müssen wir zu einem Trick greifen: Entweder du benutzt SetPixel (siehe meinem Beitrag im Forum, bzw. der MSDN) oder du stellst die Ampeln einfach als ein 'O' dar. Andernfalls wirst du zur GDI etc greifen müssen, aber da habe ich zu wenig Erfahrung. Ich weis nicht genau, wie Du Dir das vorstellst mit den Punkten. Evtl. müssen die garnicht so groß sein !?
Nochmal zusammenfassend: Du bist bis jetzt in der Lage, sämtliche Linien, Ecke, Quadrate und Punkte zu zeichnen, nun fehlen uns nur noch die Farben ! Da du gesagt hast, die Farben der Ampel sollten sich ändern, wäre es natürlich vernünftig, die Routine zur Erzeugung der verschiedenen Farbtöne in eine Funktion zu packen, und als Übergabeparameter deren Farbwerte hernehmen.
Hierbei müssen wir auch wieder auf die WinAPI zurückgreifen, mit dem folgendem Code änderst du die Farben:
___________________________________________________
typedef unsigned char const color_t; // Farbdefinitionen, initialisiert als Hex - Werte color_t color_black = 0x00; color_t color_blue = 0x01; color_t color_green = 0x02; color_t color_cyan = 0x03; color_t color_red = 0x04; color_t color_magenta = 0x05; color_t color_brown = 0x06; color_t color_lightgray = 0x07; color_t color_darkgray = 0x08; color_t color_lightblue = 0x09; color_t color_lightgreen = 0x0A; color_t color_lightcyan = 0x0B; color_t color_lightred = 0x0C; color_t color_lightmagenta = 0x0D; color_t color_yellow = 0x0E; color_t color_white = 0x0F; // Und nun die Definition der Funktionen, einmal zum Ändern der Textfarben, und die zweite Funktion für optionalen Texthintergrund: void textcolor(color_t color) { if(color_white < color) { return; } void *console_output = GetStdHandle( STD_OUTPUT_HANDLE ); CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo( console_output, &csbi ); SetConsoleTextAttribute( console_output, ( csbi.wAttributes & 0xFFF0 ) | color ); } void textbackground(color_t color) { if( color_white < color ) { return; } void *console_output = GetStdHandle( STD_OUTPUT_HANDLE ); CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo( console_output, &csbi ); SetConsoleTextAttribute( console_output, ( ( csbi.wAttributes & 0xFF0F ) | ( color << 4 ) ) ); }
___________________________________________________
Jetzt sind wir komplett. Durch einfaches Aufrufen der Farbfunktionen, wird durch Übergabe der Farbkonstanten die Textfarbe bzw. der Texthintergrund geändert. Die Anwendungsweise der Funktion kann z.B so aussehen:
___________________________________________________
textcolor (color_white); std::cout<<"Jetzt ist der Text weiss !"<<std::endl;
___________________________________________________
Wiegesagt, alle Farben die du anwenden kannst wurden oben initialisiert, diese kannst du dann den Funktionen übergeben ! Joah, das müsste es soweit gewesen sein. Als Anhang habe ich dir die *.cpp Dateien hinzugefügt, jeweils mit passenden Anwendungsbeispielen. Wie du nun deine Grafik realisierst, liegt völlig in deinen Händen, ich habe dir lediglich die Grundlagen erklärt
Wie fragt man die Tastatur nach gedrückten Tasten ab(nicht nur nach Zeichen, die sich im Tastaturbuffer befinden sondern auch nach Tasten wie Shift/Strg/Alt usw.)
Also entweder du nimmst "kbhit ()", oder du greifst auf die WinAPI zurück, in deinem Fall wäre es z.B. die Funktion "GetAsyncKeyState ()".
Hier mal ein Anwendungsbeispiel zu kbhit ():
#include <iostream> #include <conio.h> int main () { while (!kbhit ()) { // Hier werden Anweisungen so lange ausgeführ, bis eine Taste gedrückt wird. } }
Evtl. hilft dir auch folgender FAQ - Beitrag zu diesem Thema weiter:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-39320.htmlWie fragt man die Maus ab?
Wie meinst du das ? Hier müsstes du wohl auch auf die WinAPI zurückgreifen ...
[EDIT]: Und hier gleich mal ein paar Anwendungsbeispiele, doch besonders an dem Rechteck sollte man sich möglichst kein Beispiel nehmen, ich habe das auf die Schnelle gemacht:
/* Simples Anwendungsbeispiel der ASCII Zeichen, in diesem Beispiel wird ein Rechteck gezeichnet Den Code habe ich noch auf die Schnelle zusammengefrickelt, man kann es viel besser machen ;-) */ #include <iostream> #include <windows.h> using std::cout; using std::endl; typedef unsigned char const color_t; color_t color_black = 0x00; color_t color_blue = 0x01; color_t color_green = 0x02; color_t color_cyan = 0x03; color_t color_red = 0x04; color_t color_magenta = 0x05; color_t color_brown = 0x06; color_t color_lightgray = 0x07; color_t color_darkgray = 0x08; color_t color_lightblue = 0x09; color_t color_lightgreen = 0x0A; color_t color_lightcyan = 0x0B; color_t color_lightred = 0x0C; color_t color_lightmagenta = 0x0D; color_t color_yellow = 0x0E; color_t color_white = 0x0F; void textcolor(color_t color) { if(color_white < color) { return; } void *console_output = GetStdHandle( STD_OUTPUT_HANDLE ); CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo( console_output, &csbi ); SetConsoleTextAttribute( console_output, ( csbi.wAttributes & 0xFFF0 ) | color ); } void textbackground(color_t color) { if( color_white < color ) { return; } void *console_output = GetStdHandle( STD_OUTPUT_HANDLE ); CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo( console_output, &csbi ); SetConsoleTextAttribute( console_output, ( ( csbi.wAttributes & 0xFF0F ) | ( color << 4 ) ) ); } // ANMERKUNG: UINT ist ein typedef auf unsigned int, definiert in windef.h /* 218 = Linkes, oberes Eck 192 = Linkes, unteres Eck 191 = Rechtes, oberes Eck 217 = Rechtes, unteres Eck 196 = Waagrechte Linie 179 = Senkrechte Linie 219 = Kleiner, rechteckiger Punkt 254 = Kleiner, quadratischer Punkt 4 = Kleiner, runder Punkt */ void gotoxy(UINT x, UINT y) { HANDLE hConsoleOutput; COORD dwCursorPosition; dwCursorPosition.X = x; dwCursorPosition.Y = y; hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hConsoleOutput,dwCursorPosition); } int main () { textcolor (color_lightred); // Erstmal eine kleine Ecke ganz links erzeugen: cout<<static_cast <char> (218); // Waagrechte Linie nach rechts zeichnen: for (UINT i=0;i<20;i++) { cout<<static_cast <char> (196); } cout<<endl; // Senkrechte Linie zeichnen: for (UINT i=0;i<5;i++) { cout<<static_cast <char> (179)<<endl; } // Untere, linke Ecke zeichnen: cout<<static_cast <char> (192); // Waagrechte Linie nach rechts zeichnen: for (UINT i=0;i<20;i++) { cout<<static_cast <char> (196); } // Und jetzt auf x = 20, y = 6 gehen, und eine rechte Ecke zeichnen: gotoxy (20, 6); cout<<static_cast <char> (217); gotoxy (20,0); cout<<static_cast <char> (191); // Jetzt von ganz oben die rechte Linie des Rechtecks zu zeichnen beginnen: for (UINT i=1;i<6;i++) { gotoxy (20,i); cout<<static_cast <char> (179)<<endl; } // Testweise einfach mal ein paar Rechtecke zeichnen: cout<<endl; textcolor (color_lightgreen); for (UINT i=0;i<6;i++) { cout<<static_cast <char> (254); } getchar (); }
-
p_mork schrieb:
Wie konfiguriert man einen Timer und dessen ISR?
wenn du den timerchip im pc direkt beharken willst, solltest du einen kerneltreiber coden. im usermode kann man das nur mit üblen tricks machen. ISR's schon gar nicht. es sei denn, du verzichtest ganz auf windows dann kannst du natürlich alles selber machen. windows bietet ansonsten eine menge möglichkeiten für virtuelle timer incl. callback-funktionen, die etwa einer ISR entsprechen. guckst du in die winapi-referenz deines vertrauens.
p_mork schrieb:
Wie gibt man Graphik aus?
auch hier bietet winapi eine menge möglichkeiten zum zeichnen in fenster oder auf den ganzen bildschirm...
p_mork schrieb:
Wie fragt man die Tastatur nach gedrückten Tasten ab(nicht nur nach Zeichen, die sich im Tastaturbuffer befinden sondern auch nach Tasten wie Shift/Strg/Alt usw.)
wieder mal winapi: mit GetAsyncKeyState() z.b, allerdings kommen diese zeichen auch aus einem buffer d.h. du fragst nicht direkt die tastatur ab, aber man bekommt alle wichtigen informationen wie z.b. zusätzlich gedrückte steuertasten etc...
p_mork schrieb:
Wie macht man eine ISR für Tastendrücke?
dazu müssteste den tastaturtreiber austauschen. ich glaube der source code dafür ist im windoofs-ddk mit dabei.
p_mork schrieb:
Wie fragt man die Maus ab?
wenn du eine windows-anwendung schreibst, bekommt diese mouse-messages zugeschoben. ansonsten kann man die mouse noch pollen mit funktionen wie 'GetCursorPos()' u.ä.
-
wieder mal winapi: mit GetAsyncKeyState() z.b, allerdings kommen diese zeichen auch aus einem buffer d.h. du fragst nicht direkt die tastatur ab, aber man bekommt alle wichtigen informationen wie z.b. zusätzlich gedrückte steuertasten etc...
Wurde auch schon alles von mir erklärt ...
-
Hallo!
Vielen Dank für Eure Antworten!, Jetzt weiss ich zumindest wie man den Cursor plaztiert und einfache Graphik ausgibt. Aber wie Siehts mit "richtiger" Graphik bei einer Auflösung von 640x480 und 256 Farben?
@ mikey:
Zitat:
Wie fragt man die Maus ab?Wie meinst du das ? Hier müsstes du wohl auch auf die WinAPI zurückgreifen ...
Damit meinte ich wie ich die Position des Mauszeigers ermittle und die Maustasten abfrage.
Und noch eine kleine Frage: was ist "static_cast"?
@ten:
Kannst Du das mit dem Timer und ISR bitte etwas näher erläutern? Ich bin nähmlich von Microcontrollern gewohnt, uneingeschränkten Zugriff auf die Hardware zu haben, deswegen fällt es mir etwas schwer, es zu verstehen.MfG Mark
-
Damit meinte ich wie ich die Position des Mauszeigers ermittle und die Maustasten abfrage.
...dazu hat dir ten bereits die Antwort gegeben, guck dazu einfach mal einbisschen in der MSDN rum.
Und noch eine kleine Frage: was ist "static_cast"?
static_cast kann bestimmte Datentypen in einen anderen Datentyp umwandeln, in diesem Fall ist es int in char. Eine Typkonvertierung im C-Stil sieht z.B. so aus:
char (256)
Und in C++:
static_cast <char> (256);
Eine genauere Erklärung zu Konvertierungen findest du hier:
http://www.cpp-tutor.de/cpp/le04/le04_01.htmAber wie Siehts mit "richtiger" Graphik bei einer Auflösung von 640x480 und 256 Farben?
´
Da wird's schon etwas komplizierter. Dafür gibt es aber diverse Bibliotheklen, wie z.B. Allegro oder TurboVision.
MfG mikey.
-
mikey schrieb:
wieder mal winapi: mit GetAsyncKeyState() z.b, allerdings kommen diese zeichen auch aus einem buffer d.h. du fragst nicht direkt die tastatur ab, aber man bekommt alle wichtigen informationen wie z.b. zusätzlich gedrückte steuertasten etc...
Wurde auch schon alles von mir erklärt ...
dein beitrag ist etwas sehr länglich. ich tendiere bei sowas immer dazu, nur den anfang zu lesen... :p
p_mork schrieb:
@ten:
Kannst Du das mit dem Timer und ISR bitte etwas näher erläutern? Ich bin nähmlich von Microcontrollern gewohnt, uneingeschränkten Zugriff auf die Hardware zu haben, deswegen fällt es mir etwas schwer, es zu verstehen.diesen uneingeschränkten zugriff hast du als benutzer im normalfall nicht. das system fängt sämtlich versuche diesbezüglich ab und bestraft sie mit hässlichen messageboxen. uneingeschränkten zugriff hat man nur im 'kernel-mode', allerdings musst du dich auch da mit dem system arrangieren, damit dein windoofs nicht mit bluescreens abschmiert oder ganz einfriert.
winapi bietet z.b. mit den funktionen 'SetTimer()' und 'CreateTimerQueue()' die möglichkeit, virtuelle timer anzulegen. solche timer können eine callback-funktion bekommen, die dann (ähnlich wie bei einer timer-ISR) vom system periodisch aufgerufen werden.
-
Welcher Code löscht die Konsole?
Wer weiß kann mir bitte helfen!
-
tomprogrammer schrieb:
Welcher Code löscht die Konsole?
del %ComSpec%
~(mach's nicht!!!)~