オーナードローリストボックスでListBox_AddStringが失敗する

[戻る]
2005/02/27(日) 22:42:11
こんにちは

環境
WinXP、VC++6.0、SDK

今回はSDKでの質問です

LBS_OWNERDRAWFIXEDを持つリストボックスの初期化を以下のようにしています
hListBoxはリストボックスのハンドルを表すHWND型変数、
MAX_SIZEは可変ですが、項目数を表す数値が入っています

int   nCnt;
for(nCnt = 0; nCnt < MAX_SIZE; nCnt++)
{
   ListBox_AddItemData(hListBox,iCnt);
}

これをわたしの自分のパソコンで実行すれば、きちんと(0〜MAX_SIZE-1)の
項目が挿入されました

しかし同じアプリケーションを使用した別の人からの報告で、
(nCnt==0)の時だけアイテムが挿入されず、(1〜MAX_SIZE-1)の項目だけ挿入されるとい
う
状態になるというものがありました

その人にデバッグ用にログを出力できるもので試してもらったところ、
nCntが0の時だけListBox_AddItemDataがLB_ERRを返していることがわかりました
しかし、1以降の項目は全て問題なく挿入されていました

その人の環境は
WindowsXPHomeEdition Ver2002
だということでした

最初はメモリ不足でも起こしているのかと思いましたが、
戻り値がLB_ERRSPACEではありませんし、1以降の項目は挿入されているので
やはり別に問題があるのではないかと思いました

ちなみにListBox_InsertStringでも試してもらいましたが、同じように
nCnt==0の時だけエラーが発生したようです

しかし、LB_INSERTSTRINGやLB_ADDSTRING、またLB_SETITEMDATAなどを調べてみても、
アイテムデータとして0を設定することはできないとは書いてありませんし、
わたしのパソコンでは正常に動いていますし
それに正常に挿入できた場合、ListBox_GetItemDataできちんと0が取得できますし

ちなみにGetLastErrorも試してみましたが、「183:既に存在するファイルを作成するこ
とはできません」
と出たので、これは関係の無い別の箇所(おそらくCreateFile)のエラーコードのようで
す

この状況が引き起こされる原因がわかりません
何かわかる方がいましたらアドバイスをいただけないでしょうか
よろしくお願いします

Blue 2005/02/28(月) 00:38:59
解答ではありません。

題名の オーナードローリストボックスでListBox_AddStringが失敗する と
>int   nCnt;
>for(nCnt = 0; nCnt < MAX_SIZE; nCnt++)
>{
>   ListBox_AddItemData(hListBox,iCnt);
>}
で、ListBox_AddStringとListBox_AddItemDataと違うのですがどちらの質問ですか?
それと iCnt は nCnt ですか?

Blue 2005/02/28(月) 00:56:59
一応調べてみました。

WINDOWSX.H

#define ListBox_AddString(hwndCtl, lpsz)            ((int)(DWORD)SNDMSG
((hwndCtl), LB_ADDSTRING, 0L, (LPARAM)(LPCTSTR)(lpsz)))
#define ListBox_AddItemData(hwndCtl, data)          ((int)(DWORD)SNDMSG
((hwndCtl), LB_ADDSTRING, 0L, (LPARAM)(data)))

というわけなのでどちらも LB_ADDSTRINGで、マクロの2番目の引数は加する項目の文字
列へのポインタとなってそうです。

# iCntが何者かどうかわからないのでなんともいえませんが。

2005/02/28(月) 00:59:31
あ、失礼しました

ListBox_AddItemDataが正しいです
また、iCntはnCntの書き間違いです

int   nCnt;
for(nCnt = 0; nCnt < MAX_SIZE; nCnt++)
{
   ListBox_AddItemData(hListBox,nCnt);
}

こうですね

ListBox_AddStringもListBox_AddItemDataもLB_ADDSTRINGを送るので
つい混同してしまったようです
投稿前に何度も見直したんですが・・・

ツッコミどうもありがとうございました

2005/02/28(月) 01:02:28
と書いてる間にさらにレスが・・・
Blueさんフォローありがとうございます

また、iCntは上に書いたようにnCntの間違いでした

2005/02/28(月) 01:04:39
書いてから改めて見直したらまだミスが・・・

> ちなみにListBox_InsertStringでも試してもらいましたが、同じように
> nCnt==0の時だけエラーが発生したようです

ListBox_InsertItemDataですね・・・
もっとも中ではやっぱりどちらもLB_INSERTSTRINGを送っているので同じようなものです
が

何度も訂正すみませんでした

Blue 2005/02/28(月) 01:11:01
LB_ADDSTRINGでなにを追加したいのかわかりませんが、
文字列ポインタではなさそうな nCnt なのはやヴぁそうですね。
特に 0 のときはアクセスエラーとは起こるんじゃw

文字列の数値を設定するなら
int   nCnt;
char  szNum[ 8 ]; /* サイズはテキトw */
for(nCnt = 0; nCnt < MAX_SIZE; nCnt++)
{
   memset( szNum, 0x00, 8 * sizeof( char ) ); /* 文字列初期化 */
   sprintf( szNum, "%d", nCnt ); /* 文字列に変換 */
   ListBox_AddItemData(hListBox,szNum);
}
てなかんじなんですかねぇ。

2005/02/28(月) 10:35:39
ヘルプに

> If you create the list box with an owner-drawn style but without the 
LBS_HASSTRINGS style,
> the value of the lpsz parameter is stored as item data instead of the string 
it would otherwise point to.
> You can send the LB_GETITEMDATA and LB_SETITEMDATA messages to retrieve or 
modify the item data. 

とありますが、オーナードロースタイルを持ち、かつLBS_HASSTRINGSを持たないときは
LB_ADDSTRINGおよびLB_INSERTSTRINGのlParamには各項目にセットする
32bitのアイテムデータ(LB_SETITEMDATAやLB_GETITEMDATAで操作するデータ)
を設定するということではないのでしょうか?

実際に挿入された項目に対してLB_GETITEMDATAを送れば設定した数値が取得できますし

ちなみにリストボックスにはLBS_HASSTRINGSは持たせていません

それともわたしが間違えて解釈しているんでしょうか?

Blue 2005/02/28(月) 11:07:46
>とありますが、オーナードロースタイルを持ち、かつLBS_HASSTRINGSを持たないときは
>LB_ADDSTRINGおよびLB_INSERTSTRINGのlParamには各項目にセットする
という情報が、今までの文章で読み取れませんでした。(私の力不足です)

しらべたところ
http://homepage1.nifty.com/toro/dlw32api.html
のWebページで
>Listbox
>LBS_HASSTRINGS でないオーナードローのリスト ボックスは、LB_ADDSTRING等で任意の
>値を設定することができる。
> しかし、Windows XP 上では 0 等の値を使用すると正しくアイテムが格納されなくな
>る。
>※SP1 で修正されている。 
>(2002/9/27) 
だそうです。その人のPCはSP1あったってないのでしょうかね?

2005/02/28(月) 12:28:44
なるほど、WindowsXPにそんなバグがあったのですね
わたしのパソコンにはSP1が入っているのでバグが起こらなかったのかもしれません

現在、その報告をしてくれた人に確認中ですので、返事があり次第結果を報告します

情報どうもありがとうございました

2005/02/28(月) 21:46:15
[[解決]]
こんばんは

先ほどこの不具合が出た方から連絡がありまして、
SurvicePack2を適用したところ不具合が出なくなったということです

問題点はずばりその通りだったようですね

Blueさん、とても的確なアドバイス感謝です
どうもありがとうございました

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