0

SendMessage関数を使用してリストボックスの内容を表示しようとしています。ただし、ボタンを押して以下のコードを実行すると、呼び出したときにコードに次のセグメンテーション違反が発生します

SendMessage(hwndLBox,LB_GETTEXT,k,(LPARAM)lBoxitems);

セグメンテーション違反(dbgheap.c):

extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
        const void * pUserData
        )
 {
        if (!pUserData)
            return FALSE;

        if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), FALSE))
            return FALSE;

        return HeapValidate( _crtheap, 0, pHdr(pUserData) );
}

このセグメンテーション違反を引き起こすコード:

            else if(LOWORD(wParam)==ID_BUTTON_CALC){

                int getLboxitems = SendMessage(hwndLBox,LB_GETCOUNT,NULL,NULL);

                char * lBoxitems = new char[getLboxitems];

                for(unsigned int k=0; k < getLboxitems; k++){
                        SendMessage(hwndLBox,LB_GETTEXT,k,(LPARAM)lBoxitems);
                        MessageBox(hwnd,lBoxitems,"Listbox says",NULL);
                }

                delete[] lBoxitems;
            }

Visual StudioBeta2011を使用してコードをコンパイルしています。

4

2 に答える 2

1

文字列にスペースを割り当てる必要があります。char * lBoxitems = new char[getLboxitems];リストにあるアイテムの数のサイズであるchar配列を割り当てます。以下は私が思うにうまくいくはずです:

else if(LOWORD(wParam)==ID_BUTTON_CALC)
{
    int getLboxitems = SendMessage(hwndLBox, LB_GETCOUNT, NULL, NULL);

    char ** lBoxitems = new char*[getLboxitems];

    for(unsigned int k = 0; k < getLboxitems; k++)
    {
        int textlength = SendMessage(control, LB_GETTEXTLEN, (WPARAM)k, NULL);
        lBoxitems[k] = new char[textlength + 1]; // +1 for null terminator
        SendMessage(hwndLBox, LB_GETTEXT, (WPARAM)k, (LPARAM)lBoxitems[k]);
        MessageBox(hwnd, lBoxitems[k], "Listbox says" , NULL);
    }
    for (unsigned int k = 0; k < getLboxitems; k++)
    {
        delete [] lBoxitems[k];
    }
    delete[] lBoxitems;
}

ただし、std::vector<std::vector<char>>またはを使用std::vector<std::string>する方が簡単です。

else if(LOWORD(wParam)==ID_BUTTON_CALC)
{
    int getLboxitems = SendMessage(hwndLBox, LB_GETCOUNT, NULL, NULL);

    std::vector<std::string> v(getLboxitems);

    for(unsigned int k = 0; k < getLboxitems; k++)
    {
        int textlength = SendMessage(control, LB_GETTEXTLEN, (WPARAM)k, NULL);
        v[k].resize(textlength + 1);
        std::string& buff = v[k];
        SendMessage(hwndLBox, LB_GETTEXT, (WPARAM)k, (LPARAM)&buff[0]);
        MessageBox(hwnd, v[k].c_str(), "Listbox says" , NULL);
    }
}
于 2012-06-30T04:44:02.690 に答える
0

私が見る2つのこと

  1. getLboxitemsが有効な値(つまり、<= 0ではない)または途方もなく大きいことを確認しましたか?

  2. この場合、配列を適切に使用しているとは思いません。getLboxitemsのサイズの動的サイズの配列を作成します。つまり、リストボックスに5つの項目がある場合、5文字の配列を効果的に作成します(想定しているchar*やchar[]ではありません)。この方法でアレイを作成する必要があります。

    // verify with MSDN that 255 is large enough
    char* lBoxitems[255] = new char[getLboxitems][255];
    for(unsigned int k=0; k < getLboxitems; k++) {
        SendMessage(hwndLBox, LB_GETTEXT, k, (LPARAM)(lBoxitems[k]));
        MessageBox(hwnd, lBoxitems[k], "Listbox says", NULL);
    }
    

テストされていないコードに注意してください。

編集:訂正してくれたJesseGoodに感謝します。

また、このメソッドはあまりC++-yではないことを指摘したいと思います。std::vector<std::string>2D配列の代わりに使用し、SendMessage()で使用される一時配列のみを使用することをお勧めします。

于 2012-06-30T04:24:26.907 に答える