0

lParam次のように、に文字列が格納された一連のアイテムをツリービューに追加しています。

TVITEM tvi = {sizeof(TVITEM)};
tvi.mask = TVIF_TEXT | TVIF_PARAM;
tvi.pszText = const_cast<char *> (txt0.c_str());  // Display text
tvi.cchTextMax = sizeof(tvi.pszText);
tvi.lParam = (LPARAM) add0.c_str();  // A file path string

TVINSERTSTRUCT tvis;
tvis.item = tvi;
tvis.hParent = hti0;  // Some parent node

TreeView_InsertItem(tvw_filelist_, &tvis);

それらをすべて追加し終えたら、戻ってチェックします(別の関数で):

TVITEM tvi = {sizeof(TVITEM)};
char buf[200];
tvi.pszText = buf;
tvi.cchTextMax = 200;
tvi.hItem = htiTemp;  // htiTemp is the current node in the iteration
tvi.mask = TVIF_TEXT | TVIF_PARAM;

// Retrieve; address is stored in lParam.
TreeView_GetItem(tvw_filelist_, &tvi);

char out[200];
strcpy(out, "Checking: PSZTEXT: ");
strcat(out, tvi.pszText);
strcat(out, ". LPARAM: ");
strcat(out, (const char *) tvi.lParam);

...そしてLPARAMは最後に追加されたアイテムの値にリセットされました。

したがって、one, two, three, four同様のlParam値のアイテムを追加すると、チェックした後、すべてlParamのアイテムにが含まれfourます。(時々、ごみの値があります。)

ここには明らかに問題があり、修正するのはおそらく本当に簡単ですが、数時間の実験の後、何が悪いのかを見つけることができません。ヘルプ!

4

2 に答える 2

3

tvi.lParam = (LPARAM) add0.c_str();これが問題です。tvi.lParamポインタ型です。

MSDNから:

LPARAMこのタイプは、WinDef.hで次のように宣言されています。typedefLONG_PTR LPARAM;

とは何add0ですか?ローカル変数だと思います。関数が戻ると、このadd0変数は分解tvi.lParamされ、文字列のインターバフを指します。add0これで、このインターバフが解放されるためtvi.lParam、ガベージを指します。

于 2012-11-09T05:27:04.763 に答える
0

にアドレスを保存していますtvi.lParam。これは文字列のアドレスですadd0

add0スコープ外になると、アドレスは無効になります。これが、異なる値が表示される理由です。

tvi.lParam常に利用可能なアドレスを割り当てる必要があります。文字列をグローバル変数またはクラスメンバー変数にします。

ここでも、ツリーノードごとに1つの文字列が必要になります。したがって、文字列の配列を維持する必要があります。文字列が1つしかない場合は、1、2、3、4の場合と同様に、同じアドレスの値が異なります。

ありがとう。

于 2012-11-09T05:31:13.863 に答える