Solved

TreeView tooltips with Win32 api (not mfc)

Posted on 2004-10-06
4
1,428 Views
Last Modified: 2013-12-03
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
Comment
Question by:ee-user
  • 2
  • 2
4 Comments
 
LVL 14

Expert Comment

by:RichieHindle
ID: 12281948
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
 

Author Comment

by:ee-user
ID: 12315667
strcpy(nmTip->pszText, str);
results in access error.

With a List control, the infotip shows up with:
nmTip->pszText = str;
0
 
LVL 14

Accepted Solution

by:
RichieHindle earned 125 total points
ID: 12316981
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
 

Author Comment

by:ee-user
ID: 12533307
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

Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question