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

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

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

解決方法といっても、何も新しいモノは無く
フォームのローカル変数に FNowDelete: Boolean; を追加して
  1. procedure TForm1.Button1Click(Sender: TObject);  
  2. begin  
  3.     FNowDelete := True;  
  4.     ListView1.Items.Clear;  
  5.     FNowDelete := False;  
  6. end;  
  7.   
  8. procedure TForm1.ListView1Deletion(Sender: TObject; Item: TListItem);  
  9. begin  
  10.     if FNowDelete and Assigned(Item.Data) then begin  
  11.         Dispose(PInt64(Item.Data));  
  12.     end;  
  13. end;  
とか
ListView の Tag プロパティを利用して
  1. procedure TForm1.Button1Click(Sender: TObject);  
  2. begin  
  3.     ListView1.Tag := 1;  
  4.     ListView1.Items.Clear;  
  5.     ListView1.Tag := 0;  
  6. end;  
  7.   
  8. procedure TForm1.ListView1Deletion(Sender: TObject; Item: TListItem);  
  9. begin  
  10.     if (Item.ListView.Tag = 1and Assigned(Item.Data) then begin  
  11.         Dispose(PInt64(Item.Data));  
  12.     end;  
  13. end;  
とか

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

コメント