0

So I was trying to create a simple tree view using the Win32 API and CommnoControls. I've created a simple window, and in its WM_CREATE event, I've done the following:

HWND treeView = CreateWindowA(WC_TREEVIEWA, NULL, WS_VISIBLE | WS_CHILD, 10, 10,
        200, 500, window->info, (HMENU)1, GetModuleHandleA(NULL), NULL);

TVITEMA item = {0};
item.pszText = "My Item";

TVINSERTSTRUCTA insertStruct = {0};
insertStruct.hParent = NULL;
insertStruct.hInsertAfter = TVI_LAST;
insertStruct.item = item;
SendMessageA(treeView, TVM_INSERTITEMA, 0, &insertStruct);

The tree view does appear on the window, however the item (My Item) doesn't appear in it.

Is there anything else I need to do in order for it to appear? Maybe initialize something else? I tried to look in CommonControl's documentation but I didn't find anything else that would make sence to use... What am I doing wrong here?

aviad1
  • 354
  • 1
  • 10
  • 2
    If you want to insert a root item, use `TVI_ROOT` as opposed to `TVI_LAST`. More importantly, the [TVITEMA](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tvitema) structure has a `mask` field that's required to hold a bitmask of item values you want to set (`TVIF_TEXT`). – IInspectable May 12 '20 at 21:08
  • And, although there's sentimental value in supporting Windows 95, there's [Unicode in the Windows API](https://learn.microsoft.com/en-us/windows/win32/intl/unicode-in-the-windows-api), and has been for decades. – IInspectable May 12 '20 at 21:13
  • @IInspectable Thanks! It seems to work. I already know about unicode in WINAPI btw, I just used the ascii functions for a test. I have another question tho - let's say that I want to add a child item to "My Item" - how can I do that? I tried putting item.hItem in the other item's TVINSERTSTRUCT in the hParent property, but that adds the item ot the root... – aviad1 May 12 '20 at 21:19
  • 1
    [TVM_INSERTITEM](https://learn.microsoft.com/en-us/windows/win32/controls/tvm-insertitem) returns a handle to the tree item just inserted. Use that as the `hParent` value for your child item. – IInspectable May 12 '20 at 21:23
  • @IInspectable Thanks a lot! Is there a way to have a little '+' sign asside the parent item? It seems a little weird having to double-click it in order to expand it – aviad1 May 12 '20 at 21:28
  • @aviad1 add the [`TVS_HASBUTTONS`](https://learn.microsoft.com/en-us/windows/win32/controls/tree-view-control-window-styles) style when creating the TreeView: "*Displays plus (+) and minus (-) buttons next to parent items. The user clicks the buttons to expand or collapse a parent item's list of child items. To include buttons with items at the root of the tree view, TVS_LINESATROOT must also be specified.*". Read [About Tree-View Controls](https://learn.microsoft.com/en-us/windows/win32/controls/tree-view-controls). – Remy Lebeau May 12 '20 at 21:34

1 Answers1

1

Windows does not know that you provided text for the item because you failed to include TVIF_TEXT in the items mask member:

HWND treeView = CreateWindowA(WC_TREEVIEWA, NULL, WS_VISIBLE | WS_CHILD | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT, 10, 10,
        200, 500, window->info, (HMENU)1, GetModuleHandleA(NULL), NULL);


HTREEITEM hItem;
TVINSERTSTRUCTA insertStruct = {0};
TVITEMA*pItem = &insertStruct.item;
insertStruct.hParent = NULL;
insertStruct.hInsertAfter = TVI_ROOT;

pItem->mask = TVIF_TEXT;
pItem->pszText = "My Item";
hItem = (HTREEITEM) SendMessageA(treeView, TVM_INSERTITEMA, 0, (LPARAM) &insertStruct);

if (hItem)
{
    insertStruct.hParent = hItem;
    pItem->pszText = "A Child";
    hItem = (HTREEITEM) SendMessageA(treeView, TVM_INSERTITEMA, 0, (LPARAM) &insertStruct);
    if (hItem) SendMessage(treeView, TVM_ENSUREVISIBLE, 0, (LPARAM) hItem);
}

Use the line and button TVS_* styles to control how items are displayed.

Anders
  • 97,548
  • 12
  • 110
  • 164