0

アプリが 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ではありません。

ここから先に進む方法がわかりません。提案を歓迎します。

ありがとう、キャスリーン

4

0 に答える 0