Возникли проблемы при вводе кода многократного использования в подпрограмму

Я пытаюсь лучше понять причуды Visual C ++. Таким образом, я подошел к этапу, на котором я создаю программу, которая запускается как пустое окно, но когда вы щелкаете по ней, появляется контрольная доска из красных и синих квадратов (это плохо для глаз, но работает). Квадраты также чередуются между двумя цветами, если вы нажимаете на них снова. Каждый квадрат имеет размер 100×100 пикселей, и у меня в папке проекта есть файлы изображений для них (я знаю, что могу использовать последние два целых числа BitBlt использовать одно изображение, наполовину синее, наполовину красное и, следовательно, не нужное toPaintно это не проблема здесь)

Вот как сейчас выглядит моя процедура рисования (и она работает нормально, все, что здесь не объявлено, является глобальной переменной):

case WM_PAINT:
{
// 'HDC hdc' declared before the switch statement
// 'PAINTSTRUCT ps' declared before the switch statement
// 'hWnd' is the first argument to WndProc()
hdc = BeginPaint(hWnd, &ps);

HBITMAP toPaint = NULL;
BITMAP bm;

// 'xcor' and 'ycor' are the coordinates of the last left-click
// 'int counters[][]' keeps track of the number of left-clicks in each square
// 'blue' and 'red' are HBITMAPs initialized in case WM_CREATE
if (counters[xcor / 100][ycor / 100] % 2 == (xcor / 100 + ycor / 100) % 2)
toPaint = blue;
else
toPaint = red;

HDC hdcMem = CreateCompatibleDC(hdc);
HGDIOBJ hbmOld = SelectObject(hdcMem, toPaint);
GetObject(toPaint, sizeof(bm), &bm);
BitBlt(hdc, xcor - xcor % 100, ycor - ycor % 100, 100, 100, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);

EndPaint(hWnd, &ps);

break;
}

Теперь, когда бы я ни изменял размер окна, либо увеличивал, либо просто перетаскивал края, все перекрашивалось, и поскольку сохранялся только один щелчок левой кнопкой мыши, он рисовал только один квадрат, а остальные возвращались к стандартному серому цвету. , Поэтому я решил поймать WM_SIZE и перерисовать все квадраты, которые были нарисованы до этого момента:

case WM_SIZE:

hdc = BeginPaint(hWnd, &ps);
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 20; j++)
{
// checks whether that square has been drawn before
if (counters[i][j] == 0)
continue;

HBITMAP toPaint = NULL;
BITMAP bm;
if (counters[i][j] % 2 == (i + j) % 2)
toPaint = blue;
else
toPaint = red;

HDC hdcMem = CreateCompatibleDC(hdc);
HGDIOBJ hbmOld = SelectObject(hdcMem, toPaint);
GetObject(toPaint, sizeof(bm), &bm);
BitBlt(hdc, i*100, j*100, 100, 100, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);}
}
EndPaint(hWnd, &ps);

break;

Как видите, все внутри самое сокровенное forпетля, после первого if— более или менее точная копия того, что у меня было в моем WM_PAINT случай, который я считаю хорошим признаком того, что эти строки должны быть помещены в собственный вызов функции, что-то вроде DrawSquare(HWND hWnd, int i, int j, HDC handle, PAINTSTRUCT ps), Однако я не могу понять, как ориентироваться во всех указателях, ссылках и копиях. Я могу получить что-то, что компилируется, но тогда это не будет ничего рисовать.

Как бы я написал такой DrawSquare()?

0

Решение

Ну, это было проще, чем я ожидал. С помощью

void DrawSquare(HWND hWnd, HDC hdc, int x, int y)
{
HBITMAP toPaint = NULL;
BITMAP bm;
if (counters[x][y] % 2 == (x + y) % 2)
toPaint = blue;
else
toPaint = red;

HDC hdcMem = CreateCompatibleDC(hdc);
HGDIOBJ hbmOld = SelectObject(hdcMem, toPaint);
GetObject(toPaint, sizeof(bm), &bm);
BitBlt(hdc, x * 100, y * 100, 100, 100, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);

// Thanks to the comment below, to avoid memory leak
DeleteDC(hdcMem);
}

без PAINTSTRUCT работал нормально (так как я не использую его явно). Теперь мои дела выглядят так:

case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
DrawSquare(hWnd, hdc, xcor / 100, ycor / 100);

EndPaint(hWnd, &ps);

break;

case WM_SIZE:

hdc = BeginPaint(hWnd, &ps);
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 20; j++)
{
if (counters[i][j] == 0)
continue;
DrawSquare(hWnd, hdc, i, j);

}
}
EndPaint(hWnd, &ps);

break;

что намного лучше, чем у меня было.

1

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector