API Animation und Cls()?



  • Das ist mein Code:

    #include <windows.h>
    #include <math.h>
    #include <conio.h>
    #define NUM      1000
    #define TWOPI   (2 * 3.14159)
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain (HINSTANCE hInstance,
                        HINSTANCE hPrevInstance,
                        PSTR szCmdLine,
                        int iCmdShow)
    
    {
        static TCHAR szAppName[] = TEXT ("Animation");
        HWND hwnd;               /* This is the handle for our window */
        MSG msg;                 /* Here messages to the application are saved */
        WNDCLASS wndclass;       /* Data structure for the windowclass */
    
        wndclass.style           =       CS_HREDRAW | CS_VREDRAW;                 
        wndclass.lpfnWndProc     =       WndProc;
        wndclass.cbClsExtra      =       0;
        wndclass.cbWndExtra      =       0;
        wndclass.hInstance       =       hInstance;
        wndclass.hIcon           =       LoadIcon (NULL, IDI_APPLICATION);
        wndclass.hCursor         =       LoadCursor (NULL, IDC_ARROW);
        wndclass.hbrBackground   =       (HBRUSH) GetStockObject (WHITE_BRUSH);
        wndclass.lpszMenuName    =       NULL;
        wndclass.lpszClassName   =       szAppName;
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClass (&wndclass))
        {
            MessageBox (NULL, TEXT ("Dieses Programm setzt ein aktuelles Betriebsystem vorraus!"), szAppName, MB_ICONERROR);
            return 0;
        }
        /* The class is registered, let's create the program*/
        hwnd = CreateWindow (szAppName,                   /* Extended possibilites for variation */
               TEXT ("Animation mit Polyline"),
               WS_OVERLAPPEDWINDOW,
               CW_USEDEFAULT,
               CW_USEDEFAULT,
               CW_USEDEFAULT,
               CW_USEDEFAULT,
               NULL,
               NULL,        
               hInstance,
               NULL); 
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, iCmdShow);
        UpdateWindow(hwnd);
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&msg, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&msg);
            /* Send message to WindowProcedure */
            DispatchMessage(&msg);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return msg.wParam;
    }
    
    /*  This function is called by the Windows function DispatchMessage()  */
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
            static int cxClient, cyClient;
            HDC hdc;
            int i;
            PAINTSTRUCT ps;
            POINT apt[NUM];
            static int cxLinePlot, cyLinePlot;
        switch (message)                  /* handle the messages */
        {
            case WM_SIZE:
                 cxClient = LOWORD(lParam);
                 cyClient = HIWORD(lParam);
                 cxLinePlot = 0;
                 cyLinePlot = (HIWORD(lParam)/2);
            case WM_PAINT:
    
            hdc = BeginPaint(hwnd, &ps);
            for(;;)
            {
                    if(cxLinePlot==cxClient)
                    {
                                            cxLinePlot = 0;
                    }
                    cxLinePlot++;
                    //horizontaler Mittelstrich
                    MoveToEx(hdc, 0, cyLinePlot, NULL);
                    LineTo(hdc, cxClient, cyLinePlot);
                    //senkrechter Mittelstrich
                    MoveToEx(hdc, cxLinePlot, 0, NULL);
                    LineTo(hdc, cxLinePlot, cyClient);
                    //Quadrat außen Rum
                    MoveToEx(hdc, (cxLinePlot - 50), (cyLinePlot - 50), NULL);
                    LineTo(hdc, (cxLinePlot + 50), (cyLinePlot - 50));
    
                    MoveToEx(hdc, (cxLinePlot + 50), (cyLinePlot - 50), NULL);
                    LineTo(hdc, (cxLinePlot + 50), (cyLinePlot + 50));
    
                    MoveToEx(hdc, (cxLinePlot + 50), (cyLinePlot + 50), NULL);
                    LineTo(hdc, (cxLinePlot - 50), (cyLinePlot + 50));
    
                    MoveToEx(hdc, (cxLinePlot - 50), (cyLinePlot + 50), NULL);
                    LineTo(hdc, (cxLinePlot - 50), (cyLinePlot - 50));
    
                    //Kreuz
                    MoveToEx(hdc, (cxLinePlot - 50), (cyLinePlot - 50), NULL);
                    LineTo(hdc, (cxLinePlot + 50), (cyLinePlot + 50));
    
                    MoveToEx(hdc, (cxLinePlot + 50), (cyLinePlot - 50), NULL);
                    LineTo(hdc, (cxLinePlot - 50), (cyLinePlot + 50));
                    //Zeichnen
                    Polyline(hdc, apt, NUM);
                    Sleep(1);
            }
    
                EndPaint (hwnd, &ps);
                return 0;
            case WM_DESTROY:
                PostQuitMessage(0);       /* send a WM_QUIT to the message queue */
                return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    

    1. Problem: Während der Animation reagiert das Programm nicht, d. h. ich muss es mit Windows beenden.
    2. Problem: Gibt es eine Funktion wie in der Dos - Konsole System("cls"), die ich da anwenden kann? Man soll ja nicht nur einen schwartzen Bildschirm sehen können.
    Vielen dank für die Antworten im Vorraus! 🙂



  • Du hast ja auch eine Endlosschleife, was wunderst Du Dich da, dass Dein Programm nicht mehr reagiert?
    Windows ist Ereignisorientiert... und wenn Du keine Ereignisse mehr zulässt, dann kann Windows nix dafür...

    Bzgl. dem "cls": Hab ich nicht ganz verstanden... oder meinst Du OnEraseBackground ?



  • Kann man das irgendwie ohne ereignis eine animation erstellen, die nicht in einer endlosschleife abgespielt wird?? (z.B. wie hier mit Sleep(x);)
    mit cls meine ich, dass das ganze fenster komplett neu gezeichnet wird, d. h. noch einmal ne schicht weiß drauf, damit das vorherige nicht mehr zu sehen ist, und dann noch einmal eine figur.



  • WM_PAINT darf nicht hängenbleiben also ist ein

    for(;;)
    

    da nix. aber da der threadtitel api animation lautet, vermute ich dass sich was bewegen soll. am einfachsten, aber dafür auch nur begrenzt tauglich ist folgendes:

    das hier kann man zB in die WinMain setzen

    // timer initialisieren
      SetTimer(hWnd,             // handle 
        1,                       // id 
        55,                      // 55 millisekunden 
        (TIMERPROC) NULL);       // kein callback
    

    und das hier in die WndProc

    if(message==WM_TIMER)
    {
      // es gibt nur einen timer, deshalb ist mir die ID egal
      // offset++; // quasi ein counter für den timer
      InvalidateRect(hWnd,NULL,NULL); // neuzeichnen, dabei nicht löschen
    }
    

    ein google mit InvalidateRect könnte dir auch klarheit über dein fehlendes cls() geben..

    InvalidateRect(hWnd,NULL,true);
    

    das löscht vorher den zeichenbereich.

    solange sich nichts bewegt, ist es sinniger, in zB WM_CREATE n bitmap zu zeichnen, das später mit BitBlt nur noch dargestellt wird. doublebuffering benötigst du dann nicht. erst bei animationen wird das wichtig, um flackern zu vermeiden.

    du wirst mit api-animation schnell an deine grenzen stossen. aber man lernt bisschen was dabei. SetTimer ist auch nur begrenzt brauchbar, manche sagen das ding tickt nicht richtig ^^

    grüsse, die katz .. und hello world ausserdem, ich bin neu im forum 🙂



  • auch willkommen 😉
    thx, jetzt läufts


Anmelden zum Antworten