Delphi/C++ Builder の ListView の OnDeletion イベント

Delphi/C++ Builder の ListView(TListView) で、TListItem を削除したときに発生する OnDeletion イベント

ListItem の Data プロパティに関連付けたポインタを解放するときなどに便利で、下記のように利用できる
procedure TForm1.ListView1Deletion(Sender: TObject; Item: TListItem);
begin
    if Assigned(Item.Data) then begin
        Dispose(PInt64(Item.Data));
    end;
end;
しかし、このイベントは、親フォームをドッキング、アンドックさせたり、ListView の ViewStyle を変更したりしても発生してしまう。そのため正規にリストの削除を行ったときには、無効なポインタ云々のエラーが登場したりする

解決方法といっても、何も新しいモノは無く
フォームのローカル変数に FNowDelete: Boolean; を追加して
procedure TForm1.Button1Click(Sender: TObject);
begin
    FNowDelete := True;
    ListView1.Items.Clear;
    FNowDelete := False;
end;

procedure TForm1.ListView1Deletion(Sender: TObject; Item: TListItem);
begin
    if FNowDelete and Assigned(Item.Data) then begin
        Dispose(PInt64(Item.Data));
    end;
end;
とか
ListView の Tag プロパティを利用して
procedure TForm1.Button1Click(Sender: TObject);
begin
    ListView1.Tag := 1;
    ListView1.Items.Clear;
    ListView1.Tag := 0;
end;

procedure TForm1.ListView1Deletion(Sender: TObject; Item: TListItem);
begin
    if (Item.ListView.Tag = 1) and Assigned(Item.Data) then begin
        Dispose(PInt64(Item.Data));
    end;
end;
とか

全然スマートじゃないというか、そこまで管理に介在するなら、自前でポインタ解放のコードを入れたんでよさそーな

コメント