C-Code mit Fenster "zusammenbringen"



  • Hallo zusammen,

    ich bin gerade total am verzweifeln und brauche dringend ein paar gute Ratschläge. vielleicht zuerst: ich bin noch ein blutiger Anfänger, was die Programmierung angeht........

    Wir müssen für die Schule ein kleines Spiel in C erstellen, optional mit grafischer Oberfläche (ebenfalls in C). In meinem Fall handelt es sich um ein Kartenspiel.

    Das Spiel zur "normalen" Textausgabe in der Konsole ist soweit fertig und nun möchte ich die grafische Oberfläche dazu erstellen.
    Dazu arbeite ich mich bereits geraume Zeit in die Winapi Funktionen ein. Und ich denke mal, dass ich die Grundlagen soweit verstanden habe.

    Aber ich hänge jetzt an einem Punkt fest, zu dem ich einfach nirgendwo weitere Infos zu bekomme. Entweder sind alle Beiträge zur Fensterprogrammierung (und das alles recht allgemein) oder zu C.

    Und nun habe ich auf der einen Seite meinen Spiele-C-Code und auf der anderen Seite mein schönes vorbereitetes Fenster.

    Leider habe ich überhaupt keine Ahnung, wie ich die beiden zusammen bringen soll. Alles, was ich bisher ausprobiert habe, funktioniert einfach nicht die Bohne. Und so langsam läuft mir einfach die Zeit davon (Montag ist Abgabetermin....).

    Kann mir hier jemand Tipps geben oder weiß ein paar gute Links dazu?

    😕

    LG Luja





  • Supi vielen lieben Dank!!!!! Genau nach so etwas habe ich gesucht.

    Ich bin auch schon ein ganzes Stück weiter gekommen.

    Was ich gerade ganz verzweifelt suche:

    Einen Befehl, mit dem ich Buttons deaktivieren kann, ohne dass sie ausgegraut werden.

    Gibt es so einen Befehl? Den einzigen, den ich bisher gefunden habe, ist "EnableWindow". Aber da ich BitmapButtons (als Childwindow) erstellt habe, sehen die dann nicht mehr besonders schön aus.

    Gibt es da noch eine andere Funktion?

    LG Luja.



  • Luja schrieb:

    Einen Befehl, mit dem ich Buttons deaktivieren kann, ohne dass sie ausgegraut werden.

    Gibt es nicht. Das mußt Du selbst programmieren, zB indem Du selbst im Programm eine Statusvariable für aktiviert/deaktiviert verwaltest, und auf einen Buttonklick dann erst mal den Status prüfst. Bei 'deaktiviert' machst Du dann einfach nix.



  • Danke!

    Ist ja eigentlich auch losgisch. Da war es gestern wohl doch schon ein wenig zu spät zum denken.... Und manchmal verrennt man sich einfach in eine Richtung.

    Und nochmal eine blöde Anfängerfrage:

    wie kann ich am besten auf eine Eingabe (Buttonklick) warten? Ich wollte es mit einer Endlos-while-schleife versuchen, aber während dieser ist leider das ganze Fenster blockiert, so dass ich sie nicht durch einen Klick beenden kann.

    Sorry, dass ich so viel frage, aber mir läuft einfach die Zeit davon..... 😞

    LG Luja



  • case WM_COMMAND:
          {
             if (lParam == (LPARAM)Button)
             {
                if (HIWORD(wParam) == BN_CLICKED)
                {
                     MessageBox(NULL, NULL,
                           "Button wurde gedrückt",
                           MB_ICONINFORMATION | MB_OK | MB_DEFBUTTON1);
                }
             }
             return 0;
          }
    


  • Hallo,

    das habe ich in meine WndProc soweit schon eingebaut. Mein Problem ist, dass eine andere Funktion auf das Klicken warten soll.

    Meine WndProc ruft eine Funktion auf, in der das eigentliche Spiel statt findet.
    Und nun soll diese Funktion warten, bis eine Eingabe erfolgt.

    Ich habe jetzt mal mit:

    case WM_COMMAND:
    .
    .
    .
    {
     if (lParam == (LPARAM)hButton_KarteTauschen)
      {
       if (HIWORD(wParam) == BN_CLICKED)
    
    	hButton_KarteTauschen_Klick = CreateEvent(NULL,FALSE,FALSE,NULL);
      }
    .
    .
    .
    

    und in der Funktion:

    WaitForSingleObject(hButton_KarteTauschen_Klick, 1000);
    

    (und ähnliche Varianten herumprobiert. Aber bisher führt nichts dergleichen zum Erfolg.



  • Ich weis nicht ob das in deinem Fall so schlau ist(vielleicht äußert sich da noch jemand anderes dazu) aber es müsste eigentlich klappen wenn du die while-Schleife in einen eigenen Thread setzt und aus dem dann die Funktion mit dem eigentlichen Spiel aufrufst...

    Mfg



  • Hallo,

    äh, das habe ich jetzt nicht so richtig verstanden, was Du meinst......

    Vermutlich ist eh mein halber Code Schrott, weil ich gar nicht so recht weiss, was ich da tue (also bitte nicht hauen!).

    Mein Code sieht bislang grob beschrieben so aus:

    Zwei Dialgoboxen lesen zu Anfang die Namen der Spieler ein, und den Modus für das Spiel(Spieler-Spieler oder Spieler-Computer).

    Innerhalb von WM_PAINT lasse ich ganz zum Schluß nach Zeichnung des Fensters eine Funktion "Spielbeginn" aufrufen (unter der Bedingung z == 0; z wird nach einmaligem Aufruf sofort auf 1 gesetzt, damit die nur einmal aufgerufen wird).

    In der Funktion "Spielbeginn" wird nach einigen Variablen-Initialisierungen mit switch gewählt, welcher Modus ausgeführt werden soll (z.B. ein Spiel gegen den PC). Diese ruft dann die Funktion "Computer" auf.

    Und in "Computer" wiederum findet das Spiel statt. Von hier sende ich dann jeweils die Bilder der Karten an die Buttons. Hier wird auch unsere Funktion für die KI aufgerufen (wenn der PC dran ist) oder eben die Funktion, wenn der Spieler am Zug ist. (So hat das eben alles schön der Reihe nach mit der Konsolenanwendung funktioniert).

    Nun habe ich aber das Problem, dass ich nicht genau weiss, wie ich nun die Userinteraktion da rein bekommen soll. An der Stelle, wo vorher die Funktion "Spiel" aufgerufen wurde oder eben auch in dieser Funktion (das kann ich mir ja aussuchen), muss ich nun eine Interaktion zulassen und auf Klicks warten.

    Ich hatte mir ja erst so schön naiv überlegt, einfach eine Endlos-while-Schleife da einzufügen, die gar nichts macht, ausser immer wieder einen Parameter zu überprüfen:

    in der Funktion "Computer" oder eben "Spiel"(das kann ich noch machen, wie ich möchte):

    while(pause == 0)
    {
    }
    

    Und diesen wollte ich dann durch einen Klick auf den Button auf False setzen.

    case WM_COMMAND:
    .
    .
    .
    {
     if (lParam == (LPARAM)hButton_KarteTauschen)
      {
       if (HIWORD(wParam) == BN_CLICKED)
    
        pause = 1;
      }
    .
    .
    .
    

    Nur: Pustekuchen! -So lange die Funktion wartet bzw nichts tut, ist mein Hauptfenster mit seinen ganzen schönen Buttons blockiert. Ich kann also gar keine Eingaben machen (äh, habe ich schon erwähnt: bitte nicht hauen...?).

    Und da ich bereits bis hierhin schon in verschiedene Funktionen reingesprungen bin, weiss ich jetzt nicht, wie Du das meinst mit nochmal einen Thread mit einer Whileschleife aufmachen und von dort das Spiel aufrufen. Würde dann meine Funktion "Computer" dann nicht trotzdem einfach durchrauschen?
    Ich habe gerade gar keine Ahnung, wie ich meinen Code ansonsten wieder auseinander pflücken und soll.

    Gibt es nicht "einfach" eine Möglichkeit, innerhalb einer beliebigen Funktion zu sagen, warte auf den Klick eines (bestimmten) Buttons und das Hauptfenster mit seinen Childfensters für diese Eingaben "freizugeben"? Ich hatte gehofft, dass, wenn ich von diesen Funktionen ausserhalb von WndProc Nachrichten an diese senden kann, ich doch auch welche von ihr erhalten bzw auf diese warten können müsste.
    Vermutlich bin ich da wirklich ein bißchen naiv, oder?

    Zur Zeit spielt der PC nämlich leider für sich alleine...... Aber immerhin gewinnt er immer! *g*



  • Nochmal ich......

    Ich denke, dass ich dank google verstanden habe, was Du mit neuem Thread meinst. Gute Idee! Die können dann untereinander kommunizieren? Gibt es da irgenwo eine gute Anleitung für Anfänger?



  • mmhm sorry aber von Threads habe ich eigendlich überhaupt keine Ahnung, aber schau dir mal in der msdn CreateThread() und das Beispiel dazu an. Auserdem hab ich hier noch einen Artikel auf CodeProject gefunden.



  • Hallo!

    Ich will mich nochmal ganz herzlich bei Dir (und den anderen natürlich auch) für Deine (und die der anderen) Mühe bedanken!

    Aber ich hab´s jetzt aufgegeben. Bis morgen krieg ich´s nicht mehr hin.... Und diese Threads sind doch wohl eher was für fortgeschrittene Programmierer und nicht für solche DAUs wie mich.
    Ich werde morgen dann doch die Konsolenversion abgeben. Die Doku muss ich ja auch noch machen.

    Naja, shit happens.

    Aber nochmals vielen herzlichen Dank Euch allen.



  • Kein Problem.

    Und lass den Kopf nicht hängen... Einfach immer weitermachen, so hab ich es auch gelernt.

    Mfg



  • Luja schrieb:

    Nun habe ich aber das Problem, dass ich nicht genau weiss, wie ich nun die Userinteraktion da rein bekommen soll. An der Stelle, wo vorher die Funktion "Spiel" aufgerufen wurde oder eben auch in dieser Funktion (das kann ich mir ja aussuchen), muss ich nun eine Interaktion zulassen und auf Klicks warten.

    Ich hatte mir ja erst so schön naiv überlegt, einfach eine Endlos-while-Schleife da einzufügen, die gar nichts macht, ausser immer wieder einen Parameter zu überprüfen:

    in der Funktion "Computer" oder eben "Spiel"(das kann ich noch machen, wie ich möchte):

    while(pause == 0)
    {
    }
    

    Das ist in einem Windows-Programm doch - im Gegensatz zu einem Konsolenprogramm - unnötig. Solange das Windows-Programm nix zu tun hat, wartet es sowieso --> nämlich auf Nachrichten, zB auf WM_COMMAND für einen Button-Click. Wenn der Button gedrückt wird, dann stellst Du das in Deinem case WM_COMMAND: fest und rufst die benötigte Aktion auf, danach wartet die Nachrichtenwarteschleife auf die nächste Nachricht.
    Einen zweiten Thread brauchst Du nur dann, wenn in der Zeit, in der das Programm auf Nachrichten warten soll (zB auf den Buttonclick), noch etwas getan werden soll/muß (wenn zB Berechnungen ausgeführt ausgeführt werden sollen).
    Wenn aber alles so abläuft:
    Programm wartet auf User-Eingabe (Buttonclick oder ähnliches) --> Programm reagiert mit einer Aktion, die max. eine zehntel Sekunde dauert und wartet dann wieder auf die nächste Eingabe usw.
    dann brauchst Du keinen zweiten Thread zu starten.

    Im Prinzip kann man sagen, wenn Deine Konsolenversion ohne zusätzlichen Thread auskommt, dann sollte es die Windowsversion auch, denn auch bei Deiner Konsolenanwendung muß ja wohl die Interaktion mit dem User irgendwie geregelt sein ...



  • Hi,

    @Fatal Error appears: Danke für den Trost! Den kann ich gerade echt gut gebrauchen. Is teinfach immer deprimierend, wenn man sich einen Haufen Arbeit macht und dann letztendlich die "Belohnung" (ein funktionierendes Programm)dafür ausbleibt. Aber in den drei bis vier Wochen, die ich Zeit hatte, "mal eben" Windowsprogrammierung zu lernen, habe ich trotzdem viel geschafft. Muss ich ja mal sagen (und das als Belohnung für weitere Basteleien) akzeptieren.
    Aber es sah einfach schon sooooo gut aus...... 😞
    Ist halt trotzdem deprimierend.

    @Belli: ich konnte einfach den Teil nicht umsetzten, in dem mein Konsolenprogramm mit "scanf" auf eine Eingabe wartet. Das ist eigentlich schon alles. Ich hatte keine Ahnung, was ich da eintragen soll. Genau da muss es eben auf einen Buttonklick warten. Und diese Anweisung fehlt mir einfach. Aber der Rest vom Spiel sollte dann eben doch im Hauptfenster stattfinden und die "Eingaben" per Klick auf die Buttons, die ich als Aktions- und Spielkarten getarnt habe. Im ersten Teil des Spiels bin ich das umgangen, in dem ich Dialogboxen für die Eingaben benutzt habe. Die printf Anweisungen habe ich -je nachdem was gerade auszugeben war- durch Dialogboxen (Nachrichten für den User) oder eben "SendMessage" (Anweisungen an meine Fenster) ersetzt.
    Das ist eigentlich schon "alles".

    Naja, zu spät....... Setzen - sechs!

    Wenn ich mich von dem Ärger ein wenig erholt habe, werde ich sicherlich weiter nerven! 😉 Ich möchte das Spiel ja trotz allem noch zum laufen bringen. Und jetzt habe ich ja Zeit........

    Aber nochmals DANKE! 👍


Anmelden zum Antworten