TListBox OnDrawItem вызывает AV в COMCTL32.dll
Я сузил причину, по которой мое приложение генерирует нарушения прав доступа из COMCTL32.dll в TListBox::OnDrawItem. TListBox.Style является lbOwnerDrawFixed.
Приложение построено на C++ Builder XE4, работает на Win7-64 и Win8-64. Я могу сделать это на Win7, но только изнутри IDE, и только время от времени; сборка релиза на Win7 не вызывает ошибку, но на Win8 это происходит каждый раз.
Это происходит только при первом создании формы. Форма содержит кнопки для перехода к следующей / предыдущей записи, которая вызывает весь код, заполняющий элементы управления, но с этими вызовами проблем не возникает; только с этим впервые после постройки формы.
Конструктор формы устанавливает TTimer для паузы 100 мс. TTimer::OnTimer вызывает функцию, которая загружает данные в элементы управления. После загрузки TListBox вызывается событие OnDrawItem.
Если я устанавливаю TListBox.Style в lbStandard и удаляю пользовательский OnDrawItem, проблем нет.
Вот пример обработчика OnDrawItem:
void __fastcall TFieldForm::EditsListDrawItem(TWinControl *Control,
int Index, TRect &Rect, TOwnerDrawState State)
{
TListBox* t_box = (TListBox*)Control;
TCanvas* t_canvas = t_box->Canvas;
int t_offset = 2; // default text offset width
t_canvas->Brush->Color = (State.Contains(odSelected) ?
clHighlight : Panel->Color);
t_canvas->Font->Color = (State.Contains(odSelected) ?
clHighlightText : clWindowText);
t_canvas->Font->Style = TFontStyles();
t_box->ItemHeight = t_canvas->TextHeight(FieldNameLabel->Caption);
t_canvas->FillRect(Rect); // clear the rectangle
t_canvas->TextOut(Rect.Left + t_offset, Rect.Top,
t_box->Items->Strings[Index]);
}
Я проверил, чтобы убедиться, что TListBox.Canvas не NULL, но это не имело никакого значения; по-видимому, это всегда не NULL.
Я не знаю, как двигаться дальше, и приветствую предложения.
Спасибо, Кэтлин