Files
2026-04-29 17:10:47 +02:00

182 lines
6.3 KiB
C++

/*****************************************************************************/
/* TToolTip.cpp Copyright (c) Ladislav Zezula 2014 */
/*---------------------------------------------------------------------------*/
/* Implementation of TTooltip class */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
/* 16.03.14 1.00 Lad The first version of TToolTip.cpp */
/*****************************************************************************/
#include "FileTest.h"
//-----------------------------------------------------------------------------
// Tooltip implementation
TToolTip::TToolTip()
{
hWndToolTip = NULL;
szToolTipText = NULL;
cchTooltipText = 0x400;
};
TToolTip::~TToolTip()
{
Destroy();
}
BOOL TToolTip::Initialize(HINSTANCE hInst, HWND hWndParent)
{
// Sanity check
assert(hWndToolTip == NULL);
// Allocate buffer for constructing tooltip test
szToolTipText = (LPTSTR)HeapAlloc(GetProcessHeap(), 0, cchTooltipText * sizeof(TCHAR));
if(szToolTipText == NULL)
return FALSE;
// Create the tooltip window
hWndToolTip = CreateWindowEx(0,
TOOLTIPS_CLASS,
NULL,
WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hWndParent,
NULL,
hInst,
NULL);
if(hWndToolTip == NULL)
return FALSE;
// Initialize the tooltip window
SetWindowPos(hWndToolTip, HWND_TOPMOST,0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
SendMessage(hWndToolTip, TTM_SETMAXTIPWIDTH, 0, 300);
SendMessage(hWndToolTip, TTM_ACTIVATE, TRUE, 0);
return TRUE;
}
void TToolTip::Destroy()
{
if(hWndToolTip != NULL)
DestroyWindow(hWndToolTip);
hWndToolTip = NULL;
if(szToolTipText != NULL)
HeapFree(GetProcessHeap(), 0, szToolTipText);
szToolTipText = NULL;
}
//-----------------------------------------------------------------------------
// Adds a tooltip that will display user-friendly flags
BOOL TToolTip::AddToolTip(HWND hDlg, UINT nIDChild, TFlagInfo * pFlags)
{
return AddToolTipInternal(hDlg, nIDChild, LPSTR_TEXTCALLBACK, pFlags);
}
BOOL TToolTip::AddToolTip(HWND hDlg, UINT nIDChild, UINT nIDTip)
{
return AddToolTipInternal(hDlg, nIDChild, MAKEINTRESOURCE(nIDTip), NULL);
}
//-----------------------------------------------------------------------------
// Message handler
LRESULT TToolTip::HandleMessages(HWND /* hDlg */, UINT uMsg, WPARAM /* wParam */, LPARAM lParam, BOOL * pbHandled)
{
LPNMTTDISPINFO pTTDispInfo;
BOOL bHandled = FALSE;
if(uMsg == WM_NOTIFY)
{
// The message must be TTN_GETDISPINFO and the 'idFrom' must be a window handle
pTTDispInfo = (LPNMTTDISPINFO)lParam;
if(pTTDispInfo->hdr.code == TTN_GETDISPINFO && (pTTDispInfo->uFlags & TTF_IDISHWND) && pTTDispInfo->lParam != 0)
{
// Call the tooltip handler
OnGetTooltipText(pTTDispInfo);
bHandled = TRUE;
}
}
if(pbHandled != NULL)
*pbHandled = FALSE;
return 0;
}
//-----------------------------------------------------------------------------
// Protected functions
BOOL TToolTip::AddToolTipInternal(HWND hDlg, UINT nIDCtrl, LPCTSTR szTip, TFlagInfo * pFlags)
{
TTTOOLINFO ti;
TCHAR szClassName[0x80];
DWORD dwStyle;
HWND hWndChild;
BOOL bResult = FALSE;
// Only if we actually have a tooltip
if(hWndToolTip != NULL)
{
// If the child window is not valid, do nothing
hWndChild = GetDlgItem(hDlg, nIDCtrl);
if(hWndChild != NULL)
{
// If the child window is a static text without SS_NOTIFY,
// the tooltip would not activate. We need to set the SS_NOTIFY flag
GetClassName(hWndChild, szClassName, _countof(szClassName));
if(!_tcsicmp(szClassName, WC_STATIC))
{
dwStyle = GetWindowLong(hWndChild, GWL_STYLE);
if((dwStyle & SS_NOTIFY) == 0)
SetWindowLong(hWndChild, GWL_STYLE, dwStyle | SS_NOTIFY);
}
// Note: Make sure we put the size for COMCTL32.dll version 4.70
ZeroMemory(&ti, sizeof(TTTOOLINFO));
ti.cbSize = CCSIZEOF_STRUCT(TTTOOLINFO, lParam);
ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
ti.hwnd = hDlg;
ti.uId = (UINT_PTR)hWndChild;
ti.hinst = g_hInst;
ti.lpszText = (LPTSTR)szTip;
ti.lParam = (LPARAM)pFlags;
bResult = (BOOL)SendMessage(hWndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
}
}
return bResult;
}
void TToolTip::OnGetTooltipText(LPNMTTDISPINFO pTTDispInfo)
{
TFlagInfo * pFlags = (TFlagInfo *)pTTDispInfo->lParam;
TCHAR szWindowText[0x80];
DWORD dwValue32 = 0;
HWND hWndChild = (HWND)pTTDispInfo->hdr.idFrom;
// Only if the text buffer has been allocated
if(pFlags && szToolTipText)
{
// Reset the tooltip info to an empty string
szToolTipText[0] = 0;
// Retrieve the window text and convert it to 32-bit hexa value
GetWindowText(hWndChild, szWindowText, _countof(szWindowText));
if(Text2Hex32(szWindowText, &dwValue32) == ERROR_SUCCESS)
{
// Convert the flags to string
FlagsToString(pFlags, szToolTipText, cchTooltipText, dwValue32, true);
// Supply the text to the tooltip
pTTDispInfo->lpszText = szToolTipText;
pTTDispInfo->szText[0] = 0;
}
else
{
StringCchPrintf(pTTDispInfo->szText, _countof(pTTDispInfo->szText), _T("Error converting \"%s\" to 32-bit integer"), szWindowText);
}
}
}