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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 07.03.2023, 15:21   #1
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию Добавление текста в Listbox

Здравствуйте! Как можно сделать так чтобы при добавлении строки в listbox, эту строку подсвечивать цветом, допустим красным, и ещё хотелось бы узнать, возможно ли сделать так, что бы при добавление строки она подсвечивалась, но не просто подсвечивалась, а, как бы, мигала что ли т.е. строка не просто подсвечена, но она несколько раз изменяет цвет.

wm_ctlcolorlistbox?
apofioz вне форума Ответить с цитированием
Старый 07.03.2023, 17:54   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

WM_DRAWITEM
waleri на форуме Ответить с цитированием
Старый 09.03.2023, 14:57   #3
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Что нужно сделать чтобы строка, последняя добавленная строка, выделялась цветом, а после того, как она стала предпоследней(была добавлена ещё строка(строки)), она становилась стандартного цвета. Как пример того чего я бы хотел добиться - это программы в которых при совпадении неких данных эти строки подсвечиваются что бы привлечь внимание. Может даже меняют цвет несколько раз эффект мигания.

Вот код wm_drawitem, не знаю насколько он верен.
Код:
case WM_DRAWITEM:
	{
		LPDRAWITEMSTRUCT lpdi = (LPDRAWITEMSTRUCT)lParam;
		if (lpdi->CtlType & ODT_LISTBOX)
		{
			if ((lpdi->CtlID & ID_LISTBOX_USERNAME) ||
				(lpdi->CtlID & ID_LISTBOX_PASSWORD))
			{
				int Index = lpdi->itemID;
				HDC hdc = lpdi->hDC;
				RECT rc = lpdi->rcItem;
				int OldColor = SetTextColor(hdc, RGB(255, 0, 0));
				int OldAlign = SetTextAlign(hdc, TA_RIGHT);
				TCHAR szBuf[MAXUSERNAME];
				int len = SendMessage(lpdi->hwndItem, LB_GETTEXT, Index, (LPARAM)szBuf);
				szBuf[len] = '\0';
				TextOut(hdc, rc.right-len-1, rc.top, szBuf, _tcslen(szBuf));
				SetTextColor(hdc, OldColor);
				SetTextAlign(hdc, OldAlign);
				return TRUE;
			}
		}
		break;
	}
apofioz вне форума Ответить с цитированием
Старый 09.03.2023, 18:57   #4
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Вы при добавлении строки в ListBox через SendMessage в ответ получаете индекс добавленной строки. Сохраняйте его в переменной и перерисовывайте строку с совпадающим с этой переменной индексом другим цветом.

Код:
int lastString = -1;
...
lastIndex = SendMessage(hListBox, LB_ADDSTRING, ...);
...
if (lpdi->itemID == lastIndex) {
  // Тут определяете цвета выделенной строки
} else {
  // А тут обычной
}
macomics вне форума Ответить с цитированием
Старый 09.03.2023, 21:24   #5
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

WM_DRAWITEM отправляется при каждом добавлении строки в список, я правильно понимаю?

Последний раз редактировалось apofioz; 09.03.2023 в 21:33.
apofioz вне форума Ответить с цитированием
Старый 09.03.2023, 22:20   #6
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Нет. WM_DRAWITEM отправляется при каждой перерисовке окна ListBox. Это может быть не только добавление нового элемента, но и удаление элемента, разворачивание родительского окна из свернутого состояния или перетаскивание родительского окна. В общем много когда необходимо перерисовывать окно. WM_DRAWITEM это функция, которая знает как это делать и все.
macomics вне форума Ответить с цитированием
Старый 09.03.2023, 22:44   #7
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Цитата:
Сообщение от macomics Посмотреть сообщение
WM_DRAWITEM это функция, которая знает как это делать и все.
Функция? Я полагал, что это сообщение, и тот, кто это сообщение ловит тот и задаёт правила обработки....


Цитата:
Сообщение от macomics Посмотреть сообщение
WM_DRAWITEM отправляется при каждой перерисовке окна ListBox.
Но при добавлении оно всё же вызывается я про сообщение wm_drawirem...
Да, так заработало, выделяется нужная строка, строки которые были добавлены ранее рисуются цветом по умолчанию. Но заметил одну деталь, после того как строки перерисованы их нельзя выделить кликом мыши, почему? Это не очень хорошо.
И ещё по поводу бликов/мерцания/изменения цвета строки несколько раз для привлечения внимания, с этим как быть, через таймер?
apofioz вне форума Ответить с цитированием
Старый 09.03.2023, 23:29   #8
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от apofioz Посмотреть сообщение
Функция? Я полагал, что это сообщение, и тот, кто это сообщение ловит тот и задаёт правила обработки....
Сообщение это внутри системы, а вы пишите функцию обработки этого сообщения у себя в программе (пускай эта функция и заключается в ветки case более длинной функции).


Цитата:
Сообщение от apofioz Посмотреть сообщение
И ещё по поводу бликов/мерцания/изменения цвета строки несколько раз для привлечения внимания, с этим как быть, через таймер?
Точно также как и с анимацией. Таймер задает интервалы перерисовки, а при перерисовке изменяется состояние анимации (для мигания состояния может быть и два, а может быть больше при плавной смене цвета: переливание).
macomics вне форума Ответить с цитированием
Старый 10.03.2023, 14:53   #9
apofioz
Форумчанин
 
Регистрация: 22.01.2014
Сообщений: 313
По умолчанию

Цитата:
Сообщение от macomics Посмотреть сообщение
Точно также как и с анимацией.
Нужно в ветке wm_create создать таймер, а как саму анимацию, если так можно выразиться, осуществлять, после вставки сообщения в ветке wm_drawitem менять цвет текста, я правильно понимаю? В wm_timer отправить сообщение wm_drawitem, видимо, так... Или это коряво?
apofioz вне форума Ответить с цитированием
Старый 10.03.2023, 16:15   #10
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

В WM_TIMER достаточно инициировать перерисовку окна (в данном случае это ListBox), а уже окно само знает какие сообщения надо сгенерировать для его перерисовки. А в таймере достаточно вызвать
Код:
InvalidateRect(hListBox, NULL, FALSE);
При каждой перерисовке стоит проверять сколько прошло времени от начала анимации и изменять в зависимости от этого цвет текста. Для этого:
1) Сразу после вызова newLineIndex = SendMessage(hListBox, LB_ADDSTRING, ...) фиксируем время начала анимации animStart = GetTickCount();
2) При перерисовке проверяем время прошедшее от начала анимации: animCurrent = GetTickCount(); if (animCurrent - animStart < 15000) { if (((animCurrent - animStart) / 500) & 1 == 0) { Первый цвет анимации } else { Второй цвет анимации }; } else { Стандартный цвет без анимации }

В пункте 2 описана анимация длительностью 15000 мс (15 сек) и меняющая цвет текста каждые 500 мс
При этом таймер перерисовки не надо запускать с точностью до длительности анимации. Его надо запустить с точностью частоты кадров

Код:
SetTimer(hWnd, 1, 40, nullptr); // 25 кадров в секунду

Последний раз редактировалось macomics; 10.03.2023 в 16:21.
macomics вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Добавление данных в столбцы ListBox Igor 1 Microsoft Office Excel 2 07.03.2014 00:40
Добавление строк c listbox на listbox WinApi Alll_ Visual C++ 1 21.11.2013 03:34
[Delphi 7] Добавление в ListBox выделенного текста Oldcentre Помощь студентам 2 17.11.2010 22:40
Добавление пунктов в ListBox AdvanceQ Общие вопросы Delphi 3 08.01.2010 21:06
Построчное добавление в ListBox nikolai_P Microsoft Office Excel 0 18.08.2009 12:16