ListView.items.add で項目が表示されない場合の対処方法は?

解決


かなもの  2003-09-26 10:05:53  No: 5004

はじめまして かなもの と申します。
いつも、ありがたく掲示板を資料として利用させて頂いています。
今回どうしても行き詰ってしまったので、思い切って書き込みをしてみました。

内容はタイトル通りなのですが、再現率は100%ではないのです。
下記に例を書いて見ます。

list := ListView1.Items.Count;
NewItem := ListView1.Items.Add();
NewItem.Caption := Caption;//←ここにStringが入る
Label1.Caption := IntToStr(list);
Label2.Caption := IntToStr(ListView1.Items.Count);

毎秒ごとに新しい情報があるかTCP経由で監視して(読み取って)、
新しい情報が見つかったら情報を受信して、
ListViewに表示するというものを作っています。
通常では問題ありません・・・

ところが、正確な条件までは見出せなかったのですが、
ListView1.Items.Countが加わっているにも関わらず、
実際の画面には表示されない場合がある・・・という現象に悩まされています。

ですので、例文では、元々1行あった場合  Label1.Caption には「1」
Label2.Caption には「2」が表示されているにも関わらず、
実際には1行のみしか表示されていない・・・という事です。

同じ文字列でも、表示されたりされなかったりしています。
長時間立ち上げてる事を想定してまして、行が欠けるとあまりよろしくないのです。
どうも100〜200に1回ぐらいの確立で発生するようです。

BeginUpdate・EndUpdateを挟む事も試してみましたが、
表示がちらつくだけで改善はされませんでした。

又、起動直後でコンパイルしたEXEのみの起動も試みましたが、
同じく改善されませんでした。

OSも変えて見ました。XP/2000/ME/98で試してみましたが
すべてのOSで発生しました。

加えて、新しい情報が見つかって3行目が追加される・又は1行目を削除すると、
2行目が表示されるという現象も確認しました。
(表示系監視の物なので、可能な限り行削除は行いたくないのです・・・
  ですのでclearはダメでして・・・)

これらの現象に対して、何か改善策はあるのでしょうか?
ご回答のほど、よろしくお願いします。

ひき続きHELPとにらめっこします・・・

開発環境:
WIndowsXP Professional SP1
Delphi 6 Personal
P.S. あ、商用ではないですので。


Halbow  URL  2003-09-26 12:07:22  No: 5005

Halbow です。

項目が増えているのに表示されないのは、文字列が空か、空白である
可能性がありませんか。同時にリストボックスにも Add して比較して
見たらどうでしょうか。


にしの  2003-09-26 18:11:29  No: 5006

Captionの中身は正しい文字列なのでしょうか。
例えば、Caption[1]に#0(もしくは#1〜#31など、コントロールコード)が入っていたりしませんか?
OutputDebugStringなどで、BinToHexで16進数にした文字列をはき出させてみてはどうでしょう。
まずは、正しいデータかどうか確認してみてください。


かなもの  2003-09-26 19:36:16  No: 5007

ご回答有難うございます。

> 文字列が空か、空白である可能性がありませんか。
申し訳有りません。書き忘れていました。

Label3.Caption := Caption;

…とした所、内容が表示されている事を確認しております。
さらに空白の行があれば、空の行を選択出来るかと思いますが、
行そのものが追加されていないので、選択すら出来ない状態です。
又…
> 加えて、新しい情報が見つかって3行目が追加される・又は1行目を削除すると、
> 2行目が表示されるという現象も確認しました。
とあるように、行を削除すると今まで表示されていなかった行が現れるので、
ListViewへの書き込み処理自体はされているのでは?と推測しております。

> コントロールコードが入っていたりしませんか?
これは確認しておりませんでした。(知識不足)
Label3.Caption に表示されていたので悩んでおりました。
OutputDebugStringは初耳でした。コレを使って文字列の内容を確認したいと思います。

結果は追ってご報告致します。


かなもの  2003-09-27 08:50:04  No: 5008

申し訳ありませんが・・・

OutputDebugString
BinToHex

共にHELPやWebにて使い方を探しだす所から調べております。
確認には暫く時間がかかかると思われます・・・


ウォレス  2003-09-27 08:55:20  No: 5009

はじめまして。
https://www.petitmonte.com/bbs/answers?question_id=830
で話題となっておりますが、Personal版ではOutputDebugStringは使えません。(実行ファイルからなら使えます)
たかみちえさんの作成された、デバッグ用ユニットを用いるのがよかろうかと思います。


にしの  2003-09-27 09:01:47  No: 5010

Personalでしたね。
OutputDebugStringの出力結果を確かめるには(IDE環境からは)結構難しいです。
ログ出力用のTMemoなどを貼り付けて確かめてみてください。
BinToHexは、
var
  Caption: String; // これに元の文字列
  HexStr: String; // 16進数表記文字列用
という変数があったとして、

  SetLength(HexStr, Length(Caption)*2);
  BinToHex(PCHAR(Caption), PCHAR(HexStr), Length(Caption));

とすれば、HexStrに16進数表記の文字列が入ります。


かなもの  2003-09-27 10:20:15  No: 5011

使い方の説明ありがとうございます。

OutputDebugString は、実際に外部支援を使えば出来ましたが、
Labelを使って表示させております。

BinToHex は SetLength の行の所でつまづいておりました。
PChar型ですので、長さを指定しないとダメですよね。

-------------------------------------

本題の前に、説明不足の部分がありましたのでご説明します。
ListView の ViewStyle は vsReport です。
サブアイテムもあり、1行にCaptionを含め8列の表示をしております。
受信DATAの中に損失したDATAがあれば、行を削除する仕組みです。
(上の書き込みで「削除すると・・・」と言っていたのはココの事です)

さて、サブアイテムを含む行全ての値に、BinToHex の表示を試みて見ました。
しかし、行が表示されない時でも、
文字列の値の中にコントロールコードは見当たりませんでした。

加えて、表示されていない行に対して
ListView1.Items.Item[ListView1.Items.Count-1].Caption
(表示されていない行は常に一番下ですので)
の表示を試みて見た所、ListView上には表示されていないのですが
値の取得が出来ました。

損失したDATAの行を削除する時には

ListView1.Items.Item[i].Delete;

これで消していますが、本当にDeleteされているのであれば値が取得出来ないはずなので、
これが邪魔してるのは考えにくいと推測しております。

以上現在の検証報告です。


HOota  2003-09-27 16:40:03  No: 5012

表示されていない場合に、ListView1の中身をファイルに落としてみたらいかがでしょうか?SaveToFileで簡単だと思います。


Halbow  2003-09-27 17:10:40  No: 5013

Halbow です。

> 表示されていない行は常に一番下ですので

ListView1.UpdateItems(ListView1.Items.Count-1,ListView1.Items.Count-1);

を追加するたびに実行してみたらいかがでしょうか。


かなもの  2003-09-27 21:19:02  No: 5014

ご回答有難うございます。

> ListView1の中身をファイルに落としてみたらいかがでしょうか?
申し訳ないのですが、目的が記録ではなく監視なのです。
リアルタイムでの取得を重視している為、記録は避けたい所です。

> ListView1.UpdateItems(ListView1.Items.Count-1,ListView1.Items.Count-1);
> を追加するたびに実行してみたらいかがでしょうか。
これは行っておりませんでした。
HELPを見ても、いまいち意味が良く分からなかったのですが、
まずは設置して検証してみたいと思います。

結果は追ってご報告致します。


HOota  2003-09-28 05:23:37  No: 5015

デバッグの場合だけの処理です。ずっとそのままファイルに落とすわけではありません。


かなもの  2003-09-28 21:02:16  No: 5016

レスを頂きありがとうございます。

> ずっとそのままファイルに落とすわけではありません。
私の勘違いだったようで申し訳ありませんでした。
しかし、情報を読み取るという意味では、
上記に書かれている通り、すでに検証済みではあります。

値はListViewに書き込まれているようです。読み取りも可能です。
加えて調べた所、見えない行に対しての行削除も出来るようです。
(行を削除すればListView1.Items.Countで数が減りました)
問題はただ単に「表示しない」一点のみです。

1日ほど家を空けておりまして、検証が進んでおりません・・・
知人に1日ほど検証をお願いしたのですが、
現在は、以前の作成したAPPでも現象が出ていないとの事です。

引き続き検証を続けたいと思います。
結果は追ってご報告致します。


かなもの  2003-09-29 05:37:52  No: 5017

現在の結果報告を致します。

> ListView1.UpdateItems(ListView1.Items.Count-1,ListView1.Items.Count-1);
> を追加するたびに実行してみたらいかがでしょうか。
コチラを追加してから、現在は現象がみられません。
今の所安定しておりますので一度解決とさせて頂きます。

暫く様子を見て、まだ現象が発生するようであれば、
改めて書き込みをさせて頂きたいと思います。

ご回答して頂き、ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加