1

我在选项卡控件的内容区域中有一个树视图(树视图是选项卡控件的兄弟)。当我删除树视图项目,添加新的树视图项目并选择其中之一时,树视图未正确绘制;新创建+选定项目上方的所有内容都是灰色的。有没有办法让树视图在删除和插入项目后正确地绘制所有内容?

更换物品前 更换物品后

观察:

  • 如果树视图项目足够少而没有出现滚动条,则树视图看起来不错。
  • 如果树视图旁边没有选项卡控件,则树视图看起来没问题。
  • 如果树视图是选项卡控件的子视图,则树视图看起来正常(但Tab键无法使用 GetNextDlgTabItem/IsDialogMessage 在选项卡控件和树视图之间导航)。
  • 如果在插入新节点后我没有在树视图中选择任何项目,那么树视图看起来不错。

当我将项目插入树中时,我调用 TreeView_InsertItem,然后调用 TreeView_SelectItem。完整的示例要点。在示例程序中,Ctrl+R加速器替换所有树节点并导致工件。

4

1 回答 1

1

你在这里有错误:

ACCEL accel[1]***; //change to accel[2]
accel[0].fVirt = FCONTROL | FVIRTKEY;
accel[0].key = 'R';
accel[0].cmd = IDM_REGENERATETREE;
accel[1].fVirt = FCONTROL | FVIRTKEY;
accel[1].key = 'S';
accel[1].cmd = IDM_SELECTRANDOM;
HACCEL haccel = CreateAcceleratorTable(accel, 2);

尝试保存以前的项目状态时会导致显示问题。如果previousStates从中删除,则不会出现显示问题addTreeItem。要正确保存状态,您可能需要 std::map 和每个树项的一些用户标识。至少你应该使用 std::vector 使它更容易理解。

为了获得更好的视觉效果,您可以添加TVS_LINESATROOT到 TreeView 和WS_CLIPCHILDREN主窗口。

编辑:

保存以前的项目状态不应该在addTreeItem. 例如,刚刚插入的新项目还没有子项,因此无法扩展。简化addTreeItem如下:

HTREEITEM addTreeItem(HWND htree, HTREEITEM par, HTREEITEM after, LPCTSTR str, LPARAM lp) 
{
    TVINSERTSTRUCT tvins;
    tvins.hParent = par;
    tvins.hInsertAfter = after;
    tvins.itemex.mask = TVIF_TEXT | TVIF_PARAM;
    tvins.itemex.pszText = const_cast<LPTSTR>(str);
    tvins.itemex.lParam = lp;
    HTREEITEM node = TreeView_InsertItem(htree, &tvins);
    return node; 
}

要保存以前的项目状态,每个项目应该有不同的 ID。正如在此示例中发生的那样,每个节点的项目名称都不同,我们可以将其用于 map。但是如果这是一个目录结构就行不通了,我们必须使用完整路径而不是节点名。

void RootWindow::RegenerateTree()
{
    if (!m_hwndTreeView) return;
    if (!IsWindow(m_hwndTreeView)) return;
    HWND hwnd = m_hwndTreeView;

    //this will stop treeview from updating after every insert
    SetWindowRedraw(hwnd, 0);

    std::map<std::wstring, UINT> state;
    const int maxtext = 260;
    wchar_t buf[maxtext];
    std::wstring selection;

    UINT count = TreeView_GetCount(hwnd);
    if (count)
    {
        for (HTREEITEM item = TreeView_GetRoot(hwnd); item; item = nextItem(hwnd, item))
        {
            TVITEM tv{ 0 };
            tv.mask = TVIF_TEXT | TVIF_STATE;
            tv.stateMask = TVIF_TEXT | TVIF_STATE;
            tv.cchTextMax = maxtext;
            tv.pszText = buf;
            tv.hItem = item;
            if (TreeView_GetItem(hwnd, &tv))
                state[buf] = TreeView_GetItemState(hwnd, item, 
                TVIS_SELECTED | TVIS_EXPANDED);
        }
    }
    TreeView_DeleteAllItems(hwnd);

    addTreeItem...
    addTreeItem...
    addTreeItem...

    //restore previous item state here:
    if (count)
    {
        for (HTREEITEM item = TreeView_GetRoot(hwnd); item; item = nextItem(hwnd, item))
        {
            TVITEM tvitem{ 0 };
            tvitem.hItem = item;
            tvitem.mask = TVIF_TEXT;
            tvitem.cchTextMax = maxtext;
            tvitem.pszText = buf;
            if (TreeView_GetItem(hwnd, &tvitem))
                TreeView_SetItemState(hwnd, item, state[buf], 
                TVIS_SELECTED | TVIS_EXPANDED);
        }
    }

    SetWindowRedraw(hwnd, 1);
}
于 2015-05-13T02:38:40.653 回答