我已经缩小了我的应用程序生成从 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,但它没有任何区别;显然它总是非空的。
我不知道如何从这里着手,欢迎提出建议。
谢谢,凯瑟琳