>item.pszText = const_cast< LPTSTR >( static_cast< LPCTSTR >( str ) );
これで通りました。
ありがとうございます。
>そもそも、GetBuffer は文字列の内容を変更するために使うものでしょう。
なるほど。言われてみればそうですね。。。
代入するだけで関数を二つもコールするのは確かに腑に落ちないですね。
先輩がこの使い方をしてたもので真似してみました。
キャストの仕方が思いつかなかったもので・・・
> キャストの仕方が思いつかなかったもので・・・
2回キャストしなければならないので、確かにややこしいですね。
static_cast は、CString が持っているキャスト演算子を呼び出して、LPCTSTR(読み取
り専用の生の文字列のポインタ)を取得します。
これは「読み取り専用」であることに注意すべきです。
GetBuffer が返すのは書き込み用のポインタです。
const_cast で、LPCTSTR を LPTSTR に変換します。これで表面上は書き込み可能になり
ましたが、このポインタに書き込んではいけません。
読み取り専用なものを、無理やり書き込み可能にしているので、ここに書き込むと不具
合が出る可能性があります。
では、何故こんなことをするのかと言うと… LVITEM::pszText が LPTSTR 型なので、こ
うしないとエラーが出るため仕方なく、ですね。LVITEM はアイテムの情報を取得する時
にも使う構造体なので、読み取り専用に出来ないのです。
CListCtrl::GetItem を使ってアイテムの情報を取得する時には、LVITEM::pszText にセ
ットするポインタは GetBuffer で取得しましょう。
なお、一回のキャストで LPTSTR に変換することは出来ません。
LPCSTR にする時は、CString の「LPCTSTR にキャストした結果を返すキャスト演算子」
を呼び出していましたが、CString は LPTSTR に変換する演算子を持っていませんので
ね。
>CListCtrl::GetItem を使ってアイテムの情報を取得する時には、LVITEM::pszText に
>セットするポインタは GetBuffer で取得しましょう。
ん?どういう意味ですか?GetItemは取得するだけだから、セットすることはないですよ
ね?
以下の方法でCString型の文字列に代入できるはずですけど・・・(?_?)
LV_ITEM item;
CString str;
m_ListCtrl.GetItem(&item);
str = item.pszText;
> 以下の方法でCString型の文字列に代入できるはずですけど・・・(?_?)
できます?
運が悪けりゃ、不正終了で落ちますよ。それ。
LVITEM::pszText は、アイテム名を保持するバッファのポインタです。
GetItem を呼ぶのに先立って、pszText に有効なバッファのポインタを、cchTextMax
に、そのバッファのサイズを入れておかなければ、GetItem できません。
つまり、こういうこと。
LVITEM item;
CString str;
item.pszText = str.GetBuffer( 256 );
// ↑これが「GetItem で使うポインタは GetBuffer で得たものをセットする」てこと
item.cchTextMax = 256;
m_ListCtrl.GetItem( &item );
str.ReleaseBuffer();
これを、
item.pszText = const_cast< LPTSTR >( static_cast< LPCTSTR >( str ) );
って書いちゃダメですよ、って話。
>item.pszText = const_cast< LPTSTR >( static_cast< LPCTSTR >( str ) );
>って書いちゃダメですよ、って話。
この文章意味がわからなかったけど、
>item.pszText = str.GetBuffer( 256 );
>// ↑これが「GetItem で使うポインタは GetBuffer で得たものをセットする」てこと
>item.cchTextMax = 256;
>m_ListCtrl.GetItem( &item );
>str.ReleaseBuffer();
こうするとGetItemで得たitem.pszTextに格納されている文字列が
strにも格納されるという意味だったんですね?
>できます?
>運が悪けりゃ、不正終了で落ちますよ。それ。
普通にできましたよ。
だーかーらー
問題を抱えたコードがたまたま動いている ってのと
問題が無いことがわかっているコード ってのは問題の次元が違う。
たまたまでも、動きゃいい と思ってるならこの業界向きではないです。
転職なり考えたほうがいい
>こうするとGetItemで得たitem.pszTextに格納されている文字列が
>strにも格納されるという意味だったんですね?
ちがう。
っていうかスレ長すぎるよ...
>問題を抱えたコードがたまたま動いている ってのと
>問題が無いことがわかっているコード ってのは問題の次元が違う。
そんなことわかってるよ。
今回のことと関係ないでしょ!?
>たまたまでも、動きゃいい と思ってるならこの業界向きではないです。
>転職なり考えたほうがいい
そんなことてめーに言われる筋合いないよ
>っていうかスレ長すぎるよ...
長いのはダメなんて誰が決めたんだ?
> っていうかスレ長すぎるよ...
ごめんねぇ。
CString 周りのことは本題じゃなかったらしいけど、続けちゃってるから…。
>> できます?
>> 運が悪けりゃ、不正終了で落ちますよ。それ。
> 普通にできましたよ。
うん。俺は「運が悪ければ」って言った。
動いたのは、たまたま運がよかっただけ。
そういうこともあるけれど、毎回できるとは限らない。
あなたの書いたのはそういうコード。
> こうするとGetItemで得たitem.pszTextに格納されている文字列が
> strにも格納されるという意味だったんですね?
微妙に違います。
ポインタって何だか理解されてますか?
「文字列ポインタ」と「文字列」はイコールではありません。「文字列ポインタ」と
「CString」もイコールではありません。
ポインタ(pointer)は、その名の通り、「指し示すもの」でしかありません。
「文字列ポインタ」ってのは、「別の場所にある文字列を指し示すもの」です。
ポインタだけでは何の役にも立ちません。指し示す先(この場合は文字列)とペアで使
って、初めて意味があります。
item.pszText の型は LPTSTR です。これは文字列ポインタです。
item.pszText には文字列は格納されません。
item.pszText は、どこかにある、取得した文字列を格納するためのメモリ領域の場所を
指し示すためのものです。
CString は文字列ポインタではありません。これは文字列そのもの(に、ちょっと便利
な機能をつけたもの)です。
ですから、CString は、ポインタによって指し示される、実際の格納場所になることが
できます。
> item.pszText = str.GetBuffer( 256 );
> item.cchTextMax = 256;
> m_ListCtrl.GetItem( &item );
> str.ReleaseBuffer();
これは、
1:CString の内部に、実際の格納領域として 256 文字分のバッファを用意し
2:その格納領域を指し示すポインタを item.pszText にセットし
3:格納領域のサイズを、item.cchTextMax にセットし
4:CString の内部に確保したバッファに、アイテムの文字列を取得し
5:CString の後始末をする
というコードです。
> こうするとGetItemで得たitem.pszTextに格納されている文字列が
> strにも格納されるという意味だったんですね?
item.pszText は str を指すポインタでしかなく、文字列領域ではないため、
item.pszText には文字列は格納されません。
str にだけ格納されるのです。
>> item.pszText = const_cast< LPTSTR >( static_cast< LPCTSTR >( str ) );
>> って書いちゃダメですよ、って話。
> この文章意味がわからなかったけど、
CString の中にある文字列領域のポインタを得る手段は2つあり、用途によってどちら
を使うべきかが異なるということです。
CString の中にあるデータを読み取りたいだけならば、キャストを使います。
CString の中にデータを書き込みたい場合は、GetBuffer を使います。
> しかし、せっかくVCなのでできるだけC言語は使わないでやってみたかったもの
> で・・・
C 言語をよく知らないうちに手を出すと火傷しますよ。
Win32 API も MFC も、C 言語を知らずに使えるものではありません。
#キレてんじゃねぇよ…
#真面目に長文書いてたのがアホらしくなってきたorz
>ポインタって何だか理解されてますか?
理解してます。
>item.pszText の型は LPTSTR です。これは文字列ポインタです。
そうなんだ!!実体のバッファがあるのかと思ってました。
ポインタだけなんだ。
ならすべて納得できます。
>#キレてんじゃねぇよ…
あれはキレマスヨ。
いきなりでてきて言ってることは全て間違ってるわ。
あんあこといちいち発言する必要がないよ。
あれでキレナイ奴とは会話する価値がないと思うよ。
自分こそ話の内容全く理解してないと思うよ。
むいてないんじゃない?
>あれはキレマスヨ。
>いきなりでてきて言ってることは全て間違ってるわ。
素朴な疑問ですが、どこが間違っていたのですか?
転職云々は余計ですけれども。
>> 問題を抱えたコードがたまたま動いている ってのと
>> 問題が無いことがわかっているコード ってのは問題の次元が違う。
> そんなことわかってるよ。
> 今回のことと関係ないでしょ!?
関係ありますよ。思いっきり。
個人的には、キレやすい人は向いてないようにも思うのですけどね。
> 自分こそ話の内容全く理解してないと思うよ。
tetrapod さんの書き込みは正しく理解しているように読み取れたのですが、
私も何か理解できてないのでしょうか。どこでそう思われたのでしょう。
# tetrapod さんでも向いてないとすると、向いてる人ってのは相当難しいそう…。
やっぱ答えたほうがいいの?
くだらない・・・
>実体のバッファがあるのかと思ってました。
ってことで、問題を抱えたコードとは思わなかったということだよ。
>問題を抱えたコードがたまたま動いている ってのと
>問題が無いことがわかっているコード ってのは問題の次元が違う。
だから、この2行だけの意味はわかるけど、
今回とは関係ないということね。
>たまたまでも、動きゃいい と思ってるならこの業界向きではないです。
>転職なり考えたほうがいい
たまたまでも動けばいいなんてまったく思ってないよ。
この業界向きかどうかは関係ないんだよ。
この業界に向いてると思ったことは一度もないし、
向いてるか、向いてないかは俺にとって仕事を選ぶにあたって全く関係ないんだよ。
転職するかどうかは、
この俺が決めることであって、
誰かに言われる筋合いはない。
>個人的には、キレやすい人は向いてないようにも思うのですけどね。
俺から言わせるとtetrapod のほうがキレヤスイんじゃない。
わざわざあんな発言書き込むひつようがない。
俺はキレタというより、
tetrapodにその発言により不愉快になってるんだぞ!
って教えてあげたんだよ。
言われなきゃ自分が悪いと思わない奴はいっぱいいるからね。
言われてもわからない奴もいるけど・・・
まぁ、わざと不愉快にさせるために発言したんならいいけどね。
みなさん、これでわかったかな?
> 実体のバッファがあるのかと思ってました。
だったら、InsertItem、InsertItemのときにのitemには
strcpy( item.pszText, str );
てな感じで格納することになるでしょうね。
char s[ 10 ];
s = str;
っての書けませんからね。
> 長いのはダメなんて誰が決めたんだ?
一応、らららさんの掲示板を利用させてもらっている以上
無駄にリソースは使わないほうが良いということでしょう。
ただ、今回の流れはあまり無駄なことは無かったですが。
# あえて言うなら、私の誤投稿ですな。。。。orz