-
Notifications
You must be signed in to change notification settings - Fork 78
/
TToolTip.cpp
181 lines (154 loc) · 6.26 KB
/
TToolTip.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*****************************************************************************/
/* 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(NULL,
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);
}
}
}