First, I'm working in native C, using VS2019 -- no C++ -- so an answer that tells me to use some C++ function that hides everything from me will not be helpful.
OK, here's my situation:
I have a program using what is effectively a tracking tooltip (but it doesn't work if it actually has the TTF_TRACKING
style flag!). They pop up anywhere I want, when I want, and go away when I want. I can control the foreground/background colors, use the system tip icons, and even have a bold title line. I use newlines to make them multiline. All of that works great.
I would like to go one step further and actually convert them to custom draw. The documentation says that I should process the NM_CUSTOMDRAW
notifications.
Unfortunately, my program receives NO NOTIFICATIONS for the tool window. Ever.
I've put debug output in the WM_NOTIFY
handler, and even check in the program's message pump for any WM_NOTIFY
messages for any window being detected, but there are NONE.
When I send the TTM_ADDTOOL
message, I set the toolinfo.hwnd
member to the tooltip window's handle. If I change that to the owning window's handle, then the tips never display and I STILL never get WM_NOTIFY
messages.
I've tried adding the TTF_SUBCLASS
flag to the TOOLINFO
flags for TTM_ADDTOOL
, but that seems to have no effect on the behavior.
Basically, I create a 'normal' tooltip that is inactive. When I get a WM_MOUSEHOVER
over something on my screen that should have a tip, I send these messages to the tip to get it displayed in the correct location:
TTM_SETMARGIN
TTM_UPDATETIPTEXT
TTM_SETTITLE
TTM_SETTIPBKCOLOR
TTM_SETTIPTEXTCOLOR
TTM_TRACKACTIVATE
TTM_TRACKPOSITION
When I want to hide the tip, I send TTM_TRACKACTIVATE
again, but with the flag set to FALSE.
I started with the example that I was given a few years ago from my original question, and even with that code to create and add the tool, I get no WM_NOTIFY
messages. Ever.
The example only barely works, too. It uses TTF_SUBCLASS
, and the tip seems to appear at random locations, and even a single CLICK event causes the tip to stop displaying until the example is restarted.
I would prefer to skip the subclass and use TrackMouseEvent()
for the hover and leave events, and then send a TTM_POPUP
to display the tip when needed (and TTM_POP
to remove it later). If I make any of those changes, the example ceases to display any tip at all. Sigh.
Can anyone explain the precise requirements that I must meet so that my main program (the tip owner) receives notifications for the tooltip? I think that if I could actually get the notifications, I might be able to get everything else to work.
Before someone simply states:
Notification messages are sent to the window specified in the
TOOLINFO
structure when you add the tool to the tooltip.
Please be aware that statement is simply NOT [always] TRUE. I have verified that my main window's hwnd
is the same value that I am using in my TOOLINFO
struct whenever that struct is required by a TTM_
message, yet I NEVER receive WM_NOTIFY
messages in my main window's message loop. So there is more to this than that overly simplistic answer.
Can anyone direct me to some actual documentation about custom-drawn tool tips, if such a thing exists in any non-proprietary form? Otherwise, I may need to consider just creating a little popup window of my own to act like a tooltip instead, but without all of the bizarre (to me) quirks and inter-dependencies and what not.
EDIT OK, I've created a test project from Steven Engelhardt's sample code that may be downloaded from cdtip.zip and added some changes of my own. When the symbol _StevesChanges_
(first line in main.c) is defined, my code is included in the build. There are two strange (to me) differences between the behavior with my code and the original:
- If I don't use OPAQUE background mode, then the original tool tip text is still visible, despite the text/background being set the same in the WM_NOTIFY.
- With my changes compiled in, the tip only appears every other time that the mouse hovers. The WM_MOUSEHOVER event is received and does the same stuff, but only triggers the WM_NOTIFY messages on alternate calls.
Also, with the original code (my changes not included), if the tip is hidden because it expires, then it will never reappear, which is not useful. AND in the original code, the tip appears almost immediately, even when the mouse is moving, so the example is not particularly good.
EDIT 2
I think that what I'm asking is for information about dependencies and/or interactions that tooltips have on other parts of my program. For example, if I process WM_WINDOWPOSCHANGED and don't forward it to the default handler, then I will never receive WM_SIZE messages. When I changed the example to use DrawText() to measure and draw the tip text, other behaviors changed, too, like the original text showing through and even when the tip would display. I may be consuming a window message that I need to forward in order to make the tips work (in my actual production code). I can find nothing about any such interactions, but I need to know what they are. Or else I need much more detailed information about tooltip controls, the TOOLINFO structure and their interaction with Windows.
But, I think I'm going to give up on this. Three years of research into this (off and on) has yet to produce the desired information, so I'm not likely to find it now. I was just hoping to avoid creating my own custom tool tip window handler, but it seems that is the path I must follow. Unless someone is willing to share a working example of a native C project that includes a tool tip that is activated when the main program receives a WM_MOUSEHOVER and dismissed by a mouse move or click, and is custom drawn, then this question should remain unanswered.