myGully.com

myGully.com (https://mygully.com/index.php)
-   Programmierung (https://mygully.com/forumdisplay.php?f=67)
-   -   Windows Api zählt zu weit (https://mygully.com/showthread.php?t=2348609)

CJ3 26.06.11 03:08

Windows Api zählt zu weit
 
Moin moin^^
Ich versuche gerade eine Visual Novel mit meinen Mitteln zu schreiben, aber iwie spinnt Api rum.
Bei WM_KEYUP -> VK_RIGHT sollte nur einmal eine Nachricht kommen, die dann int iX um eines erhöhen soll, dh aus 0 wird 1, aus dem wird 2, und aus dieser 3, usw.
Wenn ich das ganze mache springt iX von 0 auf irgendwas...
Ich blicke nicht durch, was falsch ist, deswegen mal der ganze Code, wobei das ganze unter dem Strich, der Teil ist, wo falsch sein sollte.

Ich bedanke mich für jegliche Hilfe^^
Code:

#include <windows.h>

int iX=0;
const char cLEER[] = "                    ";

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "WindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hwnd;              /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
          0,                  /* Extended possibilites for variation */
          szClassName,        /* Classname */
          "Inazuma Fight!",      /* Title Text */
          WS_OVERLAPPEDWINDOW, /* default window */
          0,                  /* Windows decides the position */
          0,                  /* where the window ends up on the screen */
          600,                /* The programs width */
          550,                /* and height in pixels */
          HWND_DESKTOP,        /* The window is a child-window to desktop */
          NULL,                /* No menu */
          hThisInstance,      /* Program Instance handler */
          NULL                /* No Window Creation data */
          );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

  static RECT  rect;
  static bool  ArrowKeys[4];
 
  switch (message)
  {
  case WM_SIZE:
      {
        rect.left    = 0;
        rect.top    = 0;
        rect.right  = LOWORD(lParam);
        rect.bottom = HIWORD(lParam);
        return 0;
      }

     
      //Knopf runter
  /*case WM_KEYDOWN:
      {
        switch (wParam)
        {
        case VK_RIGHT:
              ++iX; InvalidateRect(hwnd, NULL, TRUE);
              break;
        default:
            return 0;
        }
        InvalidateRect(hwnd, NULL, FALSE);
        return 0;
      }*/
     
      //Hier geht der Knopf dann wieder hoch^^

/*_____________________________________________________________*/

      case WM_KEYUP:
      {
        switch (wParam)
        {
        case VK_LEFT:
            {--iX; break;
            }
        case VK_RIGHT:
            {iX= iX + 1; break;}
        default:
            return 0;
        }
        InvalidateRect(hwnd, NULL, TRUE);
        return 0;
      }
       
       
        //Hier beginnt nun "zeichnen"
      case WM_PAINT:
      {
        if(iX==0)
        {PAINTSTRUCT ps;
          HDC        hDC;

          //Texte
          const char  szText[] = "A CJ0fAil Production";
          const char szText2[] = "Made by CJ0fAil";
          const char szText3[] = "presented only to you ;D";
          //Nun der eigentliche Schreibbefehl

          hDC = BeginPaint(hwnd, &ps);
            {
            char  cX[30];
            int  iStrLen    = 0;
            SIZE  size;
            iStrLen = wsprintf(cX, "iX: %i", iX);
            GetTextExtentPoint32(hDC, cX, iStrLen, &size);
            TextOut(hDC, 555, 490, cX, iStrLen);
            TextOut(hDC, 200, 200-2*20, szText, sizeof(szText) - 1); // zweiter und dritter Parameter
            TextOut(hDC, 200, 200-1*20, szText2, sizeof(szText2) - 1); //bestimmen Position in Pixeln
            TextOut(hDC, 200, 200, szText3, sizeof(szText3) - 1); //letzter Parameter = große der
                                                                // Zeichenkette
                                                                //Eine Zeile ~ 20 Pixel^^
            }
              EndPaint(hwnd, &ps);
        }
       
        if (iX==1)
        {PAINTSTRUCT ps;
        HDC        hDC;

        //Texte
        const char  szText[] = "Inazuma Fight!";

        hDC = BeginPaint(hwnd, &ps);
            {
            char  cX[30];
            int  iStrLen    = 0;
            SIZE  size;
            iStrLen = wsprintf(cX, "iX: %i", iX);
            GetTextExtentPoint32(hDC, cX, iStrLen, &size);
            TextOut(hDC, 555, 490, cX, iStrLen);
            TextOut(hDC, 200, 200-2*20, szText, sizeof(szText) - 1);
            }
        EndPaint(hwnd, &ps);
        }
       
        if(iX=2)
        {PAINTSTRUCT ps;
          HDC        hDC;
         
          const char szText[] = "Once upon a time, in the distant past, there was a team.";
          hDC = BeginPaint(hwnd, &ps);
            {
            char  cX[30];
            int  iStrLen    = 0;
            SIZE  size;
            iStrLen = wsprintf(cX, "iX: %i", iX);
            GetTextExtentPoint32(hDC, cX, iStrLen, &size);
            TextOut(hDC, 555, 490, cX, iStrLen);
            TextOut(hDC, 0, 0, szText, sizeof(szText) - 1);
            }
        EndPaint(hwnd, &ps);
        /*Sleep(1000);
        const char szText2[] = "The team - truly worthy to be called legend... wait for it... dary - a legendary team - was supposed to be the best in Japan.";
        hDC = BeginPaint(hwnd, &ps);
            {
              TextOut(hDC, 0, 0, szText, sizeof(szText) - 1);
              TextOut(hDC, 20, 20, szText2, sizeof(szText) - 1);
            }
        EndPaint(hwnd, &ps);*/
        }
         
         
        return 0;
      }
     
        case WM_DESTROY:
            PostQuitMessage (0);      /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

Mit freundlichen Grüßen,
CJ3

Your_Conscience 26.06.11 07:14

Erstell dir mal noch eine globale bool Variable in der du speicherst, ob die Taste gerade gedrückt wurde oder nicht.
Code:

case WM_KEYUP:
      {
        switch (wParam)
        {
        case VK_LEFT:
            {if (pressedL) {--iX; pressedL = false;} break;
            }
        case VK_RIGHT:
            {if (pressedR) {++iX; pressedR = false;} break;}
        default:
            return 0;
        }
        InvalidateRect(hwnd, NULL, TRUE);
        return 0;
      }

Code:

case WM_KEYDOWN:
      {
        switch (wParam)
        {
        case VK_RIGHT:
              if (!pressedR) {++iX; InvalidateRect(hwnd, NULL, TRUE);}
              break;
        //hier sollte noch die Abfrage für die linke Maustaste hin
        default:
            return 0;
        }
        InvalidateRect(hwnd, NULL, FALSE);
        return 0;
      }


Pillewutz 26.06.11 08:15

@TE: Wer bringt Euch eigentlich bei alles in eine Methode zu schreiben?
Ist wohl übersichtlicher, wenn man am Ende 2000 Zeilen Code in zwei Methode packt.
Dann muss man ja nur zwei Methoden debuggen...

Und sicherheitshalber berechnet man ein und dengleichen Wert mindestens ein dutzend mal!
Kostet zwar Performance und Übersicht, aber sicher ist sicher...

CJ3 26.06.11 13:55

Okay, ich habe jetzt am Anfang zwei bool´sche Variablen "pressedL" und "pressedR" mit "False" initalisiert, deinen Code kopiert, ging leider nicht.

Code:

case WM_KEYDOWN:
      {
        switch (wParam)
        {
        case VK_RIGHT:
              if (!pressedR) {++iX; InvalidateRect(hwnd, NULL, TRUE);}
              break;
        //hier sollte noch die Abfrage für die linke Maustaste hin
        default:
            return 0;
        }
        InvalidateRect(hwnd, NULL, FALSE);
        return 0;
      }

Muss hier nicht auch noch hin, dass wenn VK_RIGHT gedrückt wurde, "pressedR" auf "true" springt? Ging aber auch nicht.



@Pillewutz
Ich weiß, dass ich Methoden verwenden sollte, diese wollte ich dann bei WM_PAINT verwenden, da dort verdammt viel Text und so rein muss.
Problem ist nur, dass wenn ich ganz unten eine draw()-Funktion machen will, es hwnd nicht mehr kennt...

Ich habe nun probiert ++iX mit einer for-Schleife

WM_KEYDOWN:
VK_RIGHT:
for(iXold = iX; iX<iXold + 1; iX++)

berechnen zu lassen und habe danach nochmal das Verhalten von iX mir angeschaut, das Ergebnis: bei int geht iX auf 1 und danach nicht weiter, bei long double blieb iX auf 0

EDIT:
Ich hab keine Ahnung warum aber auf einmal geht es super mit
iX++; InvalidateRect(hwnd, NULL, TRUE);

Danke für eure hilfe kann geschlossen werden =D


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:00 Uhr.

Powered by vBulletin® (Deutsch)
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.