1c2c66affSColin Finck /*
2c2c66affSColin Finck * Tool tip control
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 1998, 1999 Eric Kohl
5c2c66affSColin Finck * Copyright 2004 Robert Shearman
6c2c66affSColin Finck *
7c2c66affSColin Finck * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck * License as published by the Free Software Foundation; either
10c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck *
12c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15c2c66affSColin Finck * Lesser General Public License for more details.
16c2c66affSColin Finck *
17c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck *
21c2c66affSColin Finck * NOTES
22c2c66affSColin Finck *
23c2c66affSColin Finck * This code was audited for completeness against the documented features
24c2c66affSColin Finck * of Comctl32.dll version 6.0 on Sep. 08, 2004, by Robert Shearman.
25c2c66affSColin Finck *
26c2c66affSColin Finck * Unless otherwise noted, we believe this code to be complete, as per
27c2c66affSColin Finck * the specification mentioned above.
28c2c66affSColin Finck * If you discover missing features or bugs please note them below.
29c2c66affSColin Finck *
30c2c66affSColin Finck * TODO:
31c2c66affSColin Finck * - Custom draw support.
32c2c66affSColin Finck * - Animation.
33c2c66affSColin Finck * - Links.
34c2c66affSColin Finck * - Messages:
35c2c66affSColin Finck * o TTM_ADJUSTRECT
36c2c66affSColin Finck * o TTM_GETTITLEA
37c2c66affSColin Finck * o TTM_GETTTILEW
38c2c66affSColin Finck * o TTM_POPUP
39c2c66affSColin Finck * - Styles:
40c2c66affSColin Finck * o TTS_NOANIMATE
41c2c66affSColin Finck * o TTS_NOFADE
42c2c66affSColin Finck * o TTS_CLOSE
43c2c66affSColin Finck *
44c2c66affSColin Finck * Testing:
45c2c66affSColin Finck * - Run tests using Waite Group Windows95 API Bible Volume 2.
46c2c66affSColin Finck * The second cdrom (chapter 3) contains executables activate.exe,
47c2c66affSColin Finck * curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe,
48c2c66affSColin Finck * hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe.
49c2c66affSColin Finck *
50c2c66affSColin Finck * Timer logic.
51c2c66affSColin Finck *
52c2c66affSColin Finck * One important point to remember is that tools don't necessarily get
53c2c66affSColin Finck * a WM_MOUSEMOVE once the cursor leaves the tool, an example is when
54c2c66affSColin Finck * a tool sets TTF_IDISHWND (i.e. an entire window is a tool) because
55c2c66affSColin Finck * here WM_MOUSEMOVEs only get sent when the cursor is inside the
56c2c66affSColin Finck * client area. Therefore the only reliable way to know that the
57c2c66affSColin Finck * cursor has left a tool is to keep a timer running and check the
58c2c66affSColin Finck * position every time it expires. This is the role of timer
59c2c66affSColin Finck * ID_TIMERLEAVE.
60c2c66affSColin Finck *
61c2c66affSColin Finck *
62c2c66affSColin Finck * On entering a tool (detected in a relayed WM_MOUSEMOVE) we start
63c2c66affSColin Finck * ID_TIMERSHOW, if this times out and we're still in the tool we show
64c2c66affSColin Finck * the tip. On showing a tip we start both ID_TIMERPOP and
65c2c66affSColin Finck * ID_TIMERLEAVE. On hiding a tooltip we kill ID_TIMERPOP.
66c2c66affSColin Finck * ID_TIMERPOP is restarted on every relayed WM_MOUSEMOVE. If
67c2c66affSColin Finck * ID_TIMERPOP expires the tool is hidden and ID_TIMERPOP is killed.
68c2c66affSColin Finck * ID_TIMERLEAVE remains running - this is important as we need to
69c2c66affSColin Finck * determine when the cursor leaves the tool.
70c2c66affSColin Finck *
71c2c66affSColin Finck * When ID_TIMERLEAVE expires or on a relayed WM_MOUSEMOVE if we're
72c2c66affSColin Finck * still in the tool do nothing (apart from restart ID_TIMERPOP if
73c2c66affSColin Finck * this is a WM_MOUSEMOVE) (ID_TIMERLEAVE remains running). If we've
74c2c66affSColin Finck * left the tool and entered another one then hide the tip and start
75c2c66affSColin Finck * ID_TIMERSHOW with time ReshowTime and kill ID_TIMERLEAVE. If we're
76c2c66affSColin Finck * outside all tools hide the tip and kill ID_TIMERLEAVE. On Relayed
77c2c66affSColin Finck * mouse button messages hide the tip but leave ID_TIMERLEAVE running,
78c2c66affSColin Finck * this again will let us keep track of when the cursor leaves the
79c2c66affSColin Finck * tool.
80c2c66affSColin Finck *
81c2c66affSColin Finck *
82c2c66affSColin Finck * infoPtr->nTool is the tool the mouse was on on the last relayed MM
83c2c66affSColin Finck * or timer expiry or -1 if the mouse was not on a tool.
84c2c66affSColin Finck *
85c2c66affSColin Finck * infoPtr->nCurrentTool is the tool for which the tip is currently
86c2c66affSColin Finck * displaying text for or -1 if the tip is not shown. Actually this
87c2c66affSColin Finck * will only ever be infoPtr-nTool or -1, so it could be changed to a
88c2c66affSColin Finck * BOOL.
89c2c66affSColin Finck *
90c2c66affSColin Finck */
91c2c66affSColin Finck
92c2c66affSColin Finck
93b3fb8555SGiannis Adamopoulos
94b3fb8555SGiannis Adamopoulos #include <stdarg.h>
95b3fb8555SGiannis Adamopoulos #include <string.h>
96*0707475fSJustin Miller #include <stdlib.h>
97b3fb8555SGiannis Adamopoulos
98b3fb8555SGiannis Adamopoulos #include "windef.h"
99b3fb8555SGiannis Adamopoulos #include "winbase.h"
100b3fb8555SGiannis Adamopoulos #include "wingdi.h"
101b3fb8555SGiannis Adamopoulos #include "winuser.h"
102b3fb8555SGiannis Adamopoulos #include "winnls.h"
103b3fb8555SGiannis Adamopoulos #include "commctrl.h"
104b3fb8555SGiannis Adamopoulos #include "comctl32.h"
105b3fb8555SGiannis Adamopoulos #include "wine/debug.h"
106c2c66affSColin Finck
107c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(tooltips);
108c2c66affSColin Finck
109c2c66affSColin Finck static HICON hTooltipIcons[TTI_ERROR+1];
110c2c66affSColin Finck
111c2c66affSColin Finck typedef struct
112c2c66affSColin Finck {
113c2c66affSColin Finck UINT uFlags;
114c2c66affSColin Finck UINT uInternalFlags;
115c2c66affSColin Finck HWND hwnd;
116c2c66affSColin Finck BOOL bNotifyUnicode;
117c2c66affSColin Finck UINT_PTR uId;
118c2c66affSColin Finck RECT rect;
119c2c66affSColin Finck HINSTANCE hinst;
120c2c66affSColin Finck LPWSTR lpszText;
121c2c66affSColin Finck LPARAM lParam;
122c2c66affSColin Finck } TTTOOL_INFO;
123c2c66affSColin Finck
124c2c66affSColin Finck
125c2c66affSColin Finck typedef struct
126c2c66affSColin Finck {
127c2c66affSColin Finck HWND hwndSelf;
128c2c66affSColin Finck WCHAR szTipText[INFOTIPSIZE];
129c2c66affSColin Finck BOOL bActive;
130c2c66affSColin Finck BOOL bTrackActive;
131c2c66affSColin Finck UINT uNumTools;
132c2c66affSColin Finck COLORREF clrBk;
133c2c66affSColin Finck COLORREF clrText;
134c2c66affSColin Finck HFONT hFont;
135c2c66affSColin Finck HFONT hTitleFont;
136c2c66affSColin Finck INT xTrackPos;
137c2c66affSColin Finck INT yTrackPos;
138c2c66affSColin Finck INT nMaxTipWidth;
139c2c66affSColin Finck INT nTool; /* tool that mouse was on on last relayed mouse move */
140c2c66affSColin Finck INT nCurrentTool;
141c2c66affSColin Finck INT nTrackTool;
142c2c66affSColin Finck INT nReshowTime;
143c2c66affSColin Finck INT nAutoPopTime;
144c2c66affSColin Finck INT nInitialTime;
145c2c66affSColin Finck RECT rcMargin;
146c2c66affSColin Finck BOOL bToolBelow;
147c2c66affSColin Finck LPWSTR pszTitle;
148c2c66affSColin Finck HICON hTitleIcon;
149c2c66affSColin Finck
150c2c66affSColin Finck TTTOOL_INFO *tools;
151c2c66affSColin Finck } TOOLTIPS_INFO;
152c2c66affSColin Finck
153c2c66affSColin Finck #define ID_TIMERSHOW 1 /* show delay timer */
154c2c66affSColin Finck #define ID_TIMERPOP 2 /* auto pop timer */
155c2c66affSColin Finck #define ID_TIMERLEAVE 3 /* tool leave timer */
156c2c66affSColin Finck
157c2c66affSColin Finck
158c2c66affSColin Finck #define TOOLTIPS_GetInfoPtr(hWindow) ((TOOLTIPS_INFO *)GetWindowLongPtrW (hWindow, 0))
159c2c66affSColin Finck
160c2c66affSColin Finck /* offsets from window edge to start of text */
161c2c66affSColin Finck #define NORMAL_TEXT_MARGIN 2
162c2c66affSColin Finck #define BALLOON_TEXT_MARGIN (NORMAL_TEXT_MARGIN+8)
163c2c66affSColin Finck /* value used for CreateRoundRectRgn that specifies how much
164c2c66affSColin Finck * each corner is curved */
1653e46a867SCarl J. Bialorucki #ifdef __REACTOS__
1663e46a867SCarl J. Bialorucki #define BALLOON_ROUNDEDNESS 16
1673e46a867SCarl J. Bialorucki #define BALLOON_STEMHEIGHT 18
1683e46a867SCarl J. Bialorucki #define BALLOON_STEMWIDTH 18
1693e46a867SCarl J. Bialorucki #define BALLOON_STEMINDENT 16
1703e46a867SCarl J. Bialorucki #else
171c2c66affSColin Finck #define BALLOON_ROUNDEDNESS 20
172c2c66affSColin Finck #define BALLOON_STEMHEIGHT 13
173c2c66affSColin Finck #define BALLOON_STEMWIDTH 10
174c2c66affSColin Finck #define BALLOON_STEMINDENT 20
1753e46a867SCarl J. Bialorucki #endif // __REACTOS__
176c2c66affSColin Finck
177c2c66affSColin Finck #define BALLOON_ICON_TITLE_SPACING 8 /* horizontal spacing between icon and title */
178c2c66affSColin Finck #define BALLOON_TITLE_TEXT_SPACING 8 /* vertical spacing between icon/title and main text */
179c2c66affSColin Finck #define ICON_HEIGHT 16
180c2c66affSColin Finck #define ICON_WIDTH 16
181c2c66affSColin Finck
182c2c66affSColin Finck #define MAX_TEXT_SIZE_A 80 /* maximum retrieving text size by ANSI message */
183c2c66affSColin Finck
184c2c66affSColin Finck static LRESULT CALLBACK
185c2c66affSColin Finck TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uId, DWORD_PTR dwRef);
186c2c66affSColin Finck
187c2c66affSColin Finck static inline UINT_PTR
TOOLTIPS_GetTitleIconIndex(HICON hIcon)188c2c66affSColin Finck TOOLTIPS_GetTitleIconIndex(HICON hIcon)
189c2c66affSColin Finck {
190c2c66affSColin Finck UINT i;
191c2c66affSColin Finck for (i = 0; i <= TTI_ERROR; i++)
192c2c66affSColin Finck if (hTooltipIcons[i] == hIcon)
193c2c66affSColin Finck return i;
194c2c66affSColin Finck return (UINT_PTR)hIcon;
195c2c66affSColin Finck }
196c2c66affSColin Finck
197c2c66affSColin Finck static void
TOOLTIPS_InitSystemSettings(TOOLTIPS_INFO * infoPtr)198c2c66affSColin Finck TOOLTIPS_InitSystemSettings (TOOLTIPS_INFO *infoPtr)
199c2c66affSColin Finck {
200c2c66affSColin Finck NONCLIENTMETRICSW nclm;
201c2c66affSColin Finck
202c2c66affSColin Finck infoPtr->clrBk = comctl32_color.clrInfoBk;
203c2c66affSColin Finck infoPtr->clrText = comctl32_color.clrInfoText;
204c2c66affSColin Finck
205c2c66affSColin Finck DeleteObject (infoPtr->hFont);
206c2c66affSColin Finck nclm.cbSize = sizeof(nclm);
207c2c66affSColin Finck SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof(nclm), &nclm, 0);
208c2c66affSColin Finck infoPtr->hFont = CreateFontIndirectW (&nclm.lfStatusFont);
209c2c66affSColin Finck
210c2c66affSColin Finck DeleteObject (infoPtr->hTitleFont);
211c2c66affSColin Finck nclm.lfStatusFont.lfWeight = FW_BOLD;
212c2c66affSColin Finck infoPtr->hTitleFont = CreateFontIndirectW (&nclm.lfStatusFont);
213c2c66affSColin Finck }
214c2c66affSColin Finck
215c2c66affSColin Finck /* Custom draw routines */
216c2c66affSColin Finck static void
TOOLTIPS_customdraw_fill(const TOOLTIPS_INFO * infoPtr,NMTTCUSTOMDRAW * lpnmttcd,HDC hdc,const RECT * rcBounds,UINT uFlags)217c2c66affSColin Finck TOOLTIPS_customdraw_fill(const TOOLTIPS_INFO *infoPtr, NMTTCUSTOMDRAW *lpnmttcd,
218c2c66affSColin Finck HDC hdc, const RECT *rcBounds, UINT uFlags)
219c2c66affSColin Finck {
220c2c66affSColin Finck ZeroMemory(lpnmttcd, sizeof(NMTTCUSTOMDRAW));
221c2c66affSColin Finck lpnmttcd->uDrawFlags = uFlags;
222c2c66affSColin Finck lpnmttcd->nmcd.hdr.hwndFrom = infoPtr->hwndSelf;
223c2c66affSColin Finck lpnmttcd->nmcd.hdr.code = NM_CUSTOMDRAW;
224c2c66affSColin Finck if (infoPtr->nCurrentTool != -1) {
225c2c66affSColin Finck TTTOOL_INFO *toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
226c2c66affSColin Finck lpnmttcd->nmcd.hdr.idFrom = toolPtr->uId;
227c2c66affSColin Finck }
228c2c66affSColin Finck lpnmttcd->nmcd.hdc = hdc;
229c2c66affSColin Finck lpnmttcd->nmcd.rc = *rcBounds;
230c2c66affSColin Finck /* FIXME - dwItemSpec, uItemState, lItemlParam */
231c2c66affSColin Finck }
232c2c66affSColin Finck
233c2c66affSColin Finck static inline DWORD
TOOLTIPS_notify_customdraw(DWORD dwDrawStage,NMTTCUSTOMDRAW * lpnmttcd)234c2c66affSColin Finck TOOLTIPS_notify_customdraw (DWORD dwDrawStage, NMTTCUSTOMDRAW *lpnmttcd)
235c2c66affSColin Finck {
236c2c66affSColin Finck LRESULT result;
237c2c66affSColin Finck lpnmttcd->nmcd.dwDrawStage = dwDrawStage;
238c2c66affSColin Finck
239c2c66affSColin Finck TRACE("Notifying stage %d, flags %x, id %x\n", lpnmttcd->nmcd.dwDrawStage,
240c2c66affSColin Finck lpnmttcd->uDrawFlags, lpnmttcd->nmcd.hdr.code);
241c2c66affSColin Finck
242c2c66affSColin Finck result = SendMessageW(GetParent(lpnmttcd->nmcd.hdr.hwndFrom), WM_NOTIFY,
243c2c66affSColin Finck 0, (LPARAM)lpnmttcd);
244c2c66affSColin Finck
245c2c66affSColin Finck TRACE("Notify result %x\n", (unsigned int)result);
246c2c66affSColin Finck
247c2c66affSColin Finck return result;
248c2c66affSColin Finck }
249c2c66affSColin Finck
250c2c66affSColin Finck static void
TOOLTIPS_Refresh(const TOOLTIPS_INFO * infoPtr,HDC hdc)251c2c66affSColin Finck TOOLTIPS_Refresh (const TOOLTIPS_INFO *infoPtr, HDC hdc)
252c2c66affSColin Finck {
253c2c66affSColin Finck RECT rc;
254c2c66affSColin Finck INT oldBkMode;
255c2c66affSColin Finck HFONT hOldFont;
256c2c66affSColin Finck HBRUSH hBrush;
257c2c66affSColin Finck UINT uFlags = DT_EXTERNALLEADING;
258c2c66affSColin Finck HRGN hRgn = NULL;
259c2c66affSColin Finck DWORD dwStyle = GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE);
260c2c66affSColin Finck NMTTCUSTOMDRAW nmttcd;
261c2c66affSColin Finck DWORD cdmode;
262c2c66affSColin Finck
263c2c66affSColin Finck if (infoPtr->nMaxTipWidth > -1)
264c2c66affSColin Finck uFlags |= DT_WORDBREAK;
265c2c66affSColin Finck if (GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TTS_NOPREFIX)
266c2c66affSColin Finck uFlags |= DT_NOPREFIX;
267c2c66affSColin Finck GetClientRect (infoPtr->hwndSelf, &rc);
268c2c66affSColin Finck
269c2c66affSColin Finck hBrush = CreateSolidBrush(infoPtr->clrBk);
270c2c66affSColin Finck
271c2c66affSColin Finck oldBkMode = SetBkMode (hdc, TRANSPARENT);
272c2c66affSColin Finck SetTextColor (hdc, infoPtr->clrText);
273c2c66affSColin Finck hOldFont = SelectObject (hdc, infoPtr->hFont);
274c2c66affSColin Finck
275c2c66affSColin Finck /* Custom draw - Call PrePaint once initial properties set up */
276c2c66affSColin Finck /* Note: Contrary to MSDN, CDRF_SKIPDEFAULT still draws a tooltip */
277c2c66affSColin Finck TOOLTIPS_customdraw_fill(infoPtr, &nmttcd, hdc, &rc, uFlags);
278c2c66affSColin Finck cdmode = TOOLTIPS_notify_customdraw(CDDS_PREPAINT, &nmttcd);
279c2c66affSColin Finck uFlags = nmttcd.uDrawFlags;
280c2c66affSColin Finck
281c2c66affSColin Finck if (dwStyle & TTS_BALLOON)
282c2c66affSColin Finck {
283c2c66affSColin Finck /* create a region to store result into */
284c2c66affSColin Finck hRgn = CreateRectRgn(0, 0, 0, 0);
285c2c66affSColin Finck
286c2c66affSColin Finck GetWindowRgn(infoPtr->hwndSelf, hRgn);
287c2c66affSColin Finck
288c2c66affSColin Finck /* fill the background */
289c2c66affSColin Finck FillRgn(hdc, hRgn, hBrush);
290c2c66affSColin Finck DeleteObject(hBrush);
291c2c66affSColin Finck hBrush = NULL;
292c2c66affSColin Finck }
293c2c66affSColin Finck else
294c2c66affSColin Finck {
295c2c66affSColin Finck /* fill the background */
296c2c66affSColin Finck FillRect(hdc, &rc, hBrush);
297c2c66affSColin Finck DeleteObject(hBrush);
298c2c66affSColin Finck hBrush = NULL;
299c2c66affSColin Finck }
300c2c66affSColin Finck
301c2c66affSColin Finck if ((dwStyle & TTS_BALLOON) || infoPtr->pszTitle)
302c2c66affSColin Finck {
303c2c66affSColin Finck /* calculate text rectangle */
304c2c66affSColin Finck rc.left += (BALLOON_TEXT_MARGIN + infoPtr->rcMargin.left);
305c2c66affSColin Finck rc.top += (BALLOON_TEXT_MARGIN + infoPtr->rcMargin.top);
306c2c66affSColin Finck rc.right -= (BALLOON_TEXT_MARGIN + infoPtr->rcMargin.right);
307c2c66affSColin Finck rc.bottom -= (BALLOON_TEXT_MARGIN + infoPtr->rcMargin.bottom);
308c2c66affSColin Finck if(infoPtr->bToolBelow) rc.top += BALLOON_STEMHEIGHT;
309c2c66affSColin Finck
310c2c66affSColin Finck if (infoPtr->pszTitle)
311c2c66affSColin Finck {
312c2c66affSColin Finck RECT rcTitle = {rc.left, rc.top, rc.right, rc.bottom};
313c2c66affSColin Finck int height;
314c2c66affSColin Finck BOOL icon_present;
315c2c66affSColin Finck HFONT prevFont;
316c2c66affSColin Finck
317c2c66affSColin Finck /* draw icon */
318c2c66affSColin Finck icon_present = infoPtr->hTitleIcon &&
319c2c66affSColin Finck DrawIconEx(hdc, rc.left, rc.top, infoPtr->hTitleIcon,
320c2c66affSColin Finck ICON_WIDTH, ICON_HEIGHT, 0, NULL, DI_NORMAL);
321c2c66affSColin Finck if (icon_present)
322c2c66affSColin Finck rcTitle.left += ICON_WIDTH + BALLOON_ICON_TITLE_SPACING;
323c2c66affSColin Finck
324c2c66affSColin Finck rcTitle.bottom = rc.top + ICON_HEIGHT;
325c2c66affSColin Finck
326c2c66affSColin Finck /* draw title text */
327c2c66affSColin Finck prevFont = SelectObject (hdc, infoPtr->hTitleFont);
328c2c66affSColin Finck height = DrawTextW(hdc, infoPtr->pszTitle, -1, &rcTitle, DT_BOTTOM | DT_SINGLELINE | DT_NOPREFIX);
329c2c66affSColin Finck SelectObject (hdc, prevFont);
330c2c66affSColin Finck rc.top += height + BALLOON_TITLE_TEXT_SPACING;
331c2c66affSColin Finck }
332c2c66affSColin Finck }
333c2c66affSColin Finck else
334c2c66affSColin Finck {
335c2c66affSColin Finck /* calculate text rectangle */
336c2c66affSColin Finck rc.left += (NORMAL_TEXT_MARGIN + infoPtr->rcMargin.left);
337c2c66affSColin Finck rc.top += (NORMAL_TEXT_MARGIN + infoPtr->rcMargin.top);
338c2c66affSColin Finck rc.right -= (NORMAL_TEXT_MARGIN + infoPtr->rcMargin.right);
339c2c66affSColin Finck rc.bottom -= (NORMAL_TEXT_MARGIN + infoPtr->rcMargin.bottom);
340c2c66affSColin Finck }
341c2c66affSColin Finck
342c2c66affSColin Finck /* draw text */
343710df136SKatayama Hirofumi MZ #ifdef __REACTOS__
344710df136SKatayama Hirofumi MZ uFlags |= DT_EXPANDTABS;
345710df136SKatayama Hirofumi MZ #endif
346c2c66affSColin Finck DrawTextW (hdc, infoPtr->szTipText, -1, &rc, uFlags);
347c2c66affSColin Finck
348c2c66affSColin Finck /* Custom draw - Call PostPaint after drawing */
349c2c66affSColin Finck if (cdmode & CDRF_NOTIFYPOSTPAINT) {
350c2c66affSColin Finck TOOLTIPS_notify_customdraw(CDDS_POSTPAINT, &nmttcd);
351c2c66affSColin Finck }
352c2c66affSColin Finck
353c2c66affSColin Finck /* be polite and reset the things we changed in the dc */
354c2c66affSColin Finck SelectObject (hdc, hOldFont);
355c2c66affSColin Finck SetBkMode (hdc, oldBkMode);
356c2c66affSColin Finck
357c2c66affSColin Finck if (dwStyle & TTS_BALLOON)
358c2c66affSColin Finck {
359c2c66affSColin Finck /* frame region because default window proc doesn't do it */
360c2c66affSColin Finck INT width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
361c2c66affSColin Finck INT height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
362c2c66affSColin Finck
363c2c66affSColin Finck hBrush = GetSysColorBrush(COLOR_WINDOWFRAME);
364c2c66affSColin Finck FrameRgn(hdc, hRgn, hBrush, width, height);
365c2c66affSColin Finck }
366c2c66affSColin Finck
367c2c66affSColin Finck if (hRgn)
368c2c66affSColin Finck DeleteObject(hRgn);
369c2c66affSColin Finck }
370c2c66affSColin Finck
TOOLTIPS_GetDispInfoA(const TOOLTIPS_INFO * infoPtr,TTTOOL_INFO * toolPtr,WCHAR * buffer)371c2c66affSColin Finck static void TOOLTIPS_GetDispInfoA(const TOOLTIPS_INFO *infoPtr, TTTOOL_INFO *toolPtr, WCHAR *buffer)
372c2c66affSColin Finck {
373c2c66affSColin Finck NMTTDISPINFOA ttnmdi;
374c2c66affSColin Finck
375c2c66affSColin Finck /* fill NMHDR struct */
376c2c66affSColin Finck ZeroMemory (&ttnmdi, sizeof(NMTTDISPINFOA));
377c2c66affSColin Finck ttnmdi.hdr.hwndFrom = infoPtr->hwndSelf;
378c2c66affSColin Finck ttnmdi.hdr.idFrom = toolPtr->uId;
379c2c66affSColin Finck ttnmdi.hdr.code = TTN_GETDISPINFOA; /* == TTN_NEEDTEXTA */
380c2c66affSColin Finck ttnmdi.lpszText = ttnmdi.szText;
381c2c66affSColin Finck ttnmdi.uFlags = toolPtr->uFlags;
382c2c66affSColin Finck ttnmdi.lParam = toolPtr->lParam;
383c2c66affSColin Finck
384c2c66affSColin Finck TRACE("hdr.idFrom = %lx\n", ttnmdi.hdr.idFrom);
385c2c66affSColin Finck SendMessageW(toolPtr->hwnd, WM_NOTIFY, toolPtr->uId, (LPARAM)&ttnmdi);
386c2c66affSColin Finck
387c2c66affSColin Finck if (IS_INTRESOURCE(ttnmdi.lpszText)) {
388c2c66affSColin Finck LoadStringW(ttnmdi.hinst, LOWORD(ttnmdi.lpszText),
389c2c66affSColin Finck buffer, INFOTIPSIZE);
390c2c66affSColin Finck if (ttnmdi.uFlags & TTF_DI_SETITEM) {
391c2c66affSColin Finck toolPtr->hinst = ttnmdi.hinst;
392c2c66affSColin Finck toolPtr->lpszText = (LPWSTR)ttnmdi.lpszText;
393c2c66affSColin Finck }
394c2c66affSColin Finck }
395c2c66affSColin Finck else if (ttnmdi.lpszText == 0) {
396c2c66affSColin Finck buffer[0] = '\0';
397c2c66affSColin Finck }
398c2c66affSColin Finck else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKA) {
399c2c66affSColin Finck Str_GetPtrAtoW(ttnmdi.lpszText, buffer, INFOTIPSIZE);
400c2c66affSColin Finck if (ttnmdi.uFlags & TTF_DI_SETITEM) {
401c2c66affSColin Finck toolPtr->hinst = 0;
402c2c66affSColin Finck toolPtr->lpszText = NULL;
403c2c66affSColin Finck Str_SetPtrW(&toolPtr->lpszText, buffer);
404c2c66affSColin Finck }
405c2c66affSColin Finck }
406c2c66affSColin Finck else {
407edd99e8cSAmine Khaldi ERR("recursive text callback\n");
408c2c66affSColin Finck buffer[0] = '\0';
409c2c66affSColin Finck }
410c2c66affSColin Finck
411c858429fSKatayama Hirofumi MZ #ifndef __REACTOS_
412c2c66affSColin Finck /* no text available - try calling parent instead as per native */
413c2c66affSColin Finck /* FIXME: Unsure if SETITEM should save the value or not */
414c2c66affSColin Finck if (buffer[0] == 0x00) {
415c2c66affSColin Finck
416c2c66affSColin Finck SendMessageW(GetParent(toolPtr->hwnd), WM_NOTIFY, toolPtr->uId, (LPARAM)&ttnmdi);
417c2c66affSColin Finck
418c2c66affSColin Finck if (IS_INTRESOURCE(ttnmdi.lpszText)) {
419c2c66affSColin Finck LoadStringW(ttnmdi.hinst, LOWORD(ttnmdi.lpszText),
420c2c66affSColin Finck buffer, INFOTIPSIZE);
421c2c66affSColin Finck } else if (ttnmdi.lpszText &&
422c2c66affSColin Finck ttnmdi.lpszText != LPSTR_TEXTCALLBACKA) {
423c2c66affSColin Finck Str_GetPtrAtoW(ttnmdi.lpszText, buffer, INFOTIPSIZE);
424c2c66affSColin Finck }
425c2c66affSColin Finck }
426c858429fSKatayama Hirofumi MZ #endif
427c2c66affSColin Finck }
428c2c66affSColin Finck
TOOLTIPS_GetDispInfoW(const TOOLTIPS_INFO * infoPtr,TTTOOL_INFO * toolPtr,WCHAR * buffer)429c2c66affSColin Finck static void TOOLTIPS_GetDispInfoW(const TOOLTIPS_INFO *infoPtr, TTTOOL_INFO *toolPtr, WCHAR *buffer)
430c2c66affSColin Finck {
431c2c66affSColin Finck NMTTDISPINFOW ttnmdi;
432c2c66affSColin Finck
433c2c66affSColin Finck /* fill NMHDR struct */
434c2c66affSColin Finck ZeroMemory (&ttnmdi, sizeof(NMTTDISPINFOW));
435c2c66affSColin Finck ttnmdi.hdr.hwndFrom = infoPtr->hwndSelf;
436c2c66affSColin Finck ttnmdi.hdr.idFrom = toolPtr->uId;
437c2c66affSColin Finck ttnmdi.hdr.code = TTN_GETDISPINFOW; /* == TTN_NEEDTEXTW */
438c2c66affSColin Finck ttnmdi.lpszText = ttnmdi.szText;
439c2c66affSColin Finck ttnmdi.uFlags = toolPtr->uFlags;
440c2c66affSColin Finck ttnmdi.lParam = toolPtr->lParam;
441c2c66affSColin Finck
442c2c66affSColin Finck TRACE("hdr.idFrom = %lx\n", ttnmdi.hdr.idFrom);
443c2c66affSColin Finck SendMessageW(toolPtr->hwnd, WM_NOTIFY, toolPtr->uId, (LPARAM)&ttnmdi);
444c2c66affSColin Finck
445c2c66affSColin Finck if (IS_INTRESOURCE(ttnmdi.lpszText)) {
446c2c66affSColin Finck LoadStringW(ttnmdi.hinst, LOWORD(ttnmdi.lpszText),
447c2c66affSColin Finck buffer, INFOTIPSIZE);
448c2c66affSColin Finck if (ttnmdi.uFlags & TTF_DI_SETITEM) {
449c2c66affSColin Finck toolPtr->hinst = ttnmdi.hinst;
450c2c66affSColin Finck toolPtr->lpszText = ttnmdi.lpszText;
451c2c66affSColin Finck }
452c2c66affSColin Finck }
453c2c66affSColin Finck else if (ttnmdi.lpszText == 0) {
454c2c66affSColin Finck buffer[0] = '\0';
455c2c66affSColin Finck }
456c2c66affSColin Finck else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKW) {
457c2c66affSColin Finck Str_GetPtrW(ttnmdi.lpszText, buffer, INFOTIPSIZE);
458c2c66affSColin Finck if (ttnmdi.uFlags & TTF_DI_SETITEM) {
459c2c66affSColin Finck toolPtr->hinst = 0;
460c2c66affSColin Finck toolPtr->lpszText = NULL;
461c2c66affSColin Finck Str_SetPtrW(&toolPtr->lpszText, buffer);
462c2c66affSColin Finck }
463c2c66affSColin Finck }
464c2c66affSColin Finck else {
465edd99e8cSAmine Khaldi ERR("recursive text callback\n");
466c2c66affSColin Finck buffer[0] = '\0';
467c2c66affSColin Finck }
468c2c66affSColin Finck
469c858429fSKatayama Hirofumi MZ #ifndef __REACTOS__
470c2c66affSColin Finck /* no text available - try calling parent instead as per native */
471c2c66affSColin Finck /* FIXME: Unsure if SETITEM should save the value or not */
472c2c66affSColin Finck if (buffer[0] == 0x00) {
473c2c66affSColin Finck
474c2c66affSColin Finck SendMessageW(GetParent(toolPtr->hwnd), WM_NOTIFY, toolPtr->uId, (LPARAM)&ttnmdi);
475c2c66affSColin Finck
476c2c66affSColin Finck if (IS_INTRESOURCE(ttnmdi.lpszText)) {
477c2c66affSColin Finck LoadStringW(ttnmdi.hinst, LOWORD(ttnmdi.lpszText),
478c2c66affSColin Finck buffer, INFOTIPSIZE);
479c2c66affSColin Finck } else if (ttnmdi.lpszText &&
480c2c66affSColin Finck ttnmdi.lpszText != LPSTR_TEXTCALLBACKW) {
481c2c66affSColin Finck Str_GetPtrW(ttnmdi.lpszText, buffer, INFOTIPSIZE);
482c2c66affSColin Finck }
483c2c66affSColin Finck }
484c858429fSKatayama Hirofumi MZ #endif
485c2c66affSColin Finck
486c2c66affSColin Finck }
487c2c66affSColin Finck
488c2c66affSColin Finck static void
TOOLTIPS_GetTipText(const TOOLTIPS_INFO * infoPtr,INT nTool,WCHAR * buffer)489c2c66affSColin Finck TOOLTIPS_GetTipText (const TOOLTIPS_INFO *infoPtr, INT nTool, WCHAR *buffer)
490c2c66affSColin Finck {
491c2c66affSColin Finck TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool];
492c2c66affSColin Finck
493c2c66affSColin Finck if (IS_INTRESOURCE(toolPtr->lpszText)) {
494c2c66affSColin Finck /* load a resource */
495c2c66affSColin Finck TRACE("load res string %p %x\n",
496c2c66affSColin Finck toolPtr->hinst, LOWORD(toolPtr->lpszText));
497c2c66affSColin Finck if (!LoadStringW (toolPtr->hinst, LOWORD(toolPtr->lpszText), buffer, INFOTIPSIZE))
498c2c66affSColin Finck buffer[0] = '\0';
499c2c66affSColin Finck }
500c2c66affSColin Finck else if (toolPtr->lpszText) {
501c2c66affSColin Finck if (toolPtr->lpszText == LPSTR_TEXTCALLBACKW) {
502c2c66affSColin Finck if (toolPtr->bNotifyUnicode)
503c2c66affSColin Finck TOOLTIPS_GetDispInfoW(infoPtr, toolPtr, buffer);
504c2c66affSColin Finck else
505c2c66affSColin Finck TOOLTIPS_GetDispInfoA(infoPtr, toolPtr, buffer);
506c2c66affSColin Finck }
507c2c66affSColin Finck else {
508c2c66affSColin Finck /* the item is a usual (unicode) text */
509c2c66affSColin Finck lstrcpynW (buffer, toolPtr->lpszText, INFOTIPSIZE);
510c2c66affSColin Finck }
511c2c66affSColin Finck }
512c2c66affSColin Finck else {
513c2c66affSColin Finck /* no text available */
514c2c66affSColin Finck buffer[0] = '\0';
515c2c66affSColin Finck }
516c2c66affSColin Finck
517c2c66affSColin Finck if (!(GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & TTS_NOPREFIX)) {
518c2c66affSColin Finck WCHAR *ptrW;
519*0707475fSJustin Miller if ((ptrW = wcschr(buffer, '\t')))
520c2c66affSColin Finck *ptrW = 0;
521c2c66affSColin Finck }
522c2c66affSColin Finck
523c2c66affSColin Finck TRACE("%s\n", debugstr_w(buffer));
524c2c66affSColin Finck }
525c2c66affSColin Finck
526c2c66affSColin Finck
527c2c66affSColin Finck static void
TOOLTIPS_CalcTipSize(const TOOLTIPS_INFO * infoPtr,LPSIZE lpSize)528c2c66affSColin Finck TOOLTIPS_CalcTipSize (const TOOLTIPS_INFO *infoPtr, LPSIZE lpSize)
529c2c66affSColin Finck {
530c2c66affSColin Finck HDC hdc;
531c2c66affSColin Finck HFONT hOldFont;
532c2c66affSColin Finck DWORD style = GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE);
533c2c66affSColin Finck UINT uFlags = DT_EXTERNALLEADING | DT_CALCRECT;
534c2c66affSColin Finck RECT rc = {0, 0, 0, 0};
535c2c66affSColin Finck SIZE title = {0, 0};
536c2c66affSColin Finck
537c2c66affSColin Finck if (infoPtr->nMaxTipWidth > -1) {
538c2c66affSColin Finck rc.right = infoPtr->nMaxTipWidth;
539c2c66affSColin Finck uFlags |= DT_WORDBREAK;
540c2c66affSColin Finck }
541c2c66affSColin Finck if (style & TTS_NOPREFIX)
542c2c66affSColin Finck uFlags |= DT_NOPREFIX;
543c2c66affSColin Finck TRACE("%s\n", debugstr_w(infoPtr->szTipText));
544c2c66affSColin Finck
545c2c66affSColin Finck hdc = GetDC (infoPtr->hwndSelf);
546c2c66affSColin Finck if (infoPtr->pszTitle)
547c2c66affSColin Finck {
548c2c66affSColin Finck RECT rcTitle = {0, 0, 0, 0};
549c2c66affSColin Finck TRACE("title %s\n", debugstr_w(infoPtr->pszTitle));
550c2c66affSColin Finck if (infoPtr->hTitleIcon)
551c2c66affSColin Finck {
552c2c66affSColin Finck title.cx = ICON_WIDTH;
553c2c66affSColin Finck title.cy = ICON_HEIGHT;
554c2c66affSColin Finck }
555c2c66affSColin Finck if (title.cx != 0) title.cx += BALLOON_ICON_TITLE_SPACING;
556c2c66affSColin Finck hOldFont = SelectObject (hdc, infoPtr->hTitleFont);
557c2c66affSColin Finck DrawTextW(hdc, infoPtr->pszTitle, -1, &rcTitle, DT_SINGLELINE | DT_NOPREFIX | DT_CALCRECT);
558c2c66affSColin Finck SelectObject (hdc, hOldFont);
559c2c66affSColin Finck title.cy = max(title.cy, rcTitle.bottom - rcTitle.top) + BALLOON_TITLE_TEXT_SPACING;
560c2c66affSColin Finck title.cx += (rcTitle.right - rcTitle.left);
561c2c66affSColin Finck }
562c2c66affSColin Finck hOldFont = SelectObject (hdc, infoPtr->hFont);
563710df136SKatayama Hirofumi MZ #ifdef __REACTOS__
564710df136SKatayama Hirofumi MZ uFlags |= DT_EXPANDTABS;
565710df136SKatayama Hirofumi MZ #endif
566c2c66affSColin Finck DrawTextW (hdc, infoPtr->szTipText, -1, &rc, uFlags);
567c2c66affSColin Finck SelectObject (hdc, hOldFont);
568c2c66affSColin Finck ReleaseDC (infoPtr->hwndSelf, hdc);
569c2c66affSColin Finck
570c2c66affSColin Finck if ((style & TTS_BALLOON) || infoPtr->pszTitle)
571c2c66affSColin Finck {
572c2c66affSColin Finck lpSize->cx = max(rc.right - rc.left, title.cx) + 2*BALLOON_TEXT_MARGIN +
573c2c66affSColin Finck infoPtr->rcMargin.left + infoPtr->rcMargin.right;
574c2c66affSColin Finck lpSize->cy = title.cy + rc.bottom - rc.top + 2*BALLOON_TEXT_MARGIN +
575c2c66affSColin Finck infoPtr->rcMargin.bottom + infoPtr->rcMargin.top +
576c2c66affSColin Finck BALLOON_STEMHEIGHT;
577c2c66affSColin Finck }
578c2c66affSColin Finck else
579c2c66affSColin Finck {
580c2c66affSColin Finck lpSize->cx = rc.right - rc.left + 2*NORMAL_TEXT_MARGIN +
581c2c66affSColin Finck infoPtr->rcMargin.left + infoPtr->rcMargin.right;
582c2c66affSColin Finck lpSize->cy = rc.bottom - rc.top + 2*NORMAL_TEXT_MARGIN +
583c2c66affSColin Finck infoPtr->rcMargin.bottom + infoPtr->rcMargin.top;
584c2c66affSColin Finck }
585c2c66affSColin Finck }
586c2c66affSColin Finck
587c2c66affSColin Finck
588c2c66affSColin Finck static void
TOOLTIPS_Show(TOOLTIPS_INFO * infoPtr,BOOL track_activate)589c2c66affSColin Finck TOOLTIPS_Show (TOOLTIPS_INFO *infoPtr, BOOL track_activate)
590c2c66affSColin Finck {
591c2c66affSColin Finck TTTOOL_INFO *toolPtr;
592c2c66affSColin Finck HMONITOR monitor;
593c2c66affSColin Finck MONITORINFO mon_info;
594c2c66affSColin Finck RECT rect;
595c2c66affSColin Finck SIZE size;
596c2c66affSColin Finck NMHDR hdr;
597c2c66affSColin Finck int ptfx = 0;
598c2c66affSColin Finck DWORD style = GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE);
599edd99e8cSAmine Khaldi INT nTool, current;
600c2c66affSColin Finck
601c2c66affSColin Finck if (track_activate)
602c2c66affSColin Finck {
603c2c66affSColin Finck if (infoPtr->nTrackTool == -1)
604c2c66affSColin Finck {
605edd99e8cSAmine Khaldi TRACE("invalid tracking tool %d\n", infoPtr->nTrackTool);
606c2c66affSColin Finck return;
607c2c66affSColin Finck }
608c2c66affSColin Finck nTool = infoPtr->nTrackTool;
609c2c66affSColin Finck }
610c2c66affSColin Finck else
611c2c66affSColin Finck {
612c2c66affSColin Finck if (infoPtr->nTool == -1)
613c2c66affSColin Finck {
614edd99e8cSAmine Khaldi TRACE("invalid tool %d\n", infoPtr->nTool);
615c2c66affSColin Finck return;
616c2c66affSColin Finck }
617c2c66affSColin Finck nTool = infoPtr->nTool;
618c2c66affSColin Finck }
619c2c66affSColin Finck
620edd99e8cSAmine Khaldi TRACE("Show tooltip pre %d, %p\n", nTool, infoPtr->hwndSelf);
621edd99e8cSAmine Khaldi
622edd99e8cSAmine Khaldi current = infoPtr->nCurrentTool;
623edd99e8cSAmine Khaldi if (!track_activate)
624edd99e8cSAmine Khaldi infoPtr->nCurrentTool = infoPtr->nTool;
625c2c66affSColin Finck
626c2c66affSColin Finck TOOLTIPS_GetTipText (infoPtr, nTool, infoPtr->szTipText);
627c2c66affSColin Finck
628c2c66affSColin Finck if (infoPtr->szTipText[0] == '\0')
629edd99e8cSAmine Khaldi {
630edd99e8cSAmine Khaldi infoPtr->nCurrentTool = current;
631c2c66affSColin Finck return;
632edd99e8cSAmine Khaldi }
633c2c66affSColin Finck
634c2c66affSColin Finck toolPtr = &infoPtr->tools[nTool];
635c2c66affSColin Finck TOOLTIPS_CalcTipSize (infoPtr, &size);
636b3fb8555SGiannis Adamopoulos
637b3fb8555SGiannis Adamopoulos TRACE("Show tooltip %d, %s, size %d x %d\n", nTool, debugstr_w(infoPtr->szTipText),
638b3fb8555SGiannis Adamopoulos size.cx, size.cy);
639c2c66affSColin Finck
640c2c66affSColin Finck if (track_activate && (toolPtr->uFlags & TTF_TRACK))
641c2c66affSColin Finck {
642c2c66affSColin Finck rect.left = infoPtr->xTrackPos;
643c2c66affSColin Finck rect.top = infoPtr->yTrackPos;
644c2c66affSColin Finck ptfx = rect.left;
645c2c66affSColin Finck
646c2c66affSColin Finck if (toolPtr->uFlags & TTF_CENTERTIP)
647c2c66affSColin Finck {
648c2c66affSColin Finck rect.left -= (size.cx / 2);
649c2c66affSColin Finck if (!(style & TTS_BALLOON))
650c2c66affSColin Finck rect.top -= (size.cy / 2);
651c2c66affSColin Finck }
652c2c66affSColin Finck if (!(infoPtr->bToolBelow = (infoPtr->yTrackPos + size.cy <= GetSystemMetrics(SM_CYSCREEN))))
653c2c66affSColin Finck rect.top -= size.cy;
654c2c66affSColin Finck
655c2c66affSColin Finck if (!(toolPtr->uFlags & TTF_ABSOLUTE))
656c2c66affSColin Finck {
657c2c66affSColin Finck if (style & TTS_BALLOON)
658c2c66affSColin Finck rect.left -= BALLOON_STEMINDENT;
659c2c66affSColin Finck else
660c2c66affSColin Finck {
661c2c66affSColin Finck RECT rcTool;
662c2c66affSColin Finck
663c2c66affSColin Finck if (toolPtr->uFlags & TTF_IDISHWND)
664c2c66affSColin Finck GetWindowRect ((HWND)toolPtr->uId, &rcTool);
665c2c66affSColin Finck else
666c2c66affSColin Finck {
667c2c66affSColin Finck rcTool = toolPtr->rect;
668c2c66affSColin Finck MapWindowPoints (toolPtr->hwnd, NULL, (LPPOINT)&rcTool, 2);
669c2c66affSColin Finck }
670c2c66affSColin Finck
671c2c66affSColin Finck /* smart placement */
672c2c66affSColin Finck if ((rect.left + size.cx > rcTool.left) && (rect.left < rcTool.right) &&
673c2c66affSColin Finck (rect.top + size.cy > rcTool.top) && (rect.top < rcTool.bottom))
674c2c66affSColin Finck rect.left = rcTool.right;
675c2c66affSColin Finck }
676c2c66affSColin Finck }
677c2c66affSColin Finck }
678c2c66affSColin Finck else
679c2c66affSColin Finck {
680c2c66affSColin Finck if (toolPtr->uFlags & TTF_CENTERTIP)
681c2c66affSColin Finck {
682c2c66affSColin Finck RECT rc;
683c2c66affSColin Finck
684c2c66affSColin Finck if (toolPtr->uFlags & TTF_IDISHWND)
685c2c66affSColin Finck GetWindowRect ((HWND)toolPtr->uId, &rc);
686c2c66affSColin Finck else {
687c2c66affSColin Finck rc = toolPtr->rect;
688c2c66affSColin Finck MapWindowPoints (toolPtr->hwnd, NULL, (LPPOINT)&rc, 2);
689c2c66affSColin Finck }
690c2c66affSColin Finck rect.left = (rc.left + rc.right - size.cx) / 2;
691c2c66affSColin Finck if (style & TTS_BALLOON)
692c2c66affSColin Finck {
693c2c66affSColin Finck ptfx = rc.left + ((rc.right - rc.left) / 2);
694c2c66affSColin Finck
695c2c66affSColin Finck /* CENTERTIP ballon tooltips default to below the field
696c2c66affSColin Finck * if they fit on the screen */
697c2c66affSColin Finck if (rc.bottom + size.cy > GetSystemMetrics(SM_CYSCREEN))
698c2c66affSColin Finck {
699c2c66affSColin Finck rect.top = rc.top - size.cy;
700c2c66affSColin Finck infoPtr->bToolBelow = FALSE;
701c2c66affSColin Finck }
702c2c66affSColin Finck else
703c2c66affSColin Finck {
704c2c66affSColin Finck infoPtr->bToolBelow = TRUE;
705c2c66affSColin Finck rect.top = rc.bottom;
706c2c66affSColin Finck }
707c2c66affSColin Finck rect.left = max(0, rect.left - BALLOON_STEMINDENT);
708c2c66affSColin Finck }
709c2c66affSColin Finck else
710c2c66affSColin Finck {
711c2c66affSColin Finck rect.top = rc.bottom + 2;
712c2c66affSColin Finck infoPtr->bToolBelow = TRUE;
713c2c66affSColin Finck }
714c2c66affSColin Finck }
715c2c66affSColin Finck else
716c2c66affSColin Finck {
717c2c66affSColin Finck GetCursorPos ((LPPOINT)&rect);
718c2c66affSColin Finck if (style & TTS_BALLOON)
719c2c66affSColin Finck {
720c2c66affSColin Finck ptfx = rect.left;
721c2c66affSColin Finck if(rect.top - size.cy >= 0)
722c2c66affSColin Finck {
723c2c66affSColin Finck rect.top -= size.cy;
724c2c66affSColin Finck infoPtr->bToolBelow = FALSE;
725c2c66affSColin Finck }
726c2c66affSColin Finck else
727c2c66affSColin Finck {
728c2c66affSColin Finck infoPtr->bToolBelow = TRUE;
729c2c66affSColin Finck rect.top += 20;
730c2c66affSColin Finck }
731c2c66affSColin Finck rect.left = max(0, rect.left - BALLOON_STEMINDENT);
732c2c66affSColin Finck }
733c2c66affSColin Finck else
734c2c66affSColin Finck {
735c2c66affSColin Finck rect.top += 20;
736c2c66affSColin Finck infoPtr->bToolBelow = TRUE;
737c2c66affSColin Finck }
738c2c66affSColin Finck }
739c2c66affSColin Finck }
740c2c66affSColin Finck
741c2c66affSColin Finck TRACE("pos %d - %d\n", rect.left, rect.top);
742c2c66affSColin Finck
743c2c66affSColin Finck rect.right = rect.left + size.cx;
744c2c66affSColin Finck rect.bottom = rect.top + size.cy;
745c2c66affSColin Finck
746c2c66affSColin Finck /* check position */
747c2c66affSColin Finck
748c2c66affSColin Finck monitor = MonitorFromRect( &rect, MONITOR_DEFAULTTOPRIMARY );
749c2c66affSColin Finck mon_info.cbSize = sizeof(mon_info);
750c2c66affSColin Finck GetMonitorInfoW( monitor, &mon_info );
751c2c66affSColin Finck
7523e46a867SCarl J. Bialorucki #ifdef __REACTOS__
7533e46a867SCarl J. Bialorucki if (rect.right > mon_info.rcMonitor.right)
7543e46a867SCarl J. Bialorucki {
7553e46a867SCarl J. Bialorucki rect.left -= size.cx - (BALLOON_STEMINDENT + BALLOON_STEMWIDTH);
7563e46a867SCarl J. Bialorucki rect.right -= size.cx - (BALLOON_STEMINDENT + BALLOON_STEMWIDTH);
7573e46a867SCarl J. Bialorucki if (rect.right > mon_info.rcMonitor.right)
7583e46a867SCarl J. Bialorucki {
7593e46a867SCarl J. Bialorucki rect.left -= (rect.right - mon_info.rcMonitor.right);
7603e46a867SCarl J. Bialorucki rect.right = mon_info.rcMonitor.right;
7613e46a867SCarl J. Bialorucki }
7623e46a867SCarl J. Bialorucki }
7633e46a867SCarl J. Bialorucki
7643e46a867SCarl J. Bialorucki if (rect.left < mon_info.rcMonitor.left)
7653e46a867SCarl J. Bialorucki {
7663e46a867SCarl J. Bialorucki rect.right += abs(rect.left);
7673e46a867SCarl J. Bialorucki rect.left = 0;
7683e46a867SCarl J. Bialorucki }
7693e46a867SCarl J. Bialorucki
7703e46a867SCarl J. Bialorucki if (rect.bottom > mon_info.rcMonitor.bottom)
7713e46a867SCarl J. Bialorucki {
7723e46a867SCarl J. Bialorucki RECT rc;
7733e46a867SCarl J. Bialorucki if (toolPtr->uFlags & TTF_IDISHWND)
7743e46a867SCarl J. Bialorucki {
7753e46a867SCarl J. Bialorucki GetWindowRect((HWND)toolPtr->uId, &rc);
7763e46a867SCarl J. Bialorucki }
7773e46a867SCarl J. Bialorucki else
7783e46a867SCarl J. Bialorucki {
7793e46a867SCarl J. Bialorucki rc = toolPtr->rect;
7803e46a867SCarl J. Bialorucki MapWindowPoints(toolPtr->hwnd, NULL, (LPPOINT)&rc, 2);
7813e46a867SCarl J. Bialorucki }
7823e46a867SCarl J. Bialorucki rect.bottom = rc.top - 2;
7833e46a867SCarl J. Bialorucki rect.top = rect.bottom - size.cy;
7843e46a867SCarl J. Bialorucki }
7853e46a867SCarl J. Bialorucki #else
786c2c66affSColin Finck if( rect.right > mon_info.rcWork.right ) {
787c2c66affSColin Finck rect.left -= rect.right - mon_info.rcWork.right + 2;
788c2c66affSColin Finck rect.right = mon_info.rcWork.right - 2;
789c2c66affSColin Finck }
790c2c66affSColin Finck if (rect.left < mon_info.rcWork.left) rect.left = mon_info.rcWork.left;
791c2c66affSColin Finck
792c2c66affSColin Finck if( rect.bottom > mon_info.rcWork.bottom ) {
793c2c66affSColin Finck RECT rc;
794c2c66affSColin Finck
795c2c66affSColin Finck if (toolPtr->uFlags & TTF_IDISHWND)
796c2c66affSColin Finck GetWindowRect ((HWND)toolPtr->uId, &rc);
797c2c66affSColin Finck else {
798c2c66affSColin Finck rc = toolPtr->rect;
799c2c66affSColin Finck MapWindowPoints (toolPtr->hwnd, NULL, (LPPOINT)&rc, 2);
800c2c66affSColin Finck }
801c2c66affSColin Finck rect.bottom = rc.top - 2;
802c2c66affSColin Finck rect.top = rect.bottom - size.cy;
803c2c66affSColin Finck }
8043e46a867SCarl J. Bialorucki #endif // __REACTOS__
805c2c66affSColin Finck
806c2c66affSColin Finck AdjustWindowRectEx (&rect, GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE),
807c2c66affSColin Finck FALSE, GetWindowLongW (infoPtr->hwndSelf, GWL_EXSTYLE));
808c2c66affSColin Finck
809c2c66affSColin Finck if (style & TTS_BALLOON)
810c2c66affSColin Finck {
811c2c66affSColin Finck HRGN hRgn;
812c2c66affSColin Finck HRGN hrStem;
813c2c66affSColin Finck POINT pts[3];
814c2c66affSColin Finck
815c2c66affSColin Finck ptfx -= rect.left;
816c2c66affSColin Finck
817c2c66affSColin Finck if(infoPtr->bToolBelow)
818c2c66affSColin Finck {
819c2c66affSColin Finck pts[0].x = ptfx;
820c2c66affSColin Finck pts[0].y = 0;
8213e46a867SCarl J. Bialorucki #ifdef __REACTOS__
8223e46a867SCarl J. Bialorucki pts[1].x = max(BALLOON_STEMINDENT, ptfx - BALLOON_STEMWIDTH);
8233e46a867SCarl J. Bialorucki #else
824c2c66affSColin Finck pts[1].x = max(BALLOON_STEMINDENT, ptfx - (BALLOON_STEMWIDTH / 2));
8253e46a867SCarl J. Bialorucki #endif
826c2c66affSColin Finck pts[1].y = BALLOON_STEMHEIGHT;
827c2c66affSColin Finck pts[2].x = pts[1].x + BALLOON_STEMWIDTH;
828c2c66affSColin Finck pts[2].y = pts[1].y;
829c2c66affSColin Finck if(pts[2].x > (rect.right - rect.left) - BALLOON_STEMINDENT)
830c2c66affSColin Finck {
831c2c66affSColin Finck pts[2].x = (rect.right - rect.left) - BALLOON_STEMINDENT;
832c2c66affSColin Finck pts[1].x = pts[2].x - BALLOON_STEMWIDTH;
833c2c66affSColin Finck }
834c2c66affSColin Finck }
835c2c66affSColin Finck else
836c2c66affSColin Finck {
8373e46a867SCarl J. Bialorucki #ifdef __REACTOS__
8383e46a867SCarl J. Bialorucki pts[0].x = max(BALLOON_STEMINDENT, ptfx - BALLOON_STEMWIDTH);
8393e46a867SCarl J. Bialorucki #else
840c2c66affSColin Finck pts[0].x = max(BALLOON_STEMINDENT, ptfx - (BALLOON_STEMWIDTH / 2));
8413e46a867SCarl J. Bialorucki #endif
842c2c66affSColin Finck pts[0].y = (rect.bottom - rect.top) - BALLOON_STEMHEIGHT;
843c2c66affSColin Finck pts[1].x = pts[0].x + BALLOON_STEMWIDTH;
844c2c66affSColin Finck pts[1].y = pts[0].y;
845c2c66affSColin Finck pts[2].x = ptfx;
846c2c66affSColin Finck pts[2].y = (rect.bottom - rect.top);
847c2c66affSColin Finck if(pts[1].x > (rect.right - rect.left) - BALLOON_STEMINDENT)
848c2c66affSColin Finck {
849c2c66affSColin Finck pts[1].x = (rect.right - rect.left) - BALLOON_STEMINDENT;
850c2c66affSColin Finck pts[0].x = pts[1].x - BALLOON_STEMWIDTH;
851c2c66affSColin Finck }
852c2c66affSColin Finck }
853c2c66affSColin Finck
854b3fb8555SGiannis Adamopoulos hrStem = CreatePolygonRgn(pts, ARRAY_SIZE(pts), ALTERNATE);
855c2c66affSColin Finck
856c2c66affSColin Finck hRgn = CreateRoundRectRgn(0,
857c2c66affSColin Finck (infoPtr->bToolBelow ? BALLOON_STEMHEIGHT : 0),
858c2c66affSColin Finck rect.right - rect.left,
8593e46a867SCarl J. Bialorucki #ifdef __REACTOS__
8603e46a867SCarl J. Bialorucki (infoPtr->bToolBelow ? rect.bottom - rect.top : rect.bottom - rect.top - BALLOON_STEMHEIGHT + 1),
8613e46a867SCarl J. Bialorucki #else
862c2c66affSColin Finck (infoPtr->bToolBelow ? rect.bottom - rect.top : rect.bottom - rect.top - BALLOON_STEMHEIGHT),
8633e46a867SCarl J. Bialorucki #endif
864c2c66affSColin Finck BALLOON_ROUNDEDNESS, BALLOON_ROUNDEDNESS);
865c2c66affSColin Finck
866c2c66affSColin Finck CombineRgn(hRgn, hRgn, hrStem, RGN_OR);
867c2c66affSColin Finck DeleteObject(hrStem);
868c2c66affSColin Finck
869c2c66affSColin Finck SetWindowRgn(infoPtr->hwndSelf, hRgn, FALSE);
870c2c66affSColin Finck /* we don't free the region handle as the system deletes it when
871c2c66affSColin Finck * it is no longer needed */
872c2c66affSColin Finck }
873c2c66affSColin Finck
874b3fb8555SGiannis Adamopoulos SetWindowPos (infoPtr->hwndSelf, NULL, rect.left, rect.top,
875b3fb8555SGiannis Adamopoulos rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOACTIVATE);
876b3fb8555SGiannis Adamopoulos
877b3fb8555SGiannis Adamopoulos hdr.hwndFrom = infoPtr->hwndSelf;
878b3fb8555SGiannis Adamopoulos hdr.idFrom = toolPtr->uId;
879b3fb8555SGiannis Adamopoulos hdr.code = TTN_SHOW;
880b3fb8555SGiannis Adamopoulos SendMessageW (toolPtr->hwnd, WM_NOTIFY, toolPtr->uId, (LPARAM)&hdr);
881b3fb8555SGiannis Adamopoulos
882b3fb8555SGiannis Adamopoulos SetWindowPos (infoPtr->hwndSelf, HWND_TOPMOST, 0, 0, 0, 0,
883b3fb8555SGiannis Adamopoulos SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
884c2c66affSColin Finck
885c2c66affSColin Finck /* repaint the tooltip */
886c2c66affSColin Finck InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
887c2c66affSColin Finck UpdateWindow(infoPtr->hwndSelf);
888c2c66affSColin Finck
889c2c66affSColin Finck if (!track_activate)
890c2c66affSColin Finck {
891c2c66affSColin Finck SetTimer (infoPtr->hwndSelf, ID_TIMERPOP, infoPtr->nAutoPopTime, 0);
892edd99e8cSAmine Khaldi TRACE("timer 2 started\n");
893c2c66affSColin Finck SetTimer (infoPtr->hwndSelf, ID_TIMERLEAVE, infoPtr->nReshowTime, 0);
894edd99e8cSAmine Khaldi TRACE("timer 3 started\n");
895c2c66affSColin Finck }
896c2c66affSColin Finck }
897c2c66affSColin Finck
898c2c66affSColin Finck
899c2c66affSColin Finck static void
TOOLTIPS_Hide(TOOLTIPS_INFO * infoPtr)900c2c66affSColin Finck TOOLTIPS_Hide (TOOLTIPS_INFO *infoPtr)
901c2c66affSColin Finck {
902c2c66affSColin Finck TTTOOL_INFO *toolPtr;
903c2c66affSColin Finck NMHDR hdr;
904c2c66affSColin Finck
905edd99e8cSAmine Khaldi TRACE("Hide tooltip %d, %p.\n", infoPtr->nCurrentTool, infoPtr->hwndSelf);
906c2c66affSColin Finck
907c2c66affSColin Finck if (infoPtr->nCurrentTool == -1)
908c2c66affSColin Finck return;
909c2c66affSColin Finck
910c2c66affSColin Finck toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
911c2c66affSColin Finck KillTimer (infoPtr->hwndSelf, ID_TIMERPOP);
912c2c66affSColin Finck
913c2c66affSColin Finck hdr.hwndFrom = infoPtr->hwndSelf;
914c2c66affSColin Finck hdr.idFrom = toolPtr->uId;
915c2c66affSColin Finck hdr.code = TTN_POP;
916c2c66affSColin Finck SendMessageW (toolPtr->hwnd, WM_NOTIFY, toolPtr->uId, (LPARAM)&hdr);
917c2c66affSColin Finck
918c2c66affSColin Finck infoPtr->nCurrentTool = -1;
919c2c66affSColin Finck
920c2c66affSColin Finck SetWindowPos (infoPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
921c2c66affSColin Finck SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
922c2c66affSColin Finck }
923c2c66affSColin Finck
924c2c66affSColin Finck
925c2c66affSColin Finck static void
TOOLTIPS_TrackShow(TOOLTIPS_INFO * infoPtr)926c2c66affSColin Finck TOOLTIPS_TrackShow (TOOLTIPS_INFO *infoPtr)
927c2c66affSColin Finck {
928c2c66affSColin Finck TOOLTIPS_Show(infoPtr, TRUE);
929c2c66affSColin Finck }
930c2c66affSColin Finck
931c2c66affSColin Finck
932c2c66affSColin Finck static void
TOOLTIPS_TrackHide(const TOOLTIPS_INFO * infoPtr)933c2c66affSColin Finck TOOLTIPS_TrackHide (const TOOLTIPS_INFO *infoPtr)
934c2c66affSColin Finck {
935c2c66affSColin Finck TTTOOL_INFO *toolPtr;
936c2c66affSColin Finck NMHDR hdr;
937c2c66affSColin Finck
938c2c66affSColin Finck TRACE("hide tracking tooltip %d\n", infoPtr->nTrackTool);
939c2c66affSColin Finck
940c2c66affSColin Finck if (infoPtr->nTrackTool == -1)
941c2c66affSColin Finck return;
942c2c66affSColin Finck
943c2c66affSColin Finck toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
944c2c66affSColin Finck
945c2c66affSColin Finck hdr.hwndFrom = infoPtr->hwndSelf;
946c2c66affSColin Finck hdr.idFrom = toolPtr->uId;
947c2c66affSColin Finck hdr.code = TTN_POP;
948c2c66affSColin Finck SendMessageW (toolPtr->hwnd, WM_NOTIFY, toolPtr->uId, (LPARAM)&hdr);
949c2c66affSColin Finck
950c2c66affSColin Finck SetWindowPos (infoPtr->hwndSelf, HWND_TOP, 0, 0, 0, 0,
951c2c66affSColin Finck SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
952c2c66affSColin Finck }
953c2c66affSColin Finck
954c2c66affSColin Finck /* Structure layout is the same for TTTOOLINFOW and TTTOOLINFOA,
955c2c66affSColin Finck this helper is used in both cases. */
956c2c66affSColin Finck static INT
TOOLTIPS_GetToolFromInfoT(const TOOLTIPS_INFO * infoPtr,const TTTOOLINFOW * lpToolInfo)957c2c66affSColin Finck TOOLTIPS_GetToolFromInfoT (const TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
958c2c66affSColin Finck {
959c2c66affSColin Finck TTTOOL_INFO *toolPtr;
960c2c66affSColin Finck UINT nTool;
961c2c66affSColin Finck
962c2c66affSColin Finck for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
963c2c66affSColin Finck toolPtr = &infoPtr->tools[nTool];
964c2c66affSColin Finck
965c2c66affSColin Finck if (!(toolPtr->uFlags & TTF_IDISHWND) &&
966c2c66affSColin Finck (lpToolInfo->hwnd == toolPtr->hwnd) &&
967c2c66affSColin Finck (lpToolInfo->uId == toolPtr->uId))
968c2c66affSColin Finck return nTool;
969c2c66affSColin Finck }
970c2c66affSColin Finck
971c2c66affSColin Finck for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
972c2c66affSColin Finck toolPtr = &infoPtr->tools[nTool];
973c2c66affSColin Finck
974c2c66affSColin Finck if ((toolPtr->uFlags & TTF_IDISHWND) &&
975c2c66affSColin Finck (lpToolInfo->uId == toolPtr->uId))
976c2c66affSColin Finck return nTool;
977c2c66affSColin Finck }
978c2c66affSColin Finck
979c2c66affSColin Finck return -1;
980c2c66affSColin Finck }
981c2c66affSColin Finck
982c2c66affSColin Finck
983c2c66affSColin Finck static INT
TOOLTIPS_GetToolFromPoint(const TOOLTIPS_INFO * infoPtr,HWND hwnd,const POINT * lpPt)984c2c66affSColin Finck TOOLTIPS_GetToolFromPoint (const TOOLTIPS_INFO *infoPtr, HWND hwnd, const POINT *lpPt)
985c2c66affSColin Finck {
986c2c66affSColin Finck TTTOOL_INFO *toolPtr;
987c2c66affSColin Finck UINT nTool;
988c2c66affSColin Finck
989c2c66affSColin Finck for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
990c2c66affSColin Finck toolPtr = &infoPtr->tools[nTool];
991c2c66affSColin Finck
992c2c66affSColin Finck if (!(toolPtr->uFlags & TTF_IDISHWND)) {
993c2c66affSColin Finck if (hwnd != toolPtr->hwnd)
994c2c66affSColin Finck continue;
995c2c66affSColin Finck if (!PtInRect (&toolPtr->rect, *lpPt))
996c2c66affSColin Finck continue;
997c2c66affSColin Finck return nTool;
998c2c66affSColin Finck }
999c2c66affSColin Finck }
1000c2c66affSColin Finck
1001c2c66affSColin Finck for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
1002c2c66affSColin Finck toolPtr = &infoPtr->tools[nTool];
1003c2c66affSColin Finck
1004c2c66affSColin Finck if (toolPtr->uFlags & TTF_IDISHWND) {
1005c2c66affSColin Finck if ((HWND)toolPtr->uId == hwnd)
1006c2c66affSColin Finck return nTool;
1007c2c66affSColin Finck }
1008c2c66affSColin Finck }
1009c2c66affSColin Finck
1010c2c66affSColin Finck return -1;
1011c2c66affSColin Finck }
1012c2c66affSColin Finck
1013c2c66affSColin Finck static inline void
TOOLTIPS_CopyInfoT(const TOOLTIPS_INFO * infoPtr,INT index,TTTOOLINFOW * ti,BOOL isW)1014edd99e8cSAmine Khaldi TOOLTIPS_CopyInfoT (const TOOLTIPS_INFO *infoPtr, INT index, TTTOOLINFOW *ti, BOOL isW)
1015c2c66affSColin Finck {
1016edd99e8cSAmine Khaldi const TTTOOL_INFO *toolPtr = &infoPtr->tools[index];
1017edd99e8cSAmine Khaldi
1018edd99e8cSAmine Khaldi ti->uFlags = toolPtr->uFlags;
1019edd99e8cSAmine Khaldi ti->hwnd = toolPtr->hwnd;
1020edd99e8cSAmine Khaldi ti->uId = toolPtr->uId;
1021edd99e8cSAmine Khaldi ti->rect = toolPtr->rect;
1022edd99e8cSAmine Khaldi ti->hinst = toolPtr->hinst;
1023edd99e8cSAmine Khaldi
1024c2c66affSColin Finck if (ti->lpszText) {
1025c2c66affSColin Finck if (toolPtr->lpszText == NULL ||
1026c2c66affSColin Finck IS_INTRESOURCE(toolPtr->lpszText) ||
1027c2c66affSColin Finck toolPtr->lpszText == LPSTR_TEXTCALLBACKW)
1028c2c66affSColin Finck ti->lpszText = toolPtr->lpszText;
1029c2c66affSColin Finck else if (isW)
1030*0707475fSJustin Miller lstrcpyW (ti->lpszText, toolPtr->lpszText);
1031c2c66affSColin Finck else
1032c2c66affSColin Finck /* ANSI version, the buffer is maximum 80 bytes without null. */
1033c2c66affSColin Finck WideCharToMultiByte(CP_ACP, 0, toolPtr->lpszText, -1,
1034c2c66affSColin Finck (LPSTR)ti->lpszText, MAX_TEXT_SIZE_A, NULL, NULL);
1035c2c66affSColin Finck }
1036edd99e8cSAmine Khaldi
1037edd99e8cSAmine Khaldi if (ti->cbSize >= TTTOOLINFOW_V2_SIZE)
1038edd99e8cSAmine Khaldi ti->lParam = toolPtr->lParam;
1039edd99e8cSAmine Khaldi
1040edd99e8cSAmine Khaldi /* lpReserved is intentionally not set. */
1041c2c66affSColin Finck }
1042c2c66affSColin Finck
1043c2c66affSColin Finck static BOOL
TOOLTIPS_IsWindowActive(HWND hwnd)1044c2c66affSColin Finck TOOLTIPS_IsWindowActive (HWND hwnd)
1045c2c66affSColin Finck {
1046c2c66affSColin Finck HWND hwndActive = GetActiveWindow ();
1047c2c66affSColin Finck if (!hwndActive)
1048c2c66affSColin Finck return FALSE;
1049c2c66affSColin Finck if (hwndActive == hwnd)
1050c2c66affSColin Finck return TRUE;
1051c2c66affSColin Finck return IsChild (hwndActive, hwnd);
1052c2c66affSColin Finck }
1053c2c66affSColin Finck
1054c2c66affSColin Finck
1055c2c66affSColin Finck static INT
TOOLTIPS_CheckTool(const TOOLTIPS_INFO * infoPtr,BOOL bShowTest)1056c2c66affSColin Finck TOOLTIPS_CheckTool (const TOOLTIPS_INFO *infoPtr, BOOL bShowTest)
1057c2c66affSColin Finck {
1058c2c66affSColin Finck POINT pt;
1059c2c66affSColin Finck HWND hwndTool;
1060c2c66affSColin Finck INT nTool;
1061c2c66affSColin Finck
1062c2c66affSColin Finck GetCursorPos (&pt);
1063c2c66affSColin Finck hwndTool = (HWND)SendMessageW (infoPtr->hwndSelf, TTM_WINDOWFROMPOINT, 0, (LPARAM)&pt);
1064c2c66affSColin Finck if (hwndTool == 0)
1065c2c66affSColin Finck return -1;
1066c2c66affSColin Finck
1067c2c66affSColin Finck ScreenToClient (hwndTool, &pt);
1068c2c66affSColin Finck nTool = TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
1069c2c66affSColin Finck if (nTool == -1)
1070c2c66affSColin Finck return -1;
1071c2c66affSColin Finck
1072c2c66affSColin Finck if (!(GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TTS_ALWAYSTIP) && bShowTest)
1073c2c66affSColin Finck {
1074c2c66affSColin Finck TTTOOL_INFO *ti = &infoPtr->tools[nTool];
1075c2c66affSColin Finck HWND hwnd = (ti->uFlags & TTF_IDISHWND) ? (HWND)ti->uId : ti->hwnd;
1076c2c66affSColin Finck
1077c2c66affSColin Finck if (!TOOLTIPS_IsWindowActive(hwnd))
1078c2c66affSColin Finck {
1079c2c66affSColin Finck TRACE("not active: hwnd %p, parent %p, active %p\n",
1080c2c66affSColin Finck hwnd, GetParent(hwnd), GetActiveWindow());
1081c2c66affSColin Finck return -1;
1082c2c66affSColin Finck }
1083c2c66affSColin Finck }
1084c2c66affSColin Finck
1085c2c66affSColin Finck TRACE("tool %d\n", nTool);
1086c2c66affSColin Finck
1087c2c66affSColin Finck return nTool;
1088c2c66affSColin Finck }
1089c2c66affSColin Finck
1090c2c66affSColin Finck
1091c2c66affSColin Finck static LRESULT
TOOLTIPS_Activate(TOOLTIPS_INFO * infoPtr,BOOL activate)1092c2c66affSColin Finck TOOLTIPS_Activate (TOOLTIPS_INFO *infoPtr, BOOL activate)
1093c2c66affSColin Finck {
1094c2c66affSColin Finck infoPtr->bActive = activate;
1095c2c66affSColin Finck
1096edd99e8cSAmine Khaldi TRACE("activate %d\n", activate);
1097c2c66affSColin Finck
1098c2c66affSColin Finck if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1))
1099c2c66affSColin Finck TOOLTIPS_Hide (infoPtr);
1100c2c66affSColin Finck
1101c2c66affSColin Finck return 0;
1102c2c66affSColin Finck }
1103c2c66affSColin Finck
1104c2c66affSColin Finck
1105c2c66affSColin Finck static LRESULT
TOOLTIPS_AddToolT(TOOLTIPS_INFO * infoPtr,const TTTOOLINFOW * ti,BOOL isW)1106c2c66affSColin Finck TOOLTIPS_AddToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
1107c2c66affSColin Finck {
1108c2c66affSColin Finck TTTOOL_INFO *toolPtr;
1109c2c66affSColin Finck INT nResult;
1110c2c66affSColin Finck
1111c2c66affSColin Finck if (!ti) return FALSE;
1112c2c66affSColin Finck
1113edd99e8cSAmine Khaldi TRACE("add tool (%p) %p %ld%s\n", infoPtr->hwndSelf, ti->hwnd, ti->uId,
1114c2c66affSColin Finck (ti->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
1115c2c66affSColin Finck
1116b3fb8555SGiannis Adamopoulos if (ti->cbSize > TTTOOLINFOW_V3_SIZE && isW)
1117c2c66affSColin Finck return FALSE;
1118c2c66affSColin Finck
1119c2c66affSColin Finck if (infoPtr->uNumTools == 0) {
1120c2c66affSColin Finck infoPtr->tools = Alloc (sizeof(TTTOOL_INFO));
1121c2c66affSColin Finck toolPtr = infoPtr->tools;
1122c2c66affSColin Finck }
1123c2c66affSColin Finck else {
1124c2c66affSColin Finck TTTOOL_INFO *oldTools = infoPtr->tools;
1125c2c66affSColin Finck infoPtr->tools =
1126c2c66affSColin Finck Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools + 1));
1127c2c66affSColin Finck memcpy (infoPtr->tools, oldTools,
1128c2c66affSColin Finck infoPtr->uNumTools * sizeof(TTTOOL_INFO));
1129c2c66affSColin Finck Free (oldTools);
1130c2c66affSColin Finck toolPtr = &infoPtr->tools[infoPtr->uNumTools];
1131c2c66affSColin Finck }
1132c2c66affSColin Finck
1133c2c66affSColin Finck infoPtr->uNumTools++;
1134c2c66affSColin Finck
1135c2c66affSColin Finck /* copy tool data */
1136c2c66affSColin Finck toolPtr->uFlags = ti->uFlags;
1137c2c66affSColin Finck toolPtr->uInternalFlags = (ti->uFlags & (TTF_SUBCLASS | TTF_IDISHWND));
1138c2c66affSColin Finck toolPtr->hwnd = ti->hwnd;
1139c2c66affSColin Finck toolPtr->uId = ti->uId;
1140c2c66affSColin Finck toolPtr->rect = ti->rect;
1141c2c66affSColin Finck toolPtr->hinst = ti->hinst;
1142c2c66affSColin Finck
1143c2c66affSColin Finck if (ti->cbSize >= TTTOOLINFOW_V1_SIZE) {
1144c2c66affSColin Finck if (IS_INTRESOURCE(ti->lpszText)) {
1145c2c66affSColin Finck TRACE("add string id %x\n", LOWORD(ti->lpszText));
1146c2c66affSColin Finck toolPtr->lpszText = ti->lpszText;
1147c2c66affSColin Finck }
1148c2c66affSColin Finck else if (ti->lpszText) {
1149*0707475fSJustin Miller if (ti->lpszText == LPSTR_TEXTCALLBACKW) {
1150edd99e8cSAmine Khaldi TRACE("add CALLBACK\n");
1151c2c66affSColin Finck toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1152c2c66affSColin Finck }
1153c2c66affSColin Finck else if (isW) {
1154c2c66affSColin Finck INT len = lstrlenW (ti->lpszText);
1155edd99e8cSAmine Khaldi TRACE("add text %s\n", debugstr_w(ti->lpszText));
1156c2c66affSColin Finck toolPtr->lpszText = Alloc ((len + 1)*sizeof(WCHAR));
1157*0707475fSJustin Miller lstrcpyW (toolPtr->lpszText, ti->lpszText);
1158c2c66affSColin Finck }
1159c2c66affSColin Finck else {
1160c2c66affSColin Finck INT len = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ti->lpszText, -1, NULL, 0);
1161edd99e8cSAmine Khaldi TRACE("add text \"%s\"\n", debugstr_a((char *)ti->lpszText));
1162c2c66affSColin Finck toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
1163c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, (LPSTR)ti->lpszText, -1, toolPtr->lpszText, len);
1164c2c66affSColin Finck }
1165c2c66affSColin Finck }
1166c2c66affSColin Finck }
1167c2c66affSColin Finck
1168c2c66affSColin Finck if (ti->cbSize >= TTTOOLINFOW_V2_SIZE)
1169c2c66affSColin Finck toolPtr->lParam = ti->lParam;
1170c2c66affSColin Finck
1171c2c66affSColin Finck /* install subclassing hook */
1172c2c66affSColin Finck if (toolPtr->uInternalFlags & TTF_SUBCLASS) {
1173c2c66affSColin Finck if (toolPtr->uInternalFlags & TTF_IDISHWND) {
1174c2c66affSColin Finck SetWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1,
1175c2c66affSColin Finck (DWORD_PTR)infoPtr->hwndSelf);
1176c2c66affSColin Finck }
1177c2c66affSColin Finck else {
1178c2c66affSColin Finck SetWindowSubclass(toolPtr->hwnd, TOOLTIPS_SubclassProc, 1,
1179c2c66affSColin Finck (DWORD_PTR)infoPtr->hwndSelf);
1180c2c66affSColin Finck }
1181edd99e8cSAmine Khaldi TRACE("subclassing installed\n");
1182c2c66affSColin Finck }
1183c2c66affSColin Finck
1184c2c66affSColin Finck nResult = SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
1185c2c66affSColin Finck (WPARAM)infoPtr->hwndSelf, NF_QUERY);
1186c2c66affSColin Finck if (nResult == NFR_ANSI) {
1187c2c66affSColin Finck toolPtr->bNotifyUnicode = FALSE;
1188c2c66affSColin Finck TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
1189c2c66affSColin Finck } else if (nResult == NFR_UNICODE) {
1190c2c66affSColin Finck toolPtr->bNotifyUnicode = TRUE;
1191c2c66affSColin Finck TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
1192c2c66affSColin Finck } else {
1193edd99e8cSAmine Khaldi TRACE (" -- WM_NOTIFYFORMAT returns: %d\n", nResult);
1194c2c66affSColin Finck }
1195c2c66affSColin Finck
1196c2c66affSColin Finck return TRUE;
1197c2c66affSColin Finck }
1198c2c66affSColin Finck
TOOLTIPS_ResetSubclass(const TTTOOL_INFO * toolPtr)1199edd99e8cSAmine Khaldi static void TOOLTIPS_ResetSubclass (const TTTOOL_INFO *toolPtr)
1200edd99e8cSAmine Khaldi {
1201edd99e8cSAmine Khaldi /* Reset subclassing data. */
1202edd99e8cSAmine Khaldi if (toolPtr->uInternalFlags & TTF_SUBCLASS)
1203edd99e8cSAmine Khaldi SetWindowSubclass(toolPtr->uInternalFlags & TTF_IDISHWND ? (HWND)toolPtr->uId : toolPtr->hwnd,
1204edd99e8cSAmine Khaldi TOOLTIPS_SubclassProc, 1, 0);
1205edd99e8cSAmine Khaldi }
1206c2c66affSColin Finck
TOOLTIPS_FreeToolText(TTTOOL_INFO * toolPtr)1207*0707475fSJustin Miller static void TOOLTIPS_FreeToolText(TTTOOL_INFO *toolPtr)
1208*0707475fSJustin Miller {
1209*0707475fSJustin Miller if (toolPtr->lpszText)
1210*0707475fSJustin Miller {
1211*0707475fSJustin Miller if (!IS_INTRESOURCE(toolPtr->lpszText) && toolPtr->lpszText != LPSTR_TEXTCALLBACKW)
1212*0707475fSJustin Miller Free(toolPtr->lpszText);
1213*0707475fSJustin Miller toolPtr->lpszText = NULL;
1214*0707475fSJustin Miller }
1215*0707475fSJustin Miller }
1216*0707475fSJustin Miller
TOOLTIPS_SetToolText(TTTOOL_INFO * toolPtr,WCHAR * text,BOOL is_unicode)1217*0707475fSJustin Miller static void TOOLTIPS_SetToolText(TTTOOL_INFO *toolPtr, WCHAR *text, BOOL is_unicode)
1218*0707475fSJustin Miller {
1219*0707475fSJustin Miller int len;
1220*0707475fSJustin Miller
1221*0707475fSJustin Miller TOOLTIPS_FreeToolText (toolPtr);
1222*0707475fSJustin Miller
1223*0707475fSJustin Miller if (IS_INTRESOURCE(text))
1224*0707475fSJustin Miller toolPtr->lpszText = text;
1225*0707475fSJustin Miller else if (text == LPSTR_TEXTCALLBACKW)
1226*0707475fSJustin Miller toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1227*0707475fSJustin Miller else if (text)
1228*0707475fSJustin Miller {
1229*0707475fSJustin Miller if (is_unicode)
1230*0707475fSJustin Miller {
1231*0707475fSJustin Miller len = lstrlenW(text);
1232*0707475fSJustin Miller toolPtr->lpszText = Alloc ((len + 1) * sizeof(WCHAR));
1233*0707475fSJustin Miller if (toolPtr->lpszText)
1234*0707475fSJustin Miller lstrcpyW (toolPtr->lpszText, text);
1235*0707475fSJustin Miller }
1236*0707475fSJustin Miller else
1237*0707475fSJustin Miller {
1238*0707475fSJustin Miller len = MultiByteToWideChar(CP_ACP, 0, (char *)text, -1, NULL, 0);
1239*0707475fSJustin Miller toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
1240*0707475fSJustin Miller if (toolPtr->lpszText)
1241*0707475fSJustin Miller MultiByteToWideChar(CP_ACP, 0, (char *)text, -1, toolPtr->lpszText, len);
1242*0707475fSJustin Miller }
1243*0707475fSJustin Miller }
1244*0707475fSJustin Miller }
1245*0707475fSJustin Miller
1246c2c66affSColin Finck static LRESULT
TOOLTIPS_DelToolT(TOOLTIPS_INFO * infoPtr,const TTTOOLINFOW * ti,BOOL isW)1247c2c66affSColin Finck TOOLTIPS_DelToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
1248c2c66affSColin Finck {
1249c2c66affSColin Finck TTTOOL_INFO *toolPtr;
1250c2c66affSColin Finck INT nTool;
1251c2c66affSColin Finck
1252c2c66affSColin Finck if (!ti) return 0;
1253c2c66affSColin Finck if (isW && ti->cbSize > TTTOOLINFOW_V2_SIZE &&
1254c2c66affSColin Finck ti->cbSize != TTTOOLINFOW_V3_SIZE)
1255c2c66affSColin Finck return 0;
1256c2c66affSColin Finck if (infoPtr->uNumTools == 0)
1257c2c66affSColin Finck return 0;
1258c2c66affSColin Finck
1259c2c66affSColin Finck nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
1260c2c66affSColin Finck
1261c2c66affSColin Finck TRACE("tool %d\n", nTool);
1262c2c66affSColin Finck
1263c2c66affSColin Finck if (nTool == -1)
1264c2c66affSColin Finck return 0;
1265c2c66affSColin Finck
1266c2c66affSColin Finck /* make sure the tooltip has disappeared before deleting it */
1267c2c66affSColin Finck TOOLTIPS_Hide(infoPtr);
1268c2c66affSColin Finck
1269c2c66affSColin Finck toolPtr = &infoPtr->tools[nTool];
1270*0707475fSJustin Miller TOOLTIPS_FreeToolText (toolPtr);
1271edd99e8cSAmine Khaldi TOOLTIPS_ResetSubclass (toolPtr);
1272c2c66affSColin Finck
1273c2c66affSColin Finck /* delete tool from tool list */
1274c2c66affSColin Finck if (infoPtr->uNumTools == 1) {
1275c2c66affSColin Finck Free (infoPtr->tools);
1276c2c66affSColin Finck infoPtr->tools = NULL;
1277c2c66affSColin Finck }
1278c2c66affSColin Finck else {
1279c2c66affSColin Finck TTTOOL_INFO *oldTools = infoPtr->tools;
1280c2c66affSColin Finck infoPtr->tools =
1281c2c66affSColin Finck Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
1282c2c66affSColin Finck
1283c2c66affSColin Finck if (nTool > 0)
1284c2c66affSColin Finck memcpy (&infoPtr->tools[0], &oldTools[0],
1285c2c66affSColin Finck nTool * sizeof(TTTOOL_INFO));
1286c2c66affSColin Finck
1287c2c66affSColin Finck if (nTool < infoPtr->uNumTools - 1)
1288c2c66affSColin Finck memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
1289c2c66affSColin Finck (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
1290c2c66affSColin Finck
1291c2c66affSColin Finck Free (oldTools);
1292c2c66affSColin Finck }
1293c2c66affSColin Finck
1294c2c66affSColin Finck /* update any indices affected by delete */
1295c2c66affSColin Finck
1296c2c66affSColin Finck /* destroying tool that mouse was on on last relayed mouse move */
1297c2c66affSColin Finck if (infoPtr->nTool == nTool)
1298c2c66affSColin Finck /* -1 means no current tool (0 means first tool) */
1299c2c66affSColin Finck infoPtr->nTool = -1;
1300c2c66affSColin Finck else if (infoPtr->nTool > nTool)
1301c2c66affSColin Finck infoPtr->nTool--;
1302c2c66affSColin Finck
1303c2c66affSColin Finck if (infoPtr->nTrackTool == nTool)
1304c2c66affSColin Finck /* -1 means no current tool (0 means first tool) */
1305c2c66affSColin Finck infoPtr->nTrackTool = -1;
1306c2c66affSColin Finck else if (infoPtr->nTrackTool > nTool)
1307c2c66affSColin Finck infoPtr->nTrackTool--;
1308c2c66affSColin Finck
1309c2c66affSColin Finck if (infoPtr->nCurrentTool == nTool)
1310c2c66affSColin Finck /* -1 means no current tool (0 means first tool) */
1311c2c66affSColin Finck infoPtr->nCurrentTool = -1;
1312c2c66affSColin Finck else if (infoPtr->nCurrentTool > nTool)
1313c2c66affSColin Finck infoPtr->nCurrentTool--;
1314c2c66affSColin Finck
1315c2c66affSColin Finck infoPtr->uNumTools--;
1316c2c66affSColin Finck
1317c2c66affSColin Finck return 0;
1318c2c66affSColin Finck }
1319c2c66affSColin Finck
1320c2c66affSColin Finck static LRESULT
TOOLTIPS_EnumToolsT(const TOOLTIPS_INFO * infoPtr,UINT uIndex,TTTOOLINFOW * ti,BOOL isW)1321c2c66affSColin Finck TOOLTIPS_EnumToolsT (const TOOLTIPS_INFO *infoPtr, UINT uIndex, TTTOOLINFOW *ti,
1322c2c66affSColin Finck BOOL isW)
1323c2c66affSColin Finck {
1324edd99e8cSAmine Khaldi if (!ti || ti->cbSize < TTTOOLINFOW_V1_SIZE)
1325c2c66affSColin Finck return FALSE;
1326c2c66affSColin Finck if (uIndex >= infoPtr->uNumTools)
1327c2c66affSColin Finck return FALSE;
1328c2c66affSColin Finck
1329c2c66affSColin Finck TRACE("index=%u\n", uIndex);
1330c2c66affSColin Finck
1331edd99e8cSAmine Khaldi TOOLTIPS_CopyInfoT (infoPtr, uIndex, ti, isW);
1332c2c66affSColin Finck
1333c2c66affSColin Finck return TRUE;
1334c2c66affSColin Finck }
1335c2c66affSColin Finck
1336c2c66affSColin Finck static LRESULT
TOOLTIPS_GetBubbleSize(const TOOLTIPS_INFO * infoPtr,const TTTOOLINFOW * lpToolInfo)1337c2c66affSColin Finck TOOLTIPS_GetBubbleSize (const TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *lpToolInfo)
1338c2c66affSColin Finck {
1339c2c66affSColin Finck INT nTool;
1340c2c66affSColin Finck SIZE size;
1341c2c66affSColin Finck
1342c2c66affSColin Finck if (lpToolInfo == NULL)
1343c2c66affSColin Finck return FALSE;
1344c2c66affSColin Finck if (lpToolInfo->cbSize < TTTOOLINFOW_V1_SIZE)
1345c2c66affSColin Finck return FALSE;
1346c2c66affSColin Finck
1347c2c66affSColin Finck nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, lpToolInfo);
1348c2c66affSColin Finck if (nTool == -1) return 0;
1349c2c66affSColin Finck
1350c2c66affSColin Finck TRACE("tool %d\n", nTool);
1351c2c66affSColin Finck
1352c2c66affSColin Finck TOOLTIPS_CalcTipSize (infoPtr, &size);
1353c2c66affSColin Finck TRACE("size %d x %d\n", size.cx, size.cy);
1354c2c66affSColin Finck
1355c2c66affSColin Finck return MAKELRESULT(size.cx, size.cy);
1356c2c66affSColin Finck }
1357c2c66affSColin Finck
1358c2c66affSColin Finck static LRESULT
TOOLTIPS_GetCurrentToolT(const TOOLTIPS_INFO * infoPtr,TTTOOLINFOW * ti,BOOL isW)1359c2c66affSColin Finck TOOLTIPS_GetCurrentToolT (const TOOLTIPS_INFO *infoPtr, TTTOOLINFOW *ti, BOOL isW)
1360c2c66affSColin Finck {
1361c2c66affSColin Finck if (ti) {
1362c2c66affSColin Finck if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
1363c2c66affSColin Finck return FALSE;
1364c2c66affSColin Finck
1365edd99e8cSAmine Khaldi if (infoPtr->nCurrentTool != -1)
1366edd99e8cSAmine Khaldi TOOLTIPS_CopyInfoT (infoPtr, infoPtr->nCurrentTool, ti, isW);
1367c2c66affSColin Finck }
1368edd99e8cSAmine Khaldi
1369edd99e8cSAmine Khaldi return infoPtr->nCurrentTool != -1;
1370c2c66affSColin Finck }
1371c2c66affSColin Finck
1372c2c66affSColin Finck
1373c2c66affSColin Finck static LRESULT
TOOLTIPS_GetDelayTime(const TOOLTIPS_INFO * infoPtr,DWORD duration)1374c2c66affSColin Finck TOOLTIPS_GetDelayTime (const TOOLTIPS_INFO *infoPtr, DWORD duration)
1375c2c66affSColin Finck {
1376c2c66affSColin Finck switch (duration) {
1377c2c66affSColin Finck case TTDT_RESHOW:
1378c2c66affSColin Finck return infoPtr->nReshowTime;
1379c2c66affSColin Finck
1380c2c66affSColin Finck case TTDT_AUTOPOP:
1381c2c66affSColin Finck return infoPtr->nAutoPopTime;
1382c2c66affSColin Finck
1383c2c66affSColin Finck case TTDT_INITIAL:
1384c2c66affSColin Finck case TTDT_AUTOMATIC: /* Apparently TTDT_AUTOMATIC returns TTDT_INITIAL */
1385c2c66affSColin Finck return infoPtr->nInitialTime;
1386c2c66affSColin Finck
1387c2c66affSColin Finck default:
1388c2c66affSColin Finck WARN("Invalid duration flag %x\n", duration);
1389c2c66affSColin Finck break;
1390c2c66affSColin Finck }
1391c2c66affSColin Finck
1392c2c66affSColin Finck return -1;
1393c2c66affSColin Finck }
1394c2c66affSColin Finck
1395c2c66affSColin Finck
1396c2c66affSColin Finck static LRESULT
TOOLTIPS_GetMargin(const TOOLTIPS_INFO * infoPtr,RECT * rect)1397c2c66affSColin Finck TOOLTIPS_GetMargin (const TOOLTIPS_INFO *infoPtr, RECT *rect)
1398c2c66affSColin Finck {
1399c2c66affSColin Finck if (rect)
1400c2c66affSColin Finck *rect = infoPtr->rcMargin;
1401c2c66affSColin Finck
1402c2c66affSColin Finck return 0;
1403c2c66affSColin Finck }
1404c2c66affSColin Finck
1405c2c66affSColin Finck
1406c2c66affSColin Finck static inline LRESULT
TOOLTIPS_GetMaxTipWidth(const TOOLTIPS_INFO * infoPtr)1407c2c66affSColin Finck TOOLTIPS_GetMaxTipWidth (const TOOLTIPS_INFO *infoPtr)
1408c2c66affSColin Finck {
1409c2c66affSColin Finck return infoPtr->nMaxTipWidth;
1410c2c66affSColin Finck }
1411c2c66affSColin Finck
1412c2c66affSColin Finck
1413c2c66affSColin Finck static LRESULT
TOOLTIPS_GetTextT(const TOOLTIPS_INFO * infoPtr,TTTOOLINFOW * ti,BOOL isW)1414c2c66affSColin Finck TOOLTIPS_GetTextT (const TOOLTIPS_INFO *infoPtr, TTTOOLINFOW *ti, BOOL isW)
1415c2c66affSColin Finck {
1416c2c66affSColin Finck INT nTool;
1417c2c66affSColin Finck
1418c2c66affSColin Finck if (!ti) return 0;
1419c2c66affSColin Finck if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
1420c2c66affSColin Finck return 0;
1421c2c66affSColin Finck
1422c2c66affSColin Finck nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
1423c2c66affSColin Finck if (nTool == -1) return 0;
1424c2c66affSColin Finck
1425c2c66affSColin Finck if (infoPtr->tools[nTool].lpszText == NULL)
1426c2c66affSColin Finck return 0;
1427c2c66affSColin Finck
1428c2c66affSColin Finck if (isW) {
1429c2c66affSColin Finck ti->lpszText[0] = '\0';
1430c2c66affSColin Finck TOOLTIPS_GetTipText(infoPtr, nTool, ti->lpszText);
1431c2c66affSColin Finck }
1432c2c66affSColin Finck else {
1433c2c66affSColin Finck WCHAR buffer[INFOTIPSIZE];
1434c2c66affSColin Finck
1435c2c66affSColin Finck /* NB this API is broken, there is no way for the app to determine
1436c2c66affSColin Finck what size buffer it requires nor a way to specify how long the
1437c2c66affSColin Finck one it supplies is. According to the test result, it's up to
1438c2c66affSColin Finck 80 bytes by the ANSI version. */
1439c2c66affSColin Finck
1440c2c66affSColin Finck buffer[0] = '\0';
1441c2c66affSColin Finck TOOLTIPS_GetTipText(infoPtr, nTool, buffer);
1442c2c66affSColin Finck WideCharToMultiByte(CP_ACP, 0, buffer, -1, (LPSTR)ti->lpszText,
1443c2c66affSColin Finck MAX_TEXT_SIZE_A, NULL, NULL);
1444c2c66affSColin Finck }
1445c2c66affSColin Finck
1446c2c66affSColin Finck return 0;
1447c2c66affSColin Finck }
1448c2c66affSColin Finck
1449c2c66affSColin Finck
1450c2c66affSColin Finck static inline LRESULT
TOOLTIPS_GetTipBkColor(const TOOLTIPS_INFO * infoPtr)1451c2c66affSColin Finck TOOLTIPS_GetTipBkColor (const TOOLTIPS_INFO *infoPtr)
1452c2c66affSColin Finck {
1453c2c66affSColin Finck return infoPtr->clrBk;
1454c2c66affSColin Finck }
1455c2c66affSColin Finck
1456c2c66affSColin Finck
1457c2c66affSColin Finck static inline LRESULT
TOOLTIPS_GetTipTextColor(const TOOLTIPS_INFO * infoPtr)1458c2c66affSColin Finck TOOLTIPS_GetTipTextColor (const TOOLTIPS_INFO *infoPtr)
1459c2c66affSColin Finck {
1460c2c66affSColin Finck return infoPtr->clrText;
1461c2c66affSColin Finck }
1462c2c66affSColin Finck
1463c2c66affSColin Finck
1464c2c66affSColin Finck static inline LRESULT
TOOLTIPS_GetToolCount(const TOOLTIPS_INFO * infoPtr)1465c2c66affSColin Finck TOOLTIPS_GetToolCount (const TOOLTIPS_INFO *infoPtr)
1466c2c66affSColin Finck {
1467c2c66affSColin Finck return infoPtr->uNumTools;
1468c2c66affSColin Finck }
1469c2c66affSColin Finck
1470c2c66affSColin Finck
1471c2c66affSColin Finck static LRESULT
TOOLTIPS_GetToolInfoT(const TOOLTIPS_INFO * infoPtr,TTTOOLINFOW * ti,BOOL isW)1472c2c66affSColin Finck TOOLTIPS_GetToolInfoT (const TOOLTIPS_INFO *infoPtr, TTTOOLINFOW *ti, BOOL isW)
1473c2c66affSColin Finck {
1474c2c66affSColin Finck INT nTool;
1475edd99e8cSAmine Khaldi HWND hwnd;
1476c2c66affSColin Finck
1477c2c66affSColin Finck if (!ti) return FALSE;
1478c2c66affSColin Finck if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
1479c2c66affSColin Finck return FALSE;
1480c2c66affSColin Finck if (infoPtr->uNumTools == 0)
1481c2c66affSColin Finck return FALSE;
1482c2c66affSColin Finck
1483c2c66affSColin Finck nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
1484c2c66affSColin Finck if (nTool == -1)
1485c2c66affSColin Finck return FALSE;
1486c2c66affSColin Finck
1487c2c66affSColin Finck TRACE("tool %d\n", nTool);
1488c2c66affSColin Finck
1489edd99e8cSAmine Khaldi hwnd = ti->hwnd;
1490edd99e8cSAmine Khaldi TOOLTIPS_CopyInfoT (infoPtr, nTool, ti, isW);
1491edd99e8cSAmine Khaldi ti->hwnd = hwnd;
1492c2c66affSColin Finck
1493c2c66affSColin Finck return TRUE;
1494c2c66affSColin Finck }
1495c2c66affSColin Finck
1496c2c66affSColin Finck
1497c2c66affSColin Finck static LRESULT
TOOLTIPS_HitTestT(const TOOLTIPS_INFO * infoPtr,LPTTHITTESTINFOW lptthit,BOOL isW)1498c2c66affSColin Finck TOOLTIPS_HitTestT (const TOOLTIPS_INFO *infoPtr, LPTTHITTESTINFOW lptthit,
1499c2c66affSColin Finck BOOL isW)
1500c2c66affSColin Finck {
1501c2c66affSColin Finck INT nTool;
1502c2c66affSColin Finck
1503c2c66affSColin Finck if (lptthit == 0)
1504c2c66affSColin Finck return FALSE;
1505c2c66affSColin Finck
1506c2c66affSColin Finck nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1507c2c66affSColin Finck if (nTool == -1)
1508c2c66affSColin Finck return FALSE;
1509c2c66affSColin Finck
1510edd99e8cSAmine Khaldi TRACE("tool %d\n", nTool);
1511c2c66affSColin Finck
1512c2c66affSColin Finck /* copy tool data */
1513edd99e8cSAmine Khaldi if (lptthit->ti.cbSize >= TTTOOLINFOW_V1_SIZE)
1514edd99e8cSAmine Khaldi TOOLTIPS_CopyInfoT (infoPtr, nTool, &lptthit->ti, isW);
1515c2c66affSColin Finck
1516c2c66affSColin Finck return TRUE;
1517c2c66affSColin Finck }
1518c2c66affSColin Finck
1519c2c66affSColin Finck
1520c2c66affSColin Finck static LRESULT
TOOLTIPS_NewToolRectT(TOOLTIPS_INFO * infoPtr,const TTTOOLINFOW * ti)1521c2c66affSColin Finck TOOLTIPS_NewToolRectT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti)
1522c2c66affSColin Finck {
1523c2c66affSColin Finck INT nTool;
1524c2c66affSColin Finck
1525c2c66affSColin Finck if (!ti) return 0;
1526c2c66affSColin Finck if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
1527c2c66affSColin Finck return FALSE;
1528c2c66affSColin Finck
1529c2c66affSColin Finck nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
1530c2c66affSColin Finck
1531c2c66affSColin Finck TRACE("nTool = %d, rect = %s\n", nTool, wine_dbgstr_rect(&ti->rect));
1532c2c66affSColin Finck
1533c2c66affSColin Finck if (nTool == -1) return 0;
1534c2c66affSColin Finck
1535c2c66affSColin Finck infoPtr->tools[nTool].rect = ti->rect;
1536c2c66affSColin Finck
1537c2c66affSColin Finck return 0;
1538c2c66affSColin Finck }
1539c2c66affSColin Finck
1540c2c66affSColin Finck
1541c2c66affSColin Finck static inline LRESULT
TOOLTIPS_Pop(TOOLTIPS_INFO * infoPtr)1542c2c66affSColin Finck TOOLTIPS_Pop (TOOLTIPS_INFO *infoPtr)
1543c2c66affSColin Finck {
1544c2c66affSColin Finck TOOLTIPS_Hide (infoPtr);
1545c2c66affSColin Finck
1546c2c66affSColin Finck return 0;
1547c2c66affSColin Finck }
1548c2c66affSColin Finck
1549c2c66affSColin Finck
1550c2c66affSColin Finck static LRESULT
TOOLTIPS_RelayEvent(TOOLTIPS_INFO * infoPtr,LPMSG lpMsg)1551c2c66affSColin Finck TOOLTIPS_RelayEvent (TOOLTIPS_INFO *infoPtr, LPMSG lpMsg)
1552c2c66affSColin Finck {
1553c2c66affSColin Finck POINT pt;
1554c2c66affSColin Finck INT nOldTool;
1555c2c66affSColin Finck
1556c2c66affSColin Finck if (!lpMsg) {
1557edd99e8cSAmine Khaldi ERR("lpMsg == NULL\n");
1558c2c66affSColin Finck return 0;
1559c2c66affSColin Finck }
1560c2c66affSColin Finck
1561c2c66affSColin Finck switch (lpMsg->message) {
1562c2c66affSColin Finck case WM_LBUTTONDOWN:
1563c2c66affSColin Finck case WM_LBUTTONUP:
1564c2c66affSColin Finck case WM_MBUTTONDOWN:
1565c2c66affSColin Finck case WM_MBUTTONUP:
1566c2c66affSColin Finck case WM_RBUTTONDOWN:
1567c2c66affSColin Finck case WM_RBUTTONUP:
1568c2c66affSColin Finck TOOLTIPS_Hide (infoPtr);
1569c2c66affSColin Finck break;
1570c2c66affSColin Finck
1571c2c66affSColin Finck case WM_MOUSEMOVE:
1572c2c66affSColin Finck pt.x = (short)LOWORD(lpMsg->lParam);
1573c2c66affSColin Finck pt.y = (short)HIWORD(lpMsg->lParam);
1574c2c66affSColin Finck nOldTool = infoPtr->nTool;
1575c2c66affSColin Finck infoPtr->nTool = TOOLTIPS_GetToolFromPoint(infoPtr, lpMsg->hwnd,
1576c2c66affSColin Finck &pt);
1577c2c66affSColin Finck TRACE("tool (%p) %d %d %d\n", infoPtr->hwndSelf, nOldTool,
1578c2c66affSColin Finck infoPtr->nTool, infoPtr->nCurrentTool);
1579c2c66affSColin Finck TRACE("WM_MOUSEMOVE (%p %s)\n", infoPtr->hwndSelf, wine_dbgstr_point(&pt));
1580c2c66affSColin Finck
1581c2c66affSColin Finck if (infoPtr->nTool != nOldTool) {
1582c2c66affSColin Finck if(infoPtr->nTool == -1) { /* Moved out of all tools */
1583c2c66affSColin Finck TOOLTIPS_Hide(infoPtr);
1584c2c66affSColin Finck KillTimer(infoPtr->hwndSelf, ID_TIMERLEAVE);
1585c2c66affSColin Finck } else if (nOldTool == -1) { /* Moved from outside */
1586c2c66affSColin Finck if(infoPtr->bActive) {
1587c2c66affSColin Finck SetTimer(infoPtr->hwndSelf, ID_TIMERSHOW, infoPtr->nInitialTime, 0);
1588edd99e8cSAmine Khaldi TRACE("timer 1 started\n");
1589c2c66affSColin Finck }
1590c2c66affSColin Finck } else { /* Moved from one to another */
1591c2c66affSColin Finck TOOLTIPS_Hide (infoPtr);
1592c2c66affSColin Finck KillTimer(infoPtr->hwndSelf, ID_TIMERLEAVE);
1593c2c66affSColin Finck if(infoPtr->bActive) {
1594c2c66affSColin Finck SetTimer (infoPtr->hwndSelf, ID_TIMERSHOW, infoPtr->nReshowTime, 0);
1595edd99e8cSAmine Khaldi TRACE("timer 1 started\n");
1596c2c66affSColin Finck }
1597c2c66affSColin Finck }
1598c2c66affSColin Finck } else if(infoPtr->nCurrentTool != -1) { /* restart autopop */
1599c2c66affSColin Finck KillTimer(infoPtr->hwndSelf, ID_TIMERPOP);
1600c2c66affSColin Finck SetTimer(infoPtr->hwndSelf, ID_TIMERPOP, infoPtr->nAutoPopTime, 0);
1601c2c66affSColin Finck TRACE("timer 2 restarted\n");
1602c2c66affSColin Finck } else if(infoPtr->nTool != -1 && infoPtr->bActive) {
1603c2c66affSColin Finck /* previous show attempt didn't result in tooltip so try again */
1604c2c66affSColin Finck SetTimer(infoPtr->hwndSelf, ID_TIMERSHOW, infoPtr->nInitialTime, 0);
1605edd99e8cSAmine Khaldi TRACE("timer 1 started\n");
1606c2c66affSColin Finck }
1607c2c66affSColin Finck break;
1608c2c66affSColin Finck }
1609c2c66affSColin Finck
1610c2c66affSColin Finck return 0;
1611c2c66affSColin Finck }
1612c2c66affSColin Finck
1613c2c66affSColin Finck
1614c2c66affSColin Finck static LRESULT
TOOLTIPS_SetDelayTime(TOOLTIPS_INFO * infoPtr,DWORD duration,INT nTime)1615c2c66affSColin Finck TOOLTIPS_SetDelayTime (TOOLTIPS_INFO *infoPtr, DWORD duration, INT nTime)
1616c2c66affSColin Finck {
1617c2c66affSColin Finck switch (duration) {
1618c2c66affSColin Finck case TTDT_AUTOMATIC:
1619c2c66affSColin Finck if (nTime <= 0)
1620c2c66affSColin Finck nTime = GetDoubleClickTime();
1621c2c66affSColin Finck infoPtr->nReshowTime = nTime / 5;
1622c2c66affSColin Finck infoPtr->nAutoPopTime = nTime * 10;
1623c2c66affSColin Finck infoPtr->nInitialTime = nTime;
1624c2c66affSColin Finck break;
1625c2c66affSColin Finck
1626c2c66affSColin Finck case TTDT_RESHOW:
1627c2c66affSColin Finck if(nTime < 0)
1628c2c66affSColin Finck nTime = GetDoubleClickTime() / 5;
1629c2c66affSColin Finck infoPtr->nReshowTime = nTime;
1630c2c66affSColin Finck break;
1631c2c66affSColin Finck
1632c2c66affSColin Finck case TTDT_AUTOPOP:
1633c2c66affSColin Finck if(nTime < 0)
1634c2c66affSColin Finck nTime = GetDoubleClickTime() * 10;
1635c2c66affSColin Finck infoPtr->nAutoPopTime = nTime;
1636c2c66affSColin Finck break;
1637c2c66affSColin Finck
1638c2c66affSColin Finck case TTDT_INITIAL:
1639c2c66affSColin Finck if(nTime < 0)
1640c2c66affSColin Finck nTime = GetDoubleClickTime();
1641c2c66affSColin Finck infoPtr->nInitialTime = nTime;
1642c2c66affSColin Finck break;
1643c2c66affSColin Finck
1644c2c66affSColin Finck default:
1645c2c66affSColin Finck WARN("Invalid duration flag %x\n", duration);
1646c2c66affSColin Finck break;
1647c2c66affSColin Finck }
1648c2c66affSColin Finck
1649c2c66affSColin Finck return 0;
1650c2c66affSColin Finck }
1651c2c66affSColin Finck
1652c2c66affSColin Finck
1653c2c66affSColin Finck static LRESULT
TOOLTIPS_SetMargin(TOOLTIPS_INFO * infoPtr,const RECT * rect)1654c2c66affSColin Finck TOOLTIPS_SetMargin (TOOLTIPS_INFO *infoPtr, const RECT *rect)
1655c2c66affSColin Finck {
1656c2c66affSColin Finck if (rect)
1657c2c66affSColin Finck infoPtr->rcMargin = *rect;
1658c2c66affSColin Finck
1659c2c66affSColin Finck return 0;
1660c2c66affSColin Finck }
1661c2c66affSColin Finck
1662c2c66affSColin Finck
1663c2c66affSColin Finck static inline LRESULT
TOOLTIPS_SetMaxTipWidth(TOOLTIPS_INFO * infoPtr,INT MaxWidth)1664c2c66affSColin Finck TOOLTIPS_SetMaxTipWidth (TOOLTIPS_INFO *infoPtr, INT MaxWidth)
1665c2c66affSColin Finck {
1666c2c66affSColin Finck INT nTemp = infoPtr->nMaxTipWidth;
1667c2c66affSColin Finck
1668c2c66affSColin Finck infoPtr->nMaxTipWidth = MaxWidth;
1669c2c66affSColin Finck
1670c2c66affSColin Finck return nTemp;
1671c2c66affSColin Finck }
1672c2c66affSColin Finck
1673c2c66affSColin Finck
1674c2c66affSColin Finck static inline LRESULT
TOOLTIPS_SetTipBkColor(TOOLTIPS_INFO * infoPtr,COLORREF clrBk)1675c2c66affSColin Finck TOOLTIPS_SetTipBkColor (TOOLTIPS_INFO *infoPtr, COLORREF clrBk)
1676c2c66affSColin Finck {
1677c2c66affSColin Finck infoPtr->clrBk = clrBk;
1678c2c66affSColin Finck
1679c2c66affSColin Finck return 0;
1680c2c66affSColin Finck }
1681c2c66affSColin Finck
1682c2c66affSColin Finck
1683c2c66affSColin Finck static inline LRESULT
TOOLTIPS_SetTipTextColor(TOOLTIPS_INFO * infoPtr,COLORREF clrText)1684c2c66affSColin Finck TOOLTIPS_SetTipTextColor (TOOLTIPS_INFO *infoPtr, COLORREF clrText)
1685c2c66affSColin Finck {
1686c2c66affSColin Finck infoPtr->clrText = clrText;
1687c2c66affSColin Finck
1688c2c66affSColin Finck return 0;
1689c2c66affSColin Finck }
1690c2c66affSColin Finck
1691c2c66affSColin Finck
1692c2c66affSColin Finck static LRESULT
TOOLTIPS_SetTitleT(TOOLTIPS_INFO * infoPtr,UINT_PTR uTitleIcon,LPCWSTR pszTitle,BOOL isW)1693c2c66affSColin Finck TOOLTIPS_SetTitleT (TOOLTIPS_INFO *infoPtr, UINT_PTR uTitleIcon, LPCWSTR pszTitle,
1694c2c66affSColin Finck BOOL isW)
1695c2c66affSColin Finck {
1696c2c66affSColin Finck UINT size;
1697c2c66affSColin Finck
1698c2c66affSColin Finck TRACE("hwnd = %p, title = %s, icon = %p\n", infoPtr->hwndSelf, debugstr_w(pszTitle),
1699c2c66affSColin Finck (void*)uTitleIcon);
1700c2c66affSColin Finck
1701c2c66affSColin Finck Free(infoPtr->pszTitle);
1702c2c66affSColin Finck
1703c2c66affSColin Finck if (pszTitle)
1704c2c66affSColin Finck {
1705c2c66affSColin Finck if (isW)
1706c2c66affSColin Finck {
1707*0707475fSJustin Miller size = (lstrlenW(pszTitle)+1)*sizeof(WCHAR);
1708c2c66affSColin Finck infoPtr->pszTitle = Alloc(size);
1709c2c66affSColin Finck if (!infoPtr->pszTitle)
1710c2c66affSColin Finck return FALSE;
1711c2c66affSColin Finck memcpy(infoPtr->pszTitle, pszTitle, size);
1712c2c66affSColin Finck }
1713c2c66affSColin Finck else
1714c2c66affSColin Finck {
1715c2c66affSColin Finck size = sizeof(WCHAR)*MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszTitle, -1, NULL, 0);
1716c2c66affSColin Finck infoPtr->pszTitle = Alloc(size);
1717c2c66affSColin Finck if (!infoPtr->pszTitle)
1718c2c66affSColin Finck return FALSE;
1719c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszTitle, -1, infoPtr->pszTitle, size/sizeof(WCHAR));
1720c2c66affSColin Finck }
1721c2c66affSColin Finck }
1722c2c66affSColin Finck else
1723c2c66affSColin Finck infoPtr->pszTitle = NULL;
1724c2c66affSColin Finck
1725c2c66affSColin Finck if (uTitleIcon <= TTI_ERROR)
1726c2c66affSColin Finck infoPtr->hTitleIcon = hTooltipIcons[uTitleIcon];
1727c2c66affSColin Finck else
1728c2c66affSColin Finck infoPtr->hTitleIcon = CopyIcon((HICON)uTitleIcon);
1729c2c66affSColin Finck
1730c2c66affSColin Finck TRACE("icon = %p\n", infoPtr->hTitleIcon);
1731c2c66affSColin Finck
1732c2c66affSColin Finck return TRUE;
1733c2c66affSColin Finck }
1734c2c66affSColin Finck
1735c2c66affSColin Finck static LRESULT
TOOLTIPS_SetToolInfoT(TOOLTIPS_INFO * infoPtr,const TTTOOLINFOW * ti,BOOL isW)1736c2c66affSColin Finck TOOLTIPS_SetToolInfoT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
1737c2c66affSColin Finck {
1738c2c66affSColin Finck TTTOOL_INFO *toolPtr;
1739c2c66affSColin Finck INT nTool;
1740c2c66affSColin Finck
1741c2c66affSColin Finck if (!ti) return 0;
1742c2c66affSColin Finck if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
1743c2c66affSColin Finck return 0;
1744c2c66affSColin Finck
1745c2c66affSColin Finck nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
1746c2c66affSColin Finck if (nTool == -1) return 0;
1747c2c66affSColin Finck
1748c2c66affSColin Finck TRACE("tool %d\n", nTool);
1749c2c66affSColin Finck
1750c2c66affSColin Finck toolPtr = &infoPtr->tools[nTool];
1751c2c66affSColin Finck
1752c2c66affSColin Finck /* copy tool data */
1753c2c66affSColin Finck toolPtr->uFlags = ti->uFlags;
1754c2c66affSColin Finck toolPtr->hwnd = ti->hwnd;
1755c2c66affSColin Finck toolPtr->uId = ti->uId;
1756c2c66affSColin Finck toolPtr->rect = ti->rect;
1757c2c66affSColin Finck toolPtr->hinst = ti->hinst;
1758c2c66affSColin Finck
1759*0707475fSJustin Miller TOOLTIPS_SetToolText (toolPtr, ti->lpszText, isW);
1760c2c66affSColin Finck
1761c2c66affSColin Finck if (ti->cbSize >= TTTOOLINFOW_V2_SIZE)
1762c2c66affSColin Finck toolPtr->lParam = ti->lParam;
1763c2c66affSColin Finck
1764c2c66affSColin Finck if (infoPtr->nCurrentTool == nTool)
1765c2c66affSColin Finck {
1766c2c66affSColin Finck TOOLTIPS_GetTipText (infoPtr, infoPtr->nCurrentTool, infoPtr->szTipText);
1767c2c66affSColin Finck
1768c2c66affSColin Finck if (infoPtr->szTipText[0] == 0)
1769c2c66affSColin Finck TOOLTIPS_Hide(infoPtr);
1770c2c66affSColin Finck else
1771c2c66affSColin Finck TOOLTIPS_Show (infoPtr, FALSE);
1772c2c66affSColin Finck }
1773c2c66affSColin Finck
1774c2c66affSColin Finck return 0;
1775c2c66affSColin Finck }
1776c2c66affSColin Finck
1777c2c66affSColin Finck
1778c2c66affSColin Finck static LRESULT
TOOLTIPS_TrackActivate(TOOLTIPS_INFO * infoPtr,BOOL track_activate,const TTTOOLINFOA * ti)1779c2c66affSColin Finck TOOLTIPS_TrackActivate (TOOLTIPS_INFO *infoPtr, BOOL track_activate, const TTTOOLINFOA *ti)
1780c2c66affSColin Finck {
1781c2c66affSColin Finck if (track_activate) {
1782c2c66affSColin Finck
1783c2c66affSColin Finck if (!ti) return 0;
1784c2c66affSColin Finck if (ti->cbSize < TTTOOLINFOA_V1_SIZE)
1785c2c66affSColin Finck return FALSE;
1786c2c66affSColin Finck
1787c2c66affSColin Finck /* activate */
1788c2c66affSColin Finck infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoT (infoPtr, (const TTTOOLINFOW*)ti);
1789c2c66affSColin Finck if (infoPtr->nTrackTool != -1) {
1790edd99e8cSAmine Khaldi TRACE("activated\n");
1791c2c66affSColin Finck infoPtr->bTrackActive = TRUE;
1792c2c66affSColin Finck TOOLTIPS_TrackShow (infoPtr);
1793c2c66affSColin Finck }
1794c2c66affSColin Finck }
1795c2c66affSColin Finck else {
1796c2c66affSColin Finck /* deactivate */
1797c2c66affSColin Finck TOOLTIPS_TrackHide (infoPtr);
1798c2c66affSColin Finck
1799c2c66affSColin Finck infoPtr->bTrackActive = FALSE;
1800c2c66affSColin Finck infoPtr->nTrackTool = -1;
1801c2c66affSColin Finck
1802edd99e8cSAmine Khaldi TRACE("deactivated\n");
1803c2c66affSColin Finck }
1804c2c66affSColin Finck
1805c2c66affSColin Finck return 0;
1806c2c66affSColin Finck }
1807c2c66affSColin Finck
1808c2c66affSColin Finck
1809c2c66affSColin Finck static LRESULT
TOOLTIPS_TrackPosition(TOOLTIPS_INFO * infoPtr,LPARAM coord)1810c2c66affSColin Finck TOOLTIPS_TrackPosition (TOOLTIPS_INFO *infoPtr, LPARAM coord)
1811c2c66affSColin Finck {
1812c2c66affSColin Finck infoPtr->xTrackPos = (INT)LOWORD(coord);
1813c2c66affSColin Finck infoPtr->yTrackPos = (INT)HIWORD(coord);
1814c2c66affSColin Finck
1815c2c66affSColin Finck if (infoPtr->bTrackActive) {
1816c2c66affSColin Finck TRACE("[%d %d]\n",
1817c2c66affSColin Finck infoPtr->xTrackPos, infoPtr->yTrackPos);
1818c2c66affSColin Finck
1819c2c66affSColin Finck TOOLTIPS_TrackShow (infoPtr);
1820c2c66affSColin Finck }
1821c2c66affSColin Finck
1822c2c66affSColin Finck return 0;
1823c2c66affSColin Finck }
1824c2c66affSColin Finck
1825c2c66affSColin Finck
1826c2c66affSColin Finck static LRESULT
TOOLTIPS_Update(TOOLTIPS_INFO * infoPtr)1827c2c66affSColin Finck TOOLTIPS_Update (TOOLTIPS_INFO *infoPtr)
1828c2c66affSColin Finck {
1829c2c66affSColin Finck if (infoPtr->nCurrentTool != -1)
1830c2c66affSColin Finck UpdateWindow (infoPtr->hwndSelf);
1831c2c66affSColin Finck
1832c2c66affSColin Finck return 0;
1833c2c66affSColin Finck }
1834c2c66affSColin Finck
1835c2c66affSColin Finck
1836c2c66affSColin Finck static LRESULT
TOOLTIPS_UpdateTipTextT(TOOLTIPS_INFO * infoPtr,const TTTOOLINFOW * ti,BOOL isW)1837c2c66affSColin Finck TOOLTIPS_UpdateTipTextT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW)
1838c2c66affSColin Finck {
1839c2c66affSColin Finck TTTOOL_INFO *toolPtr;
1840c2c66affSColin Finck INT nTool;
1841c2c66affSColin Finck
1842c2c66affSColin Finck if (!ti) return 0;
1843c2c66affSColin Finck if (ti->cbSize < TTTOOLINFOW_V1_SIZE)
1844c2c66affSColin Finck return FALSE;
1845c2c66affSColin Finck
1846c2c66affSColin Finck nTool = TOOLTIPS_GetToolFromInfoT (infoPtr, ti);
1847c2c66affSColin Finck if (nTool == -1)
1848c2c66affSColin Finck return 0;
1849c2c66affSColin Finck
1850c2c66affSColin Finck TRACE("tool %d\n", nTool);
1851c2c66affSColin Finck
1852c2c66affSColin Finck toolPtr = &infoPtr->tools[nTool];
1853c2c66affSColin Finck
1854c2c66affSColin Finck toolPtr->hinst = ti->hinst;
1855c2c66affSColin Finck
1856*0707475fSJustin Miller TOOLTIPS_SetToolText(toolPtr, ti->lpszText, isW);
1857c2c66affSColin Finck
1858c2c66affSColin Finck if(infoPtr->nCurrentTool == -1) return 0;
1859c2c66affSColin Finck /* force repaint */
1860c2c66affSColin Finck if (infoPtr->bActive)
1861c2c66affSColin Finck TOOLTIPS_Show (infoPtr, FALSE);
1862c2c66affSColin Finck else if (infoPtr->bTrackActive)
1863c2c66affSColin Finck TOOLTIPS_Show (infoPtr, TRUE);
1864c2c66affSColin Finck
1865c2c66affSColin Finck return 0;
1866c2c66affSColin Finck }
1867c2c66affSColin Finck
1868c2c66affSColin Finck
1869c2c66affSColin Finck static LRESULT
TOOLTIPS_Create(HWND hwnd)1870c2c66affSColin Finck TOOLTIPS_Create (HWND hwnd)
1871c2c66affSColin Finck {
1872c2c66affSColin Finck TOOLTIPS_INFO *infoPtr;
1873c2c66affSColin Finck
1874c2c66affSColin Finck /* allocate memory for info structure */
1875c2c66affSColin Finck infoPtr = Alloc (sizeof(TOOLTIPS_INFO));
1876c2c66affSColin Finck SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
1877c2c66affSColin Finck
1878c2c66affSColin Finck /* initialize info structure */
1879c2c66affSColin Finck infoPtr->bActive = TRUE;
1880c2c66affSColin Finck infoPtr->bTrackActive = FALSE;
1881c2c66affSColin Finck
1882c2c66affSColin Finck infoPtr->nMaxTipWidth = -1;
1883c2c66affSColin Finck infoPtr->nTool = -1;
1884c2c66affSColin Finck infoPtr->nCurrentTool = -1;
1885c2c66affSColin Finck infoPtr->nTrackTool = -1;
1886c2c66affSColin Finck infoPtr->hwndSelf = hwnd;
1887c2c66affSColin Finck
1888c2c66affSColin Finck /* initialize colours and fonts */
1889c2c66affSColin Finck TOOLTIPS_InitSystemSettings(infoPtr);
1890c2c66affSColin Finck
1891c2c66affSColin Finck TOOLTIPS_SetDelayTime(infoPtr, TTDT_AUTOMATIC, 0);
1892c2c66affSColin Finck
1893c2c66affSColin Finck SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
1894c2c66affSColin Finck
1895c2c66affSColin Finck return 0;
1896c2c66affSColin Finck }
1897c2c66affSColin Finck
1898c2c66affSColin Finck
1899c2c66affSColin Finck static LRESULT
TOOLTIPS_Destroy(TOOLTIPS_INFO * infoPtr)1900c2c66affSColin Finck TOOLTIPS_Destroy (TOOLTIPS_INFO *infoPtr)
1901c2c66affSColin Finck {
1902c2c66affSColin Finck TTTOOL_INFO *toolPtr;
1903c2c66affSColin Finck UINT i;
1904c2c66affSColin Finck
1905*0707475fSJustin Miller for (i = 0; i < infoPtr->uNumTools; i++)
1906c2c66affSColin Finck {
1907*0707475fSJustin Miller toolPtr = &infoPtr->tools[i];
1908c2c66affSColin Finck
1909*0707475fSJustin Miller TOOLTIPS_FreeToolText (toolPtr);
1910edd99e8cSAmine Khaldi TOOLTIPS_ResetSubclass (toolPtr);
1911c2c66affSColin Finck }
1912edd99e8cSAmine Khaldi
1913c2c66affSColin Finck Free (infoPtr->tools);
1914c2c66affSColin Finck
1915c2c66affSColin Finck /* free title string */
1916c2c66affSColin Finck Free (infoPtr->pszTitle);
1917c2c66affSColin Finck /* free title icon if not a standard one */
1918c2c66affSColin Finck if (TOOLTIPS_GetTitleIconIndex(infoPtr->hTitleIcon) > TTI_ERROR)
1919c2c66affSColin Finck DeleteObject(infoPtr->hTitleIcon);
1920c2c66affSColin Finck
1921c2c66affSColin Finck /* delete fonts */
1922c2c66affSColin Finck DeleteObject (infoPtr->hFont);
1923c2c66affSColin Finck DeleteObject (infoPtr->hTitleFont);
1924c2c66affSColin Finck
1925c2c66affSColin Finck /* free tool tips info data */
1926c2c66affSColin Finck SetWindowLongPtrW(infoPtr->hwndSelf, 0, 0);
1927c2c66affSColin Finck Free (infoPtr);
1928c2c66affSColin Finck
1929c2c66affSColin Finck return 0;
1930c2c66affSColin Finck }
1931c2c66affSColin Finck
1932c2c66affSColin Finck
1933c2c66affSColin Finck static inline LRESULT
TOOLTIPS_GetFont(const TOOLTIPS_INFO * infoPtr)1934c2c66affSColin Finck TOOLTIPS_GetFont (const TOOLTIPS_INFO *infoPtr)
1935c2c66affSColin Finck {
1936c2c66affSColin Finck return (LRESULT)infoPtr->hFont;
1937c2c66affSColin Finck }
1938c2c66affSColin Finck
1939c2c66affSColin Finck
1940c2c66affSColin Finck static LRESULT
TOOLTIPS_MouseMessage(TOOLTIPS_INFO * infoPtr)1941c2c66affSColin Finck TOOLTIPS_MouseMessage (TOOLTIPS_INFO *infoPtr)
1942c2c66affSColin Finck {
1943c2c66affSColin Finck TOOLTIPS_Hide (infoPtr);
1944c2c66affSColin Finck
1945c2c66affSColin Finck return 0;
1946c2c66affSColin Finck }
1947c2c66affSColin Finck
1948c2c66affSColin Finck
1949c2c66affSColin Finck static LRESULT
TOOLTIPS_NCCreate(HWND hwnd)1950c2c66affSColin Finck TOOLTIPS_NCCreate (HWND hwnd)
1951c2c66affSColin Finck {
1952c2c66affSColin Finck DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
1953c2c66affSColin Finck DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
1954c2c66affSColin Finck
1955c2c66affSColin Finck dwStyle &= ~(WS_CHILD | /*WS_MAXIMIZE |*/ WS_BORDER | WS_DLGFRAME);
1956c2c66affSColin Finck dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
1957c2c66affSColin Finck
1958c2c66affSColin Finck /* WS_BORDER only draws a border round the window rect, not the
1959c2c66affSColin Finck * window region, therefore it is useless to us in balloon mode */
1960c2c66affSColin Finck if (dwStyle & TTS_BALLOON) dwStyle &= ~WS_BORDER;
1961c2c66affSColin Finck
1962c2c66affSColin Finck SetWindowLongW (hwnd, GWL_STYLE, dwStyle);
1963c2c66affSColin Finck
1964c2c66affSColin Finck dwExStyle |= WS_EX_TOOLWINDOW;
1965c2c66affSColin Finck SetWindowLongW (hwnd, GWL_EXSTYLE, dwExStyle);
1966c2c66affSColin Finck
1967c2c66affSColin Finck return TRUE;
1968c2c66affSColin Finck }
1969c2c66affSColin Finck
1970c2c66affSColin Finck
1971c2c66affSColin Finck static LRESULT
TOOLTIPS_NCHitTest(const TOOLTIPS_INFO * infoPtr,WPARAM wParam,LPARAM lParam)1972c2c66affSColin Finck TOOLTIPS_NCHitTest (const TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
1973c2c66affSColin Finck {
1974c2c66affSColin Finck INT nTool = (infoPtr->bTrackActive) ? infoPtr->nTrackTool : infoPtr->nTool;
1975c2c66affSColin Finck
1976c2c66affSColin Finck TRACE(" nTool=%d\n", nTool);
1977c2c66affSColin Finck
1978c2c66affSColin Finck if ((nTool > -1) && (nTool < infoPtr->uNumTools)) {
1979c2c66affSColin Finck if (infoPtr->tools[nTool].uFlags & TTF_TRANSPARENT) {
1980edd99e8cSAmine Khaldi TRACE("-- in transparent mode\n");
1981c2c66affSColin Finck return HTTRANSPARENT;
1982c2c66affSColin Finck }
1983c2c66affSColin Finck }
1984c2c66affSColin Finck
1985c2c66affSColin Finck return DefWindowProcW (infoPtr->hwndSelf, WM_NCHITTEST, wParam, lParam);
1986c2c66affSColin Finck }
1987c2c66affSColin Finck
1988c2c66affSColin Finck
1989c2c66affSColin Finck static LRESULT
TOOLTIPS_NotifyFormat(TOOLTIPS_INFO * infoPtr,WPARAM wParam,LPARAM lParam)1990c2c66affSColin Finck TOOLTIPS_NotifyFormat (TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
1991c2c66affSColin Finck {
1992c2c66affSColin Finck #ifdef __REACTOS__
1993c2c66affSColin Finck TTTOOL_INFO *toolPtr = infoPtr->tools;
1994c2c66affSColin Finck LRESULT nResult;
1995c2c66affSColin Finck
1996c2c66affSColin Finck TRACE("infoPtr=%p wParam=%lx lParam=%p\n", infoPtr, wParam, (PVOID)lParam);
1997c2c66affSColin Finck
1998c2c66affSColin Finck if (lParam == NF_QUERY) {
1999c2c66affSColin Finck if (toolPtr->bNotifyUnicode) {
2000c2c66affSColin Finck return NFR_UNICODE;
2001c2c66affSColin Finck } else {
2002c2c66affSColin Finck return NFR_ANSI;
2003c2c66affSColin Finck }
2004c2c66affSColin Finck }
2005c2c66affSColin Finck else if (lParam == NF_REQUERY) {
2006c2c66affSColin Finck nResult = SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
2007c2c66affSColin Finck (WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY);
2008c2c66affSColin Finck if (nResult == NFR_ANSI) {
2009c2c66affSColin Finck toolPtr->bNotifyUnicode = FALSE;
2010c2c66affSColin Finck TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
2011c2c66affSColin Finck } else if (nResult == NFR_UNICODE) {
2012c2c66affSColin Finck toolPtr->bNotifyUnicode = TRUE;
2013c2c66affSColin Finck TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
2014c2c66affSColin Finck } else {
2015c2c66affSColin Finck TRACE (" -- WM_NOTIFYFORMAT returns: error!\n");
2016c2c66affSColin Finck }
2017c2c66affSColin Finck return nResult;
2018c2c66affSColin Finck }
2019c2c66affSColin Finck #else
2020c2c66affSColin Finck FIXME ("hwnd=%p wParam=%lx lParam=%lx\n", infoPtr->hwndSelf, wParam, lParam);
2021c2c66affSColin Finck #endif
2022c2c66affSColin Finck
2023c2c66affSColin Finck return 0;
2024c2c66affSColin Finck }
2025c2c66affSColin Finck
2026c2c66affSColin Finck
2027c2c66affSColin Finck static LRESULT
TOOLTIPS_Paint(const TOOLTIPS_INFO * infoPtr,HDC hDC)2028c2c66affSColin Finck TOOLTIPS_Paint (const TOOLTIPS_INFO *infoPtr, HDC hDC)
2029c2c66affSColin Finck {
2030c2c66affSColin Finck HDC hdc;
2031c2c66affSColin Finck PAINTSTRUCT ps;
2032c2c66affSColin Finck
2033c2c66affSColin Finck hdc = (hDC == NULL) ? BeginPaint (infoPtr->hwndSelf, &ps) : hDC;
2034c2c66affSColin Finck TOOLTIPS_Refresh (infoPtr, hdc);
2035c2c66affSColin Finck if (!hDC)
2036c2c66affSColin Finck EndPaint (infoPtr->hwndSelf, &ps);
2037c2c66affSColin Finck return 0;
2038c2c66affSColin Finck }
2039c2c66affSColin Finck
2040c2c66affSColin Finck
2041c2c66affSColin Finck static LRESULT
TOOLTIPS_SetFont(TOOLTIPS_INFO * infoPtr,HFONT hFont,BOOL redraw)2042c2c66affSColin Finck TOOLTIPS_SetFont (TOOLTIPS_INFO *infoPtr, HFONT hFont, BOOL redraw)
2043c2c66affSColin Finck {
2044c2c66affSColin Finck LOGFONTW lf;
2045c2c66affSColin Finck
2046c2c66affSColin Finck if(!GetObjectW(hFont, sizeof(lf), &lf))
2047c2c66affSColin Finck return 0;
2048c2c66affSColin Finck
2049c2c66affSColin Finck DeleteObject (infoPtr->hFont);
2050c2c66affSColin Finck infoPtr->hFont = CreateFontIndirectW(&lf);
2051c2c66affSColin Finck
2052c2c66affSColin Finck DeleteObject (infoPtr->hTitleFont);
2053c2c66affSColin Finck lf.lfWeight = FW_BOLD;
2054c2c66affSColin Finck infoPtr->hTitleFont = CreateFontIndirectW(&lf);
2055c2c66affSColin Finck
2056edd99e8cSAmine Khaldi if (redraw && infoPtr->nCurrentTool != -1)
2057edd99e8cSAmine Khaldi FIXME("full redraw needed\n");
2058c2c66affSColin Finck
2059c2c66affSColin Finck return 0;
2060c2c66affSColin Finck }
2061c2c66affSColin Finck
2062c2c66affSColin Finck /******************************************************************
2063c2c66affSColin Finck * TOOLTIPS_GetTextLength
2064c2c66affSColin Finck *
2065c2c66affSColin Finck * This function is called when the tooltip receive a
2066c2c66affSColin Finck * WM_GETTEXTLENGTH message.
2067c2c66affSColin Finck *
2068c2c66affSColin Finck * returns the length, in characters, of the tip text
2069c2c66affSColin Finck */
2070c2c66affSColin Finck static inline LRESULT
TOOLTIPS_GetTextLength(const TOOLTIPS_INFO * infoPtr)2071c2c66affSColin Finck TOOLTIPS_GetTextLength(const TOOLTIPS_INFO *infoPtr)
2072c2c66affSColin Finck {
2073*0707475fSJustin Miller return lstrlenW(infoPtr->szTipText);
2074c2c66affSColin Finck }
2075c2c66affSColin Finck
2076c2c66affSColin Finck /******************************************************************
2077c2c66affSColin Finck * TOOLTIPS_OnWMGetText
2078c2c66affSColin Finck *
2079c2c66affSColin Finck * This function is called when the tooltip receive a
2080c2c66affSColin Finck * WM_GETTEXT message.
2081c2c66affSColin Finck * wParam : specifies the maximum number of characters to be copied
2082c2c66affSColin Finck * lParam : is the pointer to the buffer that will receive
2083c2c66affSColin Finck * the tip text
2084c2c66affSColin Finck *
2085c2c66affSColin Finck * returns the number of characters copied
2086c2c66affSColin Finck */
2087c2c66affSColin Finck static LRESULT
TOOLTIPS_OnWMGetText(const TOOLTIPS_INFO * infoPtr,WPARAM size,LPWSTR pszText)2088c2c66affSColin Finck TOOLTIPS_OnWMGetText (const TOOLTIPS_INFO *infoPtr, WPARAM size, LPWSTR pszText)
2089c2c66affSColin Finck {
2090c2c66affSColin Finck LRESULT res;
2091c2c66affSColin Finck
2092c2c66affSColin Finck if(!size)
2093c2c66affSColin Finck return 0;
2094c2c66affSColin Finck
2095*0707475fSJustin Miller res = min(lstrlenW(infoPtr->szTipText)+1, size);
2096c2c66affSColin Finck memcpy(pszText, infoPtr->szTipText, res*sizeof(WCHAR));
2097c2c66affSColin Finck pszText[res-1] = '\0';
2098c2c66affSColin Finck return res-1;
2099c2c66affSColin Finck }
2100c2c66affSColin Finck
2101c2c66affSColin Finck static LRESULT
TOOLTIPS_Timer(TOOLTIPS_INFO * infoPtr,INT iTimer)2102c2c66affSColin Finck TOOLTIPS_Timer (TOOLTIPS_INFO *infoPtr, INT iTimer)
2103c2c66affSColin Finck {
2104c2c66affSColin Finck INT nOldTool;
2105c2c66affSColin Finck
2106edd99e8cSAmine Khaldi TRACE("timer %d (%p) expired\n", iTimer, infoPtr->hwndSelf);
2107c2c66affSColin Finck
2108c2c66affSColin Finck switch (iTimer) {
2109c2c66affSColin Finck case ID_TIMERSHOW:
2110c2c66affSColin Finck KillTimer (infoPtr->hwndSelf, ID_TIMERSHOW);
2111c2c66affSColin Finck nOldTool = infoPtr->nTool;
2112c2c66affSColin Finck if ((infoPtr->nTool = TOOLTIPS_CheckTool (infoPtr, TRUE)) == nOldTool)
2113c2c66affSColin Finck TOOLTIPS_Show (infoPtr, FALSE);
2114c2c66affSColin Finck break;
2115c2c66affSColin Finck
2116c2c66affSColin Finck case ID_TIMERPOP:
2117c2c66affSColin Finck TOOLTIPS_Hide (infoPtr);
2118c2c66affSColin Finck break;
2119c2c66affSColin Finck
2120c2c66affSColin Finck case ID_TIMERLEAVE:
2121c2c66affSColin Finck nOldTool = infoPtr->nTool;
2122c2c66affSColin Finck infoPtr->nTool = TOOLTIPS_CheckTool (infoPtr, FALSE);
2123c2c66affSColin Finck TRACE("tool (%p) %d %d %d\n", infoPtr->hwndSelf, nOldTool,
2124c2c66affSColin Finck infoPtr->nTool, infoPtr->nCurrentTool);
2125c2c66affSColin Finck if (infoPtr->nTool != nOldTool) {
2126c2c66affSColin Finck if(infoPtr->nTool == -1) { /* Moved out of all tools */
2127c2c66affSColin Finck TOOLTIPS_Hide(infoPtr);
2128c2c66affSColin Finck KillTimer(infoPtr->hwndSelf, ID_TIMERLEAVE);
2129c2c66affSColin Finck } else if (nOldTool == -1) { /* Moved from outside */
2130c2c66affSColin Finck ERR("How did this happen?\n");
2131c2c66affSColin Finck } else { /* Moved from one to another */
2132c2c66affSColin Finck TOOLTIPS_Hide (infoPtr);
2133c2c66affSColin Finck KillTimer(infoPtr->hwndSelf, ID_TIMERLEAVE);
2134c2c66affSColin Finck if(infoPtr->bActive) {
2135c2c66affSColin Finck SetTimer (infoPtr->hwndSelf, ID_TIMERSHOW, infoPtr->nReshowTime, 0);
2136c2c66affSColin Finck TRACE("timer 1 started!\n");
2137c2c66affSColin Finck }
2138c2c66affSColin Finck }
2139c2c66affSColin Finck }
2140c2c66affSColin Finck break;
2141c2c66affSColin Finck
2142c2c66affSColin Finck default:
2143c2c66affSColin Finck ERR("Unknown timer id %d\n", iTimer);
2144c2c66affSColin Finck break;
2145c2c66affSColin Finck }
2146c2c66affSColin Finck return 0;
2147c2c66affSColin Finck }
2148c2c66affSColin Finck
2149c2c66affSColin Finck
2150c2c66affSColin Finck static LRESULT
TOOLTIPS_WinIniChange(TOOLTIPS_INFO * infoPtr)2151c2c66affSColin Finck TOOLTIPS_WinIniChange (TOOLTIPS_INFO *infoPtr)
2152c2c66affSColin Finck {
2153c2c66affSColin Finck TOOLTIPS_InitSystemSettings (infoPtr);
2154c2c66affSColin Finck
2155c2c66affSColin Finck return 0;
2156c2c66affSColin Finck }
2157c2c66affSColin Finck
2158c2c66affSColin Finck
2159c2c66affSColin Finck static LRESULT CALLBACK
TOOLTIPS_SubclassProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam,UINT_PTR uID,DWORD_PTR dwRef)2160edd99e8cSAmine Khaldi TOOLTIPS_SubclassProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uID, DWORD_PTR dwRef)
2161c2c66affSColin Finck {
2162c2c66affSColin Finck TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr ((HWND)dwRef);
2163c2c66affSColin Finck MSG msg;
2164c2c66affSColin Finck
2165edd99e8cSAmine Khaldi switch (message)
2166edd99e8cSAmine Khaldi {
2167c2c66affSColin Finck case WM_MOUSEMOVE:
2168c2c66affSColin Finck case WM_LBUTTONDOWN:
2169c2c66affSColin Finck case WM_LBUTTONUP:
2170c2c66affSColin Finck case WM_MBUTTONDOWN:
2171c2c66affSColin Finck case WM_MBUTTONUP:
2172c2c66affSColin Finck case WM_RBUTTONDOWN:
2173c2c66affSColin Finck case WM_RBUTTONUP:
2174edd99e8cSAmine Khaldi if (infoPtr)
2175edd99e8cSAmine Khaldi {
2176c2c66affSColin Finck msg.hwnd = hwnd;
2177edd99e8cSAmine Khaldi msg.message = message;
2178c2c66affSColin Finck msg.wParam = wParam;
2179c2c66affSColin Finck msg.lParam = lParam;
2180c2c66affSColin Finck TOOLTIPS_RelayEvent(infoPtr, &msg);
2181edd99e8cSAmine Khaldi }
2182c2c66affSColin Finck break;
2183edd99e8cSAmine Khaldi case WM_NCDESTROY:
2184edd99e8cSAmine Khaldi RemoveWindowSubclass(hwnd, TOOLTIPS_SubclassProc, 1);
2185edd99e8cSAmine Khaldi break;
2186c2c66affSColin Finck default:
2187c2c66affSColin Finck break;
2188c2c66affSColin Finck }
2189edd99e8cSAmine Khaldi
2190edd99e8cSAmine Khaldi return DefSubclassProc(hwnd, message, wParam, lParam);
2191c2c66affSColin Finck }
2192c2c66affSColin Finck
2193c2c66affSColin Finck
2194c2c66affSColin Finck static LRESULT CALLBACK
TOOLTIPS_WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)2195c2c66affSColin Finck TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2196c2c66affSColin Finck {
2197c2c66affSColin Finck TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2198c2c66affSColin Finck
2199c2c66affSColin Finck TRACE("hwnd=%p msg=%x wparam=%lx lParam=%lx\n", hwnd, uMsg, wParam, lParam);
2200c2c66affSColin Finck if (!infoPtr && (uMsg != WM_CREATE) && (uMsg != WM_NCCREATE))
2201c2c66affSColin Finck return DefWindowProcW (hwnd, uMsg, wParam, lParam);
2202c2c66affSColin Finck switch (uMsg)
2203c2c66affSColin Finck {
2204c2c66affSColin Finck case TTM_ACTIVATE:
2205c2c66affSColin Finck return TOOLTIPS_Activate (infoPtr, (BOOL)wParam);
2206c2c66affSColin Finck
2207c2c66affSColin Finck case TTM_ADDTOOLA:
2208c2c66affSColin Finck case TTM_ADDTOOLW:
2209c2c66affSColin Finck return TOOLTIPS_AddToolT (infoPtr, (LPTTTOOLINFOW)lParam, uMsg == TTM_ADDTOOLW);
2210c2c66affSColin Finck
2211c2c66affSColin Finck case TTM_DELTOOLA:
2212c2c66affSColin Finck case TTM_DELTOOLW:
2213c2c66affSColin Finck return TOOLTIPS_DelToolT (infoPtr, (LPTOOLINFOW)lParam,
2214c2c66affSColin Finck uMsg == TTM_DELTOOLW);
2215c2c66affSColin Finck case TTM_ENUMTOOLSA:
2216c2c66affSColin Finck case TTM_ENUMTOOLSW:
2217c2c66affSColin Finck return TOOLTIPS_EnumToolsT (infoPtr, (UINT)wParam, (LPTTTOOLINFOW)lParam,
2218c2c66affSColin Finck uMsg == TTM_ENUMTOOLSW);
2219c2c66affSColin Finck case TTM_GETBUBBLESIZE:
2220c2c66affSColin Finck return TOOLTIPS_GetBubbleSize (infoPtr, (LPTTTOOLINFOW)lParam);
2221c2c66affSColin Finck
2222c2c66affSColin Finck case TTM_GETCURRENTTOOLA:
2223c2c66affSColin Finck case TTM_GETCURRENTTOOLW:
2224c2c66affSColin Finck return TOOLTIPS_GetCurrentToolT (infoPtr, (LPTTTOOLINFOW)lParam,
2225c2c66affSColin Finck uMsg == TTM_GETCURRENTTOOLW);
2226c2c66affSColin Finck
2227c2c66affSColin Finck case TTM_GETDELAYTIME:
2228c2c66affSColin Finck return TOOLTIPS_GetDelayTime (infoPtr, (DWORD)wParam);
2229c2c66affSColin Finck
2230c2c66affSColin Finck case TTM_GETMARGIN:
2231c2c66affSColin Finck return TOOLTIPS_GetMargin (infoPtr, (LPRECT)lParam);
2232c2c66affSColin Finck
2233c2c66affSColin Finck case TTM_GETMAXTIPWIDTH:
2234c2c66affSColin Finck return TOOLTIPS_GetMaxTipWidth (infoPtr);
2235c2c66affSColin Finck
2236c2c66affSColin Finck case TTM_GETTEXTA:
2237c2c66affSColin Finck case TTM_GETTEXTW:
2238c2c66affSColin Finck return TOOLTIPS_GetTextT (infoPtr, (LPTTTOOLINFOW)lParam,
2239c2c66affSColin Finck uMsg == TTM_GETTEXTW);
2240c2c66affSColin Finck
2241c2c66affSColin Finck case TTM_GETTIPBKCOLOR:
2242c2c66affSColin Finck return TOOLTIPS_GetTipBkColor (infoPtr);
2243c2c66affSColin Finck
2244c2c66affSColin Finck case TTM_GETTIPTEXTCOLOR:
2245c2c66affSColin Finck return TOOLTIPS_GetTipTextColor (infoPtr);
2246c2c66affSColin Finck
2247c2c66affSColin Finck case TTM_GETTOOLCOUNT:
2248c2c66affSColin Finck return TOOLTIPS_GetToolCount (infoPtr);
2249c2c66affSColin Finck
2250c2c66affSColin Finck case TTM_GETTOOLINFOA:
2251c2c66affSColin Finck case TTM_GETTOOLINFOW:
2252c2c66affSColin Finck return TOOLTIPS_GetToolInfoT (infoPtr, (LPTTTOOLINFOW)lParam,
2253c2c66affSColin Finck uMsg == TTM_GETTOOLINFOW);
2254c2c66affSColin Finck
2255c2c66affSColin Finck case TTM_HITTESTA:
2256c2c66affSColin Finck case TTM_HITTESTW:
2257c2c66affSColin Finck return TOOLTIPS_HitTestT (infoPtr, (LPTTHITTESTINFOW)lParam,
2258c2c66affSColin Finck uMsg == TTM_HITTESTW);
2259c2c66affSColin Finck case TTM_NEWTOOLRECTA:
2260c2c66affSColin Finck case TTM_NEWTOOLRECTW:
2261c2c66affSColin Finck return TOOLTIPS_NewToolRectT (infoPtr, (LPTTTOOLINFOW)lParam);
2262c2c66affSColin Finck
2263c2c66affSColin Finck case TTM_POP:
2264c2c66affSColin Finck return TOOLTIPS_Pop (infoPtr);
2265c2c66affSColin Finck
2266c2c66affSColin Finck case TTM_RELAYEVENT:
2267c2c66affSColin Finck return TOOLTIPS_RelayEvent (infoPtr, (LPMSG)lParam);
2268c2c66affSColin Finck
2269c2c66affSColin Finck case TTM_SETDELAYTIME:
2270c2c66affSColin Finck return TOOLTIPS_SetDelayTime (infoPtr, (DWORD)wParam, (INT)LOWORD(lParam));
2271c2c66affSColin Finck
2272c2c66affSColin Finck case TTM_SETMARGIN:
2273c2c66affSColin Finck return TOOLTIPS_SetMargin (infoPtr, (LPRECT)lParam);
2274c2c66affSColin Finck
2275c2c66affSColin Finck case TTM_SETMAXTIPWIDTH:
2276c2c66affSColin Finck return TOOLTIPS_SetMaxTipWidth (infoPtr, (INT)lParam);
2277c2c66affSColin Finck
2278c2c66affSColin Finck case TTM_SETTIPBKCOLOR:
2279c2c66affSColin Finck return TOOLTIPS_SetTipBkColor (infoPtr, (COLORREF)wParam);
2280c2c66affSColin Finck
2281c2c66affSColin Finck case TTM_SETTIPTEXTCOLOR:
2282c2c66affSColin Finck return TOOLTIPS_SetTipTextColor (infoPtr, (COLORREF)wParam);
2283c2c66affSColin Finck
2284c2c66affSColin Finck case TTM_SETTITLEA:
2285c2c66affSColin Finck case TTM_SETTITLEW:
2286c2c66affSColin Finck return TOOLTIPS_SetTitleT (infoPtr, (UINT_PTR)wParam, (LPCWSTR)lParam,
2287c2c66affSColin Finck uMsg == TTM_SETTITLEW);
2288c2c66affSColin Finck
2289c2c66affSColin Finck case TTM_SETTOOLINFOA:
2290c2c66affSColin Finck case TTM_SETTOOLINFOW:
2291c2c66affSColin Finck return TOOLTIPS_SetToolInfoT (infoPtr, (LPTTTOOLINFOW)lParam,
2292c2c66affSColin Finck uMsg == TTM_SETTOOLINFOW);
2293c2c66affSColin Finck
2294c2c66affSColin Finck case TTM_TRACKACTIVATE:
2295c2c66affSColin Finck return TOOLTIPS_TrackActivate (infoPtr, (BOOL)wParam, (LPTTTOOLINFOA)lParam);
2296c2c66affSColin Finck
2297c2c66affSColin Finck case TTM_TRACKPOSITION:
2298c2c66affSColin Finck return TOOLTIPS_TrackPosition (infoPtr, lParam);
2299c2c66affSColin Finck
2300c2c66affSColin Finck case TTM_UPDATE:
2301c2c66affSColin Finck return TOOLTIPS_Update (infoPtr);
2302c2c66affSColin Finck
2303c2c66affSColin Finck case TTM_UPDATETIPTEXTA:
2304c2c66affSColin Finck case TTM_UPDATETIPTEXTW:
2305c2c66affSColin Finck return TOOLTIPS_UpdateTipTextT (infoPtr, (LPTTTOOLINFOW)lParam,
2306c2c66affSColin Finck uMsg == TTM_UPDATETIPTEXTW);
2307c2c66affSColin Finck
2308c2c66affSColin Finck case TTM_WINDOWFROMPOINT:
2309c2c66affSColin Finck return (LRESULT)WindowFromPoint (*((LPPOINT)lParam));
2310c2c66affSColin Finck
2311c2c66affSColin Finck case WM_CREATE:
2312c2c66affSColin Finck return TOOLTIPS_Create (hwnd);
2313c2c66affSColin Finck
2314c2c66affSColin Finck case WM_DESTROY:
2315c2c66affSColin Finck return TOOLTIPS_Destroy (infoPtr);
2316c2c66affSColin Finck
2317c2c66affSColin Finck case WM_ERASEBKGND:
2318c2c66affSColin Finck /* we draw the background in WM_PAINT */
2319c2c66affSColin Finck return 0;
2320c2c66affSColin Finck
2321c2c66affSColin Finck case WM_GETFONT:
2322c2c66affSColin Finck return TOOLTIPS_GetFont (infoPtr);
2323c2c66affSColin Finck
2324c2c66affSColin Finck case WM_GETTEXT:
2325c2c66affSColin Finck return TOOLTIPS_OnWMGetText (infoPtr, wParam, (LPWSTR)lParam);
2326c2c66affSColin Finck
2327c2c66affSColin Finck case WM_GETTEXTLENGTH:
2328c2c66affSColin Finck return TOOLTIPS_GetTextLength (infoPtr);
2329c2c66affSColin Finck
2330c2c66affSColin Finck case WM_LBUTTONDOWN:
2331c2c66affSColin Finck case WM_LBUTTONUP:
2332c2c66affSColin Finck case WM_MBUTTONDOWN:
2333c2c66affSColin Finck case WM_MBUTTONUP:
2334c2c66affSColin Finck case WM_RBUTTONDOWN:
2335c2c66affSColin Finck case WM_RBUTTONUP:
2336c2c66affSColin Finck case WM_MOUSEMOVE:
2337c2c66affSColin Finck return TOOLTIPS_MouseMessage (infoPtr);
2338c2c66affSColin Finck
2339c2c66affSColin Finck case WM_NCCREATE:
2340c2c66affSColin Finck return TOOLTIPS_NCCreate (hwnd);
2341c2c66affSColin Finck
2342c2c66affSColin Finck case WM_NCHITTEST:
2343c2c66affSColin Finck return TOOLTIPS_NCHitTest (infoPtr, wParam, lParam);
2344c2c66affSColin Finck
2345c2c66affSColin Finck case WM_NOTIFYFORMAT:
2346c2c66affSColin Finck return TOOLTIPS_NotifyFormat (infoPtr, wParam, lParam);
2347c2c66affSColin Finck
2348c2c66affSColin Finck case WM_PRINTCLIENT:
2349c2c66affSColin Finck case WM_PAINT:
2350c2c66affSColin Finck return TOOLTIPS_Paint (infoPtr, (HDC)wParam);
2351c2c66affSColin Finck
2352c2c66affSColin Finck case WM_SETFONT:
2353c2c66affSColin Finck return TOOLTIPS_SetFont (infoPtr, (HFONT)wParam, LOWORD(lParam));
2354c2c66affSColin Finck
2355c2c66affSColin Finck case WM_SYSCOLORCHANGE:
2356c2c66affSColin Finck COMCTL32_RefreshSysColors();
2357c2c66affSColin Finck return 0;
2358c2c66affSColin Finck
2359c2c66affSColin Finck case WM_TIMER:
2360c2c66affSColin Finck return TOOLTIPS_Timer (infoPtr, (INT)wParam);
2361c2c66affSColin Finck
2362c2c66affSColin Finck case WM_WININICHANGE:
2363c2c66affSColin Finck return TOOLTIPS_WinIniChange (infoPtr);
2364c2c66affSColin Finck
2365c2c66affSColin Finck default:
2366c2c66affSColin Finck if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg))
2367c2c66affSColin Finck ERR("unknown msg %04x wp=%08lx lp=%08lx\n",
2368c2c66affSColin Finck uMsg, wParam, lParam);
2369c2c66affSColin Finck return DefWindowProcW (hwnd, uMsg, wParam, lParam);
2370c2c66affSColin Finck }
2371c2c66affSColin Finck }
2372c2c66affSColin Finck
2373c2c66affSColin Finck
2374c2c66affSColin Finck VOID
TOOLTIPS_Register(void)2375c2c66affSColin Finck TOOLTIPS_Register (void)
2376c2c66affSColin Finck {
2377c2c66affSColin Finck WNDCLASSW wndClass;
2378c2c66affSColin Finck
2379c2c66affSColin Finck ZeroMemory (&wndClass, sizeof(WNDCLASSW));
2380c2c66affSColin Finck wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
2381c2c66affSColin Finck wndClass.lpfnWndProc = TOOLTIPS_WindowProc;
2382c2c66affSColin Finck wndClass.cbClsExtra = 0;
2383c2c66affSColin Finck wndClass.cbWndExtra = sizeof(TOOLTIPS_INFO *);
2384c2c66affSColin Finck wndClass.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
2385c2c66affSColin Finck wndClass.hbrBackground = 0;
2386c2c66affSColin Finck wndClass.lpszClassName = TOOLTIPS_CLASSW;
2387c2c66affSColin Finck
2388c2c66affSColin Finck RegisterClassW (&wndClass);
2389c2c66affSColin Finck
2390c2c66affSColin Finck hTooltipIcons[TTI_NONE] = NULL;
2391c2c66affSColin Finck hTooltipIcons[TTI_INFO] = LoadImageW(COMCTL32_hModule,
2392c2c66affSColin Finck (LPCWSTR)MAKEINTRESOURCE(IDI_TT_INFO_SM), IMAGE_ICON, 0, 0, 0);
2393c2c66affSColin Finck hTooltipIcons[TTI_WARNING] = LoadImageW(COMCTL32_hModule,
2394c2c66affSColin Finck (LPCWSTR)MAKEINTRESOURCE(IDI_TT_WARN_SM), IMAGE_ICON, 0, 0, 0);
2395c2c66affSColin Finck hTooltipIcons[TTI_ERROR] = LoadImageW(COMCTL32_hModule,
2396c2c66affSColin Finck (LPCWSTR)MAKEINTRESOURCE(IDI_TT_ERROR_SM), IMAGE_ICON, 0, 0, 0);
2397c2c66affSColin Finck }
2398c2c66affSColin Finck
2399c2c66affSColin Finck
2400c2c66affSColin Finck VOID
TOOLTIPS_Unregister(void)2401c2c66affSColin Finck TOOLTIPS_Unregister (void)
2402c2c66affSColin Finck {
2403c2c66affSColin Finck int i;
2404c2c66affSColin Finck for (i = TTI_INFO; i <= TTI_ERROR; i++)
2405c2c66affSColin Finck DestroyIcon(hTooltipIcons[i]);
2406c2c66affSColin Finck UnregisterClassW (TOOLTIPS_CLASSW, NULL);
2407c2c66affSColin Finck }
2408