Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.11.2022, 10:22   #1
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию Создать мигающий прямоугольник

Здравствуйте! Если это возможно, окажите помощь в следующем вопросе: нужно в окне с помощью мыши выделить прямоугольник и создать мигания этого прямоугольника.
Я хочу выделять прямоугольник так, как, например, это делается в Paint-е т.е. нажал левую клавишу мыши двигаешь, а за курсором рисуется контур прямоугольника. А вот как заставить его мигать, возможно, нужно как-то инвертировать цвет, не знаю, подскажите прав я или нет?. И..., нужно, я так понимаю, рамку прямоугольника заставить мигать, хотя, возможно, и нет.

Пока что так:
Код:
POINT pt[1000];

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	static int Index;
	PAINTSTRUCT ps;
	HPEN hPen, hOldPen;
	static COLORREF rcColor = RGB(0, 0, 0);

	switch (msg)
	{
	case WM_LBUTTONDOWN:
	{
		SetCapture(hwnd);
		Index = 0;
		pt[Index++] = { LOWORD(lParam), HIWORD(lParam) };

		InvalidateRect(hwnd, NULL, TRUE);
		return 0;
	}
	case WM_MOUSEMOVE:
	{
		if (wParam & MK_LBUTTON)
		{
			if ((Index + 1) < 1000)
				pt[Index++] = { LOWORD(lParam), HIWORD(lParam) };
			InvalidateRect(hwnd, NULL, TRUE);
		}
		return 0;
	}
	case WM_LBUTTONUP:
	{
		pt[Index] = { LOWORD(lParam), HIWORD(lParam) };
		ReleaseCapture();
		InvalidateRect(hwnd, NULL, TRUE);
		return 0;
	}
	case WM_PAINT:
	{
		HDC hdc = BeginPaint(hwnd, &ps);

		hPen = CreatePen(PS_SOLID, 1, rcColor);
		hOldPen = (HPEN)SelectObject(hdc, hPen);
		//Так не работает, возможно, нужно рисовать линии???
		//Rectangle(hdc, pt[0].x, pt[0].y, pt[Index].x, pt[Index].y);

		SelectObject(hdc, hOldPen);
		DeleteObject(hOldPen);

		EndPaint(hwnd, &ps);
		return 0;
	}
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}
apofioz вне форума Ответить с цитированием
Старый 14.11.2022, 20:27   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

А зачем вообще массив точек?
Вам надо просто сохранять точку начала и точку движения/отпускания.
Потом при рисования прямоугольника надо убедится, что координаты правильные - нужен левый верхний и нижний правый угол.
Ну и для того чтоб мигало надо запустить таймер. Смотрите SetTimer() и WM_TIMER
waleri вне форума Ответить с цитированием
Старый 15.11.2022, 05:23   #3
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
А зачем вообще массив точек?
Первоначально идея с массивом точек казалась не плохой, но попробовав и так и сяк и ничего путёвого не получив, думаю, что он не нужен. Тоже думал о трёх точках, но всё равно ничего путёвого не выходит, я нажимаю ЛКМ допустим в середине рабочей области, а прямоугольник уходит в левый верхний угол, почему, не знаю.
Кстати, а можно ли делать так, допустимо ли это?
Код:
case WM_MOUSEMOVE:
	{
		if (wParam & MK_LBUTTON)
		{
			if ((Index + 1) < 1000)
				pt[Index++] = { LOWORD(lParam), HIWORD(lParam) };
			//InvalidateRect(hwnd, NULL, TRUE);
			//Стоит ли так делать и вообще такое допустимо?
			SendMessage(hwnd, WM_PAINT, (WPARAM)wParam, 0L);
			return 0;
		}
		break;
	}

Цитата:
Сообщение от waleri Посмотреть сообщение
Потом при рисования прямоугольника надо убедится, что координаты правильные - нужен левый верхний и нижний правый угол.
А как же прорисовка во время движения, когда двигаю мышь с зажатой клавишей, я же ещё её(ЛКМ) не отпустил, значит правой нижней точки, по сути, нет. Или считать таковой каждую следующую позицию после первой?


Цитата:
Сообщение от waleri Посмотреть сообщение
Ну и для того чтоб мигало надо запустить таймер. Смотрите SetTimer() и WM_TIMER
Пока что эту тему не рассматривали, ну, а если иначе никак нельзя, то хотелось бы увидеть, как это можно сделать в данной ситуации. Хотя сейчас, на данный момент, я ещё прорисовать прямоугольник не могу так что...)
apofioz вне форума Ответить с цитированием
Старый 15.11.2022, 08:40   #4
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Вот ещё один вариант, работает, но не совсем так как мне хочется, а именно:
Код:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	static int cxClient, cyClient, Index;
	PAINTSTRUCT ps;
	HPEN hPen, hOldPen;
	static COLORREF rcColor = RGB(0, 0, 0);
	static RECT rc;
	static POINT ptBeg, ptEnd;

	switch (msg)
	{
	case WM_CREATE:
	{
		if (!SetTimer(hwnd, ID_TIMER, 500, (TIMERPROC)NULL))
			MessageBox(hwnd,
				TEXT("Failed function call"),
				TEXT("Error"), MB_OK);
		return 0;
	}
	case WM_SIZE:
	{
		cxClient = LOWORD(lParam);
		cyClient = HIWORD(lParam);

		return 0;
	}
	case WM_LBUTTONDOWN:
	{
		SetCapture(hwnd);
		ptBeg = { LOWORD(lParam), HIWORD(lParam) };

		rc.left = ptBeg.x;
		rc.top = ptBeg.y;

 		InvalidateRect(hwnd, NULL, FALSE);
		return 0;
	}
	case WM_MOUSEMOVE:
	{
		if (wParam & MK_LBUTTON)
		{
			ptEnd = { LOWORD(lParam), HIWORD(lParam) };
			InvalidateRect(hwnd, NULL, FALSE);
			return 0;
		}
		break;
	}
	case WM_LBUTTONUP:
	{
		ptEnd = { LOWORD(lParam), HIWORD(lParam) };
		rc.right  = ptEnd.x;
		rc.bottom = ptEnd.y;
		ReleaseCapture();
		InvalidateRect(hwnd, NULL, FALSE);
		return 0;
	}
	case WM_PAINT:
	{
		HDC hdc = BeginPaint(hwnd, &ps);


		if (ptEnd.x > ptBeg.x && ptEnd.y > ptBeg.y)
		{
			hPen = CreatePen(PS_SOLID, 1, rcColor);
			hOldPen = (HPEN)SelectObject(hdc, hPen);
			Rectangle(hdc, ptBeg.x, ptBeg.y, ptEnd.x, ptEnd.y);
			SelectObject(hdc, hOldPen);
			DeleteObject(hOldPen);
		}

		EndPaint(hwnd, &ps);
		return 0;
	}
	case WM_TIMER:
	{
		switch (wParam)
		{
			case ID_TIMER:
			{
				HDC hdc = GetDC(hwnd);
				InvertRect(hdc, &rc);
				ReleaseDC(hwnd, hdc);
				break;
			}
			default:
				break;
		}
		return 0;
	}
	case WM_DESTROY:
	{
                KillTimer(hwnd, ID_TIMER);
		PostQuitMessage(0);
		return 0;
	}
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}
Прямоугольник рисует, но при повторном рисовании уже другого прямоугольника как-будто бы прорисовывается фигура не тех размеров, которые должны быть т.е. я нажал ЛКМ И ЛИБО СРАЗУ, ЛИБО, КОГДА НАЧАЛ перемещать мышь фигура рисуется не с той точки с которой я начал построение. Как-то так.
2)Мигание тут всё сложнее т.к. делаю я это совсем наугад, если делать так InvertRect() как я привёл в примере кода, то мигает весь прямоугольник, а как сделать так чтобы мигала только рамка. Просто создавать перья разного цвета, допустим чёрный-белый, красный-циан...
Но самое главное мигание начинается тогда, когда я ещё прямоугольник и не создал, что это за ерунда такая.
apofioz вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Мигающий экран Capitoska Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 4 25.01.2019 16:44
Создать класс ПРЯМОУГОЛЬНИК со сторонами параллельными осям координат vutt C# (си шарп) 0 11.05.2016 03:35
Мигающий курсор при нажатии на кнопку-картинку raBpywa HTML и CSS 0 03.03.2012 14:12
Как переместить мигающий курсор? Сергей089 Паскаль, Turbo Pascal, PascalABC.NET 1 04.06.2009 17:35
Как сделать мигающий текст в Pascale??? Danilyuk Паскаль, Turbo Pascal, PascalABC.NET 1 31.05.2008 17:57