C++Builder 6のTListViewでエラーが発生する

このQ&Aのポイント
  • C++Builder 6のTListViewでリストのインデックスが範囲を超えるエラーが発生する問題があります。
  • ListView1->Items->Clear();の後にリスト項目の削除を行う際にエラーが発生します。
  • リストが33件あり、ViewStyleはvsReportです。このエラーは初回実行時にのみ発生します。
回答を見る
  • ベストアンサー

C++Builder 6 : TListView でエラー

TListView コンポーネントを配置した、フレーム内で、 ListView1->Items->Clear(); とすると、 「リストのインデックスが範囲を超えています(10)」 という意味の解らないエラーが発生します。 そこで、 int c = ListView1->Items->Count; for (int i=0; i<c; i++) {   ListView1->Items->Delete(0); } と書き換えると、残り11件のところで削除するときに上記のエラーが発生します。 リストは、33件あります。ViewStyle は、vsReport です。 また、このエラーは、2度目は発生しません。 実行して、最初に Clear() すると発生します。 どうも解らないので、質問しました。 理由や、解決方法をご存じの方、教えて下さい。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

まず、リストの状態を調べてみるとよろしいかと思います。 要所(リストの状態が変化するとこ)に #ifdef _DEBUG AnsiString asViewCount = AnsiString( LisiView1->Items->Count ); OutputDebugString( asViewCount.c_str() ); #endif デバッグして イベントログを見てみる吉。 情報が足らなければ、sprintfとか Format関数を使って+αが吉と思いますよ。あとはソースコードを追いましょ(^^;

clavia
質問者

お礼

ありがとうございました、解決しました。 いろいろ追っていくと、 別の ListView の OnDeletion でエラーが発生していました。 でもなぜ、Clear() で止まって、 実際にエラーが発生している、 OnDeletion 内で止まらないんでしょうかね?

関連するQ&A

  • ListViewの複数項目削除で再度質問です

    ArrayListのソートの件とListViewのおかしな挙動は解決できたのですが 最初に質問して解決したはずの削除の部分で再び分からなくなって しまったので質問させて頂きます。 今回は本体に今までのコードを正式に組み込んで、動作の確認を 行っていたのですが、複数件(連続や個別選択)のデータ削除を 行おうとしたら意図しないデータ(未整列状態の並びのデータ)が 削除されてしまうという事態が発生してしまいました。 これはどうすれば解決できるのでしょうか? また複数件の未読既読を制御(選択された項目に対してフラグを 入れ替える)するのも同様の方法で出来るのでしょうか? 環境はVS2005(C#)、.NET Framework2.0です。 以下に問題の削除時のコードを載せます。 private void menuDelete_Click(object sender, EventArgs e) { // 選択アイテムが0のときは反応にしない if(listView1.SelectedItems.Count == 0){ return; } if(listView1.Columns[0].Text == "差出人"){ // 受信メールのとき for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) { if (listView1.Items[sel_index].Selected) { collectionMail[DELETE].Add(collectionMail[RECEIVE][sel_index]); collectionMail[RECEIVE].RemoveAt(sel_index); } } this.textBody.Text = ""; } else if(listView1.Columns[0].Text == "宛先"){ // 送信メールのとき for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) { if (listView1.Items[sel_index].Selected) { collectionMail[DELETE].Add(collectionMail[SEND][sel_index]); collectionMail[SEND].RemoveAt(sel_index); } } this.textBody.Text = ""; } else if(listView1.Columns[0].Text == "差出人または宛先"){ // 削除メールのとき if(MessageBox.Show("選択されたメールは完全に削除されます。\nよろしいですか?", "確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK){ for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) { if (listView1.Items[sel_index].Selected) { collectionMail[DELETE].RemoveAt(sel_index); } } this.textBody.Text = ""; } } // ツリービューとリストビューの表示を更新する UpdateTreeView(); UpdateListView(); // 選択している位置がリストの件数よりも少ないとき if(currentRow < listView1.Items.Count){ // 選択していた位置-1の行にフォーカスを当て直す listView1.Items[currentRow - 1].Selected = true; listView1.Items[currentRow - 1].Focused = true; listView1.SelectedItems[0].EnsureVisible(); listView1.Select(); listView1.Focus(); } else{ // リストの件数が1以上の時 if(listView1.Items.Count > 0){ // ListViewの行数位置-1の行にフォーカスを当て直す listView1.Items[listView1.Items.Count - 1].Selected = true; listView1.Items[listView1.Items.Count - 1].Focused = true; listView1.SelectedItems[0].EnsureVisible(); listView1.Select(); listView1.Focus(); } } }

  • ListViewの複数項目削除で意図しない挙動

    前回質問した内容でほとんど複数削除は解決したように 見えたのですが、どういう条件か分からないのですが 複数選択(1件選択の場合は発生しない)して削除ロジックを 実行すると選択している項目と異なる内容の配列(ArrayList)の データを削除してしまうという事が発生します。 これは何が原因で発生しているのでしょうか? またこれの解決法をご教授頂けないでしょうか。 環境はVS2005(C#)、.NET Framework2.0です。 以下に該当部分のコードを載せます。 2000文字を超えてしまったので問題の部分以外は省略しました。 ※添付画像が見にくかったので以下のURLに再掲示しましたので 参考にしてもらえるとありがたいです。 http://angelteatime.punyu.net/questionbox_20090312.jpg 画像では350件ある受信メール(ArrayListに1件ずつMailクラスで 格納されている)の先頭から8件ぐらい選択削除をしようとしている 画面です。 private void menuDelete_Click(object sender, EventArgs e) { // 選択アイテムが0のときは反応にしない if(listView1.SelectedItems.Count == 0){ return; } if(listView1.Columns[0].Text == "差出人"){ // 受信メールのとき for (int sel_index = listView1.Items.Count - 1; sel_index > -1; sel_index--) { if (listView1.Items[sel_index].Selected) { int nIndex = (int)listView1.Items[sel_index].Tag; if (listView1.Items[sel_index].SubItems[1].Text == ((Mail)collectionMail[RECEIVE][nIndex]).subject) { collectionMail[DELETE].Add(collectionMail[RECEIVE][nIndex]); collectionMail[RECEIVE].RemoveAt(nIndex); } else{ MessageBox.Show(string.Format("選択した件名と削除するデータが異なっています。\nリスト位置件名:{0}\n実位置件名:{1}\n(リスト位置:{2}, 実位置:{3}", listView1.Items[sel_index].SubItems[1].Text, ((Mail)collectionMail[RECEIVE][nIndex]).subject, sel_index, nIndex), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } } this.textBody.Text = ""; } else if(listView1.Columns[0].Text == "宛先"){ (上記のRECEIVEがSENDに変更のみでロジック変更なし) } else if(listView1.Columns[0].Text == "差出人または宛先"){ (上記のDELETEに変更されDELETEの配列に格納されたデータを削除) } // ツリービューとリストビューの表示を更新する UpdateTreeView(); UpdateListView(); (ListViewのフォーカスを設定し直す) }

  • C++Builderの警告

    Chart1->Series[0]->Clear(); グラフのコンポーネントを上記のようにして、書き直しの初期化を行うと、以下の警告が出ます。 [C++警告]TEST.cpp(138):W8006 'TColor'を'const int'で初期化している。 動作上は問題ないのですが、警告の意図は何なのでしょう? よろしく御願いいたします。

  • ListViewとArrayListの連動がうまくいきません

    メールソフトの中で既読、未読を設定するフラグを実装しているのですが ListViewのカラムクリック時の昇順・降順設定を追加するとなぜか おかしな表示になってしまいます。 未読(フラグがtrue)の時は太字で表示されて、既読(フラグがfalse)の 場合は通常のフォントで表示するようにしてあるのですが、 指定している配列ですべてtrueにしているのにもかかわらず表示されるのは trueとfalseの結果の表示がまばらに出てしまって何が原因なのかが 分かりません。 どうすればこれを解決する事が出来るでしょうか? 環境はVS2005(C#)、.NET Framework 2.0です。 リストビューの昇順・降順ロジックはどぼんの.NET Tipsに 載っている文字列、数字、日付で比較が可能なタイプのを 使用しています。 public void UpdateListView() { ArrayList list = null; int i = 0; if (listView1.Columns[1].Text == "差出人") { // 受信メールの場合 list = collectionMail[RECEIVE]; } else if (listView1.Columns[1].Text == "差出人または宛先") { // 削除メールの場合 list = collectionMail[DELETE]; } listView1.BeginUpdate(); // リストビューの内容をクリアする listView1.Items.Clear(); // ListViewを設定する foreach (Mail mail in list) { ListViewItem item = new ListViewItem(mail.subject); item.SubItems.Add(mail.address); item.SubItems.Add(mail.date); // この2行を追加 item.Tag = i; i++; listView1.Items.Add(item); // 未読(未送信)の場合は、フォントを太字にする int index = listView1.Items.Count - 1; if (mail.notReadYet == true) { listView1.Items[index].Font = new Font(this.Font, FontStyle.Bold); } } listView1.EndUpdate(); } private void listView1_DoubleClick(object sender, EventArgs e) { Mail mail = null; ListViewItem item = listView1.SelectedItems[0]; if (listView1.Columns[1].Text == "差出人") { mail = (Mail)collectionMail[RECEIVE][(int)item.Tag]; } else if (listView1.Columns[1].Text == "差出人または宛先") { mail = (Mail)collectionMail[DELETE][(int)item.Tag]; } mail.notReadYet = false; textBox1.Text = mail.body; UpdateListView(); } private void Form1_Load(object sender, EventArgs e) { // ListViewにアイテムを追加する for (int no = 0; no < subject.Length; no++) { Mail mail = new Mail(subject[no], address[no], date[no], body[no], read[no]); collectionMail[RECEIVE].Add(mail); } UpdateTreeView(); UpdateListView(); // ListViewItemComparerの作成と設定 listViewItemSorter = new ListViewItemComparer(); listViewItemSorter.ColumnModes = new ListViewItemComparer.ComparerMode[] { ListViewItemComparer.ComparerMode.String, ListViewItemComparer.ComparerMode.String, ListViewItemComparer.ComparerMode.DateTime }; // ListViewItemSorterを指定する listView1.ListViewItemSorter = listViewItemSorter; }

  • VB.NETでフォーム間でのコントロールの参照

    VB.NETでフォーム間でのコントロールの参照が うまくいかず困っています Windows フォーム Form1とForm2があります Form1にはリストビュー(name:ListView1)を配置しています Form1_LoadイベントでListView1にアイテムを追加します Form2を表示し、Form1のListView1のアイテム数を、 取得しようとすると 0 になってしまします どうすればForm2から取得できるのでしょうか? 次のように書いています Form1_Load イベント内 ListView1.Items.Add("Item1") ListView1.Items.Add("Item2") ListView1.Items.Add("Item3") MessageBox.Show(CStr(ListView1.Items.Count), "Form1") Dim Form2 As New Form2() Form2.Show() Form2_Load イベント内 Dim Form1 As New Form1() MessageBox.Show(CStr(Form1.ListView1.Items.Count), "Form2")

  • C# ListView 自作列幅調整 描画されない

    いつもお世話になっております。 今回はC#のListViewで皆様にお聞きしたいことがあり、 質問させて頂きました。 ListViewに3列追加しListViewの幅が変更された際に 2列目のみを引き延ばすものを作りたいと思っています。 しかし、以下操作を行うと、ListViewのリサイズ等で 描画更新されない状態になってしまいます。 (また、リストアイテムをクリックするとその列は描画されるのですが、 アイテムの描画開始Y位置がおかしくなっています。)  1.縦スクロールバーが表示されるまで縮小する  2.スクロールバーのノブを下に移動  3.縦スクロールバーの表示が消えるまで拡大する サンプルコード及び画像を添付いたします。 内容は、  3列のListViewに適当なアイテムを10個追加し、  OnClientSizeChangedでClientSize.Widthと1列3列の幅から  2列目の幅を算出・設定しています。 ※画像は、以下コントロールをFormに張り付けただけのもので  問題の起こる操作をした際のものになります。 class MyListView : ListView {   public const int COL_1_WIDTH  = 30;   public const int COL_3_WIDTH  = 75;   enum LISTVIEW_COL   {     COL1,     COL2,     COL3,     NUM   }   public MyListView() {     Dock = DockStyle.Fill;     HeaderStyle = ColumnHeaderStyle.None;     FullRowSelect = true;     HideSelection = false;     View = System.Windows.Forms.View.Details;     //ヘッダ追加     ColumnHeader column1 = new ColumnHeader();     ColumnHeader column2 = new ColumnHeader();     ColumnHeader column3 = new ColumnHeader();     ColumnHeader[] columnHeaders = { column1, column2, column3 };     this.Columns.AddRange( columnHeaders );     //ヘッダ幅追加     this.Columns[( int )LISTVIEW_COL.COL1].Width = COL_1_WIDTH;  //1列固定     this.Columns[( int )LISTVIEW_COL.COL3].Width = COL_3_WIDTH; //3列固定     int width = ClientRectangle.Width;     for( int i = 0; i < Columns.Count; i++ ) {       if( i == ( int )LISTVIEW_COL.COL2 ) { continue; }       width -= Columns[i].Width;     }     //2列 リストビューの幅いっぱいになるように調節     this.Columns[( int )LISTVIEW_COL.COL2].Width = width;     //適当にアイテム追加     for( int i = 0; i < 10; i++ ) {       string[] strs = { "COL1", "COL2", "COL3" };       ListViewItem item = new ListViewItem( strs );       this.Items.Add( item );     }   }   protected override void OnClientSizeChanged( EventArgs e ) {     base.OnClientSizeChanged( e );     //2列の幅を調整     int width = ClientRectangle.Width;     for( int i = 0; i < Columns.Count; i++ ) {       if( i == ( int )LISTVIEW_COL.COL2 ) { continue; }       width -= Columns[i].Width;     }     Columns[( int )LISTVIEW_COL.COL2].Width = width;   } } 何故このようになってしまうのかご存知の方いらっしゃいましたら教えてください。

  • ファイルコピーで更新日時が変わってしまう。

    XP pro + Visual Basic 2008 で、ファイルをバックアップするためのソフトを作ろうとしています。 ListViewを二つ用意して、それぞれに対象となるフォルダー内のファイルを表示、チェックリストにチェックしたファイルを、互いのフォルダーにコピーする。のようなものを作っています。 しかしListView1からListView2へコピーを行うと、どういうわけか更新日時が数秒づれてコピーされてしまいます。逆の場合はづれが起こらないようです。 原因&解決法を教えてください。 コードは以下の通りです。    Dim i As Integer    Dim response As MsgBoxResult    i = 0    response = MsgBox("リスト1の選択ファイルをコピーしますか?", MsgBoxStyle.YesNoCancel, "確認")    If response = MsgBoxResult.No Then       GoTo CopyRist2    ElseIf response = MsgBoxResult.Cancel Then       Exit Sub    End If    Do Until i >= ListView1.Items.Count       If ListView1.Items(i).Checked = True Then          My.Computer.FileSystem.CopyFile(フォルダ1のパス & "\" & ListView1.Items(i).Text, _             フォルダ2のパス & "\" & ListView1.Items(i).Text, True)          ListView1.Items.RemoveAt(i)       Else          i = i + 1       End If    Loop CopyRist2:    i = 0    response = MsgBox("リスト2の選択ファイルをコピーしますか?", MsgBoxStyle.YesNoCancel, "確認")    If response = MsgBoxResult.No Then       Exit Sub    ElseIf response = MsgBoxResult.Cancel Then       Exit Sub    End If    Do Until i >= ListView2.Items.Count       If ListView2.Items(i).Checked = True Then          My.Computer.FileSystem.CopyFile(フォルダ2のパス & "\" & ListView2.Items(i).Text, _             フォルダ1のパス & "\" & ListView2.Items(i).Text, True)          ListView2.Items.RemoveAt(i)       Else          i = i + 1       End If    Loop 以上です。 よろしくお願いします。

  • C#の処理をリアルタイムに表示させる方法

    いつもありがとうございます。 現在、visual C#を勉強中で、とても初歩的なことを聞いてしまうかもしれませんが、 よろしくお願いします。 かなり時間がかかる処理を作っているのですが、 すべて終わるまでツールが結果を表示してくれなくて困っています。 forやforeachのループを1回回るごとに データを表示させることは可能でしょうか? また処理途中で一時停止したいです。 具体的には、listviewにデータを表示させています。 たとえば以下のような処理ですが、すべ終わって結果が 表示されるのは、1個ずつリアルタイムにリストビューに 追加されていき・・・ さらに途中で一時停止をしたいと考えています。 for (int i=0; i<10000; i++) { 処理して得られたデータを listView1.Items.Add(データ); と追加 } 以上よろしくお願いします。

  • C++ なのですがエラーが消えません

    課題のC++プログラムのエラーが消えません,教えてください. 10個の数値を入力し並び替えるプログラムなのですが並び替え部分以外は先生作成のプログラムです. どうかお願いいたします. #include <stdio.h> #define MAX 10 #define OK 0 void inputnum(int num[]); void sortnum(int num[]); void outputnum(int num[]); main(){ int num[MAX]; printf("番号 氏名\n"); inputnum(num); sortnum(num); outputnum(num); return(OK); } void inputnum(int num[]){ int i; for(i=0;i<MAX;i++,num[i]){ printf("数値%d = ", i+1); scanf("%d",&num[i]); } printf("数値入力完了\n"); } void sortnum(int num[]){ int tmp,p,q; for(p = 0; p < 9; p++){ for(q = p + 1; q < 10; q++){ if(num[p] > num[q]){ tmp = num[p]; num[p] = num[q]; num[q] = tmp; } } } printf("並び替え完了\n"); void outputnum(int num[]){ int i; for(i=0;i<MAX;i++){ printf("数値%d = %d\n",i+1,num[i]); } printf("数値出力完了\n"); }; [エラー  Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland 1142122.c: エラー E2140 1142122.c 46: ここでは宣言はできない(関数 sortnum ) エラー E2141 1142122.c 46: 宣言の構文エラー(関数 sortnum ) エラー E2134 1142122.c 54: 複合文に } がない(関数 sortnum ) *** 3 errors in Compile ***]

  • ArrayListのソートについて

    プログラム上でListViewのカラムをクリックするとソートされる プログラムを作ろうと入れたのですが、リストはソートされるのに 中身(ArrayList)がソートされていないためソート後のアイテムを クリックしても違う値しか出てきません。 それにはArrayListのソートが必要と言う事が書いてあったので 実装をしてみたのですが、比較ができないようなエラーが出て うまくソートもできませんでした。 どうすればListViewのカラムソートと連動してArrayListのソートが 出来るようになるでしょうか? 開発環境はVS2005(C#) .NET2.0です。 サンプルクラスは以下の通りです。 public void UpdateListView() { ArrayList list = null; if (listView1.Columns[1].Text == "差出人") { // 受信メールの場合 list = collectionMail[RECEIVE]; } else if (listView1.Columns[1].Text == "差出人または宛先") { // 削除メールの場合 list = collectionMail[DELETE]; } listView1.BeginUpdate(); // リストビューの内容をクリアする listView1.Items.Clear(); // ListViewを設定する foreach (Mail mail in list) { ListViewItem item = new ListViewItem(mail.subject); item.SubItems.Add(mail.address); listView1.Items.Add(item); } listView1.EndUpdate(); } private void Form1_Load(object sender, EventArgs e) { // ListViewにアイテムを追加する for (int no = 0; no < subject.Length; no++) { Mail mail = new Mail(subject[no], address[no], body[no]); collectionMail[RECEIVE].Add(mail); } UpdateTreeView(); UpdateListView(); } public class Mail { public string subject; public string address; public string body; public Mail(string subject, string address, string body) { this.subject = subject; this.address = address; this.body = body; } }

専門家に質問してみよう