Problem mit der Nachrichtenschleife?



  • Hi,
    ich versuchs ma so knapp wie möglich zu halten^^.

    Ich möchte eine Anwendung schreiben (Fenster [Grundgerüst etc.] steht schon alles) in der man eine Zahl erraten muss.
    Ich habe 2 Boxen als ChildFenster (hBox1 und hBox2), 2 Button (Beenden und Raten).

    Jetzt möchte ich, dass in hBox1 der Text "Höher bzw Tiefer oder Richtig" steht je nachdem wie nah meine Geratene Zahl an der Zufallszahl ist.

    zB ist die Zufallszahl 6. Ich tippe in hBox2 die 22 ein. Dann sollte (im optimalfall ) in hBox1. "Tiefer" stehen. Andersrumm halt dann Höher, wenn ich zB die 2 Eingebe. Treffe ich die 6, soll "Richtig" in hBox1 stehen.

    Leider funktionierts nicht so wie ich das gern hätte. Hier der auszug aus meiner Case anwendung (Sry für das Topic wenn das doch nichts mit der Nachrichtenschleife zutun hat aba bin noch neu in der WinApi^^)

    case ID_Btn_Raten:
                             {
                                if (Zufallszahl < 6)
                                {
                                   SetWindowText (hBox1, "Grösser");
                                   return (0);
                                }
                                if (Zufallszahl > 6)
                                {
                                   SetWindowText (hBox1, "kleiner");
                                   return (0);
    
                                }
                                   SetWindowText (hBox1, "RICHTIG!");
                                   return (0);
    
                             }break;
    

    hab jetzt erstmal Zufallszahl = 6 genommen damit ich besser das Programm testen kann^^

    was hab cih hier falsch gemacht? Mich verwirrt auch immer noch ein wenig, dass ich alles über diese Case (Buttons und Boxen) steuern muss^^ Doch sehr anders als eine Konsole xD

    Danke Schonmal

    Gruss
    Gizm 🙂



  • Ich fürchte du musst uns schon ein bischen mehr Code zeigen. Poste einfach mal die ganze Nachrichtenschleife...



  • //---------------Callback-Funktion----------------
    
    LRESULT CALLBACK WindowProc (HWND hWnd, UINT message,
                                 WPARAM wParam, LPARAM lParam)
    {
       // Nachrichten auswerten
       switch (message)
       {
          // Fenster schließen
          case WM_DESTROY:
               {
                  PostQuitMessage (0);
                  return (0);
               }
    
          // Bei Tastendruck (Escape=schliessen)
          case WM_KEYDOWN:
               {
                  switch (wParam)
                  {
                         case VK_ESCAPE:
                              {
                                 int Resultat2;
    
                                 Resultat2 = MessageBox (hWnd, "Wirklich beenden?",
                                                       "Programm beenden",
                                                       MB_YESNO | MB_ICONQUESTION);
    
                                 // Ja
                                 if (Resultat2 == IDYES)
                                 {
                                 PostQuitMessage (0);
                                 return (0);
                                 }
                                 return (0);
    
                              }
    
                  }
    
               }break;
    
          // Hier die Child-Buttons bearbeiten
    
          case WM_COMMAND:
               {
                  switch (wParam)
                  {
    
                        // Raten Butteon
                        case ID_Btn_Raten:
                             {
                                if (Zufallszahl < 6)
                                {
                                   SetWindowText (hBox1, "Grösser");
                                   return (0);
                                }
                                if (Zufallszahl > 6)
                                {
                                   SetWindowText (hBox1, "kleiner");
                                   return (0);
    
                                }
                                   SetWindowText (hBox1, "RICHTIG!");
                                   return (0);
    
                             }break;
    
                         // Beenden Button
                         case ID_Btn_Beenden:
                              {
                                 int Resultat;
    
                                 Resultat = MessageBox (hWnd, "Wirklich beenden?",
                                                        "Programm beenden",
                                                        MB_YESNO | MB_ICONQUESTION);
    
                                 // Ja
                                 if (Resultat == IDYES)
                                 {
                                    PostQuitMessage (0);
                                    return (0);
                                 }
    
                                 // Nein, Programm weiterlaufen lassen
                                 return (0);
    
                              }
    
                  }break;
               }break;
          }
    
                    // Nicht von uns bearbeitete Nachrichten an Windows Leiten
                    return (DefWindowProc (hWnd, message, wParam, lParam) );
    
               } // Ende von WindowProc
    

    also das wäre jetzt die komplette Callback Funktion die habe... Nachrichtn schleife an sich is ja nur

    // Nachrichtenschleife (Nachrichten abholen, bearbeiten, weiterleiten)
    
       while (GetMessage (&message, NULL, 0, 0) )
       {
          TranslateMessage (&message);
          DispatchMessage  (&message);
       }
    
       // Programm beenden
       return (int) (message.wParam);
    

    hoffe das hilft weiter sonst muss ich vllt mal den ganzen Code schicken aba das könnt ein bisschen viel sein^^



  • Ich gehe mal davon aus, dass das ganze Dialog-basierend ist:

    case WM_COMMAND:
    {
         if(lParam == (LPARAM)GetDlgItem(hWnd, ID_Btn_Raten))
         {
                //if (Zufallszahl < 6)
                                ...
         }
    return 0;
    }break;
    

    und beim anderen Button genauso. Oder hat der Beenden Button bisher getan?



  • Der Beenden Button funktioniert einwandfrei.

    dachte vllt stimmt was mit meiner schleife nicht oder so... Ist mein erstes "grösseres" Projekt mit WinApi und deshalb bin ich mir auch noch bisschen unsicher wo welcher Quellcode reingehört und so^^ aber werd das gleich mal ausprobieren.



  • Also hab es jetzt auch nochmal mit case WM_COMMAND: ausprobiert aber funktioniert trotzdem nicht.

    Weiss echt nicht wo der fehler sein könnte... Hab irgendwie das Gefühl das er die ersten if abfragen für Höher bzw. Tiefer garnicht an nimmt und nur die If-Abfrage für Richtig durchläuft.. 😕



  • weißt du der Variable Zufallszahl eig irgendwo einen wert zu?



  • Matyr schrieb:

    weißt du der Variable Zufallszahl eig irgendwo einen wert zu?

    Ja direkt am Anfang von WinMain.

    Zufallszahl = 6;

    Habs erstmal auf 6 gemacht damit ich das Programm, nach dem Kompilieren, schneller Testen kann.

    int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
                        LPSTR lpcdline, int ncmdshow)
    {
       WNDCLASSEX windowclass; // Struktur Fenstereigenschaften
       HWND       hWnd;        // Handle auf Fenster
       MSG        message;     // Nachricht
    
       // Variablen für Spiel
    
       int GerateneZahl = 0;   // Zahl, die spieler eingibt
       int Versuche = 0;       // Anzahl der Versuche 
       int Punkte;             // Punktzahl
    
       // Zufallszahl ermitteln und speichern
       Zufallszahl = 6;
    


  • Wenn die Zufalszahl = 6 ist, dann ist sie dementsprechend nicht größer als 6 und auch nicht kleiner als 6, somit werden diese beiden if Anweisungen nicht ausgeführt und er springt direkt zu Richtig.

    Mfg. Matyr



  • aso...Oh bemerk grad auch den Fehler...^^

    Ich vergleich die zufallszahl garnicht mit der eingegebenen Zahl des Spielers... Mh.. Ja okay werd mich mal drann setzen uind das korrigieren^^

    Dann muss ich also nicht Zufallszahl > 6 etc , sondern den Inhalt von hBox2 Prüfen... aber geht das so einfach ich zB

    if
    {
    hBox2 > Zufallszahl ...
    etc.

    schreibe?

    EDIT: Oder muss ich erst den Inhalt mit "GetWindowsText()" herrausholen und dann prüfen? also so:

    Spielerzahl > GetWindowsText()....?

    Weil das Text stört michein wenig wenn ich mit zahlen arbeite^^ weiss ja nciht ob die funktion beides behandelt.. zumindest hat es ja mit SetWindowsText auch funktioniert^^



  • ne GetWindowText(...) und anschließend convertieren über stringstream



  • Danke. Werd mich dann da mal durchlesen zu den Strigstreams hab damit noch nicht so viel gemacht. Aber wird hoffendlich dann klappen^^



  • Also hab das mit dem Casten jetzt gemacht, aber dann spuckt der Compiler mir immer noch den Fehler aus das nicht gecastet wurde. Also Fehlermeldung ist:

    "invalid conversion from 'int' to 'char'"

    Mein Ziel ist es ja jetzt, int GerateneZahl, für die überprüfung mit "Zufallszahl" zu benutzen. Also wolte ich erstmal das ergebniss mittels GetWindowText, den Inhalt aus hBox2 speichern und dabei direkt casten:

    int GerateneZahl = static_cast<int> (GetWindowText(hBox2, szZahl, sizeof(szZahl)));
    

    kann ich das etwa nicht mit dem normalen C++ Cast machen? Oder wo liegt hier der fehler?



  • Fehlerbehandlung ist nicht enthalten

    #include <sstream>
    
    int laenge = GetWindowTextLength(hBox2);
    
    char* buf = new char[laenge+1];
    
    GetWindowText(hBox2, buf, laenge);
    
    std::stringstream convert;
    
    convert<<buf;
    int data;
    convert>>buf;
    
    if(buf....
    

  • Mod

    Ein C++ cast geht natürlich nciht.

    Verwende atoi, oder noch einfacher GetDlgItemInt!



  • Matyr schrieb:

    Fehlerbehandlung ist nicht enthalten

    #include <sstream>
    
    int laenge = GetWindowTextLength(hBox2);
    
    char* buf = new char[laenge+1];
    
    GetWindowText(hBox2, buf, laenge);
    
    std::stringstream convert;
    
    convert<<buf;
    int data;
    convert>>buf;
    
    if(buf....
    

    Danke für den Code. Allerdings funktionierts so auch nicht.
    Habs so auf meinen Fall bezogen. Also bis zur If-Anweisung geht alles klar, nur sobald ich eine If Bedingung mit:

    if (buf > Zufallszahl)...
    

    machen möchte meckert mein Compiler:

    ISO C++ forbids comparison between pointer and integer

    Werds dann mal mit dem GetDlgItemInt versuchen. Wie genau funktioniert das? Bzw habt ihr einen guten Link den man sich angucken könnte dazu?

    Gruss
    Gizm



  • sry mein Fehler

    der letzte teil sollte eig folgendes sein:

    int data;
    convert>>data;
    
    if(data...
    


  • Ah Danke. Jetzt funktioniert es. Hab mich auch schon gefragt wofür das Einsamme int Data wohl ist xD
    Jetzt muss icvh ja eigendlich nur noch eine Schleife drummherumm packen damit er nicht nur einmal fragt oder? Denn er Reagiert nur einmal auf das klicken. Muss ich da noch irgendetwas beachten? Irgendwie die EIngabe leeren und dann einfach alles nochmal? Also zB mit einer Do...While-Schleife?



  • kannst mit SetWindowText(...); lehren aber kein plan.

    Das ist schließlich dein Project, daher musst du schon selber wissen was du machen möchtest.
    Und alles sagen hilft ja auch nicht beschäftige dich erstmal damit was der source den ich gepostet habe überhaupt macht.

    Mfg. Matyr


Anmelden zum Antworten