6

このスレッドを見て、助けようとしてくれたすべての人に感謝することから始めたいと思います.

インターネットを検索しましたが、文字列変数のテキストと同じラベル テキストを持つツリー ビュー ノードを選択する例が見つかりませんでした。

MSDN でメッセージ TVM_GETIEARCHSTRING を見つけましたが、それを使用して問題を解決できるかどうかはわかりません。できたとしても、まだ使い方がわかりません。

データベースからのテキストを保持する文字列変数があります。プログラムがロードされると、ツリー ビューには同じテキストが選択されたノードが表示されます。

これをコーディングする方法さえわからないので、いくつかの指示またはコードスニペットを手伝ってください。

私は Windows XP 上の MS Visual Studio Express 2008 で、純粋な WIN32 API を使用して C++ で作業しています。

これですべてです。もう一度、助けようとするすべての人に感謝します。どうもありがとうございました!

編集:

どちらの回答も私にとっては良いのですが、両方をマークする方法がわかりません。このサイトでは 1 つの回答しか受け入れられないようです。

二人が私を助けるために投資したすべての仕事を無視することはできなかったので、少なくとも彼の解決策が私にとっても受け入れられることを公式に述べることによって、ジョナサンに返済しようとするためにこれを書きます。ソリューションは私のコーディング スタイルにより適しています。また、両方の回答に賛成します。

4

2 に答える 2

6

ツリービュー コントロールは、ラベルを検索するための API を提供しません。アイテムを手動でトラバースし、それらを文字列と比較する必要があります。

ツリービューが 1 レベル以上の深さである場合は、アイテムをトラバースする方法 (深さ優先または幅優先) を決定する必要があります。同じラベルのアイテムが複数ある場合、これらの戦略は異なるアイテムを返す可能性があります。

実装は次のようになります。

// Helper function to return the label of a treeview item
std::wstring GetItemText( HWND hwndTV, HTREEITEM htItem )
{
    static const size_t maxLen = 128;
    WCHAR buffer[ maxLen + 1 ];

    TVITEMW tvi = { 0 };
    tvi.hItem = htItem;         // Treeview item to query
    tvi.mask = TVIF_TEXT;       // Request text only
    tvi.cchTextMax = maxLen;
    tvi.pszText = &buffer[ 0 ];
    if ( TreeView_GetItem( hwndTV, &tvi ) )
    {
        return std::wstring( tvi.pszText );
    }
    else
    {
        return std::wstring();
    }
}

ここで、実際のトラバーサルが行われます。この関数は、アイテムが検索できなくなるか一致するアイテムが見つかるまで、再帰的に呼び出されます。この実装では、大文字と小文字を区別する比較 ( wstring::operator==( const wstring& )) を使用します。別の述語が必要な場合は、必要に応じて実装を変更する必要があります。

HTREEITEM FindItemDepthFirstImpl( HWND hwndTV, HTREEITEM htStart, const std::wstring& itemText )
{
    HTREEITEM htItemMatch = NULL;

    HTREEITEM htItemCurrent = htStart;
    // Iterate over items until there are no more items or we found a match
    while ( htItemCurrent != NULL && htItemMatch == NULL )
    {
        if ( GetItemText( hwndTV, htItemCurrent ) == itemText )
        {
            htItemMatch = htItemCurrent;
        }
        else
        {
            // Traverse into child items
            htItemMatch = FindItemDepthFirstImpl( hwndTV, TreeView_GetChild( hwndTV, htItemCurrent ), itemText );
        }
        htItemCurrent = TreeView_GetNextSibling( hwndTV, htItemCurrent );
    }

    return htItemMatch;
}

次の関数は再帰をラップし、ルート要素を開始点として渡します。これは、コードで呼び出す関数です。HTREEITEM見つかった場合は を返し、NULLそうでない場合は を返します。

HTREEITEM FindItem( HWND hwndTV, const std::wstring& itemText )
{
    HTREEITEM htiRoot = TreeView_GetRoot( hwndTV );
    return FindItemDepthFirstImpl( hwndTV, htiRoot, itemText );
}
于 2013-07-21T20:42:50.713 に答える