名前 題名 ▼ 宮さん > 皆さん暑中お見舞い申し上げます。 > 環境はWindows7 Delphi6Personalです。 > http://mrxray.on.coocan.jp/Delphi/plSamples/790_ListView.htm > を参考に790_仮想リストビューの勉強をしています。 > 08_仮想リストビューにチェックボックス でつまずいています。 > どうしても項目を削除するとメモリーリークします。 > 場所はFormShowのFItem := TDataListItem.Create; > だと表示しているようなのですが、解決できません。 > マスターに変わりどなたか教えてくださいませんか。 > イメージ不器用なので○●で代用しています。 > コードはコピペしただけですが念のため。(長くなりますがm(_ _)m) > type > TplDataListItem = class; > TplDataList = class(TList) > protected > function Get(Index: Integer): TplDataListItem; > procedure Put(Index: Integer; Item: TplDataListItem); > public > destructor Destroy; override; > procedure Clear; virtual; > function Add(Item: TplDataListItem): Integer; > function IndexOf(Item: TplDataListItem): Integer; > function Remove(Item: TplDataListItem): Integer; > property Items[Index: Integer]: TplDataListItem read Get write Put; default; > end; > //プロパティはCaptionとChecedのみとした > TplDataListItem =class(TObject) > private > FCaption : String; > FChecked : Boolean; > public > property Caption : String read FCaption write FCaption; > property Checked : Boolean read FChecked write FChecked; > end; > TDataListItem = class(TplDataListItem); > TForm1 = class(TForm) > ListView1: TListView; > Panel1: TPanel; > Button2: TButton; > ImageList1: TImageList; > procedure FormCreate(Sender: TObject); > procedure FormShow(Sender: TObject); > procedure FormDestroy(Sender: TObject); > procedure ListView1Data(Sender: TObject; Item: TListItem); > procedure ListView1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); > procedure Button2Click(Sender: TObject); > private > { Private 宣言 } > DataList : TplDataList; > public > { Public 宣言 } > end; > var > Form1: TForm1; > implementation > uses CommCtrl; > { TplDataList } > > // 仮想リストビュー用のデータを格納するTplDataListの関数とメソッド類 > destructor TplDataList.Destroy; > var > i : Integer; > begin > for i := 0 to Count - 1 do begin > Items[i].Free; > end; > inherited; > end; > //----------------------------------------------------------------------------- > procedure TplDataList.Clear; > var > i : Integer; > begin > for i := 0 to Count - 1 do begin > Items[i].Free; > end; > inherited; > end; > //----------------------------------------------------------------------------- > procedure TplDataList.Put(Index: Integer; Item: TplDataListItem); > begin > inherited Items[Index] := Item; > end; > //----------------------------------------------------------------------------- > function TplDataList.Get(Index: Integer): TplDataListItem; > begin > Result := TplDataListItem(inherited Items[Index]); > end; > //----------------------------------------------------------------------------- > function TplDataList.Add(Item: TplDataListItem): Integer; > begin > Result := inherited Add(Item); > end; > //----------------------------------------------------------------------------- > function TplDataList.IndexOf(Item: TplDataListItem): Integer; > begin > Result := inherited IndexOf(Item); > end; > //----------------------------------------------------------------------------- > function TplDataList.Remove(Item: TplDataListItem): Integer; > begin > Result := inherited Remove(Item); > end; > {$R *.dfm} > > // 開始時にDataListを生成 > procedure TForm1.FormCreate(Sender: TObject); > var > ACol : TListColumn; > begin > Form1.Caption:=FormCaption; > DataList := TplDataList.Create; > //ListViewの設定 > ListView1.ViewStyle := vsReport; > ListView1.MultiSelect := True; > ListView1.OwnerData := True; //OwnerDataプロパティをTrueにしておく > ACol := ListView1.Columns.Add; > ACol.Width := 150; > ACol.Caption := '名前'; > end; > //============================================================================= > // フォームを表示したらテスト用データを作成 > //============================================================================= > procedure TForm1.FormShow(Sender: TObject); > var > i : Integer; > FItem : TDataListItem; > begin > ListView1.Items.Clear; > for i := 0 to 80 do begin // テスト用データの生成 > FItem := TDataListItem.Create; > FItem.Caption := Format('Item%.3d', [i]); > FItem.Checked := False; > DataList.Add(FItem); > end; > //ListViewにItems数を通知してListViewの表示を更新 > //OnDataHint,OnDataイベントが発生して必要なItemの描画が行われる > ListView1.Items.Count := DataList.Count; > end; > //============================================================================= > // 終了時はDataListを解放 > //============================================================================= > procedure TForm1.FormDestroy(Sender: TObject); > begin > FreeAndNil(DataList); > end; > //============================================================================= > // ListView1のOnDataイベント > // ListViewのItem.Captionの設定 > // このOnDataイベントで設定しないと無効.OnDataHintでは設定しても無効 > // チェックボックスも同様 > // [備考]ListViewのOnDataHintイベントはスクロールすれば発生する > //============================================================================= > procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem); > begin > Item.Caption := DataList[Item.Index].Caption; > //StateIconを設定 > //1,0はImageList1のアイテム番号(0はチェックなし画像) > if DataList[Item.Index].Checked then begin > Item.StateIndex := 1; > end else begin > Item.StateIndex := 0; > end; > end; > //============================================================================= > // チェックボックス上のマウスダウン(クリック)でチェックボックスのOn,Off切換 > // データリストのCheckedプロパティを変更 > // 実際の描画はListViewのRefreshメソッドを実行することで行う > //============================================================================= > procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton; > Shift: TShiftState; X, Y: Integer); > var > AItem : TListItem; > AHitTests : THitTests; > begin > AItem := ListView1.GetItemAt(X, Y); > if AItem = nil then exit; > > //マウス左ボタンの時のみ > if Button = mbLeft then begin > //座標(X,Y)がStateIcon(状態アイコンまたはビットマップ)上の場合のみ処理 > AHitTests := ListView1.GetHitTestInfoAt(X, Y); > if htOnStateIcon in AHitTests then begin > DataList[AItem.Index].Checked := not DataList[AItem.Index].Checked; > //ListViewの表示更新(OnDataイベントが発生する) > ListView1.Refresh; > end; > end; > end; > //============================================================================= > // チェックしてあるアイテムを削除する > //============================================================================= > procedure TForm1.Button2Click(Sender: TObject); > var > i : Integer; > begin > for i := DataList.Count - 1 downto 0 do begin > if DataList[i].Checked then DataList.Delete(i); > end; > ListView1.Items.Count := DataList.Count; > //ListViewの表示更新(OnDataまたはOnDataHintイベントが発生する) > ListView1.Refresh; > end; GIF,JPEG,PNG画像ファイル及びLZH,ZIPファイルをアップロードできます.600 x 1200 ピクセルを超える画像は縮小表示されます(画像クリックで拡大表示). (上限122000(120k)バイト) 削除キー Link