Napisałem program, który rysuje elipsy w podanym przez użytkownika miejscu. Problem polega na tym, że program działa dobrze jakiś czas, a potem dzieją się dziwne rzeczy. W programie rysowane elipsy są czerwone, a tło jest szare. Jak program zaczyna dziwnie działać, elipsy zmieniają kolor na czarny, a belka okna znika i przy próbie przesunięcia okna rozwala się cały windows (wizualnie), aż się nie zamknie programu i nie odświeży pulpitu - wtedy wszystko wraca do normy. Podaję kod:
#include <windows.h>
#include <stdio.h>
POINT pt[1000][2] = {{{0, 0}, {0, 0}}};
HWND uchwytOkna = 0;
int i = 0;
int ostatni = 0;
char belka[100];
LRESULT CALLBACK ProceduraOkna(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void RysujElipse(HWND uO, INT lewo, INT gora, INT prawo, INT dol);
void RysujTlo(HWND u0);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX wndclassex;
wndclassex.cbSize = sizeof (WNDCLASSEX);
wndclassex.style = CS_VREDRAW | CS_HREDRAW;
wndclassex.lpfnWndProc = ProceduraOkna;
wndclassex.cbClsExtra = 0;
wndclassex.cbWndExtra = 0;
wndclassex.hInstance = hInstance;
wndclassex.hIcon = LoadIcon(0, (LPCTSTR)IDI_APPLICATION);
wndclassex.hCursor = LoadCursor(0, (LPCTSTR)IDC_ARROW);
wndclassex.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wndclassex.lpszMenuName = 0;
wndclassex.lpszClassName = "Standardowe Okno";
wndclassex.hIconSm = LoadIcon(0, (LPCTSTR)IDI_APPLICATION);
RegisterClassEx(&wndclassex);
uchwytOkna = CreateWindowEx(
0,
"Standardowe Okno",
"Program \"Rysowanie Elips v. 1.0\" - Elipsy: 0",
WS_OVERLAPPEDWINDOW,
0, 0,
800, 500,
0,
0,
hInstance,
0);
ShowWindow(uchwytOkna, SW_NORMAL);
UpdateWindow(uchwytOkna);
MSG msg;
for (;;)
{
if (0 != GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (msg.message == WM_QUIT) break;
}
return (int)msg.wParam;
}
LRESULT CALLBACK ProceduraOkna(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
MessageBox(hWnd, "Program do rysowania elips.\nMozna narysowac max. 1000 elips.\nz - cofanie\nx - ponawianie\n\nAutor: Michal Pawlowski", "informacja", MB_OK | MB_ICONINFORMATION);
return 0;
case WM_LBUTTONDOWN:
{
pt[i][0].x = LOWORD(lParam);
pt[i][0].y = HIWORD(lParam);
}
return 0;
case WM_LBUTTONUP:
{
if (pt[i][0].x != LOWORD(lParam) && pt[i][0].y != HIWORD(lParam) && i < 1000)
{
pt[i][1].x = LOWORD(lParam);
pt[i][1].y = HIWORD(lParam);
RysujElipse(hWnd, pt[i][0].x, pt[i][0].y, pt[i][1].x, pt[i][1].y);
i++;
ostatni = i;
sprintf(belka, "Program \"Rysowanie elips v. 1.0\" - Elipsy: %d", i);
SetWindowText(hWnd, belka);
}
}
return 0;
case WM_MOUSEMOVE:
if (wParam & MK_LBUTTON)
{
RysujTlo(hWnd);
for(int j = 0; j < i; j++)
RysujElipse(hWnd, pt[j][0].x, pt[j][0].y, pt[j][1].x, pt[j][1].y);
RysujElipse(hWnd, pt[i][0].x, pt[i][0].y, LOWORD(lParam), HIWORD(lParam));
}
case WM_CHAR:
{
if (wParam == 'z' && i > 0)
{
i--;
RysujTlo(hWnd);
for (int j = 0; j < i; j++)
RysujElipse(hWnd, pt[j][0].x, pt[j][0].y, pt[j][1].x, pt[j][1].y);
sprintf(belka, "Program \"Rysowanie elips v. 1.0\" - Elipsy: %d", i);
SetWindowText(hWnd, belka);
}
if (wParam == 'x' && i < ostatni)
{
i++;
RysujTlo(hWnd);
for (int j = 0; j < i; j++)
RysujElipse(hWnd, pt[j][0].x, pt[j][0].y, pt[j][1].x, pt[j][1].y);
sprintf(belka, "Program \"Rysowanie elips v. 1.0\" - Elipsy: %d", i);
SetWindowText(hWnd, belka);
}
return 0;
}
case WM_PAINT:
for (int j = 0; j < i; j++)
RysujElipse(hWnd, pt[j][0].x, pt[j][0].y, pt[j][1].x, pt[j][1].y);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
void RysujElipse(HWND uO, INT lewo, INT gora, INT prawo, INT dol)
{
HDC hdc = 0;
hdc = GetDC(uO);
SelectObject(hdc, CreatePen(PS_SOLID, 1, RGB(255, 0, 0)));
SelectObject(hdc, GetStockObject(NULL_BRUSH));
Ellipse(hdc, lewo, gora, prawo, dol);
ReleaseDC(uO, hdc);
ValidateRect(uO, 0);
DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
}
void RysujTlo(HWND u0)
{
HDC hdc = 0;
hdc = GetDC(u0);
SelectObject(hdc, GetStockObject(NULL_PEN));
SelectObject(hdc, GetStockObject(GRAY_BRUSH));
Rectangle(hdc, 0, 0, 2000, 2000);
ReleaseDC(u0, hdc);
ValidateRect(u0, 0);
}