Метод DrawItem () выполняется повторно - PullRequest
1 голос
/ 29 октября 2008

Я использовал нарисованную владельцем стратегию для класса CMyListBox, который происходит от CListBox. Я хочу, чтобы метод DrawItem () выполнялся только при вставке элемента в список. Но метод вызывается много раз. Как я могу изменить, чтобы вызвать его, когда мне нужно.

Ответы [ 3 ]

1 голос
/ 29 октября 2008

Вы всегда можете кэшировать начальный чертеж, выводя содержимое в растровое изображение в памяти и затем рисуя его, это означает, что вам нужно отслеживать, когда что-то изменилось, чтобы вы могли запустить реальный код повторной обработки снова. Это действительно помогает запускать код рендеринга каждый раз, когда его много.

1 голос
/ 29 октября 2008

Я сделал именно то, что предлагает Кирон, кэшируя растровые изображения, но только в очень дорогом коде рендеринга. На самом деле мне нужно сохранить несколько кэшированных «состояний» в зависимости от того, выделен ли элемент, отключен, нормально и т. Д. (Это для кнопок панели инструментов, а не для списка - но я думаю, что это применимо). Я кеширую предварительно отрендеренное изображение только тогда, когда оно мне нужно - таким образом я кеширую только «состояния», которые мне действительно нужны.

Мой рисунок был чистыми GDI-звонками. В основном растровые манипуляции и другие рисунки, которые просто требуют времени, плюс меня перерисовывали слишком часто (без веской причины - длинная история).

Изменение основ в структуре, которую я использовал (MFC и Stingray), просто не было вариантом. Кэширование было последним средством после того, как все другие оптимизации были недостаточно хороши (чертовски медленные виртуальные машины !!).

Обычно рисование достаточно быстрое , чтобы сделать, когда вы признаны недействительным (в данном случае DrawItem). Я хотел бы взглянуть на то, что именно вы делаете в DrawItem. Я хотел бы изучить кэширование данных и вычислений, которые необходимы для рендеринга, а , а не самого рендеринга (например, окончательных растровых изображений), если нет других вариантов.

Кроме того, я прочитал, что рендеринг в Vista более оптимизирован, они кэшируют то, что вы нарисовали в своем окне, чтобы уменьшить цикл недействительности / перерисовки, когда, например, окно перемещается из-за другого.

0 голосов
/ 29 октября 2008

Метод DrawItem () вызывается всякий раз, когда требуется нарисовать любой элемент в списке. Если вы не ответите на него, вы, скорее всего, получите пустую область в вашем списке, где извлеченные данные были стерты, а вы не обновили их. Если вы действительно не думаете, что рисунок необходим, вы можете сделать что-то вроде

void CMyListBox::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
   if (!m_DrawingEnabled)
     return;
}

Где m_DrawingEnabled - это член, которого вы поддерживаете, чтобы остановить ненужные розыгрыши,

...