たけです。
リストビューへの文字列の設定で↓のようにしたところ
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なんでしょう?
なにやらリストビューがよくわからなくなってきました。
漠然とした質問ですがこのあたりをどうかご教授ください。
回答じゃ無いよ
1.
>変数iの領域を破壊してしまいました
2.
>↓のようにやるとOKだったので、こちらが書き方として正解でしょうか?
>item.pszText = str.GetBuffer(sizeof(str)); 「strはCStringの変数」
3.
>でもこれってhogeインスタンスはすぐ消えちゃうのになぜOKなんでしょう?
質問の種類は表題の「リストビューにCStringの値をセット」に対して
1.と3.違う質問になっていると思うが
どれを最初に解決したいの?
「2.」についての個人的意見を言わせてもらえば、コンパイルが通って、実行が出来
デバックしても、領域破壊やアサートされなければ「OK」と解釈して良いんじゃない
ですか(使用目的にあっていればですけど)
すいません。2、3の順に解決したいです。
3は、2を悩んでいるうちにわいた疑問です。
>↓のようにやるとOKだったので、こちらが書き方として正解でしょうか?
>item.pszText = str.GetBuffer(sizeof(str)); 「strはCStringの変数」
正解かどうかは別にして、特に問題はないでしょう。
但し、strを後で使う予定があるのでしたら、ReleaseBufferを忘れずに
>構造体 hoge = どこかから取得
>item.pszText = hoge.text; 「textはcharの配列」
>
>とやってもOKですよね。
>でもこれってhogeインスタンスはすぐ消えちゃうのになぜOKなんでしょう?
SetItemの時点で、文字列の内容がリストビュー内部に保存されるとお考え下さい。
余談ですが、この場合はSetItemの代わりにSetItemTextを使うことも出来ますよ。
私も以前すごく悩みました。
>↓のようにやると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はずしってあんまり気分良くありませんが。
すみません。かぶってしまいました。
>item.pszText = (LPSTR)(LPSTSTR)str ;
更に間違ってました。
item.pszText = (LPTSTR)(LPCTSTR)str ;
>>item.pszText = str.GetBuffer(sizeof(str)); 「strはCStringの変数」
>正解かどうかは別にして、特に問題はないでしょう。
GetBufferの引数を見ていませんでした・・
てつやさんの様に直す必要があります。
>>item.pszText = str.GetBuffer(sizeof(str)); 「strはCStringの変数」
item.pszText = str.GetBuffer(0);
でOK。
GetBufferの引数は、「最低限必要なサイズ」です。
例えば、10を指定すると、
バッファが10バイト未満なら、10バイトに拡張されますが、
10以上なら、切り詰められたりせず、現在のバッファがそのまま返されます。
# なので、GetBuffer(sizeof(str)) は不自然ですが、偶然問題なく動きます。
たくさん、レスがついてる!皆様ありがとうございます。
>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を忘れずに
> ところで、どこかのHPでもみかけたのですがREEさんの↓の意味だけわかりません。
> これについても出来たらご教授ください。
> >但し、strを後で使う予定があるのでしたら、ReleaseBufferを忘れずに
ヘルプを読んでも分からないなら、
その旨を記載し、何処が分からないのか訊いたほうがよいです。
ヘルプを読んでないなら、ヘルプを読みましょう。
すいません。ヘルプ読んでみたらわかりました。
今回の場合、GetBuffer()を使用したCStringをその後
使用しないので、ReleaseBuffer()も必要ないようです。
1の方法(constをとる方法)でちゃんと動作したとありますが、
違う環境でやってみたらちゃんと動作しないかもしれません。
無理やりやるのはよくないんじゃないかな~(多分)
CListCtrl::SetItemTextを使えば、もっとすっきりするかも
もともと悩んでいた箇所には、SetItemText()を使用しました。
CStringの値が直接、引数に使えるようなので。