#c #api #winapi #gdi
#c #API #winapi #gdi
Вопрос:
Как я могу очистить определенный прямоугольник? Я отображаю круги и текст внутри каждого круга (вывод текста) в окне. Я пытаюсь реализовать это так, чтобы при нажатии левой кнопки мыши на определенный круг круг и текст исчезали, то есть очищать прямоугольник, в котором расположены круг и текст.
#include <windows.h>;
#include <ctime>
#include <cmath>
struct Cell {
int x, y;
struct rgb {
int r, g, b,z;
}
mainColor,
borderColor,
circleColor,
textColor,
circleSize,
circleBorderColor;
};
HWND hWnd;
HDC hdc;
HPALETTE hPal;
BOOL bForceBkgd;
COLORREF color;
HBRUSH brush;
const int rectSize = 90;
const int circleSize = 40;
int y = 0, x = 0, yCoord, xCoord;
char buf[50];
bool flag = 0;
Cell cells[7][7];
HINSTANCE hInst; //Дескриптор програми
LPCTSTR szWindowClass = "QWERTY";
LPCTSTR szTitle = " ";
// Попередній опис функцій
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
bool isInCircle(int x, int y, int x0, int y0, int R) {
if (pow((x - x0), 2) pow((y - y0), 2) <= pow(R, 2)) {
return true;
}
return false;
}
// main program
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
srand(time(NULL));
MSG msg;
// window class register
MyRegisterClass(hInstance);
// creating a program window
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
// messages processing cycle
while (GetMessage(amp;msg, NULL, 0, 0))
{
TranslateMessage(amp;msg);
DispatchMessage(amp;msg);
}
return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_SHIELD);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = GetSysColorBrush(COLOR_WINDOW 3);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
return RegisterClassEx(amp;wcex);
}
// FUNCTION: InitInstance (HANDLE, int)
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance;
hWnd = CreateWindow(szWindowClass, // window class name
szTitle, // program name
WS_OVERLAPPED | WS_SYSMENU,
400, // position on x
0, // position on y
718,
790,
NULL,
NULL,
hInstance,
NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
// FUNCTION: WndProc (HWND, unsigned, WORD, LONG)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
RECT rt;
HPEN pen;
static unsigned short index = 0, index1 = 0, strSize = 257;
static char* str = new char[strSize];
static unsigned short const strSize1 = 500;
switch (message)
{
case WM_CREATE: //the message will appear when creating a window
for (int i = 0; i < 7; i )
{
for (int j = 0; j < 7; j )
{
//serial numberoftheelement
cells[i][j].x = j;
cells[i][j].y = i;
//setting the grid color
cells[i][j].borderColor.r = 0 12 * (i j);
cells[i][j].borderColor.g = 0;
cells[i][j].borderColor.b = 255 - 12 * (i j);
//setting the colorofthe circle
cells[i][j].circleColor.r = rand() % 256;
cells[i][j].circleColor.g = rand() % 256;
cells[i][j].circleColor.b = rand() % 256;
//setting textcolor
cells[i][j].textColor.r = rand() % 256;
cells[i][j].textColor.g = rand() % 256;
cells[i][j].textColor.b = rand() % 256;
//setting circleSize
}
}
break;
case WM_PAINT: //redraw the widow
hdc = BeginPaint(hWnd, amp;ps); //start graphical output
GetClientRect(hWnd, amp;rt);
SetBkMode(hdc, TRANSPARENT);
//cycle of creating a grid with circles
for (int i = 0; i < 7; i )
{
for (int j = 0; j < 7; j )
{
//Setting a custom pen and fill for the grid
pen = CreatePen(PS_SOLID, 5, RGB(cells[i][j].borderColor.r, cells[i][j].borderColor.g, cells[i][j].borderColor.b));
brush = CreateSolidBrush(RGB(cells[i][j].mainColor.r, cells[i][j].mainColor.g, cells[i][j].mainColor.b));
SelectObject(hdc, brush);
SelectObject(hdc, pen);
//Meshing
Rectangle(hdc, cells[i][j].x * rectSize, cells[i][j].y * rectSize circleSize, (cells[i][j].x 1) * rectSize, (cells[i][j].y 1) * rectSize circleSize);
//Remove Penand Mesh Fill
DeleteObject(pen);
DeleteObject(brush);
//Setting a custom pen and fill for circles
if (i < 1 amp;amp; j < 6) {
int z = 1 rand() % (30 - 1);
//int z = 10;
pen = CreatePen(PS_SOLID, 5, RGB(cells[i][j].circleBorderColor.r, cells[i][j].circleBorderColor.g, cells[i][j].circleBorderColor.b));
brush = CreateSolidBrush(RGB(cells[i][j].circleColor.r, cells[i][j].circleColor.g, cells[i][j].circleColor.b));
SelectObject(hdc, brush);
SelectObject(hdc, pen);
//Making circles
Ellipse(hdc, cells[i][j].x * rectSize z, cells[i][j].y * rectSize z circleSize, (cells[i][j].x 1) * rectSize - z, (cells[i][j].y 1) * rectSize - z circleSize);
//Remove pen and circle fill
DeleteObject(pen);
DeleteObject(brush);
char arr[strSize1];
for (int i = 0; i < strSize1;)
{
char ch = rand() % 127;
if (isalnum(ch))
{
arr[i] = ch;
i;
}
}
// text output
SetTextColor(hdc, RGB(cells[i][j].textColor.r, cells[i][j].textColor.g, cells[i][j].textColor.b));
TextOut(hdc, cells[i][j].x * rectSize 40, cells[i][j].y * rectSize circleSize 39, amp;arr[index ], 1);
}
}
}
//Displaying text on the screen
EndPaint(hWnd, amp;ps);
break;
case WM_MOUSEMOVE:
y = HIWORD(lParam);
x = LOWORD(lParam);
rt.top = 7;
rt.left = 0;
rt.right = 7 * rectSize;
rt.bottom = circleSize;
break;
case WM_LBUTTONDOWN:
yCoord = y;
xCoord = x;
yCoord -= circleSize;
yCoord /= rectSize;
xCoord /= rectSize;
//Checking if coordinates are included in circle coordinates
if (xCoord < 7 amp;amp; yCoord < 7 amp;amp; isInCircle(x, y - circleSize, xCoord * rectSize rectSize / 2, yCoord * rectSize rectSize / 2, (rectSize - 20) / 2)) {
//InvalidateRect(hWnd, NULL, TRUE);
GetPixel(hdc, x, y);
flag = 1;
flag = 1;
}
break;
case WM_DESTROY: //completion of work
PostQuitMessage(0);
break;
default:
//Processing messages that are not processed by the user
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Комментарии:
1. Вам нужно использовать чистую кисть
2. Обычно вам нужно помнить каждый объект, который вы рисуете. Затем при удалении одного вы должны стереть фон и при необходимости снова нарисовать другой объект в этой области.
3. Поместите информацию о каждом круге в список и
WM_PAINT
нарисуйте то, что есть в списке. Когда пользователь нажимает на круг, удалите запись для этого круга из списка и сделайте окно недействительным, чтобы вызвать перерисовку.4. Вы использовали случайные числа в
WM_PAINT
, что приведет к тому, что эллипс и текст будут отличаться при каждом перерисовывании. Подумайте о том, чтобы переместить их вWM_CREATE
. Вы можете использоватьInvalidateRect
WM_LBUTTONDOWN
и указать клиентские координаты прямоугольника области обновления, что устранит мерцание и увеличит скорость перерисовки.