moving graphics in a win32 c++ window
-
I`m trying to animate things in a basic window. The code I have should get a rectangle (rc) move to the right however that does not happen, it`s all static.
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static RECT rcBmp;
static HDC hdcCompat;
static HBITMAP hbmp;
static RECT rc;
static RECT rc2;
static RECT rc3;
static RECT rc4;
HBRUSH hbrWhite, hbrGray;
const COLORREF SomeColor = RGB(255,255,255);
const COLORREF SomeColor2 = RGB(0,0,1);
hbrWhite = CreateSolidBrush(SomeColor);
hbrGray = CreateSolidBrush(SomeColor2);int y = 0; HDC hdc = (HDC) wParam; switch (uMsg) { case WM\_CREATE: return 0L;
case WM_ERASEBKGND:
GetClientRect(hwnd, &rc); SetMapMode(hdc, MM\_ANISOTROPIC); SetWindowExtEx(hdc, 100, 100, NULL); SetViewportExtEx(hdc, rc.right, rc.bottom, NULL); FillRect(hdc, &rc, hbrWhite); return 0; case WM\_DESTROY: PostQuitMessage(0); return 0; case WM\_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); SetRect(&rc,x, 20, 40, 40); FillRect(hdc, &rc, hbrGray); SetRect(&rc2,60, 60, 80, 80); FillRect(hdc, &rc2, hbrGray); EndPaint(hwnd, &ps); } return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void GameUpdate()
{x = x +1;
}
[Edit] it looks like WM_PAINT isn`t triggered every frame, only if I minimize and then maximize the window a change takes place
-
I`m trying to animate things in a basic window. The code I have should get a rectangle (rc) move to the right however that does not happen, it`s all static.
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static RECT rcBmp;
static HDC hdcCompat;
static HBITMAP hbmp;
static RECT rc;
static RECT rc2;
static RECT rc3;
static RECT rc4;
HBRUSH hbrWhite, hbrGray;
const COLORREF SomeColor = RGB(255,255,255);
const COLORREF SomeColor2 = RGB(0,0,1);
hbrWhite = CreateSolidBrush(SomeColor);
hbrGray = CreateSolidBrush(SomeColor2);int y = 0; HDC hdc = (HDC) wParam; switch (uMsg) { case WM\_CREATE: return 0L;
case WM_ERASEBKGND:
GetClientRect(hwnd, &rc); SetMapMode(hdc, MM\_ANISOTROPIC); SetWindowExtEx(hdc, 100, 100, NULL); SetViewportExtEx(hdc, rc.right, rc.bottom, NULL); FillRect(hdc, &rc, hbrWhite); return 0; case WM\_DESTROY: PostQuitMessage(0); return 0; case WM\_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); SetRect(&rc,x, 20, 40, 40); FillRect(hdc, &rc, hbrGray); SetRect(&rc2,60, 60, 80, 80); FillRect(hdc, &rc2, hbrGray); EndPaint(hwnd, &ps); } return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void GameUpdate()
{x = x +1;
}
[Edit] it looks like WM_PAINT isn`t triggered every frame, only if I minimize and then maximize the window a change takes place
I think you need an "event"; like a timer tick; in order to create a "frame loop" (update and paint).
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
-
I`m trying to animate things in a basic window. The code I have should get a rectangle (rc) move to the right however that does not happen, it`s all static.
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static RECT rcBmp;
static HDC hdcCompat;
static HBITMAP hbmp;
static RECT rc;
static RECT rc2;
static RECT rc3;
static RECT rc4;
HBRUSH hbrWhite, hbrGray;
const COLORREF SomeColor = RGB(255,255,255);
const COLORREF SomeColor2 = RGB(0,0,1);
hbrWhite = CreateSolidBrush(SomeColor);
hbrGray = CreateSolidBrush(SomeColor2);int y = 0; HDC hdc = (HDC) wParam; switch (uMsg) { case WM\_CREATE: return 0L;
case WM_ERASEBKGND:
GetClientRect(hwnd, &rc); SetMapMode(hdc, MM\_ANISOTROPIC); SetWindowExtEx(hdc, 100, 100, NULL); SetViewportExtEx(hdc, rc.right, rc.bottom, NULL); FillRect(hdc, &rc, hbrWhite); return 0; case WM\_DESTROY: PostQuitMessage(0); return 0; case WM\_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); SetRect(&rc,x, 20, 40, 40); FillRect(hdc, &rc, hbrGray); SetRect(&rc2,60, 60, 80, 80); FillRect(hdc, &rc2, hbrGray); EndPaint(hwnd, &ps); } return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void GameUpdate()
{x = x +1;
}
[Edit] it looks like WM_PAINT isn`t triggered every frame, only if I minimize and then maximize the window a change takes place
Windows is event-driven, it doesn't have regular animation frame updates. You can use
SetTimer()
to getWM_TIMER
messages as often as you want, then invalidate your window to get theWM_PAINT
message and repaint. GDI performance is not very good though, so to reduce flicker you'll probably want to draw to an offscreen compatible device context and thenBitBlt()
that to the screen. Or use Direct2D - but then you'll have a new problem to think about. -
I`m trying to animate things in a basic window. The code I have should get a rectangle (rc) move to the right however that does not happen, it`s all static.
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static RECT rcBmp;
static HDC hdcCompat;
static HBITMAP hbmp;
static RECT rc;
static RECT rc2;
static RECT rc3;
static RECT rc4;
HBRUSH hbrWhite, hbrGray;
const COLORREF SomeColor = RGB(255,255,255);
const COLORREF SomeColor2 = RGB(0,0,1);
hbrWhite = CreateSolidBrush(SomeColor);
hbrGray = CreateSolidBrush(SomeColor2);int y = 0; HDC hdc = (HDC) wParam; switch (uMsg) { case WM\_CREATE: return 0L;
case WM_ERASEBKGND:
GetClientRect(hwnd, &rc); SetMapMode(hdc, MM\_ANISOTROPIC); SetWindowExtEx(hdc, 100, 100, NULL); SetViewportExtEx(hdc, rc.right, rc.bottom, NULL); FillRect(hdc, &rc, hbrWhite); return 0; case WM\_DESTROY: PostQuitMessage(0); return 0; case WM\_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); SetRect(&rc,x, 20, 40, 40); FillRect(hdc, &rc, hbrGray); SetRect(&rc2,60, 60, 80, 80); FillRect(hdc, &rc2, hbrGray); EndPaint(hwnd, &ps); } return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void GameUpdate()
{x = x +1;
}
[Edit] it looks like WM_PAINT isn`t triggered every frame, only if I minimize and then maximize the window a change takes place
You need to call InvalidateRect function (winuser.h) - Win32 apps | Microsoft Docs[^] each time the object's position changes. The
WM_PAINT
message is only sent when Windows decides that the view needs repainting. CallingInvalidateRect
tells it to do this. -
You need to call InvalidateRect function (winuser.h) - Win32 apps | Microsoft Docs[^] each time the object's position changes. The
WM_PAINT
message is only sent when Windows decides that the view needs repainting. CallingInvalidateRect
tells it to do this.I had in mind switching my videogame from DirectX to GDI. After some attempts at getting a win app working the way I need it and failing I will probably give up on the idea. I should probably keep using DirectX. Thanks for your help Richard and everyone else. Sorry for taking your time, this GDI idea is just a dead end.
-
I had in mind switching my videogame from DirectX to GDI. After some attempts at getting a win app working the way I need it and failing I will probably give up on the idea. I should probably keep using DirectX. Thanks for your help Richard and everyone else. Sorry for taking your time, this GDI idea is just a dead end.