Showing a balloon tip at a specific position, then removing it

Today's Little Program shows a balloon tip at a specific position, then manually removes it.

Start with our scratch program and make these changes:

#pragma comment(linker, \
    "\"/manifestdependency:type='Win32' "\
    "name='Microsoft.Windows.Common-Controls' "\
    "version='' "\
    "processorArchitecture='*' "\
    "publicKeyToken='6595b64144ccf1df' "\

HWND g_hwndTT;

OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
  g_hwndTT = CreateWindow(TOOLTIPS_CLASS, nullptr,
            0, 0, 0, 0, hwnd, nullptr, g_hinst, nullptr);
  g_ti.uFlags = TTF_TRACK;
  g_ti.hwnd = hwnd;
  g_ti.lpszText = TEXT("Hi there");
  SendMessage(g_hwndTT, TTM_ADDTOOL, 0, (LPARAM)&g_ti);

  return TRUE;

void OnChar(HWND hwnd, TCHAR ch, int cRepeat)
  POINT pt;
  switch (ch) {
  case TEXT(' '):
    if (GetCursorPos(&pt)) {
      SendMessage(g_hwndTT, TTM_TRACKPOSITION, 0, MAKELPARAM(pt.x, pt.y));
      SendMessage(g_hwndTT, TTM_TRACKACTIVATE, TRUE, (LPARAM)&g_ti);
  case 27: // ESCAPE
    SendMessage(g_hwndTT, TTM_TRACKACTIVATE, FALSE, 0);


When our main window is created, we also create a balloon-style tooltip and add a tracking tool. Normally, the tooltip control appears and disappears automatically, at a position of the tooltip's choosing. Tracking tooltips are managed manually, so you can specify exactly when and where they appear, and you also manually remove them from the screen. At startup, we add the tool but do not show the balloon tooltip yet.

When the user presses the space bar, we get the current cursor position and tell the tracking tooltip to appear at exactly that location, then we activate tracking mode. The result: The balloon tip appears, and the tip of the balloon points directly at the mouse cursor.

When the user presses the ESC key, we deactivate tracking mode, which removes the tooltip from the screen.

Comments (5)
  1. MV says:

    Why do tooltips disappear so quickly (especially in IE)?  I often can't read the entire thing before it disappears, and so I have to drift off and back on so it will re-appear.  

    [This doesn't really have anything to do with coding tracking tooltips, but at the risk of encouraging off-topic discussion: They are probably using the default timeouts. -Raymond]
  2. Joshua says:

    It lead to us completely reimplementing tooltips since there is no obvious way to change the timeout from .NET (there probably is a way but it was faster to reimplement tooltips than find it.) Turns out tracking tooltips are really easy to implement by hand.

  3. Myria says:

    Is having the common controls entry in your manifest enough to get the version 6 common controls DLL to load, or do you have to load the DLL somehow as well? I've only worked with manifests for msvc*.dll, which is its own different bundle of joy.

    Raymond, what is your feeling on TCHAR at this point? Windows 9x is long gone, so is there a reason to use TCHAR instead of WCHAR?

    [It depends on how your component is loaded. Search MSDN for "common controls manifst" for your options. I use TCHAR as a concession to people who have to maintain old code that is still ANSI-based. -Raymond]
  4. 12BitSlab says:

    @ Joshua — changing the timeout on tooltips from managed code is very easy.  The tooltips provide props to do that.  You are correct in that it is darn near impossible to control where the tooltips apear outside of some win32 interfacing.

  5. Joshua says:

    @12BitSlab: And I did indeed have to control where they ended up.

Comments are closed.

Skip to main content