Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1573
  • Last Modified:

TreeView tooltips with Win32 api (not mfc)

I'm attempting to get the ToolTips for a TreeView to work. I was able to intercept a message when the mouse hovers over the TreeView item, but I didn't know what to do next.
 
case WM_NOTIFY:
  pnmhdr = (LPNMHDR) lParam;
  // TreeView
  if (pnmhdr->hwndFrom == hWndTree) {
    if (pnmhdr->code == TVN_SELCHANGED || pnmhdr->code == TVN_KEYDOWN) {
      LoadDocument(lParam);
    }
    else if (code == TVN_GETINFOTIP) {  // Gets here
      NMLVGETINFOTIP* nmTip = (NMLVGETINFOTIP*)lParam;
      nmTip.pszText = greeting;  // set to "Hello"
      nmTip.cchTextMax = 20;
//      SendMessageA(????????????);
      }
  }
  break;// WM_NOTIFY
 
Once the TVN_GETINFOTIP message is handled, what next?  I was trying to just put up a "Hello" message at first. I've gotten something similar to work with MFC ListControl, but want to use native Win32 api calls.
0
ee-user
Asked:
ee-user
  • 2
  • 2
1 Solution
 
RichieHindleCommented:
The problem is this line:

   nmTip.pszText = greeting;  // set to "Hello"

nmTip.pszText is a pointer to a buffer that you should copy your new string into,
whereas all you're doing is making the pointer point elsewhere, which has no effect.
You need to do this instead:

   strcpy(nmTip.pszText, greeting);
0
 
ee-userAuthor Commented:
strcpy(nmTip->pszText, str);
results in access error.

With a List control, the infotip shows up with:
nmTip->pszText = str;
0
 
RichieHindleCommented:
Sorry, I got that completely wrong.  The real problem is here:

NMLVGETINFOTIP* nmTip = (NMLVGETINFOTIP*)lParam;

You're using NMLVGETINFOTIP (ListView) rather than NMTVGETINFOTIP (TreeView).  Change the 'L's to 'T's and you should see it working.

Here's a complete working sample:

/* treeview.c - compile with cl treeview.c -link user32.lib comctl32.lib */

#define STRICT
#include <windows.h>
#include <commctrl.h>
#include <string.h>

HWND g_mainWnd = NULL;
HWND g_treeWnd = NULL;
HANDLE g_hInst = NULL;

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
    WNDCLASS wc;
    MSG msg;
    INITCOMMONCONTROLSEX iccex;
   
    g_hInst = hInstance;

    iccex.dwSize = sizeof(iccex);
    iccex.dwICC = ICC_WIN95_CLASSES ;
    InitCommonControlsEx(&iccex);
   
    memset(&wc, '\0', sizeof(wc));
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.hInstance   = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor  = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszClassName = "EE_TreeViewExample";
    RegisterClass(&wc);

    g_mainWnd = CreateWindowEx(0, "EE_TreeViewExample", "TreeView Example",
                               WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,  0, CW_USEDEFAULT, 0,
                               NULL, NULL, hInstance, NULL);
    ShowWindow(g_mainWnd, SW_SHOW);
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
   
    return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    TVITEM tvi;
    TVINSERTSTRUCT tvins;
    LPNMHDR pnmhdr;
    char debugMessage[1000];
   
    switch (uMsg)
    {
    case WM_CREATE:
        g_treeWnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
                                   WS_CHILD | WS_VISIBLE | TVS_INFOTIP,
                                   0, 0, 10, 10, hWnd, NULL, g_hInst, 0);
        memset(&tvi, '\0', sizeof(tvi));
        tvi.mask = TVIF_TEXT;
        tvi.pszText = "Hello world";
        tvi.cchTextMax = lstrlen(tvi.pszText);
        tvins.item = tvi;
        tvins.hInsertAfter = NULL;
        tvins.hParent = TVI_ROOT;
        SendMessage(g_treeWnd, TVM_INSERTITEM, 0, (LPARAM) (LPTVINSERTSTRUCT) &tvins);
        break;

    case WM_SIZE:
        MoveWindow(g_treeWnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
        break;

    case WM_NOTIFY:
        pnmhdr = (LPNMHDR) lParam;
        if (pnmhdr->hwndFrom == g_treeWnd && pnmhdr->code == TVN_GETINFOTIP)
        {
            NMTVGETINFOTIP* nmTip = (NMTVGETINFOTIP*)lParam;
            nmTip->pszText = "Hello";
            nmTip->cchTextMax = 5;
        }
       
        break;
     
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
   
    default:
        return (DefWindowProc(hWnd, uMsg, wParam, lParam));
    }
   
    return 0;
}
0
 
ee-userAuthor Commented:
THANKS!

Sorry to be slow checking your answer ... and realizing my error with using "LV" rather than "TV". That cleared up everything :-)

One of those "forehead, meet palm" blunders on my part :-(
0

Featured Post

Restore individual SQL databases with ease

Veeam Explorer for Microsoft SQL Server delivers an easy-to-use, wizard-driven interface for restoring your databases from a backup. No expert SQL background required. Web interface provides a complete view of all available SQL databases to simplify the recovery of lost database

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now