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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 15.02.2023, 14:22   #1
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию Вывод графики в диалоговых окнах.

Здраствуйте! Если я создал диалоговое окно и несколько элементов управления на нём, "listbox", "button", соответственно в листбоксе будут содержаться данные, которые нужно извлечь и исходя из данных построить график. Графи - это цилиндр. Я выделил область, куда бы я хотел выводить график(объявил глобально структуру RECT) и вот что получается: когда я выбираю данные для первого отображения, то всё работает удовлетворительно, как только я выбираю следующие данные график не перерисовывается, а исчезает. Так как в данном случае график - это цилиндр и, по условию, в верху и в низу цилиндра должны быть идентификационное данные(я их пытаюсь вывести в объекты "static") , то график исчезает и одна идентификационная строка над
графиком, дело в том, что я пытаюсь сделать так чтобы с движением графика строка была строго над ним на расстоянии, скажем, высоты символа и поэтому её нужно перемещать, нижняя строка не перемещается, и, соответственно, не затирается. Что это за косяк такой?

ВЫВОД Я ВЫДЕЛИЛ В ОТДЕЛЬНЫЕ ФУНКЦИИ
Эта функция рисует график.
Код:
BOOL DrawCylinder(HDC hdc, const POINT& ptLocation,
	const int Height, const int radius,
	COLORREF crOutlineCylinder,
	const int weightPen = 1,
	COLORREF crBaseCylinder = RGB(0, 0, 0),
	COLORREF crBarrelCylinder = RGB(0, 0, 0))
{
	POINT ptBeg = { ptLocation.x - radius, ptLocation.y };
	HPEN hPen = CreatePen(PS_SOLID, weightPen, crOutlineCylinder);
	if (!hPen)
	{
		return FALSE;
	}
	HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
	if (!hOldPen)
	{
		return FALSE;
	}
	if (!DrawLine(hdc, ptBeg.x, ptBeg.y, ptBeg.x, ptBeg.y + Height))
	{
		MessageBox(NULL, TEXT("First DrawLine"), TEXT("ERROR"), MB_OK);
		return FALSE;
	}
	//POINT ptCenter;
	if (!Arc(hdc, ptBeg.x, ptBeg.y - (radius / 3), ptLocation.x + radius,
		ptLocation.y + (radius / 3), ptLocation.x + radius,
		ptLocation.y, ptLocation.x + radius, ptLocation.y))
	{
		MessageBox(NULL, TEXT("First Arc"), TEXT("ERROR"), MB_OK);
		return FALSE;
	}
	if (!DrawLine(hdc, ptLocation.x + radius, ptLocation.y,
		ptLocation.x + radius, ptLocation.y + Height))
	{
		MessageBox(NULL, TEXT("Second DrawLine"), TEXT("ERROR"), MB_OK);
		return FALSE;
	}
	ptBeg.x = ptLocation.x;
	ptBeg.y = ptLocation.y + Height;
	if (!Arc(hdc, ptBeg.x - radius, ptBeg.y - (radius / 3),
		ptBeg.x + radius, ptBeg.y + (radius / 3),
		ptBeg.x + radius, ptBeg.y, ptBeg.x + radius, ptBeg.y))
	{
		MessageBox(NULL, TEXT("Second Arc"), TEXT("ERROR"), MB_OK);
		return FALSE;
	}

	HBRUSH hBrush = CreateSolidBrush(crBaseCylinder);
	HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
	if (!ExtFloodFill(hdc, ptLocation.x, ptLocation.y,
		crOutlineCylinder, FLOODFILLBORDER))
	{
		DWORD er = GetLastError();
		TCHAR szError[128];
		_stprintf_s(szError, 128, TEXT("First ExtFloorFill %d"), er);
		//MessageBox(NULL, szError, TEXT("ERROR"), MB_OK);

		return FALSE;
	}


	SelectObject(hdc, hOldBrush);
	DeleteObject(hBrush);
	//++++++
	hBrush = CreateSolidBrush(crBarrelCylinder);
	hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
	if (!ExtFloodFill(hdc, ptLocation.x, ptLocation.y + (Height >> 1),
		crOutlineCylinder, FLOODFILLBORDER))
	{
		MessageBox(NULL, TEXT("Second ExtFloorFill"), TEXT("ERROR"), MB_OK);
		return FALSE;
	}
	if (!ExtFloodFill(hdc, ptBeg.x, ptBeg.y,
		crOutlineCylinder, FLOODFILLBORDER))
	{
		//MessageBox(NULL, TEXT("Third ExtFloorFill"), TEXT("ERROR"), MB_OK);
		return FALSE;
	}
	SelectObject(hdc, hOldBrush);
	DeleteObject(hBrush);
	SelectObject(hdc, hOldPen);
	DeleteObject(hPen);
	hBrush = hOldBrush = NULL;
	return TRUE;
}
А эта должна подготовить данные для прорисовки цилиндра.
Код:
BOOL DrawDiagramParam(HWND hDlg, HDC hdc, TCHAR* szToks[], int iSizeToks)
{
	
	TEXTMETRIC tm;
	GetTextMetrics(hdc, &tm);
	int cxChar = tm.tmAveCharWidth + 1;
	int cyChar = tm.tmHeight + tm.tmExternalLeading;
	int topIndent = 3 * cyChar / 2;
	int leftIndent = 30; //Отступ от левой границы.

	MapDialogRect(hDlg, &rcDiagram);

	//+++++++++++++++++++++++
	//Вычислить радиус эллипса и высоту цилиндра.
	int radius = (((rcDiagram.right) - (leftIndent << 1)) >> 1);
	int height = ((rcDiagram.bottom) - (radius / 3) - (radius / 3)) - (rcDiagram.top + cyChar);


	HWND hStateRating = GetDlgItem(hDlg, ID_STATIC_RATING);
	HWND hStateName  = GetDlgItem(hDlg, ID_STATIC_NAME);
	//Здесь преобразую значение рейтинга участника в число и 
	//и вычисляю высоту графика занво.
	int rating = _ttoi(szToks[iSizeToks - 1]);
	height = (height * rating) / 100;
	//Это вычисление центра для пстроения эллипса
	POINT loc = { rcDiagram.left + leftIndent + radius,
				 (rcDiagram.bottom - (radius / 3)) - height };

	//Попытка двигать статик элемент управления для вывода рейтига
	/*MoveWindow(hStateRating, rcDiagram.left + cxChar, 
		loc.y -(radius / 3) - (5 * cyChar / 3),
		rcDiagram.right, 3 * cyChar / 2, TRUE);*/

	DrawCylinder(hdc, loc, height, radius, RGB(128, 128, 0), 1,
		RGB(0, 255, 124),
		RGB(0, 255, 124));


	/*MoveWindow(hStateName, rcDiagram.left + leftIndent,
		rcDiagram.bottom - tm.tmHeight + tm.tmExternalLeading,
		_tcslen(szToks[0]) * tm.tmAveCharWidth,
		tm.tmHeight + tm.tmExternalLeading, TRUE);*/
		
	SetWindowText(hStateRating, TEXT("\0"));
	SetWindowText(hStateName, TEXT("\0"));
	SetWindowText(hStateRating, szToks[iSizeToks - 1]);
	SetWindowText(hStateName, szToks[0]);
	

	return TRUE;
}
P.S.
Странно, но значения структуры rcDiagram почему-то меняются, хотя я их нигде не меняю, эти значения должны указывать координаты области вывода графика и всё.


Так с этим разобрался. Теперь такой вопрос: "Как выводить в окно диалога , какие способы, более изящно, не знаю, более трудозатратно?" WM_PAINT в диалоговых окнах недопустим, значит есть что-то альтернативное.

Последний раз редактировалось apofioz; 15.02.2023 в 23:14.
apofioz вне форума Ответить с цитированием
Старый 15.02.2023, 23:18   #2
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Функция окна диалоговой панели не обрабатывает сообщения wm_paint, wm_create и wm_destroy, почему?
apofioz вне форума Ответить с цитированием
Старый 15.02.2023, 23:29   #3
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,357
По умолчанию

Цитата:
Сообщение от apofioz Посмотреть сообщение
WM_PAINT в диалоговых окнах недопустим, значит есть что-то альтернативное.
С чего вы взяли?
waleri вне форума Ответить с цитированием
Старый 16.02.2023, 00:47   #4
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

А что, есть иное мнение или это опять чих в никуда.
apofioz вне форума Ответить с цитированием
Старый 16.02.2023, 15:06   #5
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Как выводить график в элемент управления "static", не пойму как обрабатывать сообщение WM_DRAWITEM?
Стоит ли вообще в статик выводить подобные графические элементы(в данном случае цилиндр)?
apofioz вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как отследить нажатие кнопок в диалоговых окнах? Bezdar Microsoft Office Excel 11 12.08.2015 15:19
Быстрый вывод графики gusluk Мультимедиа в Delphi 13 13.04.2012 17:28
Ввод и вывод выполнить с встроенных диалоговых окон InputBox и MsgBox Anti123 Microsoft Office Excel 3 23.03.2012 18:12
таймер и вывод графики Volkogriz Мультимедиа в Delphi 4 08.12.2007 12:11
Вывод графики в DBGrid Saro БД в Delphi 0 20.04.2007 11:39