user2868331
user2868331

Reputation: 333

Win32 Creating a TreeView

I downloaded a very basic sample Win32 application and want to add a tree view to it. Here is my WinMain at the moment.

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = NULL;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = NULL;

    if(!RegisterClassEx(&wc)) {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "My Window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL) {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&Msg, NULL, 0, 0) > 0) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

    return Msg.wParam;
}

It works like a normal window.

I have read a lot of pages on creating tree views, but it simply isn't obvious to a noob like me. I changed my class in the CreateWindowEx function to be WC_TREEVIEW, so my WinMain now looks like this:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = NULL;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = NULL;

    /*if(!RegisterClassEx(&wc)) {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }*/

    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        /*g_szClassName*/WC_TREEVIEW,
        "My Window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL) {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&Msg, NULL, 0, 0) > 0) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

    return Msg.wParam;
}

The problem is now that, the window doesn't load in my Windows theme, the close button looks different. Also, my menu does not show up.

Here is the code to create the Tree View (Tree View does not show up):

struct treeView {
    HWND hwnd;
    TV_INSERTSTRUCT insert;
    HTREEITEM parent;
    HTREEITEM before;
    HTREEITEM root;
};

case WM_CREATE:
{
    struct treeView resourcesTreeView;

    resourcesTreeView.hwnd = GetDlgItem(hwnd, ID_RESOURCES_TREE_VIEW);
    resourcesTreeView.insert.hParent = NULL;
    resourcesTreeView.insert.hInsertAfter = TVI_ROOT;
    resourcesTreeView.insert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
resourcesTreeView.insert.item.pszText = "Parent";
    resourcesTreeView.insert.item.iImage = 0;
    resourcesTreeView.insert.item.iSelectedImage = 1;
    resourcesTreeView.parent = (HTREEITEM)SendDlgItemMessage(hwnd, ID_RESOURCES_TREE_VIEW, TVM_INSERTITEM, 0, (LPARAM)&resourcesTreeView.insert);
    resourcesTreeView.root = resourcesTreeView.parent;
    resourcesTreeView.before = resourcesTreeView.parent;
    UpdateWindow(hwnd);
}

I have made sure to include the:

case WM_INITDIALOG:
{
    /*INITCOMMONCONTROLSEX icc;
    icc.dwSize = sizeof(icc);
    icc.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&icc);*/
    InitCommonControls();
}

Upvotes: 3

Views: 5005

Answers (1)

Jonathan Potter
Jonathan Potter

Reputation: 37182

WM_INITDIALOG is only sent to dialogs, but you are creating your windows manually. You should put the call to InitCommonControls() in your WinMain() function before you try to create the tree control.

Controls like trees don't work well as top-level windows which is what you're trying to do. Put your window class back how it was, so that you have a working window, and then add the following after the call to ShowWindow():

RECT rc;
GetClientRect(hwnd, &rc);

HWND hwndTree = CreateWindowEx(
    WS_EX_CLIENTEDGE,
    WC_TREEVIEW,
    0,
    WS_CHILD | WS_VISIBLE,
    0, 0, rc.right, rc.bottom,
    hwnd, NULL, hInstance, NULL);

That should give you a tree control as a child of your top-level window. You can then start playing around with adding items to it by sending messages to hwndTree.

Upvotes: 3

Related Questions