Archived

This topic is now archived and is closed to further replies.

Fuzztrek

Tooltip help..

Recommended Posts

Fuzztrek    572
I''ve been making a little win32 application, and so far things have been going pretty well.. I have a little window and a menu with some options, one of them opening up a dialog box with lots of controls. I thought I should add some tooltips to these controls to make some of them more clear, so I searched both the "For Beginners" and "General Programming" forums, but found nothing that helped me. I searched google, but most of the sites that came up told how to use MFC tooltips. I found the tooltip control section at MSDN, however, and that helped a lot. I have a basic idea of how tooltips work, however so far everything I''ve tried doesn''t work. I have a tool tip class, which just creates a tooltip and adds it to a vector of HWND''s. Here is my "add" code:
void CToolTips::AddTip(HWND Main, HWND Owner, LPTSTR Text)
{
	INITCOMMONCONTROLSEX icex;

	icex.dwSize = sizeof(icex);
    icex.dwICC  = ICC_BAR_CLASSES;

	if(!InitCommonControlsEx(&icex))
		return;

	m_Tips.push_back(CreateWindow(TOOLTIPS_CLASS, TEXT(Text), WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT, 0, (HMENU)0, m_hInst, 0));



	TOOLINFO ti;

	ti.cbSize = sizeof(TOOLINFO);
	ti.uFlags = TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE;
	ti.hwnd = Owner;
	ti.uId = (UINT)Main;
	ti.hinst = m_hInst;
	ti.lpszText = LPSTR_TEXTCALLBACK;
	ti.rect.left = ti.rect.top = ti.rect.bottom = ti.rect.right = 0;

	if(!SendMessage(m_Tips.back(), TTM_ADDTOOL, 0, (LPARAM)&ti))
	{
		MessageBox(Owner, "Failed to create ToolTip", "Error", MB_ICONERROR | MB_OK);
		return;
	}

	SendMessage(m_Tips.back(), TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)&ti);
}
This is pretty much the exact same thing that is on MSDN. However, as far as I can tell, there is no place to put the tool tip text. I tried assigning "lpszText" to the text parameter, and that did work, however all of my tooltips appeared in the top-left corner of my screen. I added this update (tracking) function:
	void Update(LPARAM lParam)
	{
		if(m_Visible)
			for(std::vector<HWND>::iterator i = m_Tips.begin(); i < m_Tips.end(); i++)
				SendMessage(*i, TTM_TRACKPOSITION, 0, (LPARAM)MAKELPARAM(GET_X_LPARAM(lParam) + X_OFFSET,
				GET_Y_LPARAM(lParam) + Y_OFFSET));
	}
(Again.. the same thing off of MSDN) This made the tooltips move around, but they were always on and never went away, and ALL of them were on. I can''t figure out how to make them only appear for one control... Do I have to impliment the "visible" variable different, so each control has it''s own visibility status? Or is it something else? Sorry if I''ve been unclear.. I can provide more code if needed. Thanks in advance!

Share this post


Link to post
Share on other sites
Colin Jeanne    1114
quote:

If lpszText is set to LPSTR_TEXTCALLBACK, the control sends the TTN_GETDISPINFO notification message to the owner window to retrieve the text.


To grab the text, handle the TTN_GETDISPINFO. You might need to subclass the controls to do this or you could set this parameter to a char array which leads me to...

quote:

I tried assigning "lpszText" to the text parameter, and that did work


Can you be more specific? Were there error messages? Did functions fail?

quote:

all of my tooltips appeared in the top-left corner of my screen.


Try allowing the ToolTip to subclass the owner control by specifying TTF_SUBCLASS or relay messages to the ToolTip using TTM_RELAYEVENT.


Thanks Salsa!Colin Jeanne | Invader''s Realm
"I forgot I had the Scroll Lock key until a few weeks ago when some asshole program used it. It even used it right" - Conner McCloud

Share this post


Link to post
Share on other sites
Fuzztrek    572
Thanks for replying!

quote:
Original post by Invader X
quote:

If lpszText is set to LPSTR_TEXTCALLBACK, the control sends the TTN_GETDISPINFO notification message to the owner window to retrieve the text.


To grab the text, handle the TTN_GETDISPINFO. You might need to subclass the controls to do this or you could set this parameter to a char array which leads me to...


This clears some stuff up... I wasn''t sure where it was getting the text before.

quote:

quote:

I tried assigning "lpszText" to the text parameter, and that did work


Can you be more specific? Were there error messages? Did functions fail?


This did work, however:
quote:

quote:

all of my tooltips appeared in the top-left corner of my screen.


Try allowing the ToolTip to subclass the owner control by specifying TTF_SUBCLASS or relay messages to the ToolTip using TTM_RELAYEVENT.



I tried specifying TTF_SUBCLASS, but that didnt'' change anything.

I think I should be able to get it work if I figure out how to use TTN_GETDISPINFO. I looked it up, but I''m not sure how you check for it in WM_NOTIFY (and what to do with it afterwards.) I should be able to modify my class to work like that. Thanks again!

Share this post


Link to post
Share on other sites
Fuzztrek    572
I looked into the tooltip section more at MSDN, and found everything I needed I was a little confused at first, however after realizing that I could get the size of ANY control using GetClientRect, things became a lot clearer. I'll just post what I did for the archives:

My class is extremely simple. I have a vector of HWND's, an HINSTANCE variable. The control's HWND, and the text for the tool tip is sent to the "AddTip" function. Here, the tooltip window is created using "CreateWindow" and pushed onto a vector (which is resized in the beginning to hold the approximate amount of tips.) The window position is set, and then a TOOLINFO structure is filled out.

Finally, the RECT of the control is retrieved and an ADDTOOL message is sent. After all of this, everything seems to work!

Here is the code (EDIT: updated to be one function):


void AddTip(HINSTANCE hInst, HWND Owner, LPTSTR Text)
{
HWND tip = CreateWindow(TOOLTIPS_CLASS, TEXT(""), WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, 0, (HMENU)0, hInst, 0);

SetWindowPos(tip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

TOOLINFO ti;

ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_SUBCLASS;
ti.hwnd = Owner;
ti.uId = 0;
ti.hinst = hInst;
ti.lpszText = Text;

RECT rect;
GetClientRect(Owner, &rect);
ti.rect = rect;

SendMessage(tip, TTM_ADDTOOL, 0, (LPARAM)(LPTOOLINFO)&ti);
}


Thanks for pointing me in the right direction, Invader X! It helped a lot.

EDIT: I guess I don't need the vector afterall, since I don't need to grab the tooltip at all after the function exits.. So it doesn't even have to be a class!

[edited by - Fuzztrek on March 28, 2004 9:36:39 PM]

Share this post


Link to post
Share on other sites