GDI Animation C ++ не работает должным образом - PullRequest
0 голосов
/ 25 ноября 2011

Я пытаюсь оживить некоторые квадраты, используя класс для этих объектов. когда вызывается метод MoveSquare, квадраты перемещаются только на один шаг, затем они останавливаются

Когда я пытаюсь использовать значение, возвращаемое rand()%50 вместо STEP, квадраты сдвигаются.

Так может кто-нибудь сказать мне, в чем проблема? Почему они не двигаются каждый раз при получении сообщения WM_TIMER. Вот мой код:

#include "Square.h"
#define STEP 10

void Square::DrawSquare(HDC hdc,int rx,int ry, int lx, int ly) {

    Rectangle(hdc,x+rx,y+ry,x+lx,y+ly);
}


void Square::MoveSquare(HWND hwnd_ ,int mod_x_Size,int mod_y_Size) {

       x=x+STEP;
       y=y+STEP;

       InvalidateRect(hwnd_,NULL,TRUE);
}


Square::Square(void) {

    x=0;
    y=0; 
}

Square::~Square(void) {

} 

Функция получения и ответа на системные сообщения

LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {

    PAINTSTRUCT ps;

    HDC hdc;

    Square square[NUMARUL_DE_FIGURI];

       HBRUSH shapeColor;

    switch (msg) {


case WM_SIZE :       
        mod_x_Size = LOWORD (lparam) ;
        mod_y_Size = HIWORD (lparam) ;
        break ;

case WM_TIMER:

     for (int i=0;i<NUMARUL_DE_FIGURI;i++) {
            square[i].MoveSquare(hwnd,mod_x_Size,mod_y_Size);
     }

case WM_PAINT: 

    hdc = BeginPaint(hwnd, &ps);
    hdc = GetDC(hwnd);

   for (int i=0;i<NUMARUL_DE_FIGURI;i++) {

        shapeColor = (HBRUSH)SelectObject(hdc, CreateSolidBrush(RGB(255,255,255)));

        square[i].DrawSquare(hdc,(mod_x_Size/2)-((i*60)+60),(mod_y_Size/2)-((i*60)+60),(mod_x_Size/2)-((i*60)+120),(mod_y_Size/2)-((i*60)+120)); 
    }

    ReleaseDC(hwnd,hdc);

    EndPaint(hwnd, &ps);

    break;

case WM_DESTROY:
       KillTimer(hwnd,1);
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hwnd, msg, wparam, lparam);
    }

    return 0;
}

я установил таймер в основной функции

Ответы [ 2 ]

1 голос
/ 25 ноября 2011
  1. Вызов InvalideRect и UpdateWindow в WM_TIMER событии. Добавьте break; в конце события WM_TIMER. Переход в обработчик WM_PAINT без реального сообщения WM_PAINT не будет иметь эффекта.

  2. В обработчике WM_PAINT используйте HDC, возвращаемый BeginPaint. * не вызов GetDC при обработке WM_PAINT.

РЕДАКТИРОВАТЬ -
Ваш square является локальной переменной для WndProc, и он будет инициализироваться в (0,0) каждый раз, когда вызывается WndProc. Вы можете изменить его на static.

Попробуйте и посмотрите, может ли это решить проблему.

0 голосов
/ 25 ноября 2011

Если вы хотите, чтобы «квадрат» перекрашивался при каждом событии WM_TIMER, то недостаточно просто вызвать InvalidateRect, так как это просто пометит область, как это необходимо для перекраски. Вызовите UpdateWindow, чтобы вызвать новое событие WM_PAINT.

...