TreeView - 获取所选节点

时间:2014-05-01 21:21:42

标签: c++ winapi

我可以填充树节点但我无法获取所选项目。在通知部分,您将看到我正在尝试调用TreeView_GetItem,但电视返回为null。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    NMHDR  *nmptr;
    HTREEITEM tvi;

    switch (message)
    {

        case WM_CREATE:
        {           
            RECT rc;            
            GetClientRect(hWnd, &rc);
            INITCOMMONCONTROLSEX icex;
            icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
            icex.dwICC  =  ICC_WIN95_CLASSES | ICC_BAR_CLASSES | ICC_DATE_CLASSES | ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES;
            InitCommonControlsEx(&icex);

            hTreeWin = CreateWindowEx(0,
                            WC_TREEVIEW,
                            TEXT("Tree View"),
                            WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES | TVS_HASBUTTONS |TVS_TRACKSELECT | TVS_LINESATROOT,
                            0, 
                            0, 
                            200,//rc.right, 
                            rc.bottom,
                            hWnd, 
                            (HMENU)IDM_TREE_WIN, 
                            hInst, 
                            NULL); 

            InitTreeViewImageLists(hTreeWin);

        }
        break;
        case WM_NOTIFY:
        {
            LPNMHDR lpnmh = (LPNMHDR) lParam;

            if( lpnmh->idFrom == IDM_TREE_WIN  )  // if this is our treeview control
            {
                switch( lpnmh->code )  // let us filter notifications
                {     
                    case TVN_SELCHANGED:
                        {                       
                            TVITEM tv;  
                            tv.mask = TVIF_PARAM;


                            TreeView_GetItem(hTreeWin, &tv);    
                            //tv is null
                            MessageBox(NULL,std::to_wstring(tv.lParam).c_str(), L"", MB_OK);
                        }
                        break;
                    default:
                        break;
                }
            }
        } 
        break;
        case WM_COMMAND:
            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            case IDM_OPEN_PST:
                TestPstStuff();
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    return 0;
}

以下是我填充Treeview的方法

HTREEITEM writeTreeView(const pstsdk::folder fi, HTREEITEM parentTV)
{
        HTREEITEM hPrev = (HTREEITEM)TVI_FIRST; 
    try
    {
        TVITEM tvi; 
        TVINSERTSTRUCT tvins; 
        HTREEITEM hPrevRootItem = NULL; 
        HTREEITEM hPrevLev2Item = NULL; 
        HTREEITEM hti; 
        tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;  

        std::wstring x = fi.get_name().c_str();

        tvi.pszText = (LPWSTR)x.c_str(); //text to display
        tvi.cchTextMax = sizeof(tvi.pszText)/sizeof(tvi.pszText[0]); 

        tvi.lParam = (LPARAM)fi.get_id(); 
        tvins.item = tvi; 
        tvins.hInsertAfter = parentTV; 
        tvins.hParent = parentTV;

        // Add the item to the tree-view control. 
        hPrev = (HTREEITEM)SendMessage(hTreeWin, TVM_INSERTITEM, 
            0, (LPARAM)(LPTVINSERTSTRUCT)&tvins); 

        if (fi.get_hierarchy_table().size() > 0)
        {
            for (pstsdk::folder::folder_iterator i = fi.sub_folder_begin(); i !=  fi.sub_folder_end(); ++i)
            {
                writeTreeView(*i, hPrev);
            }
        }
    }
    catch(exception e)
    {
        std::string _str = e.what();    
    }
    return hPrev;
}

1 个答案:

答案 0 :(得分:1)

收到TVN_SELCHANGED通知后,

lParam已经可用,因此您的代码需要看起来像

case TVN_SELCHANGED:
{   LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lParam;
    MessageBox(NULL,std::to_wstring(pnmtv->itemNew.lParam).c_str(), L"", MB_OK);
    break;
}