XTipComboBox - Display tooltips for combobox






4.47/5 (28 votes)
XTipComboBox implements a combobox with tooltips for the data items (both in the list box and in the edit box)
Introduction
XTipComboBox displays tooltips for a combobox, just like tooltips are displayed for a tree control whose items are too long to fit in tree control's client area. When a listbox item in combobox is too long to fit in the listbox, a tooltip will be displayed that allows viewing of complete text. Similarly, a tooltip is displayed when text in combo's edit box is too wide for edit box.Here is how the tooltips look - note that the tooltip colors will match what is being tooltipped:
Implementation Notes
CXTipComboBox
is derived from CComboBox, and implements one virtual function and four message handlers:
PreSubclassWindow()
- this virtual function allows us to create tooltip window, add combobox as its tool, and perform other initialization. Note use ofTTF_TRANSPARENT
. This flag tells tooltip control to forward mouse messages (including mouse clicks) to the parent window. In the case of the listbox, this will prevent twoCBN_SELENDOK
messages from being sent to the parent dialog.
OnCtlColor()
- This is not what you think. According to MSDN article HOWTO: Subclass CListBox and CEdit Inside of CComboBox (Q174667), this is actually recommended way of subclassing listbox of a combobox. We use this to subclass listbox only - for edit box, it is simpler to handle insideCXTipComboBox
.
OnMouseMove()
- This message handler catches mouse moves, and when mouse is inside combo client rect, tooltip will be activated.
OnTimer()
- A timer is used only when a tooltip is being displayed. When code inOnTimer()
detects that mouse is no longer inside client rect, tooltip is removed.
OnDestroy()
- Unsubclasses the listbox.
Note that nearly identical code is implemented for first four functions in XTipComboBox.cpp and XTipListBox.cpp.
Tooltip Notes
As mentioned above, tooltip is created inPreSubclassWindow()
: // create tooltip m_hWndToolTip = ::CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, m_hWnd, NULL, NULL, NULL); ASSERT(m_hWndToolTip); // initialize toolinfo struct memset(&m_ToolInfo, 0, sizeof(m_ToolInfo)); m_ToolInfo.cbSize = sizeof(m_ToolInfo); m_ToolInfo.uFlags = TTF_TRACK | TTF_TRANSPARENT; m_ToolInfo.hwnd = m_hWnd; // add combo box ::SendMessage(m_hWndToolTip, TTM_SETMAXTIPWIDTH, 0, SHRT_MAX); ::SendMessage(m_hWndToolTip, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &m_ToolInfo); ::SendMessage(m_hWndToolTip, TTM_SETTIPBKCOLOR, ::GetSysColor(COLOR_HIGHLIGHT), 0); ::SendMessage(m_hWndToolTip, TTM_SETTIPTEXTCOLOR, ::GetSysColor(COLOR_HIGHLIGHTTEXT), 0); // reduce top & bottom margins CRect rectMargins(0,-1,0,-1); ::SendMessage(m_hWndToolTip, TTM_SETMARGIN, 0, (LPARAM)&rectMargins); // set font CFont *pFont = GetFont(); ::SendMessage(m_hWndToolTip, WM_SETFONT, (WPARAM)(HFONT)*pFont, FALSE);In typical dialog box situations, you would need to use
RelayEvent()
along with LPSTR_TEXTCALLBACK
to pass tooltip text to tooltip control. Since we are dealing with two separate controls (edit box and list box) wrapped in one combobox control, it is easier to intercept mouse moves and position the tooltip ourselves. Inside OnMouseMove()
, we determine position of the mouse, get text underneath, and calculate whether text will fit inside client rect. If it won't fit, we display tooltip, using TTM_TRACKACTIVATE
message. Here we also set text and background colors for tooltip, depending on what is being tooltipped. Finally, a timer is used to keep track of when mouse moves outside client rect, so that tooltip will be removed.
How To Use
To integrate CXTipComboBox
into your app, you first need to add following files to your project:
- XTipComboBox.cpp
- XTipComboBox.h
- XTipListBox.cpp
- XTipListBox.h
Next, include header file XTipComboBox.h in appropriate project files (usually, dialog header files). Now you are ready to start using CXTipComboBox
. If you already have a dialog box with combobox controls, just replace CComboBox
with CXTipComboBox
in the dialog header file. There is no extra initialization you need to do.
Demo App
The XTipComboBoxTest.exe demo shows how to useCXTipComboBox
.
Revision History
Version 1.0 - 2003 June 30
- Initial public release.
Usage
This software is released into the public domain. You are free to use it in any way you like. If you modify it or extend it, please to consider posting new code here for everyone to share. This software is provided "as is" with no expressed or implied warranty. I accept no liability for any damage or loss of business that this software may cause.