リストビューにCStringの値をセット

[戻る]
たけ 2004/11/08(月) 22:04:29
たけです。

リストビューへの文字列の設定で↓のようにしたところ

for (int i = 0; i < 10; i++) {

    // 行の挿入
    item.mask         = LVIF_TEXT;
    item.iItem        = m_listCtrl.GetItemCount();
    char szIndex[20];
    sprintf(szIndex, "%d", metaTable.nIndex);
    item.iSubItem     = 0;
    item.pszText =szIndex;
    m_listCtrl.InsertItem(&item);

    item.iSubItem     = 1;
    item.pszText      = metaTable.szQueryNo;
    m_listCtrl.SetItem(&item);

    item.iSubItem     = 2;
    strcpy(item.pszText,CStringの値); ←←←←←←問題箇所
    m_listCtrl.SetItem(&item);
}

↑の問題箇所のところで、変数iの領域を破壊してしまいました。

よくよく考えてみたら十分な領域が確保されていない領域に
文字列をコピーしたんだからおかしくなって当然ですが

↓のようにやるとOKだったので、こちらが書き方として正解でしょうか?
item.pszText = str.GetBuffer(sizeof(str)); 「strはCStringの変数」

また、
構造体 hoge = どこかから取得
item.pszText = hoge.text;  「textはcharの配列」

とやってもOKですよね。
でもこれってhogeインスタンスはすぐ消えちゃうのになぜOKなんでしょう?

なにやらリストビューがよくわからなくなってきました。
漠然とした質問ですがこのあたりをどうかご教授ください。

wood 2004/11/09(火) 05:52:26
回答じゃ無いよ

1.
>変数iの領域を破壊してしまいました
2.
>↓のようにやるとOKだったので、こちらが書き方として正解でしょうか?
>item.pszText = str.GetBuffer(sizeof(str)); 「strはCStringの変数」
3.
>でもこれってhogeインスタンスはすぐ消えちゃうのになぜOKなんでしょう?

質問の種類は表題の「リストビューにCStringの値をセット」に対して
1.と3.違う質問になっていると思うが
どれを最初に解決したいの?

「2.」についての個人的意見を言わせてもらえば、コンパイルが通って、実行が出来
デバックしても、領域破壊やアサートされなければ「OK」と解釈して良いんじゃない
ですか(使用目的にあっていればですけど)

たけ 2004/11/09(火) 09:39:40
すいません。2、3の順に解決したいです。
3は、2を悩んでいるうちにわいた疑問です。

REE 2004/11/09(火) 09:52:09
>↓のようにやるとOKだったので、こちらが書き方として正解でしょうか?
>item.pszText = str.GetBuffer(sizeof(str)); 「strはCStringの変数」

正解かどうかは別にして、特に問題はないでしょう。
但し、strを後で使う予定があるのでしたら、ReleaseBufferを忘れずに


>構造体 hoge = どこかから取得
>item.pszText = hoge.text;  「textはcharの配列」
>
>とやってもOKですよね。
>でもこれってhogeインスタンスはすぐ消えちゃうのになぜOKなんでしょう?

SetItemの時点で、文字列の内容がリストビュー内部に保存されるとお考え下さい。

余談ですが、この場合はSetItemの代わりにSetItemTextを使うことも出来ますよ。

てつや 2004/11/09(火) 09:53:37
私も以前すごく悩みました。

>↓のようにやるとOKだったので、こちらが書き方として正解でしょうか?
>item.pszText = str.GetBuffer(sizeof(str)); 「strはCStringの変数」
ビミョーに不正解です。
item.pszText = str.GetBuffer(str.GetLength() + 1 );
sizeof(str)ってstrのサイズです。実際の長さを入れます。

>また、
>構造体 hoge = どこかから取得
>item.pszText = hoge.text;  「textはcharの配列」
>
>とやってもOKですよね。
>でもこれってhogeインスタンスはすぐ消えちゃうのになぜOKなんでしょう?

SetItemで内部的にコピーしているみたいです。SetItemした後は、
消えてしまってかまいません。

item.pszText = (LPSTR)(LPSTSTR)str ;
でも良いみたいです。constはずしってあんまり気分良くありませんが。

てつや 2004/11/09(火) 09:54:51
すみません。かぶってしまいました。

てつや 2004/11/09(火) 09:59:04
>item.pszText = (LPSTR)(LPSTSTR)str ;
更に間違ってました。
item.pszText = (LPTSTR)(LPCTSTR)str ;

REE 2004/11/09(火) 10:36:38
>>item.pszText = str.GetBuffer(sizeof(str)); 「strはCStringの変数」

>正解かどうかは別にして、特に問題はないでしょう。

GetBufferの引数を見ていませんでした・・
てつやさんの様に直す必要があります。

dairygoods 2004/11/09(火) 11:33:54
>>item.pszText = str.GetBuffer(sizeof(str)); 「strはCStringの変数」

item.pszText = str.GetBuffer(0); 
でOK。

GetBufferの引数は、「最低限必要なサイズ」です。
例えば、10を指定すると、
バッファが10バイト未満なら、10バイトに拡張されますが、
10以上なら、切り詰められたりせず、現在のバッファがそのまま返されます。

# なので、GetBuffer(sizeof(str)) は不自然ですが、偶然問題なく動きます。

たけ 2004/11/09(火) 13:06:06
たくさん、レスがついてる!皆様ありがとうございます。

>SetItemの時点で、文字列の内容がリストビュー内部に保存されるとお考え下さい。
あ!、なるほど。これで3の悩みは解決です。

そして、みなさんに教えて頂いた方法(下の3つ)は
全てちゃんと動作しました。

1.
item.pszText = (LPTSTR)(LPCTSTR)str ;

2.
item.pszText = str.GetBuffer(0); 

3.
SetItemText(x, y, str);

CStringの値をセットしたい場合は、状況に応じて1〜3を
使用します。

ところで、どこかのHPでもみかけたのですがREEさんの↓の意味だけわかりません。
これについても出来たらご教授ください。
>但し、strを後で使う予定があるのでしたら、ReleaseBufferを忘れずに

dairygoods 2004/11/09(火) 17:26:58
> ところで、どこかのHPでもみかけたのですがREEさんの↓の意味だけわかりません。
> これについても出来たらご教授ください。
> >但し、strを後で使う予定があるのでしたら、ReleaseBufferを忘れずに

ヘルプを読んでも分からないなら、
その旨を記載し、何処が分からないのか訊いたほうがよいです。

ヘルプを読んでないなら、ヘルプを読みましょう。

たけ 2004/11/09(火) 21:38:31
[[解決]]
すいません。ヘルプ読んでみたらわかりました。
今回の場合、GetBuffer()を使用したCStringをその後
使用しないので、ReleaseBuffer()も必要ないようです。

hasimoto 2004/11/10(水) 23:27:11
1の方法(constをとる方法)でちゃんと動作したとありますが、
違う環境でやってみたらちゃんと動作しないかもしれません。
無理やりやるのはよくないんじゃないかな〜(多分)

REE 2004/11/11(木) 10:20:44
CListCtrl::SetItemTextを使えば、もっとすっきりするかも

たけ 2004/11/13(土) 10:40:46
もともと悩んでいた箇所には、SetItemText()を使用しました。
CStringの値が直接、引数に使えるようなので。

isshi 2004/11/13(土) 13:24:09
>1の方法(constをとる方法)でちゃんと動作したとありますが、
>違う環境でやってみたらちゃんと動作しないかもしれません。
>無理やりやるのはよくないんじゃないかな〜(多分)
私も同じ意見ですが、CListCtrl::SetItemText の実装を見ると
思いっきり const はずしをしています。

古いスレッドには追加発言できません。