source: trunk/src/comctl32/tooltips.c@ 285

Last change on this file since 285 was 285, checked in by cbratschi, 26 years ago

toolbar customize dialog enhanced (not yet finished)

File size: 63.8 KB
Line 
1/* $Id: tooltips.c,v 1.11 1999-07-07 17:08:43 cbratschi Exp $ */
2/*
3 * Tool tip control
4 *
5 * Copyright 1998 Eric Kohl
6 * Copyright 1999 Achim Hasenmueller
7 * Copyright 1999 Christoph Bratschi
8 *
9 * TODO:
10 * - Custom draw support.
11 *
12 * Testing:
13 * - Run tests using Waite Group Windows95 API Bible Volume 2.
14 * The second cdrom (chapter 3) contains executables activate.exe,
15 * curtool.exe, deltool.exe, enumtools.exe, getinfo.exe, getiptxt.exe,
16 * hittest.exe, needtext.exe, newrect.exe, updtext.exe and winfrpt.exe.
17 */
18
19/* CB: Odin32 problems
20 - WM_NCCREATE not handled first -> title bar visible if WS_POPUP wasn't set before
21 - CS_SAVEBITS: window movements are slow, bug in Open32?
22*/
23
24#include <string.h>
25
26#include "winbase.h"
27#include "commctrl.h"
28#include "tooltips.h"
29#include "comctl32.h"
30
31#define ID_TIMERSHOW 1 /* show delay timer */
32#define ID_TIMERPOP 2 /* auto pop timer */
33#define ID_TIMERLEAVE 3 /* tool leave timer */
34
35
36extern LPSTR COMCTL32_aSubclass; /* global subclassing atom */
37
38/* property name of tooltip window handle */
39/*#define TT_SUBCLASS_PROP "CC32SubclassInfo" */
40
41#define TOOLTIPS_GetInfoPtr(hWindow) ((TOOLTIPS_INFO *)GetWindowLongA (hWindow, 0))
42
43LRESULT CALLBACK
44TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
45
46
47static VOID
48TOOLTIPS_Refresh (HWND hwnd, HDC hdc)
49{
50 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(hwnd);
51 RECT rc;
52 INT oldBkMode;
53 HFONT hOldFont;
54 HBRUSH hBrush;
55 UINT uFlags = DT_EXTERNALLEADING;
56
57 if (infoPtr->nMaxTipWidth > -1) uFlags |= DT_WORDBREAK;
58 if (GetWindowLongA(hwnd,GWL_STYLE) & TTS_NOPREFIX) uFlags |= DT_NOPREFIX;
59 GetClientRect(hwnd,&rc);
60
61 /* fill the background */
62 hBrush = CreateSolidBrush(infoPtr->clrBk);
63 FillRect(hdc,&rc,hBrush);
64 DeleteObject(hBrush);
65
66 /* calculate text rectangle */
67 rc.left += (2+infoPtr->rcMargin.left);
68 rc.top += (2+infoPtr->rcMargin.top);
69 rc.right -= (2+infoPtr->rcMargin.right);
70 rc.bottom -= (2+infoPtr->rcMargin.bottom);
71
72 /* draw text */
73 oldBkMode = SetBkMode(hdc,TRANSPARENT);
74 SetTextColor(hdc,infoPtr->clrText);
75 hOldFont = SelectObject(hdc,infoPtr->hFont);
76 DrawTextW(hdc,infoPtr->szTipText,-1,&rc,uFlags);
77 SelectObject(hdc,hOldFont);
78 if (oldBkMode != TRANSPARENT) SetBkMode(hdc,oldBkMode);
79}
80
81
82static VOID
83TOOLTIPS_GetTipText(HWND hwnd,TOOLTIPS_INFO *infoPtr,INT nTool)
84{
85 TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool];
86
87 if ((toolPtr->hinst) && (HIWORD((UINT)toolPtr->lpszText) == 0))
88 {
89 /* load a resource */
90// TRACE (tooltips,"load res string %x %x\n",toolPtr->hinst,(int)toolPtr->lpszText);
91 LoadStringW(toolPtr->hinst,(UINT)toolPtr->lpszText,infoPtr->szTipText,INFOTIPSIZE);
92 } else if (toolPtr->lpszText)
93 {
94 if (toolPtr->lpszText == LPSTR_TEXTCALLBACKW)
95 {
96 NMTTDISPINFOA ttnmdi;
97
98 /* fill NMHDR struct */
99 ZeroMemory (&ttnmdi,sizeof(NMTTDISPINFOA));
100 ttnmdi.hdr.hwndFrom = hwnd;
101 ttnmdi.hdr.idFrom = toolPtr->uId;
102 ttnmdi.hdr.code = TTN_GETDISPINFOA;
103 ttnmdi.lpszText = (LPSTR)&ttnmdi.szText;
104 ttnmdi.uFlags = toolPtr->uFlags;
105 ttnmdi.lParam = toolPtr->lParam;
106 // TRACE (tooltips, "hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
107 SendMessageA (toolPtr->hwnd,WM_NOTIFY,(WPARAM)toolPtr->uId,(LPARAM)&ttnmdi);
108
109 if ((ttnmdi.hinst) && (HIWORD((UINT)ttnmdi.szText) == 0))
110 {
111 LoadStringW (ttnmdi.hinst,(UINT)ttnmdi.szText,infoPtr->szTipText,INFOTIPSIZE);
112 if (ttnmdi.uFlags & TTF_DI_SETITEM)
113 {
114 toolPtr->hinst = ttnmdi.hinst;
115 toolPtr->lpszText = (LPWSTR)ttnmdi.szText;
116 }
117 } else if (ttnmdi.szText[0])
118 {
119 lstrcpynAtoW(infoPtr->szTipText,ttnmdi.szText,INFOTIPSIZE);
120 if (ttnmdi.uFlags & TTF_DI_SETITEM)
121 {
122 INT len = lstrlenA(ttnmdi.szText);
123 toolPtr->hinst = 0;
124 toolPtr->lpszText = COMCTL32_Alloc((len+1)* sizeof(WCHAR));
125 lstrcpyAtoW(toolPtr->lpszText,ttnmdi.szText);
126 }
127 } else if (ttnmdi.lpszText == 0)
128 {
129 /* no text available */
130 infoPtr->szTipText[0] = '\0';
131 } else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKA)
132 {
133 lstrcpynAtoW(infoPtr->szTipText,ttnmdi.lpszText,INFOTIPSIZE);
134 if (ttnmdi.uFlags & TTF_DI_SETITEM)
135 {
136 INT len = lstrlenA(ttnmdi.lpszText);
137 toolPtr->hinst = 0;
138 toolPtr->lpszText = COMCTL32_Alloc((len+1)*sizeof(WCHAR));
139 lstrcpyAtoW(toolPtr->lpszText,ttnmdi.lpszText);
140 }
141 } else
142 {
143// ERR (tooltips, "recursive text callback!\n");
144 infoPtr->szTipText[0] = '\0';
145 }
146 } else
147 {
148 /* the item is a usual (unicode) text */
149 lstrcpynW(infoPtr->szTipText,toolPtr->lpszText,INFOTIPSIZE);
150 }
151 }
152 else
153 {
154 /* no text available */
155 infoPtr->szTipText[0] = '\0';
156 }
157
158// TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
159}
160
161static VOID
162TOOLTIPS_CalcTipRect (HWND hwnd,TOOLTIPS_INFO *infoPtr,TTTOOL_INFO *toolPtr,LPRECT lpRect)
163{
164 HDC hdc;
165 HFONT hOldFont;
166 UINT uFlags = DT_EXTERNALLEADING | DT_CALCRECT;
167 RECT rc = {0,0,0,0};
168 SIZE size;
169
170 if (infoPtr->nMaxTipWidth > -1)
171 {
172 rc.right = infoPtr->nMaxTipWidth;
173 uFlags |= DT_WORDBREAK;
174 }
175 if (GetWindowLongA(hwnd,GWL_STYLE) & TTS_NOPREFIX) uFlags |= DT_NOPREFIX;
176// TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
177
178 hdc = GetDC(hwnd);
179 hOldFont = SelectObject(hdc,infoPtr->hFont);
180 DrawTextW(hdc,infoPtr->szTipText,-1,&rc,uFlags);
181 SelectObject(hdc,hOldFont);
182 ReleaseDC(hwnd,hdc);
183
184 size.cx = rc.right-rc.left+4+infoPtr->rcMargin.left+infoPtr->rcMargin.right;
185 size.cy = rc.bottom-rc.top+4+infoPtr->rcMargin.bottom+infoPtr->rcMargin.top;
186
187 //CB: optimize
188
189 if (toolPtr->uFlags & TTF_ABSOLUTE)
190 {
191 rc.left = infoPtr->xTrackPos;
192 rc.top = infoPtr->yTrackPos;
193
194 if (toolPtr->uFlags & TTF_CENTERTIP)
195 {
196 rc.left -= (size.cx/2);
197 rc.top -= (size.cy/2);
198 }
199 } else
200 {
201 RECT rcTool;
202
203 if (toolPtr->uFlags & TTF_IDISHWND)
204 {
205 GetWindowRect((HWND)toolPtr->uId,&rcTool); //screen coordinates
206 } else
207 {
208 rcTool = toolPtr->rect;
209 MapWindowPoints(toolPtr->hwnd,(HWND)0,(LPPOINT)&rcTool,2);
210 }
211
212 if (toolPtr->uFlags & TTF_CENTERTIP)
213 {
214 if (infoPtr->bTrackActive)
215 {
216 GetCursorPos((LPPOINT)&rc);
217 rc.top += 20;
218 rc.left -= (size.cx / 2);
219 rc.top -= (size.cy / 2);
220 } else
221 {
222 rc.left = (rcTool.left + rcTool.right-size.cx)/ 2;
223 rc.top = rcTool.bottom+2;
224 }
225
226 } else
227 {
228 GetCursorPos((LPPOINT)&rc);
229 rc.top += 20;
230 }
231
232 /* smart placement */
233 if (infoPtr->bTrackActive)
234 {
235 if ((rc.left + size.cx > rcTool.left) && (rc.left < rcTool.right) &&
236 (rc.top + size.cy > rcTool.top) && (rc.top < rcTool.bottom))
237 rc.left = rcTool.right;
238 }
239 }
240
241// TRACE (tooltips, "pos %d - %d\n", rect.left, rect.top);
242
243 rc.right = rc.left+size.cx;
244 rc.bottom = rc.top+size.cy;
245
246 AdjustWindowRectEx (&rc,GetWindowLongA(hwnd,GWL_STYLE),
247 FALSE,GetWindowLongA(hwnd,GWL_EXSTYLE));
248
249 *lpRect = rc;
250
251}
252
253
254static VOID
255TOOLTIPS_Show (HWND hwnd, TOOLTIPS_INFO *infoPtr)
256{
257 TTTOOL_INFO *toolPtr;
258 RECT rect;
259 HDC hdc;
260 NMHDR hdr;
261
262 if (infoPtr->nTool == -1)
263 {
264// TRACE (tooltips, "invalid tool (-1)!\n");
265 return;
266 }
267
268 infoPtr->nCurrentTool = infoPtr->nTool;
269
270// TRACE (tooltips, "Show tooltip pre %d!\n", infoPtr->nTool);
271 TOOLTIPS_GetTipText(hwnd,infoPtr,infoPtr->nCurrentTool);
272
273 if (infoPtr->szTipText[0] == '\0')
274 {
275 infoPtr->nCurrentTool = -1;
276 return;
277 }
278
279// TRACE (tooltips, "Show tooltip %d!\n", infoPtr->nCurrentTool);
280 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
281
282 hdr.hwndFrom = hwnd;
283 hdr.idFrom = toolPtr->uId;
284 hdr.code = TTN_SHOW;
285 SendMessageA(toolPtr->hwnd,WM_NOTIFY,
286 (WPARAM)toolPtr->uId,(LPARAM)&hdr);
287
288// TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
289
290 TOOLTIPS_CalcTipRect(hwnd,infoPtr,toolPtr,&rect);
291
292 SetWindowPos (hwnd,HWND_TOP,rect.left,rect.top,
293 rect.right-rect.left,rect.bottom-rect.top,
294 SWP_SHOWWINDOW | SWP_NOACTIVATE);
295
296 /* repaint the tooltip */
297 hdc = GetDC(hwnd);
298 TOOLTIPS_Refresh(hwnd,hdc);
299 ReleaseDC(hwnd,hdc);
300
301 SetTimer (hwnd,ID_TIMERPOP,infoPtr->nAutoPopTime,0);
302}
303
304
305static VOID
306TOOLTIPS_Hide (HWND hwnd, TOOLTIPS_INFO *infoPtr)
307{
308 TTTOOL_INFO *toolPtr;
309 NMHDR hdr;
310
311 if (infoPtr->nCurrentTool == -1)
312 return;
313
314 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
315// TRACE (tooltips, "Hide tooltip %d!\n", infoPtr->nCurrentTool);
316 KillTimer (hwnd, ID_TIMERPOP);
317
318 hdr.hwndFrom = hwnd;
319 hdr.idFrom = toolPtr->uId;
320 hdr.code = TTN_POP;
321 SendMessageA (toolPtr->hwnd, WM_NOTIFY,
322 (WPARAM)toolPtr->uId, (LPARAM)&hdr);
323
324 infoPtr->nCurrentTool = -1;
325
326 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
327 SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
328}
329
330
331static VOID
332TOOLTIPS_TrackShow (HWND hwnd, TOOLTIPS_INFO *infoPtr)
333{
334 TTTOOL_INFO *toolPtr;
335 RECT rect;
336 HDC hdc;
337 NMHDR hdr;
338
339 if (infoPtr->nTrackTool == -1)
340 {
341// TRACE (tooltips, "invalid tracking tool (-1)!\n");
342 return;
343 }
344
345// TRACE (tooltips, "show tracking tooltip pre %d!\n", infoPtr->nTrackTool);
346
347 TOOLTIPS_GetTipText(hwnd,infoPtr,infoPtr->nTrackTool);
348
349 if (infoPtr->szTipText[0] == '\0')
350 {
351 infoPtr->nTrackTool = -1;
352 return;
353 }
354
355// TRACE (tooltips, "show tracking tooltip %d!\n", infoPtr->nTrackTool);
356 toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
357
358 hdr.hwndFrom = hwnd;
359 hdr.idFrom = toolPtr->uId;
360 hdr.code = TTN_SHOW;
361 SendMessageA(toolPtr->hwnd,WM_NOTIFY,(WPARAM)toolPtr->uId,(LPARAM)&hdr);
362
363// TRACE (tooltips, "\"%s\"\n", debugstr_w(infoPtr->szTipText));
364
365 TOOLTIPS_CalcTipRect(hwnd,infoPtr,toolPtr,&rect);
366
367 SetWindowPos (hwnd,HWND_TOP,rect.left,rect.top,
368 rect.right-rect.left,rect.bottom-rect.top,
369 SWP_SHOWWINDOW | SWP_NOACTIVATE );
370
371 hdc = GetDC (hwnd);
372 TOOLTIPS_Refresh (hwnd, hdc);
373 ReleaseDC (hwnd, hdc);
374}
375
376
377static VOID
378TOOLTIPS_TrackHide (HWND hwnd, TOOLTIPS_INFO *infoPtr)
379{
380 TTTOOL_INFO *toolPtr;
381 NMHDR hdr;
382
383 if (infoPtr->nTrackTool == -1)
384 return;
385
386 toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
387// TRACE (tooltips, "hide tracking tooltip %d!\n", infoPtr->nTrackTool);
388
389 hdr.hwndFrom = hwnd;
390 hdr.idFrom = toolPtr->uId;
391 hdr.code = TTN_POP;
392 SendMessageA (toolPtr->hwnd, WM_NOTIFY,
393 (WPARAM)toolPtr->uId, (LPARAM)&hdr);
394
395 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
396 SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
397}
398
399
400static INT
401TOOLTIPS_GetToolFromInfoA (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOA lpToolInfo)
402{
403 TTTOOL_INFO *toolPtr;
404 INT nTool;
405
406 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
407 toolPtr = &infoPtr->tools[nTool];
408
409 if (!(toolPtr->uFlags & TTF_IDISHWND) &&
410 (lpToolInfo->hwnd == toolPtr->hwnd) &&
411 (lpToolInfo->uId == toolPtr->uId))
412 return nTool;
413 }
414
415 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
416 toolPtr = &infoPtr->tools[nTool];
417
418 if ((toolPtr->uFlags & TTF_IDISHWND) &&
419 (lpToolInfo->uId == toolPtr->uId))
420 return nTool;
421 }
422
423 return -1;
424}
425
426
427static INT
428TOOLTIPS_GetToolFromInfoW (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOW lpToolInfo)
429{
430 TTTOOL_INFO *toolPtr;
431 INT nTool;
432
433 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
434 toolPtr = &infoPtr->tools[nTool];
435
436 if (!(toolPtr->uFlags & TTF_IDISHWND) &&
437 (lpToolInfo->hwnd == toolPtr->hwnd) &&
438 (lpToolInfo->uId == toolPtr->uId))
439 return nTool;
440 }
441
442 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
443 toolPtr = &infoPtr->tools[nTool];
444
445 if ((toolPtr->uFlags & TTF_IDISHWND) &&
446 (lpToolInfo->uId == toolPtr->uId))
447 return nTool;
448 }
449
450 return -1;
451}
452
453
454static INT
455TOOLTIPS_GetToolFromPoint (TOOLTIPS_INFO *infoPtr, HWND hwnd, LPPOINT lpPt)
456{
457 TTTOOL_INFO *toolPtr;
458 INT nTool;
459
460 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
461 toolPtr = &infoPtr->tools[nTool];
462
463 if (!(toolPtr->uFlags & TTF_IDISHWND)) {
464 if (hwnd != toolPtr->hwnd)
465 continue;
466 if (!PtInRect (&toolPtr->rect, *lpPt))
467 continue;
468 return nTool;
469 }
470 }
471
472 for (nTool = 0; nTool < infoPtr->uNumTools; nTool++) {
473 toolPtr = &infoPtr->tools[nTool];
474
475 if (toolPtr->uFlags & TTF_IDISHWND) {
476 if ((HWND)toolPtr->uId == hwnd)
477 return nTool;
478 }
479 }
480
481 return -1;
482}
483
484
485static INT
486TOOLTIPS_GetToolFromMessage (TOOLTIPS_INFO *infoPtr, HWND hwndTool)
487{
488 DWORD dwPos;
489 POINT pt;
490
491 dwPos = GetMessagePos ();
492 pt.x = (INT)LOWORD(dwPos);
493 pt.y = (INT)HIWORD(dwPos);
494 ScreenToClient (hwndTool, &pt);
495
496 return TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
497}
498
499
500static BOOL
501TOOLTIPS_IsWindowActive (HWND hwnd)
502{
503 HWND hwndActive = GetActiveWindow ();
504 if (!hwndActive)
505 return FALSE;
506 if (hwndActive == hwnd)
507 return TRUE;
508 return IsChild (hwndActive, hwnd);
509}
510
511
512static INT
513TOOLTIPS_CheckTool (HWND hwnd, BOOL bShowTest)
514{
515 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
516 POINT pt;
517 HWND hwndTool;
518 INT nTool;
519
520 GetCursorPos (&pt);
521 hwndTool = SendMessageA (hwnd, TTM_WINDOWFROMPOINT, 0, (LPARAM)&pt);
522 if (hwndTool == 0)
523 return -1;
524
525 ScreenToClient (hwndTool, &pt);
526 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, hwndTool, &pt);
527 if (nTool == -1)
528 return -1;
529
530 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TTS_ALWAYSTIP) && bShowTest) {
531 if (!TOOLTIPS_IsWindowActive (GetWindow (hwnd, GW_OWNER)))
532 return -1;
533 }
534
535// TRACE (tooltips, "tool %d\n", nTool);
536
537 return nTool;
538}
539
540
541static LRESULT
542TOOLTIPS_Activate (HWND hwnd, WPARAM wParam, LPARAM lParam)
543{
544 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(hwnd);
545
546 infoPtr->bActive = (BOOL)wParam;
547
548// if (infoPtr->bActive)
549// TRACE (tooltips, "activate!\n");
550
551 if (!(infoPtr->bActive) && (infoPtr->nCurrentTool != -1))
552 TOOLTIPS_Hide (hwnd, infoPtr);
553
554 return 0;
555}
556
557
558static VOID TOOLTIPS_Subclass(HWND hwnd,TTTOOL_INFO *toolPtr)
559{
560 if (toolPtr->uFlags & TTF_SUBCLASS)
561 {
562 if (toolPtr->uFlags & TTF_IDISHWND)
563 {
564 LPTT_SUBCLASS_INFO lpttsi =
565 (LPTT_SUBCLASS_INFO)GetPropA((HWND)toolPtr->uId,COMCTL32_aSubclass);
566 if (lpttsi == NULL)
567 {
568 lpttsi = (LPTT_SUBCLASS_INFO)COMCTL32_Alloc(sizeof(TT_SUBCLASS_INFO));
569 lpttsi->wpOrigProc =
570 (WNDPROC)SetWindowLongA ((HWND)toolPtr->uId,
571 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
572 lpttsi->hwndToolTip = hwnd;
573 lpttsi->uRefCount++;
574 SetPropA ((HWND)toolPtr->uId,COMCTL32_aSubclass,(HANDLE)lpttsi);
575 }
576// else
577// WARN (tooltips, "A window tool must only be listed once!\n");
578 } else
579 {
580 LPTT_SUBCLASS_INFO lpttsi =
581 (LPTT_SUBCLASS_INFO)GetPropA (toolPtr->hwnd, COMCTL32_aSubclass);
582 if (lpttsi == NULL)
583 {
584 lpttsi = (LPTT_SUBCLASS_INFO)COMCTL32_Alloc(sizeof(TT_SUBCLASS_INFO));
585 lpttsi->wpOrigProc =
586 (WNDPROC)SetWindowLongA (toolPtr->hwnd,
587 GWL_WNDPROC,(LONG)TOOLTIPS_SubclassProc);
588 lpttsi->hwndToolTip = hwnd;
589 lpttsi->uRefCount++;
590 SetPropA(toolPtr->hwnd,COMCTL32_aSubclass,(HANDLE)lpttsi);
591 } else lpttsi->uRefCount++;
592 }
593// TRACE (tooltips, "subclassing installed!\n");
594 }
595}
596
597static VOID TOOLTIPS_Desubclass(TTTOOL_INFO *toolPtr)
598{
599 if (toolPtr->uFlags & TTF_SUBCLASS)
600 {
601 if (toolPtr->uFlags & TTF_IDISHWND)
602 {
603 LPTT_SUBCLASS_INFO lpttsi =
604 (LPTT_SUBCLASS_INFO)GetPropA((HWND)toolPtr->uId,COMCTL32_aSubclass);
605 if (lpttsi)
606 {
607 SetWindowLongA ((HWND)toolPtr->uId,GWL_WNDPROC,(LONG)lpttsi->wpOrigProc);
608 RemovePropA ((HWND)toolPtr->uId,COMCTL32_aSubclass);
609 COMCTL32_Free(&lpttsi);
610 }
611// else
612// ERR (tooltips, "Invalid data handle!\n");
613 } else
614 {
615 LPTT_SUBCLASS_INFO lpttsi =
616 (LPTT_SUBCLASS_INFO)GetPropA(toolPtr->hwnd,COMCTL32_aSubclass);
617 if (lpttsi)
618 {
619 if (lpttsi->uRefCount == 1)
620 {
621 SetWindowLongA((HWND)toolPtr->uId,GWL_WNDPROC,(LONG)lpttsi->wpOrigProc);
622 RemovePropA((HWND)toolPtr->uId,COMCTL32_aSubclass);
623 COMCTL32_Free(&lpttsi);
624 } else lpttsi->uRefCount--;
625 }
626// else
627// ERR (tooltips, "Invalid data handle!\n");
628 }
629 }
630}
631
632static LRESULT
633TOOLTIPS_AddToolA(HWND hwnd,WPARAM wParam,LPARAM lParam)
634{
635 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(hwnd);
636 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
637 TTTOOL_INFO *toolPtr;
638
639 if (lpToolInfo == NULL) return FALSE;
640 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA) return FALSE;
641
642// TRACE (tooltips, "add tool (%x) %x %d%s!\n",
643// hwnd, lpToolInfo->hwnd, lpToolInfo->uId,
644// (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
645
646 if (infoPtr->uNumTools == 0)
647 {
648 infoPtr->tools = COMCTL32_Alloc(sizeof(TTTOOL_INFO));
649 toolPtr = infoPtr->tools;
650 } else
651 {
652 TTTOOL_INFO *oldTools = infoPtr->tools;
653 INT x;
654
655 toolPtr = NULL;
656
657 //check if toolinfo already exists
658 for (x = 0;x < infoPtr->uNumTools;x++)
659 {
660 if (lpToolInfo->hwnd == infoPtr->tools[x].hwnd && lpToolInfo->uId == infoPtr->tools[x].uId)
661 {
662 //return toolPtr
663 toolPtr = &infoPtr->tools[x];
664 //free allocated memory
665 TOOLTIPS_Desubclass(toolPtr);
666 if ((toolPtr->hinst) && (toolPtr->lpszText))
667 {
668 if (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(toolPtr->lpszText);
669 }
670
671 break;
672 }
673 }
674
675 if (toolPtr == NULL)
676 {
677 infoPtr->tools = COMCTL32_Alloc (sizeof(TTTOOL_INFO)*(infoPtr->uNumTools+1));
678 memcpy(infoPtr->tools,oldTools,infoPtr->uNumTools*sizeof(TTTOOL_INFO));
679 COMCTL32_Free(oldTools);
680 toolPtr = &infoPtr->tools[infoPtr->uNumTools];
681 }
682 }
683
684 infoPtr->uNumTools++;
685
686 /* copy tool data */
687 toolPtr->uFlags = lpToolInfo->uFlags;
688 toolPtr->hwnd = lpToolInfo->hwnd;
689 toolPtr->uId = lpToolInfo->uId;
690 toolPtr->rect = lpToolInfo->rect;
691 toolPtr->hinst = lpToolInfo->hinst;
692
693 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0))
694 {
695// TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
696 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
697 } else if (lpToolInfo->lpszText)
698 {
699 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA)
700 {
701// TRACE (tooltips, "add CALLBACK!\n");
702 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
703 } else
704 {
705 INT len = lstrlenA (lpToolInfo->lpszText);
706// TRACE (tooltips, "add text \"%s\"!\n", lpToolInfo->lpszText);
707 toolPtr->lpszText = COMCTL32_Alloc((len+1)*sizeof(WCHAR));
708 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
709 }
710 } else toolPtr->lpszText = NULL;
711
712 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
713 toolPtr->lParam = lpToolInfo->lParam;
714
715 /* install subclassing hook */
716 TOOLTIPS_Subclass(hwnd,toolPtr);
717
718 return TRUE;
719}
720
721
722static LRESULT
723TOOLTIPS_AddToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
724{
725 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
726 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
727 TTTOOL_INFO *toolPtr;
728
729 if (lpToolInfo == NULL)
730 return FALSE;
731 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
732 return FALSE;
733
734// TRACE (tooltips, "add tool (%x) %x %d%s!\n",
735// hwnd, lpToolInfo->hwnd, lpToolInfo->uId,
736// (lpToolInfo->uFlags & TTF_IDISHWND) ? " TTF_IDISHWND" : "");
737
738 if (infoPtr->uNumTools == 0)
739 {
740 infoPtr->tools = COMCTL32_Alloc (sizeof(TTTOOL_INFO));
741 toolPtr = infoPtr->tools;
742 } else
743 {
744 TTTOOL_INFO *oldTools = infoPtr->tools;
745 INT x;
746
747 toolPtr = NULL;
748
749 //check if toolinfo already exists
750 for (x = 0;x < infoPtr->uNumTools;x++)
751 {
752 if (lpToolInfo->hwnd == infoPtr->tools[x].hwnd && lpToolInfo->uId == infoPtr->tools[x].uId)
753 {
754 //return toolPtr
755 toolPtr = &infoPtr->tools[x];
756 //free allocated memory
757 TOOLTIPS_Desubclass(toolPtr);
758 if ((toolPtr->hinst) && (toolPtr->lpszText))
759 {
760 if (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(toolPtr->lpszText);
761 }
762
763 break;
764 }
765 }
766
767 if (toolPtr == NULL)
768 {
769 infoPtr->tools = COMCTL32_Alloc(sizeof(TTTOOL_INFO)*(infoPtr->uNumTools+1));
770 memcpy (infoPtr->tools,oldTools,infoPtr->uNumTools*sizeof(TTTOOL_INFO));
771 COMCTL32_Free(oldTools);
772 toolPtr = &infoPtr->tools[infoPtr->uNumTools];
773 }
774 }
775
776 infoPtr->uNumTools++;
777
778 /* copy tool data */
779 toolPtr->uFlags = lpToolInfo->uFlags;
780 toolPtr->hwnd = lpToolInfo->hwnd;
781 toolPtr->uId = lpToolInfo->uId;
782 toolPtr->rect = lpToolInfo->rect;
783 toolPtr->hinst = lpToolInfo->hinst;
784
785 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
786// TRACE (tooltips, "add string id %x!\n", (int)lpToolInfo->lpszText);
787 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
788 }
789 else if (lpToolInfo->lpszText) {
790 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW) {
791// TRACE (tooltips, "add CALLBACK!\n");
792 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
793 }
794 else {
795 INT len = lstrlenW (lpToolInfo->lpszText);
796// TRACE (tooltips, "add text \"%s\"!\n",
797// debugstr_w(lpToolInfo->lpszText));
798 toolPtr->lpszText = COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
799 lstrcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
800 }
801 }
802
803 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
804 toolPtr->lParam = lpToolInfo->lParam;
805
806 /* install subclassing hook */
807 TOOLTIPS_Subclass(hwnd,toolPtr);
808
809 return TRUE;
810}
811
812
813static LRESULT
814TOOLTIPS_DelToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
815{
816 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
817 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
818 TTTOOL_INFO *toolPtr;
819 INT nTool;
820
821 if (lpToolInfo == NULL)
822 return 0;
823 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
824 return 0;
825 if (infoPtr->uNumTools == 0)
826 return 0;
827
828 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
829 if (nTool == -1) return 0;
830
831// TRACE (tooltips, "tool %d\n", nTool);
832
833 /* delete text string */
834 toolPtr = &infoPtr->tools[nTool];
835 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
836 if (toolPtr->lpszText != LPSTR_TEXTCALLBACKW)
837 COMCTL32_Free (toolPtr->lpszText);
838 }
839
840 /* remove subclassing */
841 TOOLTIPS_Desubclass(toolPtr);
842
843 /* delete tool from tool list */
844 if (infoPtr->uNumTools == 1) {
845 COMCTL32_Free (infoPtr->tools);
846 infoPtr->tools = NULL;
847 }
848 else {
849 TTTOOL_INFO *oldTools = infoPtr->tools;
850 infoPtr->tools =
851 COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
852
853 if (nTool > 0)
854 memcpy (&infoPtr->tools[0], &oldTools[0],
855 nTool * sizeof(TTTOOL_INFO));
856
857 if (nTool < infoPtr->uNumTools - 1)
858 memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
859 (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
860
861 COMCTL32_Free (oldTools);
862 }
863
864 infoPtr->uNumTools--;
865
866 return 0;
867}
868
869
870static LRESULT
871TOOLTIPS_DelToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
872{
873 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
874 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
875 TTTOOL_INFO *toolPtr;
876 INT nTool;
877
878 if (lpToolInfo == NULL)
879 return 0;
880 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
881 return 0;
882 if (infoPtr->uNumTools == 0)
883 return 0;
884
885 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
886 if (nTool == -1) return 0;
887
888// TRACE (tooltips, "tool %d\n", nTool);
889
890 /* delete text string */
891 toolPtr = &infoPtr->tools[nTool];
892 if ((toolPtr->hinst) && (toolPtr->lpszText)) {
893 if (toolPtr->lpszText != LPSTR_TEXTCALLBACKW)
894 COMCTL32_Free (toolPtr->lpszText);
895 }
896
897 /* remove subclassing */
898 TOOLTIPS_Desubclass(toolPtr);
899
900 /* delete tool from tool list */
901 if (infoPtr->uNumTools == 1) {
902 COMCTL32_Free (infoPtr->tools);
903 infoPtr->tools = NULL;
904 }
905 else {
906 TTTOOL_INFO *oldTools = infoPtr->tools;
907 infoPtr->tools =
908 COMCTL32_Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
909
910 if (nTool > 0)
911 memcpy (&infoPtr->tools[0], &oldTools[0],
912 nTool * sizeof(TTTOOL_INFO));
913
914 if (nTool < infoPtr->uNumTools - 1)
915 memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
916 (infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
917
918 COMCTL32_Free (oldTools);
919 }
920
921 infoPtr->uNumTools--;
922
923 return 0;
924}
925
926
927static LRESULT
928TOOLTIPS_EnumToolsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
929{
930 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
931 UINT uIndex = (UINT)wParam;
932 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
933 TTTOOL_INFO *toolPtr;
934
935 if (lpToolInfo == NULL)
936 return FALSE;
937 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
938 return FALSE;
939 if (uIndex >= infoPtr->uNumTools)
940 return FALSE;
941
942// TRACE (tooltips, "index=%u\n", uIndex);
943
944 toolPtr = &infoPtr->tools[uIndex];
945
946 /* copy tool data */
947 lpToolInfo->uFlags = toolPtr->uFlags;
948 lpToolInfo->hwnd = toolPtr->hwnd;
949 lpToolInfo->uId = toolPtr->uId;
950 lpToolInfo->rect = toolPtr->rect;
951 lpToolInfo->hinst = toolPtr->hinst;
952/* lpToolInfo->lpszText = toolPtr->lpszText; */
953 lpToolInfo->lpszText = NULL; /* FIXME */
954
955 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
956 lpToolInfo->lParam = toolPtr->lParam;
957
958 return TRUE;
959}
960
961
962static LRESULT
963TOOLTIPS_EnumToolsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
964{
965 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
966 UINT uIndex = (UINT)wParam;
967 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
968 TTTOOL_INFO *toolPtr;
969
970 if (lpToolInfo == NULL)
971 return FALSE;
972 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
973 return FALSE;
974 if (uIndex >= infoPtr->uNumTools)
975 return FALSE;
976
977// TRACE (tooltips, "index=%u\n", uIndex);
978
979 toolPtr = &infoPtr->tools[uIndex];
980
981 /* copy tool data */
982 lpToolInfo->uFlags = toolPtr->uFlags;
983 lpToolInfo->hwnd = toolPtr->hwnd;
984 lpToolInfo->uId = toolPtr->uId;
985 lpToolInfo->rect = toolPtr->rect;
986 lpToolInfo->hinst = toolPtr->hinst;
987/* lpToolInfo->lpszText = toolPtr->lpszText; */
988 lpToolInfo->lpszText = NULL; /* FIXME */
989
990 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
991 lpToolInfo->lParam = toolPtr->lParam;
992
993 return TRUE;
994}
995
996
997static LRESULT
998TOOLTIPS_GetCurrentToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
999{
1000 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1001 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1002 TTTOOL_INFO *toolPtr;
1003
1004 if (lpToolInfo == NULL)
1005 return FALSE;
1006 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1007 return FALSE;
1008
1009 if (lpToolInfo) {
1010 if (infoPtr->nCurrentTool > -1) {
1011 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
1012
1013 /* copy tool data */
1014 lpToolInfo->uFlags = toolPtr->uFlags;
1015 lpToolInfo->rect = toolPtr->rect;
1016 lpToolInfo->hinst = toolPtr->hinst;
1017/* lpToolInfo->lpszText = toolPtr->lpszText; */
1018 lpToolInfo->lpszText = NULL; /* FIXME */
1019
1020 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
1021 lpToolInfo->lParam = toolPtr->lParam;
1022
1023 return TRUE;
1024 }
1025 else
1026 return FALSE;
1027 }
1028 else
1029 return (infoPtr->nCurrentTool != -1);
1030
1031 return FALSE;
1032}
1033
1034
1035static LRESULT
1036TOOLTIPS_GetCurrentToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1037{
1038 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1039 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1040 TTTOOL_INFO *toolPtr;
1041
1042 if (lpToolInfo == NULL)
1043 return FALSE;
1044 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1045 return FALSE;
1046
1047 if (lpToolInfo) {
1048 if (infoPtr->nCurrentTool > -1) {
1049 toolPtr = &infoPtr->tools[infoPtr->nCurrentTool];
1050
1051 /* copy tool data */
1052 lpToolInfo->uFlags = toolPtr->uFlags;
1053 lpToolInfo->rect = toolPtr->rect;
1054 lpToolInfo->hinst = toolPtr->hinst;
1055/* lpToolInfo->lpszText = toolPtr->lpszText; */
1056 lpToolInfo->lpszText = NULL; /* FIXME */
1057
1058 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1059 lpToolInfo->lParam = toolPtr->lParam;
1060
1061 return TRUE;
1062 }
1063 else
1064 return FALSE;
1065 }
1066 else
1067 return (infoPtr->nCurrentTool != -1);
1068
1069 return FALSE;
1070}
1071
1072
1073static LRESULT
1074TOOLTIPS_GetDelayTime (HWND hwnd, WPARAM wParam, LPARAM lParam)
1075{
1076 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1077
1078 switch (wParam) {
1079 case TTDT_AUTOMATIC:
1080 return infoPtr->nAutomaticTime;
1081
1082 case TTDT_RESHOW:
1083 return infoPtr->nReshowTime;
1084
1085 case TTDT_AUTOPOP:
1086 return infoPtr->nAutoPopTime;
1087
1088 case TTDT_INITIAL:
1089 return infoPtr->nInitialTime;
1090 }
1091
1092 return 0;
1093}
1094
1095
1096static LRESULT
1097TOOLTIPS_GetMargin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1098{
1099 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1100 LPRECT lpRect = (LPRECT)lParam;
1101
1102 lpRect->left = infoPtr->rcMargin.left;
1103 lpRect->right = infoPtr->rcMargin.right;
1104 lpRect->bottom = infoPtr->rcMargin.bottom;
1105 lpRect->top = infoPtr->rcMargin.top;
1106
1107 return 0;
1108}
1109
1110
1111static LRESULT
1112TOOLTIPS_GetMaxTipWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
1113{
1114 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1115
1116 return infoPtr->nMaxTipWidth;
1117}
1118
1119
1120static LRESULT
1121TOOLTIPS_GetTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1122{
1123 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1124 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1125 INT nTool;
1126
1127 if (lpToolInfo == NULL)
1128 return 0;
1129 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1130 return 0;
1131
1132 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1133 if (nTool == -1) return 0;
1134
1135 TOOLTIPS_GetTipText(hwnd,infoPtr,nTool);
1136
1137 lstrcpyWtoA(lpToolInfo->lpszText,infoPtr->szTipText);
1138
1139 return 0;
1140}
1141
1142
1143static LRESULT
1144TOOLTIPS_GetTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1145{
1146 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1147 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1148 INT nTool;
1149
1150 if (lpToolInfo == NULL)
1151 return 0;
1152 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1153 return 0;
1154
1155 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1156 if (nTool == -1) return 0;
1157
1158 TOOLTIPS_GetTipText(hwnd,infoPtr,nTool);
1159
1160 lstrcpyW(lpToolInfo->lpszText,infoPtr->szTipText);
1161
1162 return 0;
1163}
1164
1165
1166static LRESULT
1167TOOLTIPS_GetTipBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1168{
1169 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1170 return infoPtr->clrBk;
1171}
1172
1173
1174static LRESULT
1175TOOLTIPS_GetTipTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1176{
1177 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1178 return infoPtr->clrText;
1179}
1180
1181
1182static LRESULT
1183TOOLTIPS_GetToolCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
1184{
1185 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1186 return infoPtr->uNumTools;
1187}
1188
1189
1190static LRESULT
1191TOOLTIPS_GetToolInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1192{
1193 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1194 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1195 TTTOOL_INFO *toolPtr;
1196 INT nTool;
1197
1198 if (lpToolInfo == NULL)
1199 return FALSE;
1200 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1201 return FALSE;
1202 if (infoPtr->uNumTools == 0)
1203 return FALSE;
1204
1205 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1206 if (nTool == -1)
1207 return FALSE;
1208
1209// TRACE (tooltips, "tool %d\n", nTool);
1210
1211 toolPtr = &infoPtr->tools[nTool];
1212
1213 /* copy tool data */
1214 lpToolInfo->uFlags = toolPtr->uFlags;
1215 lpToolInfo->rect = toolPtr->rect;
1216 lpToolInfo->hinst = toolPtr->hinst;
1217/* lpToolInfo->lpszText = toolPtr->lpszText; */
1218 lpToolInfo->lpszText = NULL; /* FIXME */
1219
1220 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
1221 lpToolInfo->lParam = toolPtr->lParam;
1222
1223 return TRUE;
1224}
1225
1226
1227static LRESULT
1228TOOLTIPS_GetToolInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1229{
1230 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1231 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1232 TTTOOL_INFO *toolPtr;
1233 INT nTool;
1234
1235 if (lpToolInfo == NULL)
1236 return FALSE;
1237 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1238 return FALSE;
1239 if (infoPtr->uNumTools == 0)
1240 return FALSE;
1241
1242 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1243 if (nTool == -1)
1244 return FALSE;
1245
1246// TRACE (tooltips, "tool %d\n", nTool);
1247
1248 toolPtr = &infoPtr->tools[nTool];
1249
1250 /* copy tool data */
1251 lpToolInfo->uFlags = toolPtr->uFlags;
1252 lpToolInfo->rect = toolPtr->rect;
1253 lpToolInfo->hinst = toolPtr->hinst;
1254/* lpToolInfo->lpszText = toolPtr->lpszText; */
1255 lpToolInfo->lpszText = NULL; /* FIXME */
1256
1257 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1258 lpToolInfo->lParam = toolPtr->lParam;
1259
1260 return TRUE;
1261}
1262
1263
1264static LRESULT
1265TOOLTIPS_HitTestA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1266{
1267 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1268 LPTTHITTESTINFOA lptthit = (LPTTHITTESTINFOA)lParam;
1269 TTTOOL_INFO *toolPtr;
1270 INT nTool;
1271
1272 if (lptthit == 0)
1273 return FALSE;
1274
1275 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1276 if (nTool == -1)
1277 return FALSE;
1278
1279// TRACE (tooltips, "tool %d!\n", nTool);
1280
1281 /* copy tool data */
1282 if (lptthit->ti.cbSize >= sizeof(TTTOOLINFOA)) {
1283 toolPtr = &infoPtr->tools[nTool];
1284
1285 lptthit->ti.uFlags = toolPtr->uFlags;
1286 lptthit->ti.hwnd = toolPtr->hwnd;
1287 lptthit->ti.uId = toolPtr->uId;
1288 lptthit->ti.rect = toolPtr->rect;
1289 lptthit->ti.hinst = toolPtr->hinst;
1290/* lptthit->ti.lpszText = toolPtr->lpszText; */
1291 lptthit->ti.lpszText = NULL; /* FIXME */
1292 lptthit->ti.lParam = toolPtr->lParam;
1293 }
1294
1295 return TRUE;
1296}
1297
1298
1299static LRESULT
1300TOOLTIPS_HitTestW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1301{
1302 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1303 LPTTHITTESTINFOW lptthit = (LPTTHITTESTINFOW)lParam;
1304 TTTOOL_INFO *toolPtr;
1305 INT nTool;
1306
1307 if (lptthit == 0)
1308 return FALSE;
1309
1310 nTool = TOOLTIPS_GetToolFromPoint (infoPtr, lptthit->hwnd, &lptthit->pt);
1311 if (nTool == -1)
1312 return FALSE;
1313
1314// TRACE (tooltips, "tool %d!\n", nTool);
1315
1316 /* copy tool data */
1317 if (lptthit->ti.cbSize >= sizeof(TTTOOLINFOW)) {
1318 toolPtr = &infoPtr->tools[nTool];
1319
1320 lptthit->ti.uFlags = toolPtr->uFlags;
1321 lptthit->ti.hwnd = toolPtr->hwnd;
1322 lptthit->ti.uId = toolPtr->uId;
1323 lptthit->ti.rect = toolPtr->rect;
1324 lptthit->ti.hinst = toolPtr->hinst;
1325/* lptthit->ti.lpszText = toolPtr->lpszText; */
1326 lptthit->ti.lpszText = NULL; /* FIXME */
1327 lptthit->ti.lParam = toolPtr->lParam;
1328 }
1329
1330 return TRUE;
1331}
1332
1333
1334static LRESULT
1335TOOLTIPS_NewToolRectA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1336{
1337 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1338 LPTTTOOLINFOA lpti = (LPTTTOOLINFOA)lParam;
1339 INT nTool;
1340
1341 if (lpti == NULL)
1342 return 0;
1343 if (lpti->cbSize < TTTOOLINFO_V1_SIZEA)
1344 return FALSE;
1345
1346 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
1347 if (nTool == -1) return 0;
1348
1349 infoPtr->tools[nTool].rect = lpti->rect;
1350
1351 return 0;
1352}
1353
1354
1355static LRESULT
1356TOOLTIPS_NewToolRectW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1357{
1358 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1359 LPTTTOOLINFOW lpti = (LPTTTOOLINFOW)lParam;
1360 INT nTool;
1361
1362 if (lpti == NULL)
1363 return 0;
1364 if (lpti->cbSize < TTTOOLINFO_V1_SIZEW)
1365 return FALSE;
1366
1367 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpti);
1368 if (nTool == -1) return 0;
1369
1370 infoPtr->tools[nTool].rect = lpti->rect;
1371
1372 return 0;
1373}
1374
1375
1376static LRESULT
1377TOOLTIPS_Pop (HWND hwnd, WPARAM wParam, LPARAM lParam)
1378{
1379 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1380
1381 TOOLTIPS_Hide (hwnd, infoPtr);
1382
1383 return 0;
1384}
1385
1386
1387static LRESULT
1388TOOLTIPS_RelayEvent (HWND hwnd, WPARAM wParam, LPARAM lParam)
1389{
1390 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1391 LPMSG lpMsg = (LPMSG)lParam;
1392 POINT pt;
1393
1394 if (lParam == 0)
1395 {
1396// ERR (tooltips, "lpMsg == NULL!\n");
1397 return 0;
1398 }
1399
1400 switch (lpMsg->message)
1401 {
1402 case WM_LBUTTONDOWN:
1403 case WM_LBUTTONUP:
1404 case WM_MBUTTONDOWN:
1405 case WM_MBUTTONUP:
1406 case WM_RBUTTONDOWN:
1407 case WM_RBUTTONUP:
1408 pt = lpMsg->pt;
1409 ScreenToClient(lpMsg->hwnd,&pt);
1410 infoPtr->nOldTool = infoPtr->nTool;
1411 infoPtr->nTool = TOOLTIPS_GetToolFromPoint(infoPtr,lpMsg->hwnd,&pt);
1412// TRACE (tooltips, "tool (%x) %d %d\n",
1413// hwnd, infoPtr->nOldTool, infoPtr->nTool);
1414 TOOLTIPS_Hide (hwnd, infoPtr);
1415 break;
1416
1417 case WM_MOUSEMOVE:
1418 pt = lpMsg->pt;
1419 ScreenToClient(lpMsg->hwnd,&pt);
1420 infoPtr->nOldTool = infoPtr->nTool;
1421 infoPtr->nTool = TOOLTIPS_GetToolFromPoint(infoPtr,lpMsg->hwnd,&pt);
1422// TRACE (tooltips, "tool (%x) %d %d\n",
1423// hwnd, infoPtr->nOldTool, infoPtr->nTool);
1424// TRACE (tooltips, "WM_MOUSEMOVE (%04x %ld %ld)\n",
1425// hwnd, pt.x, pt.y);
1426
1427 if (infoPtr->bActive && (infoPtr->nTool != infoPtr->nOldTool))
1428 {
1429 if (infoPtr->nOldTool == -1)
1430 {
1431 SetTimer(hwnd,ID_TIMERSHOW,infoPtr->nInitialTime,0);
1432// TRACE (tooltips, "timer 1 started!\n");
1433 } else
1434 {
1435 TOOLTIPS_Hide(hwnd,infoPtr);
1436 SetTimer (hwnd,ID_TIMERSHOW,infoPtr->nReshowTime,0);
1437// TRACE (tooltips, "timer 2 started!\n");
1438 }
1439 }
1440 if (infoPtr->nCurrentTool != -1)
1441 {
1442 SetTimer(hwnd,ID_TIMERLEAVE,100,0);
1443// TRACE (tooltips, "timer 3 started!\n");
1444 }
1445 break;
1446 }
1447
1448 return 0;
1449}
1450
1451
1452static LRESULT
1453TOOLTIPS_SetDelayTime (HWND hwnd, WPARAM wParam, LPARAM lParam)
1454{
1455 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1456 INT nTime = (INT)LOWORD(lParam);
1457
1458 switch (wParam) {
1459 case TTDT_AUTOMATIC:
1460 if (nTime == 0) {
1461 infoPtr->nAutomaticTime = 500;
1462 infoPtr->nReshowTime = 100;
1463 infoPtr->nAutoPopTime = 5000;
1464 infoPtr->nInitialTime = 500;
1465 }
1466 else {
1467 infoPtr->nAutomaticTime = nTime;
1468 infoPtr->nReshowTime = nTime / 5;
1469 infoPtr->nAutoPopTime = nTime * 10;
1470 infoPtr->nInitialTime = nTime;
1471 }
1472 break;
1473
1474 case TTDT_RESHOW:
1475 infoPtr->nReshowTime = nTime;
1476 break;
1477
1478 case TTDT_AUTOPOP:
1479 infoPtr->nAutoPopTime = nTime;
1480 break;
1481
1482 case TTDT_INITIAL:
1483 infoPtr->nInitialTime = nTime;
1484 break;
1485 }
1486
1487 return 0;
1488}
1489
1490
1491static LRESULT
1492TOOLTIPS_SetMargin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1493{
1494 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1495 LPRECT lpRect = (LPRECT)lParam;
1496
1497 infoPtr->rcMargin.left = lpRect->left;
1498 infoPtr->rcMargin.right = lpRect->right;
1499 infoPtr->rcMargin.bottom = lpRect->bottom;
1500 infoPtr->rcMargin.top = lpRect->top;
1501
1502 return 0;
1503}
1504
1505
1506static LRESULT
1507TOOLTIPS_SetMaxTipWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
1508{
1509 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1510 INT nTemp = infoPtr->nMaxTipWidth;
1511
1512 infoPtr->nMaxTipWidth = (INT)lParam;
1513
1514 return nTemp;
1515}
1516
1517
1518static LRESULT
1519TOOLTIPS_SetTipBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1520{
1521 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1522
1523 infoPtr->clrBk = (COLORREF)wParam;
1524
1525 return 0;
1526}
1527
1528
1529static LRESULT
1530TOOLTIPS_SetTipTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1531{
1532 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1533
1534 infoPtr->clrText = (COLORREF)wParam;
1535
1536 return 0;
1537}
1538
1539
1540static LRESULT
1541TOOLTIPS_SetToolInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1542{
1543 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1544 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1545 TTTOOL_INFO *toolPtr;
1546 INT nTool;
1547
1548 if (lpToolInfo == NULL)
1549 return 0;
1550 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA)
1551 return 0;
1552
1553 nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
1554 if (nTool == -1) return 0;
1555
1556// TRACE (tooltips, "tool %d\n", nTool);
1557
1558 toolPtr = &infoPtr->tools[nTool];
1559
1560 /* copy tool data */
1561 toolPtr->uFlags = lpToolInfo->uFlags;
1562 toolPtr->hwnd = lpToolInfo->hwnd;
1563 toolPtr->uId = lpToolInfo->uId;
1564 toolPtr->rect = lpToolInfo->rect;
1565 toolPtr->hinst = lpToolInfo->hinst;
1566
1567 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
1568// TRACE (tooltips, "set string id %x!\n", (INT)lpToolInfo->lpszText);
1569 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
1570 }
1571 else if (lpToolInfo->lpszText) {
1572 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA)
1573 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1574 else {
1575 if (toolPtr->lpszText) {
1576 COMCTL32_Free (toolPtr->lpszText);
1577 toolPtr->lpszText = NULL;
1578 }
1579 if (lpToolInfo->lpszText) {
1580 INT len = lstrlenA (lpToolInfo->lpszText);
1581 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1582 lstrcpyAtoW (toolPtr->lpszText, lpToolInfo->lpszText);
1583 }
1584 }
1585 }
1586
1587 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOA))
1588 toolPtr->lParam = lpToolInfo->lParam;
1589
1590 return 0;
1591}
1592
1593
1594static LRESULT
1595TOOLTIPS_SetToolInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1596{
1597 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1598 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1599 TTTOOL_INFO *toolPtr;
1600 INT nTool;
1601
1602 if (lpToolInfo == NULL)
1603 return 0;
1604 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1605 return 0;
1606
1607 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1608 if (nTool == -1) return 0;
1609
1610// TRACE (tooltips, "tool %d\n", nTool);
1611
1612 toolPtr = &infoPtr->tools[nTool];
1613
1614 /* copy tool data */
1615 toolPtr->uFlags = lpToolInfo->uFlags;
1616 toolPtr->hwnd = lpToolInfo->hwnd;
1617 toolPtr->uId = lpToolInfo->uId;
1618 toolPtr->rect = lpToolInfo->rect;
1619 toolPtr->hinst = lpToolInfo->hinst;
1620
1621 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
1622// TRACE (tooltips, "set string id %x!\n", (INT)lpToolInfo->lpszText);
1623 toolPtr->lpszText = lpToolInfo->lpszText;
1624 }
1625 else if (lpToolInfo->lpszText) {
1626 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW)
1627 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1628 else {
1629 if (toolPtr->lpszText) {
1630 COMCTL32_Free (toolPtr->lpszText);
1631 toolPtr->lpszText = NULL;
1632 }
1633 if (lpToolInfo->lpszText) {
1634 INT len = lstrlenW (lpToolInfo->lpszText);
1635 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1636 lstrcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
1637 }
1638 }
1639 }
1640
1641 if (lpToolInfo->cbSize >= sizeof(TTTOOLINFOW))
1642 toolPtr->lParam = lpToolInfo->lParam;
1643
1644 return 0;
1645}
1646
1647
1648static LRESULT
1649TOOLTIPS_TrackActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
1650{
1651 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1652 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1653
1654 if (lpToolInfo == NULL) return 0;
1655 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA) return FALSE;
1656
1657 if ((BOOL)wParam)
1658 {
1659 /* activate */
1660 infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoA(infoPtr,lpToolInfo);
1661 if (infoPtr->nTrackTool != -1)
1662 {
1663// TRACE (tooltips, "activated!\n");
1664 infoPtr->bTrackActive = TRUE;
1665 TOOLTIPS_TrackShow(hwnd,infoPtr);
1666 }
1667 } else
1668 {
1669 /* deactivate */
1670 TOOLTIPS_TrackHide(hwnd,infoPtr);
1671
1672 infoPtr->bTrackActive = FALSE;
1673 infoPtr->nTrackTool = -1;
1674
1675// TRACE (tooltips, "deactivated!\n");
1676 }
1677
1678 return 0;
1679}
1680
1681
1682static LRESULT
1683TOOLTIPS_TrackPosition (HWND hwnd, WPARAM wParam, LPARAM lParam)
1684{
1685 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1686
1687 infoPtr->xTrackPos = (INT)LOWORD(lParam);
1688 infoPtr->yTrackPos = (INT)HIWORD(lParam);
1689
1690 if (infoPtr->bTrackActive)
1691 {
1692// TRACE (tooltips, "[%d %d]\n",
1693// infoPtr->xTrackPos, infoPtr->yTrackPos);
1694 TOOLTIPS_TrackShow(hwnd,infoPtr);
1695 }
1696
1697 return 0;
1698}
1699
1700
1701static LRESULT
1702TOOLTIPS_Update (HWND hwnd, WPARAM wParam, LPARAM lParam)
1703{
1704 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1705
1706 if (infoPtr->nCurrentTool != -1)
1707 UpdateWindow (hwnd);
1708
1709 return 0;
1710}
1711
1712
1713static LRESULT
1714TOOLTIPS_UpdateTipTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1715{
1716 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1717 LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
1718 TTTOOL_INFO *toolPtr;
1719 INT nTool;
1720
1721 if (lpToolInfo == NULL) return 0;
1722 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEA) return FALSE;
1723
1724 nTool = TOOLTIPS_GetToolFromInfoA(infoPtr,lpToolInfo);
1725 if (nTool == -1) return 0;
1726
1727// TRACE (tooltips, "tool %d\n", nTool);
1728
1729 toolPtr = &infoPtr->tools[nTool];
1730
1731 /* copy tool text */
1732 toolPtr->hinst = lpToolInfo->hinst;
1733
1734 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0))
1735 {
1736 toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
1737 } else if (lpToolInfo->lpszText)
1738 {
1739 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKA) toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1740 else
1741 {
1742 if (toolPtr->lpszText)
1743 {
1744 COMCTL32_Free(toolPtr->lpszText);
1745 toolPtr->lpszText = NULL;
1746 }
1747 if (lpToolInfo->lpszText)
1748 {
1749 INT len = lstrlenA(lpToolInfo->lpszText);
1750 toolPtr->lpszText = COMCTL32_Alloc((len+1)*sizeof(WCHAR));
1751 lstrcpyAtoW(toolPtr->lpszText,lpToolInfo->lpszText);
1752 }
1753 }
1754 }
1755
1756 /* force repaint */
1757 if (infoPtr->bActive) TOOLTIPS_Show(hwnd,infoPtr);
1758 else if (infoPtr->bTrackActive) TOOLTIPS_TrackShow(hwnd,infoPtr);
1759
1760 return 0;
1761}
1762
1763
1764static LRESULT
1765TOOLTIPS_UpdateTipTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1766{
1767 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1768 LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
1769 TTTOOL_INFO *toolPtr;
1770 INT nTool;
1771
1772 if (lpToolInfo == NULL)
1773 return 0;
1774 if (lpToolInfo->cbSize < TTTOOLINFO_V1_SIZEW)
1775 return FALSE;
1776
1777 nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
1778 if (nTool == -1)
1779 return 0;
1780
1781// TRACE (tooltips, "tool %d\n", nTool);
1782
1783 toolPtr = &infoPtr->tools[nTool];
1784
1785 /* copy tool text */
1786 toolPtr->hinst = lpToolInfo->hinst;
1787
1788 if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)){
1789 toolPtr->lpszText = lpToolInfo->lpszText;
1790 }
1791 else if (lpToolInfo->lpszText) {
1792 if (lpToolInfo->lpszText == LPSTR_TEXTCALLBACKW)
1793 toolPtr->lpszText = LPSTR_TEXTCALLBACKW;
1794 else {
1795 if (toolPtr->lpszText) {
1796 COMCTL32_Free (toolPtr->lpszText);
1797 toolPtr->lpszText = NULL;
1798 }
1799 if (lpToolInfo->lpszText) {
1800 INT len = lstrlenW (lpToolInfo->lpszText);
1801 toolPtr->lpszText = COMCTL32_Alloc ((len+1)*sizeof(WCHAR));
1802 lstrcpyW (toolPtr->lpszText, lpToolInfo->lpszText);
1803 }
1804 }
1805 }
1806
1807 /* force repaint */
1808 if (infoPtr->bActive)
1809 TOOLTIPS_Show (hwnd, infoPtr);
1810 else if (infoPtr->bTrackActive)
1811 TOOLTIPS_TrackShow (hwnd, infoPtr);
1812
1813 return 0;
1814}
1815
1816
1817static LRESULT
1818TOOLTIPS_WindowFromPoint (HWND hwnd, WPARAM wParam, LPARAM lParam)
1819{
1820 return WindowFromPoint (*((LPPOINT)lParam));
1821}
1822
1823
1824
1825static LRESULT
1826TOOLTIPS_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1827{
1828 TOOLTIPS_INFO *infoPtr;
1829 NONCLIENTMETRICSA nclm;
1830 INT nResult;
1831
1832 /* allocate memory for info structure */
1833 infoPtr = (TOOLTIPS_INFO *)COMCTL32_Alloc(sizeof(TOOLTIPS_INFO));
1834 SetWindowLongA(hwnd,0,(DWORD)infoPtr);
1835
1836 /* initialize info structure */
1837 infoPtr->szTipText[0] = '\0';
1838 infoPtr->bActive = TRUE;
1839 infoPtr->bTrackActive = FALSE;
1840 infoPtr->clrBk = GetSysColor(COLOR_INFOBK);
1841 infoPtr->clrText = GetSysColor(COLOR_INFOTEXT);
1842 infoPtr->xTrackPos = 0;
1843 infoPtr->yTrackPos = 0;
1844
1845 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1846 SystemParametersInfoA(SPI_GETNONCLIENTMETRICS,0,&nclm,0);
1847 infoPtr->hFont = CreateFontIndirectA(&nclm.lfStatusFont);
1848
1849 infoPtr->nMaxTipWidth = -1;
1850 infoPtr->nTool = -1;
1851 infoPtr->nOldTool = -1;
1852 infoPtr->nCurrentTool = -1;
1853 infoPtr->nTrackTool = -1;
1854
1855 infoPtr->nAutomaticTime = 500;
1856 infoPtr->nReshowTime = 100;
1857 infoPtr->nAutoPopTime = 5000;
1858 infoPtr->nInitialTime = 500;
1859
1860 SetRectEmpty(&infoPtr->rcMargin);
1861
1862 nResult = (INT)SendMessageA(GetParent(hwnd),WM_NOTIFYFORMAT,(WPARAM)hwnd,(LPARAM)NF_QUERY);
1863// if (nResult == NFR_ANSI)
1864// TRACE (tooltips, " -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
1865// else if (nResult == NFR_UNICODE)
1866// FIXME (tooltips, " -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
1867// else
1868// FIXME (tooltips, " -- WM_NOTIFYFORMAT returns: error!\n");
1869
1870 SetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
1871
1872 return 0;
1873}
1874
1875
1876static LRESULT
1877TOOLTIPS_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1878{
1879 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr(hwnd);
1880 TTTOOL_INFO *toolPtr;
1881 INT i;
1882
1883 /* free tools */
1884 if (infoPtr->tools)
1885 {
1886 for (i = 0;i < infoPtr->uNumTools;i++)
1887 {
1888 toolPtr = &infoPtr->tools[i];
1889 if ((toolPtr->hinst) && (toolPtr->lpszText))
1890 {
1891 if (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) COMCTL32_Free(toolPtr->lpszText);
1892 }
1893
1894 /* remove subclassing */
1895 TOOLTIPS_Desubclass(toolPtr);
1896
1897 }
1898 COMCTL32_Free (infoPtr->tools);
1899 }
1900
1901 /* delete font */
1902 DeleteObject (infoPtr->hFont);
1903
1904 /* free tool tips info data */
1905 COMCTL32_Free(infoPtr);
1906
1907 return 0;
1908}
1909
1910
1911static LRESULT
1912TOOLTIPS_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
1913{
1914 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1915 RECT rect;
1916 HBRUSH hBrush;
1917
1918 hBrush = CreateSolidBrush (infoPtr->clrBk);
1919 GetClientRect (hwnd, &rect);
1920 FillRect ((HDC)wParam, &rect, hBrush);
1921 DeleteObject (hBrush);
1922
1923 return FALSE;
1924}
1925
1926
1927static LRESULT
1928TOOLTIPS_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1929{
1930 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1931
1932 return infoPtr->hFont;
1933}
1934
1935
1936static LRESULT
1937TOOLTIPS_MouseMessage (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1938{
1939 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1940
1941 TOOLTIPS_Hide (hwnd, infoPtr);
1942
1943 return 0;
1944}
1945
1946
1947static LRESULT
1948TOOLTIPS_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
1949{
1950 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1951 DWORD dwExStyle = GetWindowLongA(hwnd,GWL_EXSTYLE);
1952
1953 dwStyle &= 0x0000FFFF;
1954 dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
1955 SetWindowLongA(hwnd,GWL_STYLE,dwStyle);
1956
1957 SetWindowLongA(hwnd,GWL_EXSTYLE,dwExStyle | WS_EX_TOOLWINDOW);
1958
1959 return TRUE;
1960}
1961
1962
1963static LRESULT
1964TOOLTIPS_NCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1965{
1966 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
1967 INT nTool = (infoPtr->bTrackActive) ? infoPtr->nTrackTool : infoPtr->nTool;
1968
1969// TRACE (tooltips, " nTool=%d\n", nTool);
1970
1971 if ((nTool > -1) && (nTool < infoPtr->uNumTools)) {
1972 if (infoPtr->tools[nTool].uFlags & TTF_TRANSPARENT) {
1973// TRACE (tooltips, "-- in transparent mode!\n");
1974 return HTTRANSPARENT;
1975 }
1976 }
1977
1978 return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
1979}
1980
1981
1982static LRESULT
1983TOOLTIPS_Paint (HWND hwnd, WPARAM wParam, LPARAM lParam)
1984{
1985 HDC hdc;
1986 PAINTSTRUCT ps;
1987
1988 hdc = (wParam == 0) ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1989 TOOLTIPS_Refresh (hwnd, hdc);
1990 if (!wParam)
1991 EndPaint (hwnd, &ps);
1992 return 0;
1993}
1994
1995
1996static LRESULT
1997TOOLTIPS_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1998{
1999 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2000
2001 infoPtr->hFont = (HFONT)wParam;
2002
2003 if ((LOWORD(lParam)) & (infoPtr->nCurrentTool != -1))
2004 {
2005 /* force repaint */
2006 if (infoPtr->bActive) TOOLTIPS_Show(hwnd,infoPtr);
2007 else if (infoPtr->bTrackActive) TOOLTIPS_TrackShow(hwnd,infoPtr);
2008 }
2009
2010 return 0;
2011}
2012/******************************************************************
2013 * TOOLTIPS_OnWMGetTextLength
2014 *
2015 * This function is called when the tooltip receive a
2016 * WM_GETTEXTLENGTH message.
2017 * wParam : not used
2018 * lParam : not used
2019 *
2020 * returns the length, in characters, of the tip text
2021 ******************************************************************/
2022static LRESULT
2023TOOLTIPS_OnWMGetTextLength(HWND hwnd, WPARAM wParam, LPARAM lParam)
2024{
2025 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2026 return lstrlenW(infoPtr->szTipText);
2027}
2028/******************************************************************
2029 * TOOLTIPS_OnWMGetText
2030 *
2031 * This function is called when the tooltip receive a
2032 * WM_GETTEXT message.
2033 * wParam : specifies the maximum number of characters to be copied
2034 * lParam : is the pointer to the buffer that will receive
2035 * the tip text
2036 *
2037 * returns the number of characters copied
2038 ******************************************************************/
2039static LRESULT
2040TOOLTIPS_OnWMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
2041{
2042 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2043 INT length;
2044
2045 if(!infoPtr || !(infoPtr->szTipText))
2046 return 0;
2047
2048 length = lstrlenW(infoPtr->szTipText);
2049 /* When wParam is smaller than the lenght of the tip text
2050 copy wParam characters of the tip text and return wParam */
2051 if(wParam < length)
2052 {
2053 lstrcpynWtoA((LPSTR)lParam,infoPtr->szTipText,(UINT)wParam);//includes 0 terminator
2054 return wParam;
2055 }
2056 lstrcpyWtoA((LPSTR)lParam,infoPtr->szTipText);
2057 return length;
2058
2059}
2060
2061static LRESULT
2062TOOLTIPS_Timer (HWND hwnd, WPARAM wParam, LPARAM lParam)
2063{
2064 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2065
2066// TRACE (tooltips, "timer %d (%x) expired!\n", wParam, hwnd);
2067 switch (wParam)
2068 {
2069 case ID_TIMERSHOW:
2070 KillTimer(hwnd,ID_TIMERSHOW);
2071 if (TOOLTIPS_CheckTool(hwnd,TRUE) == infoPtr->nTool)
2072 TOOLTIPS_Show(hwnd,infoPtr);
2073 break;
2074
2075 case ID_TIMERPOP:
2076 TOOLTIPS_Hide (hwnd, infoPtr);
2077 break;
2078
2079 case ID_TIMERLEAVE:
2080 KillTimer (hwnd,ID_TIMERLEAVE);
2081 if (TOOLTIPS_CheckTool(hwnd,FALSE) == -1)
2082 {
2083 infoPtr->nTool = -1;
2084 infoPtr->nOldTool = -1;
2085 TOOLTIPS_Hide(hwnd,infoPtr);
2086 }
2087 break;
2088 }
2089
2090 return 0;
2091}
2092
2093
2094static LRESULT
2095TOOLTIPS_WinIniChange (HWND hwnd, WPARAM wParam, LPARAM lParam)
2096{
2097 TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
2098 NONCLIENTMETRICSA nclm;
2099
2100 infoPtr->clrBk = GetSysColor (COLOR_INFOBK);
2101 infoPtr->clrText = GetSysColor (COLOR_INFOTEXT);
2102
2103 DeleteObject (infoPtr->hFont);
2104 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
2105 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
2106 infoPtr->hFont = CreateFontIndirectA (&nclm.lfStatusFont);
2107
2108 return 0;
2109}
2110
2111
2112LRESULT CALLBACK
2113TOOLTIPS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2114{
2115 LPTT_SUBCLASS_INFO lpttsi =
2116 (LPTT_SUBCLASS_INFO)GetPropA (hwnd, COMCTL32_aSubclass);
2117 TOOLTIPS_INFO *infoPtr;
2118 UINT nTool;
2119
2120 switch (uMsg) {
2121 case WM_LBUTTONDOWN:
2122 case WM_LBUTTONUP:
2123 case WM_MBUTTONDOWN:
2124 case WM_MBUTTONUP:
2125 case WM_RBUTTONDOWN:
2126 case WM_RBUTTONUP:
2127 infoPtr = TOOLTIPS_GetInfoPtr(lpttsi->hwndToolTip);
2128 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2129
2130// TRACE (tooltips, "subclassed mouse message %04x\n", uMsg);
2131 infoPtr->nOldTool = infoPtr->nTool;
2132 infoPtr->nTool = nTool;
2133 TOOLTIPS_Hide (lpttsi->hwndToolTip, infoPtr);
2134 break;
2135
2136 case WM_MOUSEMOVE:
2137 infoPtr = TOOLTIPS_GetInfoPtr (lpttsi->hwndToolTip);
2138 nTool = TOOLTIPS_GetToolFromMessage (infoPtr, hwnd);
2139
2140// TRACE (tooltips, "subclassed WM_MOUSEMOVE\n");
2141 infoPtr->nOldTool = infoPtr->nTool;
2142 infoPtr->nTool = nTool;
2143
2144 if ((infoPtr->bActive) &&
2145 (infoPtr->nTool != infoPtr->nOldTool)) {
2146 if (infoPtr->nOldTool == -1) {
2147 SetTimer (hwnd, ID_TIMERSHOW,
2148 infoPtr->nInitialTime, 0);
2149// TRACE (tooltips, "timer 1 started!\n");
2150 }
2151 else {
2152 TOOLTIPS_Hide (lpttsi->hwndToolTip, infoPtr);
2153 SetTimer (hwnd, ID_TIMERSHOW,
2154 infoPtr->nReshowTime, 0);
2155// TRACE (tooltips, "timer 2 started!\n");
2156 }
2157 }
2158 if (infoPtr->nCurrentTool != -1) {
2159 SetTimer (hwnd, ID_TIMERLEAVE, 100, 0);
2160// TRACE (tooltips, "timer 3 started!\n");
2161 }
2162 break;
2163 }
2164
2165 return CallWindowProcA (lpttsi->wpOrigProc, hwnd, uMsg, wParam, lParam);
2166}
2167
2168
2169LRESULT CALLBACK
2170TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2171{
2172 switch (uMsg)
2173 {
2174 case TTM_ACTIVATE:
2175 return TOOLTIPS_Activate (hwnd, wParam, lParam);
2176
2177 case TTM_ADDTOOLA:
2178 return TOOLTIPS_AddToolA (hwnd, wParam, lParam);
2179
2180 case TTM_ADDTOOLW:
2181 return TOOLTIPS_AddToolW (hwnd, wParam, lParam);
2182
2183 case TTM_DELTOOLA:
2184 return TOOLTIPS_DelToolA (hwnd, wParam, lParam);
2185
2186 case TTM_DELTOOLW:
2187 return TOOLTIPS_DelToolW (hwnd, wParam, lParam);
2188
2189 case TTM_ENUMTOOLSA:
2190 return TOOLTIPS_EnumToolsA (hwnd, wParam, lParam);
2191
2192 case TTM_ENUMTOOLSW:
2193 return TOOLTIPS_EnumToolsW (hwnd, wParam, lParam);
2194
2195 case TTM_GETCURRENTTOOLA:
2196 return TOOLTIPS_GetCurrentToolA (hwnd, wParam, lParam);
2197
2198 case TTM_GETCURRENTTOOLW:
2199 return TOOLTIPS_GetCurrentToolW (hwnd, wParam, lParam);
2200
2201 case TTM_GETDELAYTIME:
2202 return TOOLTIPS_GetDelayTime (hwnd, wParam, lParam);
2203
2204 case TTM_GETMARGIN:
2205 return TOOLTIPS_GetMargin (hwnd, wParam, lParam);
2206
2207 case TTM_GETMAXTIPWIDTH:
2208 return TOOLTIPS_GetMaxTipWidth (hwnd, wParam, lParam);
2209
2210 case TTM_GETTEXTA:
2211 return TOOLTIPS_GetTextA (hwnd, wParam, lParam);
2212
2213 case TTM_GETTEXTW:
2214 return TOOLTIPS_GetTextW (hwnd, wParam, lParam);
2215
2216 case TTM_GETTIPBKCOLOR:
2217 return TOOLTIPS_GetTipBkColor (hwnd, wParam, lParam);
2218
2219 case TTM_GETTIPTEXTCOLOR:
2220 return TOOLTIPS_GetTipTextColor (hwnd, wParam, lParam);
2221
2222 case TTM_GETTOOLCOUNT:
2223 return TOOLTIPS_GetToolCount (hwnd, wParam, lParam);
2224
2225 case TTM_GETTOOLINFOA:
2226 return TOOLTIPS_GetToolInfoA (hwnd, wParam, lParam);
2227
2228 case TTM_GETTOOLINFOW:
2229 return TOOLTIPS_GetToolInfoW (hwnd, wParam, lParam);
2230
2231 case TTM_HITTESTA:
2232 return TOOLTIPS_HitTestA (hwnd, wParam, lParam);
2233
2234 case TTM_HITTESTW:
2235 return TOOLTIPS_HitTestW (hwnd, wParam, lParam);
2236
2237 case TTM_NEWTOOLRECTA:
2238 return TOOLTIPS_NewToolRectA (hwnd, wParam, lParam);
2239
2240 case TTM_NEWTOOLRECTW:
2241 return TOOLTIPS_NewToolRectW (hwnd, wParam, lParam);
2242
2243 case TTM_POP:
2244 return TOOLTIPS_Pop (hwnd, wParam, lParam);
2245
2246 case TTM_RELAYEVENT:
2247 return TOOLTIPS_RelayEvent (hwnd, wParam, lParam);
2248
2249 case TTM_SETDELAYTIME:
2250 return TOOLTIPS_SetDelayTime (hwnd, wParam, lParam);
2251
2252 case TTM_SETMARGIN:
2253 return TOOLTIPS_SetMargin (hwnd, wParam, lParam);
2254
2255 case TTM_SETMAXTIPWIDTH:
2256 return TOOLTIPS_SetMaxTipWidth (hwnd, wParam, lParam);
2257
2258 case TTM_SETTIPBKCOLOR:
2259 return TOOLTIPS_SetTipBkColor (hwnd, wParam, lParam);
2260
2261 case TTM_SETTIPTEXTCOLOR:
2262 return TOOLTIPS_SetTipTextColor (hwnd, wParam, lParam);
2263
2264 case TTM_SETTOOLINFOA:
2265 return TOOLTIPS_SetToolInfoA (hwnd, wParam, lParam);
2266
2267 case TTM_SETTOOLINFOW:
2268 return TOOLTIPS_SetToolInfoW (hwnd, wParam, lParam);
2269
2270 case TTM_TRACKACTIVATE:
2271 return TOOLTIPS_TrackActivate (hwnd, wParam, lParam);
2272
2273 case TTM_TRACKPOSITION:
2274 return TOOLTIPS_TrackPosition (hwnd, wParam, lParam);
2275
2276 case TTM_UPDATE:
2277 return TOOLTIPS_Update (hwnd, wParam, lParam);
2278
2279 case TTM_UPDATETIPTEXTA:
2280 return TOOLTIPS_UpdateTipTextA (hwnd, wParam, lParam);
2281
2282 case TTM_UPDATETIPTEXTW:
2283 return TOOLTIPS_UpdateTipTextW (hwnd, wParam, lParam);
2284
2285 case TTM_WINDOWFROMPOINT:
2286 return TOOLTIPS_WindowFromPoint (hwnd, wParam, lParam);
2287
2288
2289 case WM_CREATE:
2290 return TOOLTIPS_Create (hwnd, wParam, lParam);
2291
2292 case WM_DESTROY:
2293 return TOOLTIPS_Destroy (hwnd, wParam, lParam);
2294
2295 case WM_ERASEBKGND:
2296 return TOOLTIPS_EraseBackground (hwnd, wParam, lParam);
2297
2298 case WM_GETFONT:
2299 return TOOLTIPS_GetFont (hwnd, wParam, lParam);
2300
2301 case WM_GETTEXT:
2302 return TOOLTIPS_OnWMGetText (hwnd, wParam, lParam);
2303
2304 case WM_GETTEXTLENGTH:
2305 return TOOLTIPS_OnWMGetTextLength (hwnd, wParam, lParam);
2306
2307
2308 case WM_LBUTTONDOWN:
2309 case WM_LBUTTONUP:
2310 case WM_MBUTTONDOWN:
2311 case WM_MBUTTONUP:
2312 case WM_RBUTTONDOWN:
2313 case WM_RBUTTONUP:
2314 case WM_MOUSEMOVE:
2315 return TOOLTIPS_MouseMessage (hwnd, uMsg, wParam, lParam);
2316
2317 case WM_NCCREATE:
2318 return TOOLTIPS_NCCreate (hwnd, wParam, lParam);
2319
2320 case WM_NCHITTEST:
2321 return TOOLTIPS_NCHitTest (hwnd, wParam, lParam);
2322
2323/* case WM_NOTIFYFORMAT: */
2324/* return TOOLTIPS_NotifyFormat (hwnd, wParam, lParam); */
2325
2326 case WM_PAINT:
2327 return TOOLTIPS_Paint (hwnd, wParam, lParam);
2328
2329 case WM_SETFONT:
2330 return TOOLTIPS_SetFont (hwnd, wParam, lParam);
2331
2332 case WM_TIMER:
2333 return TOOLTIPS_Timer (hwnd, wParam, lParam);
2334
2335 case WM_WININICHANGE:
2336 return TOOLTIPS_WinIniChange (hwnd, wParam, lParam);
2337
2338 default:
2339// if (uMsg >= WM_USER)
2340// ERR (tooltips, "unknown msg %04x wp=%08x lp=%08lx\n",
2341// uMsg, wParam, lParam);
2342 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
2343 }
2344 return 0;
2345}
2346
2347
2348VOID
2349TOOLTIPS_Register (VOID)
2350{
2351 WNDCLASSA wndClass;
2352
2353 if (GlobalFindAtomA (TOOLTIPS_CLASSA)) return;
2354
2355 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2356 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
2357 wndClass.lpfnWndProc = (WNDPROC)TOOLTIPS_WindowProc;
2358 wndClass.cbClsExtra = 0;
2359 wndClass.cbWndExtra = sizeof(TOOLTIPS_INFO *);
2360 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
2361 wndClass.hbrBackground = 0;
2362 wndClass.lpszClassName = TOOLTIPS_CLASSA;
2363
2364 RegisterClassA (&wndClass);
2365}
2366
2367
2368VOID
2369TOOLTIPS_Unregister (VOID)
2370{
2371 if (GlobalFindAtomA (TOOLTIPS_CLASSA))
2372 UnregisterClassA (TOOLTIPS_CLASSA, (HINSTANCE)NULL);
2373}
2374
Note: See TracBrowser for help on using the repository browser.