TListView AdvancedCustomDrawItem рисует черный прямоугольник при наведении курсора мыши [дубликат]

Все, что хранится в NSUserDefaults, может (относительно) легко открываться и считываться, будь то на устройстве или в (незашифрованном) резервном копировании iCloud или на Mac с синхронизацией.

Брелок, с другой стороны, предназначен для таких вещей, как сертификаты и пароли . Я связал статью под названием «Как не хранить пароли в iOS», которая также дает немного более полезную информацию.

13
задан Community 23 May 2017 в 11:46
поделиться

2 ответа

Это обходной путь для дефектного поведения, а не ответ на вопрос, есть ли ошибка в VCL и несколько мыслей.

Обходной путь - установить фоновый режим устройства контекст, назначенный общим элементом управления для рисования элементов, по сравнению с прозрачным, после выполнения пользовательского чертежа:

procedure TForm1.ListViewCustomDrawSubItem(Sender: TCustomListView;
  Item: TListItem; SubItem: Integer; State: TCustomDrawState;
  var DefaultDraw: Boolean);
var
  R: TRect;
begin
  if not [CustomDrawing] then  // <- If we're not gonna do anything do not
    Exit;                      //    fiddle with the DC in any way

  DefaultDraw := False;
  ListView_GetSubItemRect(Sender.Handle, Item.Index, SubItem, LVIR_BOUNDS, @R);
  Sender.Canvas.MoveTo(R.Left, R.Top);
  Sender.Canvas.LineTo(R.Right-1, R.Bottom-1);

  SetBkMode(Sender.Canvas.Handle, TRANSPARENT); // <- will effect the next [sub]item
end; 

В цикле краски [sub], картина всегда выполняется сверху вниз, элементы с более низким индексом отправляются NM_CUSTOMDRAW уведомления до тех, у кого более высокие индексы. Когда мышь перемещается из одной строки в другую, нужно перерисовать две строки - одну, которая теряет состояние hot , а другая - получает его. Казалось бы, когда пользовательский чертеж не действует, рисование строки, которая теряет горячее состояние, оставляет DC в нежелательном состоянии. Это не проблема при перемещении мыши вверх, потому что этот элемент нарисован последним.

Пользовательский чертеж Элементы управления ListView и TreeView отличаются от пользовательского рисования других элементов управления и несколько сложны (см. Custom Draw With Элементы управления List-View и Tree-View ). Но вы полностью контролируете весь процесс. Код в NM_CUSTOMDRAW случае TCustomListView.CNNotify в «comctrls.pas» VCL одинаково сложный. Но, несмотря на то, что вам предоставлена ​​куча пользовательских обработчиков чертежей (половина из них advanced ), вы не можете контролировать то, что делает VCL. Например, вы не можете вернуть CDRF_xxx, который вам нужен, или вы не можете установить желаемый clrTextBk. Мое предубежденное мнение состоит в том, что есть проблема с ошибкой / дизайном в управлении представлением списка Delphi , но у меня нет ничего более конкретного, чем интуиция, как при поиске обходного пути.

12
ответ дан Sertac Akyuz 17 August 2018 в 08:55
поделиться
  • 1
    Большое спасибо Sertac, это решает мою проблему – David Heffernan 24 November 2011 в 16:08
  • 2
    @David - Добро пожаловать! Несмотря на мое мнение, неплохо было бы протестировать обходной путь при появлении новой версии comctl32.dll. – Sertac Akyuz 24 November 2011 в 16:30
  • 3
    Работа по-прежнему работает над устранением этой ошибки в Delphi 10.1 Berlin. – Jerry Dodge 10 June 2018 в 16:22
  • 4
    Я использую C ++ и, к сожалению, это предложение ничего не делает для меня; в моем случае я получаю белую заливку, когда ее затрагивают. Кроме того, если я префиксую свои DrawTextW() вызовы с помощью SetBkMode(TRANSPARENT), а затем снова переустанавливаю его на предыдущее значение, перемещение мыши приводит к страшному прозрачному перегрузке, несмотря на то, что мой обработчик ТАКЖЕ заполняет прямоугольник раньше! Если я использую OPAQUE вместо этого, проблема, как показано в оригинальном вопросе Дэвида, происходит с черным прямоугольником. Я не уверен, что список делает так странно, но он что-то делает ... Также не уверен, что я должен задать отдельный вопрос. – andlabs 14 June 2018 в 02:12
  • 5
    И в re Marjan выше, добавление LVS_EX_DOUBLEBUFFER не исправляет его. – andlabs 14 June 2018 в 02:17

У меня нет подсказки для черного прямоугольника в текстовой позиции, но недостающее горячее отслеживание связано с DefaultDraw := False; в вашем коде. OnCustomDrawSubItem вызывается только для subitem <> 0, поэтому первый столбец отображается по умолчанию, а второй использует ваш код. Пользовательский чертеж первого столбца можно сделать с помощью OnCustomDrawItem.

0
ответ дан Uwe Raabe 17 August 2018 в 08:55
поделиться
  • 1
    Боюсь, я ввел вас в заблуждение с помощью плохо продуманного примера. FillRect в первой версии Q был всего лишь чем-то, чтобы отобразить черный прямоугольник. Я изменил вопрос и изменил код и скриншот, чтобы понять, что это черный прямоугольник. Фактически, значение DefaultDraw не имеет отношения к черному прямоугольнику. – David Heffernan 19 November 2011 в 13:03
  • 2
    Понимаю. С вашим измененным примером проблема с отключенным горячим отслеживанием, похоже, сейчас решена. Это было вызвано только рисованием прямоугольника, а не параметром DefaultDraw. Замечание: в моей системе прямоугольник черного текста появляется только тогда, когда вы перемещаете мышь от более низкого до более высокого индексированного элемента, но не при переходе от более высокого к нижнему. – Uwe Raabe 19 November 2011 в 13:22
  • 3
    Вам просто нужно сделать некоторые GDI, чтобы это проявилось. Я выбрал FillRect, но это был плохой выбор. И да, я вижу то же, что и вы, с более низким до более высокого индекса. Извините за путаницу. – David Heffernan 19 November 2011 в 13:25
Другие вопросы по тегам:

Похожие вопросы: