Fixes for FreeBSD.
[wine] / dlls / comctl32 / toolbar.c
1 /*
2  * Toolbar control
3  *
4  * Copyright 1998 Eric Kohl
5  *
6  * TODO:
7  *   - A little bug in TOOLBAR_DrawMasked()
8  *   - Button wrapping (under construction).
9  *   - Messages.
10  *   - Notifications.
11  *   - Fix TB_SETROWS.
12  *   - Tooltip support (almost complete).
13  *   - Unicode suppport.
14  *   - Internal COMMCTL32 bitmaps.
15  *   - Fix TOOLBAR_SetButtonInfo32A.
16  *   - Fix TOOLBAR_Customize. (Customize dialog.)
17  *
18  * Testing:
19  *   - Run tests using Waite Group Windows95 API Bible Volume 2.
20  *     The second cdrom contains executables addstr.exe, btncount.exe,
21  *     btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
22  *     enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
23  *     indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
24  *     setparnt.exe, setrows.exe, toolwnd.exe.
25  *   - Microsofts controlspy examples.
26  */
27
28 #include "windows.h"
29 #include "commctrl.h"
30 #include "sysmetrics.h"
31 #include "cache.h"
32 #include "toolbar.h"
33 #include "win.h"
34 #include "debug.h"
35
36 // #define __NEW_WRAP_CODE__
37
38 #define SEPARATOR_WIDTH    8
39 #define SEPARATOR_HEIGHT   5
40 #define TOP_BORDER         2
41 #define BOTTOM_BORDER      2
42
43
44
45 #define TOOLBAR_GetInfoPtr(wndPtr) ((TOOLBAR_INFO *)wndPtr->wExtra[0])
46
47
48 static void
49 TOOLBAR_DrawFlatSeparator (LPRECT32 lpRect, HDC32 hdc)
50 {
51     INT32 x = (lpRect->left + lpRect->right) / 2 - 1;
52     INT32 yBottom = lpRect->bottom - 3;
53     INT32 yTop = lpRect->top + 1;
54
55     SelectObject32 ( hdc, GetSysColorPen32 (COLOR_3DSHADOW));
56     MoveToEx32 (hdc, x, yBottom, NULL);
57     LineTo32 (hdc, x, yTop);
58     x++;
59     SelectObject32 ( hdc, GetSysColorPen32 (COLOR_3DHILIGHT));
60     MoveToEx32 (hdc, x, yBottom, NULL);
61     LineTo32 (hdc, x, yTop);
62 }
63
64
65 static void
66 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
67                     HDC32 hdc, INT32 nState)
68 {
69     RECT32   rcText = btnPtr->rect;
70     HFONT32  hOldFont;
71     INT32    nOldBkMode;
72     COLORREF clrOld;
73
74     /* draw text */
75     if ((btnPtr->iString > -1) && (btnPtr->iString < infoPtr->nNumStrings)) {
76         InflateRect32 (&rcText, -3, -3);
77         rcText.top += infoPtr->nBitmapHeight;
78         if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
79             OffsetRect32 (&rcText, 1, 1);
80
81         hOldFont = SelectObject32 (hdc, infoPtr->hFont);
82         nOldBkMode = SetBkMode32 (hdc, TRANSPARENT);
83         if (!(nState & TBSTATE_ENABLED)) {
84             clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_3DHILIGHT));
85             OffsetRect32 (&rcText, 1, 1);
86             DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
87                          &rcText, infoPtr->dwDTFlags);
88             SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW));
89             OffsetRect32 (&rcText, -1, -1);
90             DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
91                          &rcText, infoPtr->dwDTFlags);
92         }
93         else if (nState & TBSTATE_INDETERMINATE) {
94             clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW));
95             DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
96                          &rcText, infoPtr->dwDTFlags);
97         }
98         else {
99             clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_BTNTEXT));
100             DrawText32A (hdc, infoPtr->strings[btnPtr->iString], -1,
101                          &rcText, infoPtr->dwDTFlags);
102         }
103
104         SetTextColor32 (hdc, clrOld);
105         SelectObject32 (hdc, hOldFont);
106         if (nOldBkMode != TRANSPARENT)
107             SetBkMode32 (hdc, nOldBkMode);
108     }
109 }
110
111
112 static void
113 TOOLBAR_DrawPattern (HDC32 hdc, LPRECT32 lpRect)
114 {
115     HBRUSH32 hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ());
116     INT32 cx = lpRect->right - lpRect->left;
117     INT32 cy = lpRect->bottom - lpRect->top;
118     PatBlt32 (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
119     SelectObject32 (hdc, hbr);
120 }
121
122
123 static void
124 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
125                     HDC32 hdc, INT32 x, INT32 y)
126 {
127     /* FIXME: this function is a hack since it uses image list
128               internals directly */
129
130     HDC32 hdcImageList = CreateCompatibleDC32 (0);
131     HDC32 hdcMask = CreateCompatibleDC32 (0);
132     HIMAGELIST himl = infoPtr->himlDef;
133     HBITMAP32 hbmMask;
134
135     /* create new bitmap */
136     hbmMask = CreateBitmap32 (himl->cx, himl->cy, 1, 1, NULL);
137     SelectObject32 (hdcMask, hbmMask);
138
139     /* copy the mask bitmap */
140     SelectObject32 (hdcImageList, himl->hbmMask);
141     SetBkColor32 (hdcImageList, RGB(255, 255, 255));
142     SetTextColor32 (hdcImageList, RGB(0, 0, 0));
143     BitBlt32 (hdcMask, 0, 0, himl->cx, himl->cy,
144               hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
145
146 #if 0
147     /* add white mask from image */
148     SelectObject32 (hdcImageList, himl->hbmImage);
149     SetBkColor32 (hdcImageList, RGB(0, 0, 0));
150     BitBlt32 (hdcMask, 0, 0, himl->cx, himl->cy,
151               hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
152 #endif
153
154     /* draw the new mask */
155     SelectObject32 (hdc, GetSysColorBrush32 (COLOR_3DHILIGHT));
156     BitBlt32 (hdc, x+1, y+1, himl->cx, himl->cy,
157               hdcMask, 0, 0, 0xB8074A);
158
159     SelectObject32 (hdc, GetSysColorBrush32 (COLOR_3DSHADOW));
160     BitBlt32 (hdc, x, y, himl->cx, himl->cy,
161               hdcMask, 0, 0, 0xB8074A);
162
163     DeleteObject32 (hbmMask);
164     DeleteDC32 (hdcMask);
165     DeleteDC32 (hdcImageList);
166 }
167
168
169 static void
170 TOOLBAR_DrawButton (WND *wndPtr, TBUTTON_INFO *btnPtr, HDC32 hdc)
171 {
172     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
173     BOOL32 bFlat = (wndPtr->dwStyle & TBSTYLE_FLAT);
174     RECT32 rc;
175
176     if (btnPtr->fsState & TBSTATE_HIDDEN) return;
177
178     rc = btnPtr->rect;
179     if (btnPtr->fsStyle & TBSTYLE_SEP) {
180         if ((bFlat) && (btnPtr->idCommand == 0))
181             TOOLBAR_DrawFlatSeparator (&btnPtr->rect, hdc);
182         return;
183     }
184
185     /* disabled */
186     if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
187         DrawEdge32 (hdc, &rc, EDGE_RAISED,
188                     BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
189
190         TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
191
192         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
193         return;
194     }
195
196     /* pressed TBSTYLE_BUTTON */
197     if (btnPtr->fsState & TBSTATE_PRESSED) {
198         DrawEdge32 (hdc, &rc, EDGE_SUNKEN,
199                     BF_RECT | BF_MIDDLE | BF_ADJUST);
200         ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
201                         rc.left+2, rc.top+2, ILD_NORMAL);
202         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
203         return;
204     }
205
206     /* checked TBSTYLE_CHECK*/
207     if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
208         (btnPtr->fsState & TBSTATE_CHECKED)) {
209         if (bFlat)
210             DrawEdge32 (hdc, &rc, BDR_SUNKENOUTER,
211                         BF_RECT | BF_MIDDLE | BF_ADJUST);
212         else
213             DrawEdge32 (hdc, &rc, EDGE_SUNKEN,
214                         BF_RECT | BF_MIDDLE | BF_ADJUST);
215
216         TOOLBAR_DrawPattern (hdc, &rc);
217         ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
218                         rc.left+2, rc.top+2, ILD_NORMAL);
219         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
220         return;
221     }
222
223     /* indeterminate */ 
224     if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
225         DrawEdge32 (hdc, &rc, EDGE_RAISED,
226                     BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
227
228         TOOLBAR_DrawPattern (hdc, &rc);
229         TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
230         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
231         return;
232     }
233
234     /* normal state */
235     DrawEdge32 (hdc, &rc, EDGE_RAISED,
236                 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
237     ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
238                     rc.left+1, rc.top+1, ILD_NORMAL);
239     TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
240 }
241
242
243 static void
244 TOOLBAR_Refresh (WND *wndPtr, HDC32 hdc)
245 {
246     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
247     TBUTTON_INFO *btnPtr;
248     INT32 i;
249
250     /* draw buttons */
251     btnPtr = infoPtr->buttons;
252     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
253         TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
254 }
255
256
257 static void
258 TOOLBAR_CalcStrings (WND *wndPtr, LPSIZE32 lpSize)
259 {
260     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
261     TBUTTON_INFO *btnPtr;
262     INT32 i;
263     HDC32 hdc;
264     HFONT32 hOldFont;
265     SIZE32 sz;
266
267     lpSize->cx = 0;
268     lpSize->cy = 0;
269     hdc = GetDC32 (0);
270     hOldFont = SelectObject32 (hdc, infoPtr->hFont);
271
272     btnPtr = infoPtr->buttons;
273     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
274         if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
275             (btnPtr->iString > -1) &&
276             (btnPtr->iString < infoPtr->nNumStrings)) {
277             LPSTR lpText = infoPtr->strings[btnPtr->iString];
278             GetTextExtentPoint32A (hdc, lpText, lstrlen32A(lpText), &sz);
279             if (sz.cx > lpSize->cx)
280                 lpSize->cx = sz.cx;
281             if (sz.cy > lpSize->cy)
282                 lpSize->cy = sz.cy;
283         }
284     }
285
286     SelectObject32 (hdc, hOldFont);
287     ReleaseDC32 (0, hdc);
288
289     TRACE (toolbar, "string size %d x %d!\n", lpSize->cx, lpSize->cy);
290 }
291
292
293 static void
294 TOOLBAR_CalcToolbar (WND *wndPtr)
295 {
296     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
297     TBUTTON_INFO *btnPtr, *grpPtr;
298     INT32 i, j, nRows;
299     INT32 x, y, cx, cy;
300     BOOL32 bWrap;
301     SIZE32  sizeString;
302 /* --- new --- */
303     INT32  nGrpCount = 0;
304     INT32  grpX;
305 /* --- end new --- */
306
307     TOOLBAR_CalcStrings (wndPtr, &sizeString);
308
309     if (sizeString.cy > 0)
310         infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
311     else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
312         infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
313
314     if (sizeString.cx > infoPtr->nBitmapWidth)
315         infoPtr->nButtonWidth = sizeString.cx + 6;
316     else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
317         infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
318
319     x  = infoPtr->nIndent;
320     y  = TOP_BORDER;
321     cx = infoPtr->nButtonWidth;
322     cy = infoPtr->nButtonHeight;
323     nRows = 0;
324
325     /* calculate the size of each button according to it's style */
326 //     TOOLBAR_CalcButtons (wndPtr);
327
328     infoPtr->rcBound.top = y;
329     infoPtr->rcBound.left = x;
330     infoPtr->rcBound.bottom = y + cy;
331     infoPtr->rcBound.right = x;
332
333     btnPtr = infoPtr->buttons;
334     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
335         bWrap = FALSE;
336
337         if (btnPtr->fsState & TBSTATE_HIDDEN) {
338             SetRectEmpty32 (&btnPtr->rect);
339             continue;
340         }
341
342 #ifdef __NEW_WRAP_CODE__
343 //#if 0
344         if (btnPtr->fsStyle & TBSTYLE_SEP) {
345             /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
346             /* it is the actual width of the separator. This is used for */
347             /* custom controls in toolbars.                              */
348             if ((wndPtr->dwStyle & TBSTYLE_WRAPABLE) &&
349                 (btnPtr->fsState & TBSTATE_WRAP)) {
350                 x = 0;
351                 y += cy;
352                 cx = infoPtr->nWidth;
353                 cy = ((btnPtr->iBitmap > 0) ?
354                      btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3;
355 //              nRows++;
356 //              bWrap = TRUE;
357             }
358             else
359                 cx = (btnPtr->iBitmap > 0) ?
360                      btnPtr->iBitmap : SEPARATOR_WIDTH;
361         }
362         else {
363             /* this must be a button */
364             cx = infoPtr->nButtonWidth;
365         }
366 //#endif
367
368 /* --- begin test --- */
369         if ((i >= nGrpCount) && (btnPtr->fsStyle & TBSTYLE_GROUP)) {
370             for (j = i, grpX = x, nGrpCount = 0; j < infoPtr->nNumButtons; j++) {
371                 grpPtr = &infoPtr->buttons[j];
372                 if (grpPtr->fsState & TBSTATE_HIDDEN)
373                     continue;
374
375                 grpX += cx;
376
377                 if ((grpPtr->fsStyle & TBSTYLE_SEP) ||
378                     !(grpPtr->fsStyle & TBSTYLE_GROUP) ||
379                     (grpX > infoPtr->nWidth)) {
380                     nGrpCount = j;
381                     break;
382                 }
383                 else if (grpX + x > infoPtr->nWidth) {
384                     bWrap = TRUE;
385                     nGrpCount = j;
386                     break;
387                 }
388             }
389         }
390
391         bWrap = ((bWrap || (x + cx > infoPtr->nWidth)) &&
392                  (wndPtr->dwStyle & TBSTYLE_WRAPABLE));
393         if (bWrap) {
394             nRows++;
395             y += cy;
396             x  = infoPtr->nIndent;
397             bWrap = FALSE;
398         }
399
400         SetRect32 (&btnPtr->rect, x, y, x + cx, y + cy);
401
402         btnPtr->nRow = nRows;
403         x += cx;
404
405         if (btnPtr->fsState & TBSTATE_WRAP) {
406             nRows++;
407             y += (cy + SEPARATOR_HEIGHT);
408             x  = infoPtr->nIndent;
409         }
410
411         infoPtr->nRows = nRows + 1;
412
413 /* --- end test --- */
414 #else
415         if (btnPtr->fsStyle & TBSTYLE_SEP) {
416             /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
417             /* it is the actual width of the separator. This is used for */
418             /* custom controls in toolbars.                              */
419             if ((wndPtr->dwStyle & TBSTYLE_WRAPABLE) &&
420                 (btnPtr->fsState & TBSTATE_WRAP)) {
421                 x = 0;
422                 y += cy;
423                 cx = infoPtr->nWidth;
424                 cy = ((btnPtr->iBitmap > 0) ?
425                      btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3;
426                 nRows++;
427                 bWrap = TRUE;
428             }
429             else
430                 cx = (btnPtr->iBitmap > 0) ?
431                      btnPtr->iBitmap : SEPARATOR_WIDTH;
432         }
433         else {
434             /* this must be a button */
435             cx = infoPtr->nButtonWidth;
436         }
437
438         btnPtr->rect.left   = x;
439         btnPtr->rect.top    = y;
440         btnPtr->rect.right  = x + cx;
441         btnPtr->rect.bottom = y + cy;
442
443         if (infoPtr->rcBound.left > x)
444             infoPtr->rcBound.left = x;
445         if (infoPtr->rcBound.right < x + cx)
446             infoPtr->rcBound.right = x + cx;
447         if (infoPtr->rcBound.bottom < y + cy)
448             infoPtr->rcBound.bottom = y + cy;
449
450         if (infoPtr->hwndToolTip) {
451             TTTOOLINFO32A ti;
452
453             ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
454             ti.cbSize = sizeof(TTTOOLINFO32A);
455             ti.hwnd = wndPtr->hwndSelf;
456             ti.uId = btnPtr->idCommand;
457             ti.rect = btnPtr->rect;
458             SendMessage32A (infoPtr->hwndToolTip, TTM_NEWTOOLRECT32A,
459                             0, (LPARAM)&ti);
460         }
461
462         if (bWrap) {
463             x = 0;
464             y += cy;
465             if (i < infoPtr->nNumButtons)
466                 nRows++;
467         }
468         else
469             x += cx;
470 #endif
471     }
472
473     infoPtr->nHeight = y + cy + BOTTOM_BORDER;
474     TRACE (toolbar, "toolbar height %d\n", infoPtr->nHeight);
475 }
476
477
478 static INT32
479 TOOLBAR_InternalHitTest (WND *wndPtr, LPPOINT32 lpPt)
480 {
481     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
482     TBUTTON_INFO *btnPtr;
483     INT32 i;
484     
485     btnPtr = infoPtr->buttons;
486     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
487         if (btnPtr->fsState & TBSTATE_HIDDEN)
488             continue;
489
490         if (btnPtr->fsStyle & TBSTYLE_SEP) {
491             if (PtInRect32 (&btnPtr->rect, *lpPt)) {
492                 TRACE (toolbar, " ON SEPARATOR %d!\n", i);
493                 return -i;
494             }
495         }
496         else {
497             if (PtInRect32 (&btnPtr->rect, *lpPt)) {
498                 TRACE (toolbar, " ON BUTTON %d!\n", i);
499                 return i;
500             }
501         }
502     }
503
504     TRACE (toolbar, " NOWHERE!\n");
505     return -1;
506 }
507
508
509 static INT32
510 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT32 idCommand)
511 {
512     TBUTTON_INFO *btnPtr;
513     INT32 i;
514
515     btnPtr = infoPtr->buttons;
516     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
517         if (btnPtr->idCommand == idCommand) {
518             TRACE (toolbar, "command=%d index=%d\n", idCommand, i);
519             return i;
520         }
521     }
522     TRACE (toolbar, "no index found for command=%d\n", idCommand);
523     return -1;
524 }
525
526
527 static INT32
528 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT32 nIndex)
529 {
530     TBUTTON_INFO *btnPtr;
531     INT32 nRunIndex;
532
533     if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
534         return -1;
535
536     /* check index button */
537     btnPtr = &infoPtr->buttons[nIndex];
538     if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
539         if (btnPtr->fsState & TBSTATE_CHECKED)
540             return nIndex;
541     }
542
543     /* check previous buttons */
544     nRunIndex = nIndex - 1;
545     while (nRunIndex >= 0) {
546         btnPtr = &infoPtr->buttons[nRunIndex];
547         if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
548             if (btnPtr->fsState & TBSTATE_CHECKED)
549                 return nRunIndex;
550         }
551         else
552             break;
553         nRunIndex--;
554     }
555
556     /* check next buttons */
557     nRunIndex = nIndex + 1;
558     while (nRunIndex < infoPtr->nNumButtons) {
559         btnPtr = &infoPtr->buttons[nRunIndex];  
560         if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
561             if (btnPtr->fsState & TBSTATE_CHECKED)
562                 return nRunIndex;
563         }
564         else
565             break;
566         nRunIndex++;
567     }
568
569     return -1;
570 }
571
572
573 static VOID
574 TOOLBAR_RelayEvent (HWND32 hwndTip, HWND32 hwndMsg, UINT32 uMsg,
575                     WPARAM32 wParam, LPARAM lParam)
576 {
577     MSG32 msg;
578
579     msg.hwnd = hwndMsg;
580     msg.message = uMsg;
581     msg.wParam = wParam;
582     msg.lParam = lParam;
583     msg.time = GetMessageTime ();
584     msg.pt.x = LOWORD(GetMessagePos ());
585     msg.pt.y = HIWORD(GetMessagePos ());
586
587     SendMessage32A (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
588 }
589
590
591 static LRESULT
592 TOOLBAR_AddBitmap (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
593 {
594     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
595     LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
596     INT32 nIndex = 0;
597
598     if ((!lpAddBmp) || ((INT32)wParam <= 0))
599         return -1;
600
601     TRACE (toolbar, "adding %d bitmaps!\n", wParam);
602
603     if (!(infoPtr->himlDef)) {
604         /* create new default image list */
605         TRACE (toolbar, "creating default image list!\n");
606         infoPtr->himlDef =
607             ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
608                               ILC_COLOR | ILC_MASK, (INT32)wParam, 2);
609     }
610
611 #if 0
612     if (!(infoPtr->himlDis)) {
613         /* create new disabled image list */
614         TRACE (toolbar, "creating disabled image list!\n");
615         infoPtr->himlDis =
616             ImageList_Create (infoPtr->nBitmapWidth, 
617                               infoPtr->nBitmapHeight, ILC_COLOR | ILC_MASK,
618                               (INT32)wParam, 2);
619     }
620 #endif
621
622     /* Add bitmaps to the default image list */
623     if (lpAddBmp->hInst == (HINSTANCE32)0) {
624         nIndex = 
625             ImageList_AddMasked (infoPtr->himlDef, (HBITMAP32)lpAddBmp->nID,
626                                  CLR_DEFAULT);
627     }
628     else if (lpAddBmp->hInst == HINST_COMMCTRL) {
629         /* add internal bitmaps */
630         FIXME (toolbar, "internal bitmaps not supported!\n");
631
632         /* Hack to "add" some reserved images within the image list 
633            to get the right image indices */
634         nIndex = ImageList_GetImageCount (infoPtr->himlDef);
635         ImageList_SetImageCount (infoPtr->himlDef, nIndex + (INT32)wParam);
636     }
637     else {
638         HBITMAP32 hBmp =
639             LoadBitmap32A (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
640
641         nIndex = ImageList_AddMasked (infoPtr->himlDef, hBmp, CLR_DEFAULT);
642
643         DeleteObject32 (hBmp); 
644     }
645
646
647     infoPtr->nNumBitmaps += (INT32)wParam;
648
649     return nIndex;
650 }
651
652
653 static LRESULT
654 TOOLBAR_AddButtons32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
655 {
656     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
657     LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
658     INT32 nOldButtons, nNewButtons, nAddButtons, nCount;
659     HDC32 hdc;
660
661     TRACE (toolbar, "adding %d buttons!\n", wParam);
662
663     nAddButtons = (UINT32)wParam;
664     nOldButtons = infoPtr->nNumButtons;
665     nNewButtons = nOldButtons + nAddButtons;
666
667     if (infoPtr->nNumButtons == 0) {
668         infoPtr->buttons =
669             COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
670     }
671     else {
672         TBUTTON_INFO *oldButtons = infoPtr->buttons;
673         infoPtr->buttons =
674             COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
675         memcpy (&infoPtr->buttons[0], &oldButtons[0],
676                 nOldButtons * sizeof(TBUTTON_INFO));
677         COMCTL32_Free (oldButtons);
678     }
679
680     infoPtr->nNumButtons = nNewButtons;
681
682     /* insert new button data */
683     for (nCount = 0; nCount < nAddButtons; nCount++) {
684         TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
685         btnPtr->iBitmap   = lpTbb[nCount].iBitmap;
686         btnPtr->idCommand = lpTbb[nCount].idCommand;
687         btnPtr->fsState   = lpTbb[nCount].fsState;
688         btnPtr->fsStyle   = lpTbb[nCount].fsStyle;
689         btnPtr->dwData    = lpTbb[nCount].dwData;
690         btnPtr->iString   = lpTbb[nCount].iString;
691
692         if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
693             TTTOOLINFO32A ti;
694
695             ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
696             ti.cbSize   = sizeof (TTTOOLINFO32A);
697             ti.hwnd     = wndPtr->hwndSelf;
698             ti.uId      = btnPtr->idCommand;
699             ti.hinst    = 0;
700             ti.lpszText = LPSTR_TEXTCALLBACK32A;
701
702             SendMessage32A (infoPtr->hwndToolTip, TTM_ADDTOOL32A,
703                             0, (LPARAM)&ti);
704         }
705     }
706
707     TOOLBAR_CalcToolbar (wndPtr);
708
709     hdc = GetDC32 (wndPtr->hwndSelf);
710     TOOLBAR_Refresh (wndPtr, hdc);
711     ReleaseDC32 (wndPtr->hwndSelf, hdc);
712
713     return TRUE;
714 }
715
716
717 // << TOOLBAR_AddButtons32W >>
718
719
720 static LRESULT
721 TOOLBAR_AddString32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
722 {
723     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
724     INT32 nIndex;
725
726     if ((wParam) && (HIWORD(lParam) == 0)) {
727         char szString[256];
728         INT32 len;
729         TRACE (toolbar, "adding string from resource!\n");
730
731         len = LoadString32A ((HINSTANCE32)wParam, (UINT32)lParam,
732                              szString, 256);
733
734         TRACE (toolbar, "len=%d \"%s\"\n", len, szString);
735         nIndex = infoPtr->nNumStrings;
736         if (infoPtr->nNumStrings == 0) {
737             infoPtr->strings =
738                 COMCTL32_Alloc (sizeof(char *));
739         }
740         else {
741             char **oldStrings = infoPtr->strings;
742             infoPtr->strings =
743                 COMCTL32_Alloc (sizeof(char *) * (infoPtr->nNumStrings + 1));
744             memcpy (&infoPtr->strings[0], &oldStrings[0],
745                     sizeof(char *) * infoPtr->nNumStrings);
746             COMCTL32_Free (oldStrings);
747         }
748
749         infoPtr->strings[infoPtr->nNumStrings] =
750             COMCTL32_Alloc (sizeof(char)*(len+1));
751         lstrcpy32A (infoPtr->strings[infoPtr->nNumStrings], szString);
752         infoPtr->nNumStrings++;
753     }
754     else {
755         char *p = (char*)lParam;
756         INT32 len;
757
758         if (p == NULL) return -1;
759         TRACE (toolbar, "adding string(s) from array!\n");
760         nIndex = infoPtr->nNumStrings;
761         while (*p) {
762             len = lstrlen32A (p);
763             TRACE (toolbar, "len=%d \"%s\"\n", len, p);
764
765             if (infoPtr->nNumStrings == 0) {
766                 infoPtr->strings =
767                     COMCTL32_Alloc (sizeof(char *));
768             }
769             else {
770                 char **oldStrings = infoPtr->strings;
771                 infoPtr->strings =
772                     COMCTL32_Alloc (sizeof(char *) * (infoPtr->nNumStrings + 1));
773                 memcpy (&infoPtr->strings[0], &oldStrings[0],
774                         sizeof(char *) * infoPtr->nNumStrings);
775                 COMCTL32_Free (oldStrings);
776             }
777
778             infoPtr->strings[infoPtr->nNumStrings] =
779                 COMCTL32_Alloc (sizeof(char)*(len+1));
780             lstrcpy32A (infoPtr->strings[infoPtr->nNumStrings], p);
781             infoPtr->nNumStrings++;
782
783             p += (len+1);
784         }
785     }
786
787     return nIndex;
788 }
789
790
791 // << TOOLBAR_AddString32W >>
792
793
794 static LRESULT
795 TOOLBAR_AutoSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
796 {
797     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
798     RECT32 parent_rect;
799     HWND32 parent;
800     INT32  x, y, cx, cy;
801     UINT32 uPosFlags = 0;
802
803     TRACE (toolbar, "resize forced!\n");
804
805     parent = GetParent32 (wndPtr->hwndSelf);
806     GetClientRect32(parent, &parent_rect);
807
808     if (wndPtr->dwStyle & CCS_NORESIZE) {
809         uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
810         cx = 0;
811         cy = 0;
812     }
813     else {
814         infoPtr->nWidth = parent_rect.right - parent_rect.left;
815         TOOLBAR_CalcToolbar (wndPtr);
816         cy = infoPtr->nHeight;
817         cx = infoPtr->nWidth;
818     }
819
820     if (wndPtr->dwStyle & CCS_NOPARENTALIGN)
821         uPosFlags |= SWP_NOMOVE;
822
823     if (!(wndPtr->dwStyle & CCS_NODIVIDER))
824         cy += sysMetrics[SM_CYEDGE];
825
826     infoPtr->bAutoSize = TRUE;
827     SetWindowPos32 (wndPtr->hwndSelf, HWND_TOP, parent_rect.left, parent_rect.top,
828                     cx, cy, uPosFlags);
829
830     return 0;
831 }
832
833
834 static LRESULT
835 TOOLBAR_ButtonCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
836 {
837     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
838
839     return infoPtr->nNumButtons;
840 }
841
842
843 static LRESULT
844 TOOLBAR_ButtonStructSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
845 {
846     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
847
848     if (infoPtr == NULL) {
849         ERR (toolbar, "(0x%08lx, 0x%08x, 0x%08lx)\n", (DWORD)wndPtr, wParam, lParam);
850         ERR (toolbar, "infoPtr == NULL!\n");
851         return 0;
852     }
853
854     infoPtr->dwStructSize = (DWORD)wParam;
855
856     return 0;
857 }
858
859
860 static LRESULT
861 TOOLBAR_ChangeBitmap (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
862 {
863     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
864     TBUTTON_INFO *btnPtr;
865     HDC32 hdc;
866     INT32 nIndex;
867
868     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
869     if (nIndex == -1)
870         return FALSE;
871
872     btnPtr = &infoPtr->buttons[nIndex];
873     btnPtr->iBitmap = LOWORD(lParam);
874
875     hdc = GetDC32 (wndPtr->hwndSelf);
876     TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
877     ReleaseDC32 (wndPtr->hwndSelf, hdc);
878
879     return TRUE;
880 }
881
882
883 static LRESULT
884 TOOLBAR_CheckButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
885 {
886     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
887     TBUTTON_INFO *btnPtr;
888     HDC32 hdc;
889     INT32 nIndex;
890     INT32 nOldIndex = -1;
891
892     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
893     if (nIndex == -1)
894         return FALSE;
895
896     btnPtr = &infoPtr->buttons[nIndex];
897
898     if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
899         return FALSE;
900
901     if (LOWORD(lParam) == FALSE)
902         btnPtr->fsState &= ~TBSTATE_CHECKED;
903     else {
904         if (btnPtr->fsStyle & TBSTYLE_GROUP) {
905             nOldIndex = 
906                 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
907             if (nOldIndex == nIndex)
908                 return 0;
909             if (nOldIndex != -1)
910                 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
911         }
912         btnPtr->fsState |= TBSTATE_CHECKED;
913     }
914
915     hdc = GetDC32 (wndPtr->hwndSelf);
916     if (nOldIndex != -1)
917         TOOLBAR_DrawButton (wndPtr, &infoPtr->buttons[nOldIndex], hdc);
918     TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
919     ReleaseDC32 (wndPtr->hwndSelf, hdc);
920
921     /* FIXME: Send a WM_NOTIFY?? */
922
923     return TRUE;
924 }
925
926
927 static LRESULT
928 TOOLBAR_CommandToIndex (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
929 {
930     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
931
932     return TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
933 }
934
935
936 static LRESULT
937 TOOLBAR_Customize (WND *wndPtr)
938 {
939     FIXME (toolbar, "customization not implemented!\n");
940
941     return 0;
942 }
943
944
945 static LRESULT
946 TOOLBAR_DeleteButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
947 {
948     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
949     INT32 nIndex = (INT32)wParam;
950
951     if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
952         return FALSE;
953
954     if ((infoPtr->hwndToolTip) && 
955         !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
956         TTTOOLINFO32A ti;
957
958         ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
959         ti.cbSize   = sizeof (TTTOOLINFO32A);
960         ti.hwnd     = wndPtr->hwndSelf;
961         ti.uId      = infoPtr->buttons[nIndex].idCommand;
962
963         SendMessage32A (infoPtr->hwndToolTip, TTM_DELTOOL32A, 0, (LPARAM)&ti);
964     }
965
966     if (infoPtr->nNumButtons == 1) {
967         TRACE (toolbar, " simple delete!\n");
968         COMCTL32_Free (infoPtr->buttons);
969         infoPtr->buttons = NULL;
970         infoPtr->nNumButtons = 0;
971     }
972     else {
973         TBUTTON_INFO *oldButtons = infoPtr->buttons;
974         TRACE(toolbar, "complex delete! [nIndex=%d]\n", nIndex);
975
976         infoPtr->nNumButtons--;
977         infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
978         if (nIndex > 0) {
979             memcpy (&infoPtr->buttons[0], &oldButtons[0],
980                     nIndex * sizeof(TBUTTON_INFO));
981         }
982
983         if (nIndex < infoPtr->nNumButtons) {
984             memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
985                     (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
986         }
987
988         COMCTL32_Free (oldButtons);
989     }
990
991     TOOLBAR_CalcToolbar (wndPtr);
992
993     InvalidateRect32 (wndPtr->hwndSelf, NULL, TRUE);
994     UpdateWindow32 (wndPtr->hwndSelf);
995
996     return TRUE;
997 }
998
999
1000 static LRESULT
1001 TOOLBAR_EnableButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1002 {
1003     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1004     TBUTTON_INFO *btnPtr;
1005     HDC32 hdc;
1006     INT32 nIndex;
1007
1008     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1009     if (nIndex == -1)
1010         return FALSE;
1011
1012     btnPtr = &infoPtr->buttons[nIndex];
1013     if (LOWORD(lParam) == FALSE)
1014         btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
1015     else
1016         btnPtr->fsState |= TBSTATE_ENABLED;
1017
1018     hdc = GetDC32 (wndPtr->hwndSelf);
1019     TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
1020     ReleaseDC32 (wndPtr->hwndSelf, hdc);
1021
1022     return TRUE;
1023 }
1024
1025
1026 // << TOOLBAR_GetAnchorHighlight >>
1027
1028
1029 static LRESULT
1030 TOOLBAR_GetBitmap (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1031 {
1032     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1033     INT32 nIndex;
1034
1035     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1036     if (nIndex == -1)
1037         return -1;
1038
1039     return infoPtr->buttons[nIndex].iBitmap;
1040 }
1041
1042
1043 static __inline__ LRESULT
1044 TOOLBAR_GetBitmapFlags (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1045 {
1046     return (GetDeviceCaps32 (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
1047 }
1048
1049
1050 static LRESULT
1051 TOOLBAR_GetButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1052 {
1053     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1054     LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1055     INT32 nIndex = (INT32)wParam;
1056     TBUTTON_INFO *btnPtr;
1057
1058     if (infoPtr == NULL) return FALSE;
1059     if (lpTbb == NULL) return FALSE;
1060
1061     if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1062         return FALSE;
1063
1064     btnPtr = &infoPtr->buttons[nIndex];
1065     lpTbb->iBitmap   = btnPtr->iBitmap;
1066     lpTbb->idCommand = btnPtr->idCommand;
1067     lpTbb->fsState   = btnPtr->fsState;
1068     lpTbb->fsStyle   = btnPtr->fsStyle;
1069     lpTbb->dwData    = btnPtr->dwData;
1070     lpTbb->iString   = btnPtr->iString;
1071
1072     return TRUE;
1073 }
1074
1075
1076 static LRESULT
1077 TOOLBAR_GetButtonInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1078 {
1079     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1080     LPTBBUTTONINFO32A lpTbInfo = (LPTBBUTTONINFO32A)lParam;
1081     TBUTTON_INFO *btnPtr;
1082     INT32 nIndex;
1083
1084     if (infoPtr == NULL) return -1;
1085     if (lpTbInfo == NULL) return -1;
1086     if (lpTbInfo->cbSize < sizeof(LPTBBUTTONINFO32A)) return -1;
1087
1088     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1089     if (nIndex == -1)
1090         return -1;
1091
1092     btnPtr = &infoPtr->buttons[nIndex];
1093
1094     if (lpTbInfo->dwMask & TBIF_COMMAND)
1095         lpTbInfo->idCommand = btnPtr->idCommand;
1096     if (lpTbInfo->dwMask & TBIF_IMAGE)
1097         lpTbInfo->iImage = btnPtr->iBitmap;
1098     if (lpTbInfo->dwMask & TBIF_LPARAM)
1099         lpTbInfo->lParam = btnPtr->dwData;
1100     if (lpTbInfo->dwMask & TBIF_SIZE)
1101         lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1102     if (lpTbInfo->dwMask & TBIF_STATE)
1103         lpTbInfo->fsState = btnPtr->fsState;
1104     if (lpTbInfo->dwMask & TBIF_STYLE)
1105         lpTbInfo->fsStyle = btnPtr->fsStyle;
1106     if (lpTbInfo->dwMask & TBIF_TEXT) {
1107         if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
1108             lstrcpyn32A (lpTbInfo->pszText, 
1109                          (LPSTR)infoPtr->strings[btnPtr->iString],
1110                          lpTbInfo->cchText);
1111     }
1112
1113     return nIndex;
1114 }
1115
1116
1117 // << TOOLBAR_GetButtonInfo32W >>
1118
1119
1120 static LRESULT
1121 TOOLBAR_GetButtonSize (WND *wndPtr)
1122 {
1123     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1124
1125     return MAKELONG((WORD)infoPtr->nButtonWidth,
1126                     (WORD)infoPtr->nButtonHeight);
1127 }
1128
1129
1130 static LRESULT
1131 TOOLBAR_GetButtonText32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1132 {
1133     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1134     INT32 nIndex, nStringIndex;
1135
1136     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1137     if (nIndex == -1)
1138         return -1;
1139
1140     nStringIndex = infoPtr->buttons[nIndex].iString;
1141
1142     TRACE (toolbar, "index=%d stringIndex=%d\n", nIndex, nStringIndex);
1143
1144     if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
1145         return -1;
1146
1147     if (lParam == 0) return -1;
1148
1149     lstrcpy32A ((LPSTR)lParam, (LPSTR)infoPtr->strings[nStringIndex]);
1150
1151     return lstrlen32A ((LPSTR)infoPtr->strings[nStringIndex]);
1152 }
1153
1154
1155 // << TOOLBAR_GetButtonText32W >>
1156 // << TOOLBAR_GetColorScheme >>
1157
1158
1159 static LRESULT
1160 TOOLBAR_GetDisabledImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1161 {
1162     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1163
1164     if (wndPtr->dwStyle & TBSTYLE_FLAT)
1165         return (LRESULT)infoPtr->himlDis;
1166     else
1167         return 0;
1168 }
1169
1170
1171 __inline__ static LRESULT
1172 TOOLBAR_GetExtendedStyle (WND *wndPtr)
1173 {
1174     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1175
1176     return infoPtr->dwExStyle;
1177 }
1178
1179
1180 static LRESULT
1181 TOOLBAR_GetHotImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1182 {
1183     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1184
1185     if (wndPtr->dwStyle & TBSTYLE_FLAT)
1186         return (LRESULT)infoPtr->himlHot;
1187     else
1188         return 0;
1189 }
1190
1191
1192 // << TOOLBAR_GetHotItem >>
1193
1194
1195 static LRESULT
1196 TOOLBAR_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1197 {
1198     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1199
1200     if (wndPtr->dwStyle & TBSTYLE_FLAT)
1201         return (LRESULT)infoPtr->himlDef;
1202     else
1203         return 0;
1204 }
1205
1206
1207 // << TOOLBAR_GetInsertMark >>
1208 // << TOOLBAR_GetInsertMarkColor >>
1209
1210
1211 static LRESULT
1212 TOOLBAR_GetItemRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1213 {
1214     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1215     TBUTTON_INFO *btnPtr;
1216     LPRECT32     lpRect;
1217     INT32        nIndex;
1218
1219     if (infoPtr == NULL) return FALSE;
1220     nIndex = (INT32)wParam;
1221     btnPtr = &infoPtr->buttons[nIndex];
1222     if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1223         return FALSE;
1224     lpRect = (LPRECT32)lParam;
1225     if (lpRect == NULL) return FALSE;
1226     if (btnPtr->fsState & TBSTATE_HIDDEN) return FALSE;
1227     
1228     lpRect->left   = btnPtr->rect.left;
1229     lpRect->right  = btnPtr->rect.right;
1230     lpRect->bottom = btnPtr->rect.bottom;
1231     lpRect->top    = btnPtr->rect.top;
1232
1233     return TRUE;
1234 }
1235
1236
1237 static LRESULT
1238 TOOLBAR_GetMaxSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1239 {
1240     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1241     LPSIZE32 lpSize = (LPSIZE32)lParam;
1242
1243     if (lpSize == NULL)
1244         return FALSE;
1245
1246     lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
1247     lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
1248
1249     TRACE (toolbar, "maximum size %d x %d\n",
1250            infoPtr->rcBound.right - infoPtr->rcBound.left,
1251            infoPtr->rcBound.bottom - infoPtr->rcBound.top);
1252
1253     return TRUE;
1254 }
1255
1256
1257 // << TOOLBAR_GetObject >>
1258 // << TOOLBAR_GetPadding >>
1259
1260
1261 static LRESULT
1262 TOOLBAR_GetRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1263 {
1264     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1265     TBUTTON_INFO *btnPtr;
1266     LPRECT32     lpRect;
1267     INT32        nIndex;
1268
1269     if (infoPtr == NULL) return FALSE;
1270     nIndex = (INT32)wParam;
1271     btnPtr = &infoPtr->buttons[nIndex];
1272     if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1273         return FALSE;
1274     lpRect = (LPRECT32)lParam;
1275     if (lpRect == NULL) return FALSE;
1276     
1277     lpRect->left   = btnPtr->rect.left;
1278     lpRect->right  = btnPtr->rect.right;
1279     lpRect->bottom = btnPtr->rect.bottom;
1280     lpRect->top    = btnPtr->rect.top;
1281
1282     return TRUE;
1283 }
1284
1285
1286 static LRESULT
1287 TOOLBAR_GetRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1288 {
1289     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1290
1291     if (wndPtr->dwStyle & TBSTYLE_WRAPABLE)
1292         return infoPtr->nRows;
1293     else
1294         return 1;
1295 }
1296
1297
1298 static LRESULT
1299 TOOLBAR_GetState (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1300 {
1301     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1302     INT32 nIndex;
1303
1304     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1305     if (nIndex == -1) return -1;
1306
1307     return infoPtr->buttons[nIndex].fsState;
1308 }
1309
1310
1311 static LRESULT
1312 TOOLBAR_GetStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1313 {
1314     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1315     INT32 nIndex;
1316
1317     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1318     if (nIndex == -1) return -1;
1319
1320     return infoPtr->buttons[nIndex].fsStyle;
1321 }
1322
1323
1324 static LRESULT
1325 TOOLBAR_GetTextRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1326 {
1327     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1328
1329     if (infoPtr == NULL)
1330         return 0;
1331
1332     return infoPtr->nMaxTextRows;
1333 }
1334
1335
1336 static LRESULT
1337 TOOLBAR_GetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1338 {
1339     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1340
1341     if (infoPtr == NULL) return 0;
1342     return infoPtr->hwndToolTip;
1343 }
1344
1345
1346 static LRESULT
1347 TOOLBAR_GetUnicodeFormat (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1348 {
1349     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1350
1351     TRACE (toolbar, "%s hwnd=0x%04x stub!\n", 
1352            infoPtr->bUnicode ? "TRUE" : "FALSE", wndPtr->hwndSelf);
1353
1354     return infoPtr->bUnicode;
1355 }
1356
1357
1358 static LRESULT
1359 TOOLBAR_HideButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1360 {
1361     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1362     TBUTTON_INFO *btnPtr;
1363     INT32 nIndex;
1364
1365     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1366     if (nIndex == -1)
1367         return FALSE;
1368
1369     btnPtr = &infoPtr->buttons[nIndex];
1370     if (LOWORD(lParam) == FALSE)
1371         btnPtr->fsState &= ~TBSTATE_HIDDEN;
1372     else
1373         btnPtr->fsState |= TBSTATE_HIDDEN;
1374
1375     TOOLBAR_CalcToolbar (wndPtr);
1376
1377     InvalidateRect32 (wndPtr->hwndSelf, NULL, TRUE);
1378     UpdateWindow32 (wndPtr->hwndSelf);
1379
1380     return TRUE;
1381 }
1382
1383
1384 __inline__ static LRESULT
1385 TOOLBAR_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1386 {
1387     return TOOLBAR_InternalHitTest (wndPtr, (LPPOINT32)lParam);
1388 }
1389
1390
1391 static LRESULT
1392 TOOLBAR_Indeterminate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1393 {
1394     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1395     TBUTTON_INFO *btnPtr;
1396     HDC32 hdc;
1397     INT32 nIndex;
1398
1399     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1400     if (nIndex == -1)
1401         return FALSE;
1402
1403     btnPtr = &infoPtr->buttons[nIndex];
1404     if (LOWORD(lParam) == FALSE)
1405         btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
1406     else
1407         btnPtr->fsState |= TBSTATE_INDETERMINATE;
1408
1409     hdc = GetDC32 (wndPtr->hwndSelf);
1410     TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
1411     ReleaseDC32 (wndPtr->hwndSelf, hdc);
1412
1413     return TRUE;
1414 }
1415
1416
1417 static LRESULT
1418 TOOLBAR_InsertButton32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1419 {
1420     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1421     LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1422     INT32 nIndex = (INT32)wParam;
1423     TBUTTON_INFO *oldButtons;
1424     HDC32 hdc;
1425
1426     if (lpTbb == NULL) return FALSE;
1427     if (nIndex < 0) return FALSE;
1428
1429     TRACE (toolbar, "inserting button index=%d\n", nIndex);
1430     if (nIndex > infoPtr->nNumButtons) {
1431         nIndex = infoPtr->nNumButtons;
1432         TRACE (toolbar, "adjust index=%d\n", nIndex);
1433     }
1434
1435     oldButtons = infoPtr->buttons;
1436     infoPtr->nNumButtons++;
1437     infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
1438     /* pre insert copy */
1439     if (nIndex > 0) {
1440         memcpy (&infoPtr->buttons[0], &oldButtons[0],
1441                 nIndex * sizeof(TBUTTON_INFO));
1442     }
1443
1444     /* insert new button */
1445     infoPtr->buttons[nIndex].iBitmap   = lpTbb->iBitmap;
1446     infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
1447     infoPtr->buttons[nIndex].fsState   = lpTbb->fsState;
1448     infoPtr->buttons[nIndex].fsStyle   = lpTbb->fsStyle;
1449     infoPtr->buttons[nIndex].dwData    = lpTbb->dwData;
1450     infoPtr->buttons[nIndex].iString   = lpTbb->iString;
1451
1452     if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
1453         TTTOOLINFO32A ti;
1454
1455         ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
1456         ti.cbSize   = sizeof (TTTOOLINFO32A);
1457         ti.hwnd     = wndPtr->hwndSelf;
1458         ti.uId      = lpTbb->idCommand;
1459         ti.hinst    = 0;
1460         ti.lpszText = LPSTR_TEXTCALLBACK32A;
1461
1462         SendMessage32A (infoPtr->hwndToolTip, TTM_ADDTOOL32A,
1463                         0, (LPARAM)&ti);
1464     }
1465
1466     /* post insert copy */
1467     if (nIndex < infoPtr->nNumButtons - 1) {
1468         memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
1469                 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
1470     }
1471
1472     COMCTL32_Free (oldButtons);
1473
1474     TOOLBAR_CalcToolbar (wndPtr);
1475
1476     hdc = GetDC32 (wndPtr->hwndSelf);
1477     TOOLBAR_Refresh (wndPtr, hdc);
1478     ReleaseDC32 (wndPtr->hwndSelf, hdc);
1479
1480     return TRUE;
1481 }
1482
1483
1484 // << TOOLBAR_InsertButton32W >>
1485 // << TOOLBAR_InsertMarkHitTest >>
1486
1487
1488 static LRESULT
1489 TOOLBAR_IsButtonChecked (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1490 {
1491     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1492     INT32 nIndex;
1493
1494     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1495     if (nIndex == -1)
1496         return FALSE;
1497
1498     return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
1499 }
1500
1501
1502 static LRESULT
1503 TOOLBAR_IsButtonEnabled (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1504 {
1505     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1506     INT32 nIndex;
1507
1508     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1509     if (nIndex == -1)
1510         return FALSE;
1511
1512     return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
1513 }
1514
1515
1516 static LRESULT
1517 TOOLBAR_IsButtonHidden (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1518 {
1519     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1520     INT32 nIndex;
1521
1522     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1523     if (nIndex == -1)
1524         return FALSE;
1525
1526     return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
1527 }
1528
1529
1530 static LRESULT
1531 TOOLBAR_IsButtonHighlighted (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1532 {
1533     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1534     INT32 nIndex;
1535
1536     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1537     if (nIndex == -1)
1538         return FALSE;
1539
1540     return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
1541 }
1542
1543
1544 static LRESULT
1545 TOOLBAR_IsButtonIndeterminate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1546 {
1547     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1548     INT32 nIndex;
1549
1550     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1551     if (nIndex == -1)
1552         return FALSE;
1553
1554     return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
1555 }
1556
1557
1558 static LRESULT
1559 TOOLBAR_IsButtonPressed (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1560 {
1561     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1562     INT32 nIndex;
1563
1564     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1565     if (nIndex == -1)
1566         return FALSE;
1567
1568     return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
1569 }
1570
1571
1572 // << TOOLBAR_LoadImages >>
1573 // << TOOLBAR_MapAccelerator >>
1574 // << TOOLBAR_MarkButton >>
1575 // << TOOLBAR_MoveButton >>
1576
1577
1578 static LRESULT
1579 TOOLBAR_PressButton (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1580 {
1581     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1582     TBUTTON_INFO *btnPtr;
1583     HDC32 hdc;
1584     INT32 nIndex;
1585
1586     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1587     if (nIndex == -1)
1588         return FALSE;
1589
1590     btnPtr = &infoPtr->buttons[nIndex];
1591     if (LOWORD(lParam) == FALSE)
1592         btnPtr->fsState &= ~TBSTATE_PRESSED;
1593     else
1594         btnPtr->fsState |= TBSTATE_PRESSED;
1595
1596     hdc = GetDC32 (wndPtr->hwndSelf);
1597     TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
1598     ReleaseDC32 (wndPtr->hwndSelf, hdc);
1599
1600     return TRUE;
1601 }
1602
1603
1604 // << TOOLBAR_ReplaceBitmap >>
1605
1606
1607 static LRESULT
1608 TOOLBAR_SaveRestore32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1609 {
1610 #if 0
1611     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1612     LPTBSAVEPARAMS32A lpSave = (LPTBSAVEPARAMS32A)lParam;
1613
1614     if (lpSave == NULL) return 0;
1615
1616     if ((BOOL32)wParam) {
1617         /* save toolbar information */
1618         FIXME (toolbar, "save to \"%s\" \"%s\"\n",
1619                lpSave->pszSubKey, lpSave->pszValueName);
1620
1621
1622     }
1623     else {
1624         /* restore toolbar information */
1625
1626         FIXME (toolbar, "restore from \"%s\" \"%s\"\n",
1627                lpSave->pszSubKey, lpSave->pszValueName);
1628
1629
1630     }
1631 #endif
1632
1633     return 0;
1634 }
1635
1636
1637 // << TOOLBAR_SaveRestore32W >>
1638 // << TOOLBAR_SetAnchorHighlight >>
1639
1640
1641 static LRESULT
1642 TOOLBAR_SetBitmapSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1643 {
1644     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1645
1646     if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
1647         return FALSE;
1648
1649     infoPtr->nBitmapWidth = (INT32)LOWORD(lParam);
1650     infoPtr->nBitmapHeight = (INT32)HIWORD(lParam);
1651
1652     return TRUE;
1653 }
1654
1655
1656 static LRESULT
1657 TOOLBAR_SetButtonInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1658 {
1659     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1660     LPTBBUTTONINFO32A lptbbi = (LPTBBUTTONINFO32A)lParam;
1661     TBUTTON_INFO *btnPtr;
1662     INT32 nIndex;
1663
1664     if (lptbbi == NULL)
1665         return FALSE;
1666     if (lptbbi->cbSize < sizeof(LPTBBUTTONINFO32A))
1667         return FALSE;
1668     
1669     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1670     if (nIndex == -1)
1671         return FALSE;
1672
1673     btnPtr = &infoPtr->buttons[nIndex];
1674     if (lptbbi->dwMask & TBIF_COMMAND)
1675         btnPtr->idCommand = lptbbi->idCommand;
1676     if (lptbbi->dwMask & TBIF_IMAGE)
1677         btnPtr->iBitmap = lptbbi->iImage;
1678     if (lptbbi->dwMask & TBIF_LPARAM)
1679         btnPtr->dwData = lptbbi->lParam;
1680 //    if (lptbbi->dwMask & TBIF_SIZE)
1681 //      btnPtr->cx = lptbbi->cx;
1682     if (lptbbi->dwMask & TBIF_STATE)
1683         btnPtr->fsState = lptbbi->fsState;
1684     if (lptbbi->dwMask & TBIF_STYLE)
1685         btnPtr->fsStyle = lptbbi->fsStyle;
1686
1687     if (lptbbi->dwMask & TBIF_TEXT) {
1688         if ((btnPtr->iString >= 0) || 
1689             (btnPtr->iString < infoPtr->nNumStrings)) {
1690 #if 0
1691             CHAR **lpString = &infoPtr->strings[btnPtr->iString];
1692             INT32 len = lstrlen32A (lptbbi->pszText);
1693             *lpString = COMCTL32_ReAlloc (lpString, sizeof(char)*(len+1));
1694 #endif
1695
1696             /* this is the ultimate sollution */
1697 //          Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText);
1698         }
1699     }
1700
1701     return TRUE;
1702 }
1703
1704
1705 // << TOOLBAR_SetButtonInfo32W >>
1706
1707
1708 static LRESULT
1709 TOOLBAR_SetButtonSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1710 {
1711     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1712
1713     if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
1714         return FALSE;
1715
1716     infoPtr->nButtonWidth = (INT32)LOWORD(lParam);
1717     infoPtr->nButtonHeight = (INT32)HIWORD(lParam);
1718
1719     return TRUE;
1720 }
1721
1722
1723 static LRESULT
1724 TOOLBAR_SetButtonWidth (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1725 {
1726     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1727
1728     if (infoPtr == NULL)
1729         return FALSE;
1730
1731     infoPtr->cxMin = (INT32)LOWORD(lParam);
1732     infoPtr->cxMax = (INT32)HIWORD(lParam);
1733
1734     return TRUE;
1735 }
1736
1737
1738 static LRESULT
1739 TOOLBAR_SetCmdId (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1740 {
1741     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1742     INT32 nIndex = (INT32)wParam;
1743
1744     if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1745         return FALSE;
1746
1747     infoPtr->buttons[nIndex].idCommand = (INT32)lParam;
1748
1749     if (infoPtr->hwndToolTip) {
1750
1751         FIXME (toolbar, "change tool tip!\n");
1752
1753     }
1754
1755     return TRUE;
1756 }
1757
1758
1759 // << TOOLBAR_SetColorScheme >>
1760
1761
1762 static LRESULT
1763 TOOLBAR_SetDisabledImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1764 {
1765     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1766     HIMAGELIST himlTemp;
1767
1768     if (!(wndPtr->dwStyle & TBSTYLE_FLAT))
1769         return 0;
1770
1771     himlTemp = infoPtr->himlDis;
1772     infoPtr->himlDis = (HIMAGELIST)lParam;
1773
1774     /* FIXME: redraw ? */
1775
1776     return (LRESULT)himlTemp; 
1777 }
1778
1779
1780 static LRESULT
1781 TOOLBAR_SetDrawTextFlags (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1782 {
1783     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1784     DWORD dwTemp;
1785
1786     dwTemp = infoPtr->dwDTFlags;
1787     infoPtr->dwDTFlags =
1788         (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
1789
1790     return (LRESULT)dwTemp;
1791 }
1792
1793
1794 static LRESULT
1795 TOOLBAR_SetExtendedStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1796 {
1797     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1798     DWORD dwTemp;
1799
1800     dwTemp = infoPtr->dwExStyle;
1801     infoPtr->dwExStyle = (DWORD)lParam;
1802
1803     return (LRESULT)dwTemp; 
1804 }
1805
1806
1807 static LRESULT
1808 TOOLBAR_SetHotImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1809 {
1810     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1811     HIMAGELIST himlTemp;
1812
1813     if (!(wndPtr->dwStyle & TBSTYLE_FLAT))
1814         return 0;
1815
1816     himlTemp = infoPtr->himlHot;
1817     infoPtr->himlHot = (HIMAGELIST)lParam;
1818
1819     /* FIXME: redraw ? */
1820
1821     return (LRESULT)himlTemp; 
1822 }
1823
1824
1825 // << TOOLBAR_SetHotItem >>
1826
1827
1828 static LRESULT
1829 TOOLBAR_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1830 {
1831     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1832     HIMAGELIST himlTemp;
1833
1834     if (!(wndPtr->dwStyle & TBSTYLE_FLAT))
1835         return 0;
1836
1837     himlTemp = infoPtr->himlDef;
1838     infoPtr->himlDef = (HIMAGELIST)lParam;
1839
1840     /* FIXME: redraw ? */
1841
1842     return (LRESULT)himlTemp; 
1843 }
1844
1845
1846 static LRESULT
1847 TOOLBAR_SetIndent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1848 {
1849     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1850     HDC32 hdc;
1851
1852     infoPtr->nIndent = (INT32)wParam;
1853     TOOLBAR_CalcToolbar (wndPtr);
1854     hdc = GetDC32 (wndPtr->hwndSelf);
1855     TOOLBAR_Refresh (wndPtr, hdc);
1856     ReleaseDC32 (wndPtr->hwndSelf, hdc);
1857
1858     return TRUE;
1859 }
1860
1861
1862 // << TOOLBAR_SetInsertMark >>
1863
1864
1865 static LRESULT
1866 TOOLBAR_SetInsertMarkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1867 {
1868     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1869
1870     infoPtr->clrInsertMark = (COLORREF)lParam;
1871
1872     /* FIXME : redraw ??*/
1873
1874     return 0;
1875 }
1876
1877
1878 static LRESULT
1879 TOOLBAR_SetMaxTextRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1880 {
1881     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1882
1883     if (infoPtr == NULL)
1884         return FALSE;
1885
1886     infoPtr->nMaxTextRows = (INT32)wParam;
1887
1888     return TRUE;
1889 }
1890
1891
1892 // << TOOLBAR_SetPadding >>
1893
1894
1895 static LRESULT
1896 TOOLBAR_SetParent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1897 {
1898     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1899     HWND32 hwndOldNotify;
1900
1901     if (infoPtr == NULL) return 0;
1902     hwndOldNotify = infoPtr->hwndNotify;
1903     infoPtr->hwndNotify = (HWND32)wParam;
1904
1905     return hwndOldNotify;
1906 }
1907
1908
1909 static LRESULT
1910 TOOLBAR_SetRows (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1911 {
1912     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1913     LPRECT32 lprc = (LPRECT32)lParam;
1914     HDC32 hdc;
1915
1916     if (LOWORD(wParam) > 1) {
1917
1918         FIXME (toolbar, "multiple rows not supported!\n");
1919
1920     }
1921
1922     /* recalculate toolbar */
1923     TOOLBAR_CalcToolbar (wndPtr);
1924
1925     /* return bounding rectangle */
1926     if (lprc) {
1927         lprc->left   = infoPtr->rcBound.left;
1928         lprc->right  = infoPtr->rcBound.right;
1929         lprc->top    = infoPtr->rcBound.top;
1930         lprc->bottom = infoPtr->rcBound.bottom;
1931     }
1932
1933     /* repaint toolbar */
1934     hdc = GetDC32 (wndPtr->hwndSelf);
1935     TOOLBAR_Refresh (wndPtr, hdc);
1936     ReleaseDC32 (wndPtr->hwndSelf, hdc);
1937
1938     return 0;
1939 }
1940
1941
1942 static LRESULT
1943 TOOLBAR_SetState (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1944 {
1945     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1946     TBUTTON_INFO *btnPtr;
1947     HDC32 hdc;
1948     INT32 nIndex;
1949
1950     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1951     if (nIndex == -1)
1952         return FALSE;
1953
1954     btnPtr = &infoPtr->buttons[nIndex];
1955     btnPtr->fsState = LOWORD(lParam);
1956
1957     hdc = GetDC32 (wndPtr->hwndSelf);
1958     TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
1959     ReleaseDC32 (wndPtr->hwndSelf, hdc);
1960
1961     return TRUE;
1962 }
1963
1964
1965 static LRESULT
1966 TOOLBAR_SetStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1967 {
1968     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1969     TBUTTON_INFO *btnPtr;
1970     HDC32 hdc;
1971     INT32 nIndex;
1972
1973     nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT32)wParam);
1974     if (nIndex == -1)
1975         return FALSE;
1976
1977     btnPtr = &infoPtr->buttons[nIndex];
1978     btnPtr->fsStyle = LOWORD(lParam);
1979
1980     hdc = GetDC32 (wndPtr->hwndSelf);
1981     TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
1982     ReleaseDC32 (wndPtr->hwndSelf, hdc);
1983
1984     if (infoPtr->hwndToolTip) {
1985
1986         FIXME (toolbar, "change tool tip!\n");
1987
1988     }
1989
1990     return TRUE;
1991 }
1992
1993
1994 __inline__ static LRESULT
1995 TOOLBAR_SetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1996 {
1997     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
1998
1999     if (infoPtr == NULL) return 0;
2000     infoPtr->hwndToolTip = (HWND32)wParam;
2001     return 0;
2002 }
2003
2004
2005 static LRESULT
2006 TOOLBAR_SetUnicodeFormat (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2007 {
2008     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
2009     BOOL32 bTemp;
2010
2011     TRACE (toolbar, "%s hwnd=0x%04x stub!\n", 
2012            ((BOOL32)wParam) ? "TRUE" : "FALSE", wndPtr->hwndSelf);
2013
2014     bTemp = infoPtr->bUnicode;
2015     infoPtr->bUnicode = (BOOL32)wParam;
2016
2017     return bTemp;
2018 }
2019
2020
2021 static LRESULT
2022 TOOLBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2023 {
2024     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
2025     LOGFONT32A logFont;
2026
2027     /* initialize info structure */
2028     infoPtr->nButtonHeight = 22;
2029     infoPtr->nButtonWidth = 23;
2030     infoPtr->nBitmapHeight = 15;
2031     infoPtr->nBitmapWidth = 16;
2032
2033     infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
2034     infoPtr->nRows = 1;
2035     infoPtr->nMaxTextRows = 1;
2036     infoPtr->cxMin = -1;
2037     infoPtr->cxMax = -1;
2038
2039     infoPtr->bCaptured = FALSE;
2040     infoPtr->bUnicode = FALSE;
2041     infoPtr->nButtonDown = -1;
2042     infoPtr->nOldHit = -1;
2043
2044     infoPtr->hwndNotify = GetParent32 (wndPtr->hwndSelf);
2045     infoPtr->bTransparent = (wndPtr->dwStyle & TBSTYLE_FLAT);
2046     infoPtr->nHotItem = -1;
2047     infoPtr->dwDTFlags = DT_CENTER;
2048
2049     SystemParametersInfo32A (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
2050     infoPtr->hFont = CreateFontIndirect32A (&logFont);
2051
2052     if (wndPtr->dwStyle & TBSTYLE_TOOLTIPS) {
2053         /* Create tooltip control */
2054         infoPtr->hwndToolTip =
2055             CreateWindowEx32A (0, TOOLTIPS_CLASS32A, NULL, TTS_ALWAYSTIP,
2056                                CW_USEDEFAULT32, CW_USEDEFAULT32,
2057                                CW_USEDEFAULT32, CW_USEDEFAULT32,
2058                                wndPtr->hwndSelf, 0, 0, 0);
2059
2060         /* Send NM_TOOLTIPSCREATED notification */
2061         if (infoPtr->hwndToolTip) {
2062             NMTOOLTIPSCREATED nmttc;
2063
2064             nmttc.hdr.hwndFrom = wndPtr->hwndSelf;
2065             nmttc.hdr.idFrom = wndPtr->wIDmenu;
2066             nmttc.hdr.code = NM_TOOLTIPSCREATED;
2067             nmttc.hwndToolTips = infoPtr->hwndToolTip;
2068
2069             SendMessage32A (infoPtr->hwndNotify, WM_NOTIFY,
2070                             (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmttc);
2071         }
2072     }
2073
2074     return 0;
2075 }
2076
2077
2078 static LRESULT
2079 TOOLBAR_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2080 {
2081     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
2082
2083     /* delete tooltip control */
2084     if (infoPtr->hwndToolTip)
2085         DestroyWindow32 (infoPtr->hwndToolTip);
2086
2087     /* delete button data */
2088     if (infoPtr->buttons)
2089         COMCTL32_Free (infoPtr->buttons);
2090
2091     /* delete strings */
2092     if (infoPtr->strings) {
2093         INT32 i;
2094         for (i = 0; i < infoPtr->nNumStrings; i++)
2095             if (infoPtr->strings[i])
2096                 COMCTL32_Free (infoPtr->strings[i]);
2097
2098         COMCTL32_Free (infoPtr->strings);
2099     }
2100
2101     /* destroy default image list */
2102     if (infoPtr->himlDef)
2103         ImageList_Destroy (infoPtr->himlDef);
2104
2105     /* destroy disabled image list */
2106     if (infoPtr->himlDis)
2107         ImageList_Destroy (infoPtr->himlDis);
2108
2109     /* destroy hot image list */
2110     if (infoPtr->himlHot)
2111         ImageList_Destroy (infoPtr->himlHot);
2112
2113     /* delete default font */
2114     if (infoPtr->hFont)
2115         DeleteObject32 (infoPtr->hFont);
2116
2117     /* free toolbar info data */
2118     COMCTL32_Free (infoPtr);
2119
2120     return 0;
2121 }
2122
2123
2124 static LRESULT
2125 TOOLBAR_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2126 {
2127     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
2128
2129     if (infoPtr->bTransparent)
2130         return SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_ERASEBKGND,
2131                                wParam, lParam);
2132
2133     return DefWindowProc32A (wndPtr->hwndSelf, WM_ERASEBKGND, wParam, lParam);
2134 }
2135
2136
2137 static LRESULT
2138 TOOLBAR_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2139 {
2140     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
2141     TBUTTON_INFO *btnPtr;
2142     POINT32 pt;
2143     INT32   nHit;
2144     HDC32   hdc;
2145
2146     pt.x = (INT32)LOWORD(lParam);
2147     pt.y = (INT32)HIWORD(lParam);
2148     nHit = TOOLBAR_InternalHitTest (wndPtr, &pt);
2149
2150     if (nHit >= 0) {
2151         btnPtr = &infoPtr->buttons[nHit];
2152         if (!(btnPtr->fsState & TBSTATE_ENABLED))
2153             return 0;
2154         SetCapture32 (wndPtr->hwndSelf);
2155         infoPtr->bCaptured = TRUE;
2156         infoPtr->nButtonDown = nHit;
2157
2158         btnPtr->fsState |= TBSTATE_PRESSED;
2159
2160         hdc = GetDC32 (wndPtr->hwndSelf);
2161         TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
2162         ReleaseDC32 (wndPtr->hwndSelf, hdc);
2163     }
2164     else if (wndPtr->dwStyle & CCS_ADJUSTABLE)
2165         TOOLBAR_Customize (wndPtr);
2166
2167     return 0;
2168 }
2169
2170
2171 static LRESULT
2172 TOOLBAR_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2173 {
2174     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
2175     TBUTTON_INFO *btnPtr;
2176     POINT32 pt;
2177     INT32   nHit;
2178     HDC32   hdc;
2179
2180     if (infoPtr->hwndToolTip)
2181         TOOLBAR_RelayEvent (infoPtr->hwndToolTip, wndPtr->hwndSelf,
2182                             WM_LBUTTONDOWN, wParam, lParam);
2183
2184     pt.x = (INT32)LOWORD(lParam);
2185     pt.y = (INT32)HIWORD(lParam);
2186     nHit = TOOLBAR_InternalHitTest (wndPtr, &pt);
2187
2188     if (nHit >= 0) {
2189         btnPtr = &infoPtr->buttons[nHit];
2190         if (!(btnPtr->fsState & TBSTATE_ENABLED))
2191             return 0;
2192
2193         SetCapture32 (wndPtr->hwndSelf);
2194         infoPtr->bCaptured = TRUE;
2195         infoPtr->nButtonDown = nHit;
2196         infoPtr->nOldHit = nHit;
2197
2198         btnPtr->fsState |= TBSTATE_PRESSED;
2199
2200         hdc = GetDC32 (wndPtr->hwndSelf);
2201         TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
2202         ReleaseDC32 (wndPtr->hwndSelf, hdc);
2203     }
2204
2205     return 0;
2206 }
2207
2208
2209 static LRESULT
2210 TOOLBAR_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2211 {
2212     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
2213     TBUTTON_INFO *btnPtr;
2214     POINT32 pt;
2215     INT32   nHit;
2216     INT32   nOldIndex = -1;
2217     HDC32   hdc;
2218     BOOL32  bSendMessage = TRUE;
2219
2220     if (infoPtr->hwndToolTip)
2221         TOOLBAR_RelayEvent (infoPtr->hwndToolTip, wndPtr->hwndSelf,
2222                             WM_LBUTTONUP, wParam, lParam);
2223
2224     pt.x = (INT32)LOWORD(lParam);
2225     pt.y = (INT32)HIWORD(lParam);
2226     nHit = TOOLBAR_InternalHitTest (wndPtr, &pt);
2227
2228     if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
2229         infoPtr->bCaptured = FALSE;
2230         ReleaseCapture ();
2231         btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
2232         btnPtr->fsState &= ~TBSTATE_PRESSED;
2233
2234         if (nHit == infoPtr->nButtonDown) {
2235             if (btnPtr->fsStyle & TBSTYLE_CHECK) {
2236                 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
2237                     nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
2238                         infoPtr->nButtonDown);
2239                     if (nOldIndex == infoPtr->nButtonDown)
2240                         bSendMessage = FALSE;
2241                     if ((nOldIndex != infoPtr->nButtonDown) && 
2242                         (nOldIndex != -1))
2243                         infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
2244                     btnPtr->fsState |= TBSTATE_CHECKED;
2245                 }
2246                 else {
2247                     if (btnPtr->fsState & TBSTATE_CHECKED)
2248                         btnPtr->fsState &= ~TBSTATE_CHECKED;
2249                     else
2250                         btnPtr->fsState |= TBSTATE_CHECKED;
2251                 }
2252             }
2253         }
2254         else
2255             bSendMessage = FALSE;
2256
2257         hdc = GetDC32 (wndPtr->hwndSelf);
2258         if (nOldIndex != -1)
2259             TOOLBAR_DrawButton (wndPtr, &infoPtr->buttons[nOldIndex], hdc);
2260         TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
2261         ReleaseDC32 (wndPtr->hwndSelf, hdc);
2262
2263         if (bSendMessage)
2264             SendMessage32A (infoPtr->hwndNotify, WM_COMMAND,
2265                             MAKEWPARAM(btnPtr->idCommand, 0),
2266                             (LPARAM)wndPtr->hwndSelf);
2267
2268         infoPtr->nButtonDown = -1;
2269         infoPtr->nOldHit = -1;
2270     }
2271
2272     return 0;
2273 }
2274
2275
2276 static LRESULT
2277 TOOLBAR_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2278 {
2279     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
2280     TBUTTON_INFO *btnPtr;
2281     POINT32 pt;
2282     INT32   nHit;
2283     HDC32   hdc;
2284
2285     if (infoPtr->hwndToolTip)
2286         TOOLBAR_RelayEvent (infoPtr->hwndToolTip, wndPtr->hwndSelf,
2287                             WM_MOUSEMOVE, wParam, lParam);
2288
2289     pt.x = (INT32)LOWORD(lParam);
2290     pt.y = (INT32)HIWORD(lParam);
2291     nHit = TOOLBAR_InternalHitTest (wndPtr, &pt);
2292
2293     if (infoPtr->bCaptured) {
2294         if (infoPtr->nOldHit != nHit) {
2295             btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
2296             if (infoPtr->nOldHit == infoPtr->nButtonDown) {
2297                 btnPtr->fsState &= ~TBSTATE_PRESSED;
2298                 hdc = GetDC32 (wndPtr->hwndSelf);
2299                 TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
2300                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
2301             }
2302             else if (nHit == infoPtr->nButtonDown) {
2303                 btnPtr->fsState |= TBSTATE_PRESSED;
2304                 hdc = GetDC32 (wndPtr->hwndSelf);
2305                 TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
2306                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
2307             }
2308         }
2309         infoPtr->nOldHit = nHit;
2310     }
2311
2312     return 0;
2313 }
2314
2315
2316 __inline__ static LRESULT
2317 TOOLBAR_NCActivate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2318 {
2319 //    if (wndPtr->dwStyle & CCS_NODIVIDER)
2320         return DefWindowProc32A (wndPtr->hwndSelf, WM_NCACTIVATE,
2321                                  wParam, lParam);
2322 //    else
2323 //      return TOOLBAR_NCPaint (wndPtr, wParam, lParam);
2324 }
2325
2326
2327 __inline__ static LRESULT
2328 TOOLBAR_NCCalcSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2329 {
2330     if (!(wndPtr->dwStyle & CCS_NODIVIDER))
2331         ((LPRECT32)lParam)->top += sysMetrics[SM_CYEDGE];
2332
2333     return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCALCSIZE, wParam, lParam);
2334 }
2335
2336
2337 static LRESULT
2338 TOOLBAR_NCCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2339 {
2340     TOOLBAR_INFO *infoPtr;
2341
2342     /* allocate memory for info structure */
2343     infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
2344     wndPtr->wExtra[0] = (DWORD)infoPtr;
2345
2346     if (infoPtr == NULL) {
2347         ERR (toolbar, "could not allocate info memory!\n");
2348         return 0;
2349     }
2350
2351     if ((TOOLBAR_INFO*)wndPtr->wExtra[0] != infoPtr) {
2352         ERR (toolbar, "pointer assignment error!\n");
2353         return 0;
2354     }
2355
2356     /* paranoid!! */
2357     infoPtr->dwStructSize = sizeof(TBBUTTON);
2358
2359     /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
2360     if (!wndPtr->hInstance)
2361         wndPtr->hInstance = wndPtr->parent->hInstance;
2362
2363     return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCREATE, wParam, lParam);
2364 }
2365
2366
2367 static LRESULT
2368 TOOLBAR_NCPaint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2369 {
2370     HWND32 hwnd = wndPtr->hwndSelf;
2371     HDC32 hdc;
2372
2373     if ( wndPtr->dwStyle & WS_MINIMIZE ||
2374         !WIN_IsWindowDrawable( wndPtr, 0 )) return 0; /* Nothing to do */
2375
2376     DefWindowProc32A (hwnd, WM_NCPAINT, wParam, lParam);
2377
2378     if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return 0;
2379
2380     if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
2381                         wndPtr->rectClient.top-wndPtr->rectWindow.top,
2382                         wndPtr->rectClient.right-wndPtr->rectWindow.left,
2383                         wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
2384         == NULLREGION){
2385         ReleaseDC32( hwnd, hdc );
2386         return 0;
2387     }
2388
2389     if (!(wndPtr->flags & WIN_MANAGED) && !(wndPtr->dwStyle & CCS_NODIVIDER))
2390         DrawEdge32 (hdc, &wndPtr->rectWindow, EDGE_ETCHED, BF_TOP);
2391
2392     ReleaseDC32( hwnd, hdc );
2393
2394     return 0;
2395 }
2396
2397
2398 __inline__ static LRESULT
2399 TOOLBAR_Notify (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2400 {
2401     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
2402     LPNMHDR lpnmh = (LPNMHDR)lParam;
2403
2404     TRACE (toolbar, "passing WM_NOTIFY!\n");
2405
2406     if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
2407         SendMessage32A (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
2408
2409 #if 0
2410         if (lpnmh->code == TTN_GETDISPINFO32A) {
2411             LPNMTTDISPINFO32A lpdi = (LPNMTTDISPINFO32A)lParam;
2412
2413             FIXME (toolbar, "retrieving ASCII string\n");
2414
2415         }
2416         else if (lpnmh->code == TTN_GETDISPINFO32W) {
2417             LPNMTTDISPINFO32W lpdi = (LPNMTTDISPINFO32W)lParam;
2418
2419             FIXME (toolbar, "retrieving UNICODE string\n");
2420
2421         }
2422 #endif
2423     }
2424
2425     return 0;
2426 }
2427
2428
2429 static LRESULT
2430 TOOLBAR_Paint (WND *wndPtr, WPARAM32 wParam)
2431 {
2432     HDC32 hdc;
2433     PAINTSTRUCT32 ps;
2434
2435     hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
2436     TOOLBAR_Refresh (wndPtr, hdc);
2437     if (!wParam)
2438         EndPaint32 (wndPtr->hwndSelf, &ps);
2439     return 0;
2440 }
2441
2442
2443 static LRESULT
2444 TOOLBAR_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2445 {
2446     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
2447     RECT32 parent_rect;
2448     HWND32 parent;
2449     INT32  x, y, cx, cy;
2450     INT32  flags;
2451     UINT32 uPosFlags = 0;
2452
2453     /* Resize deadlock check */
2454     if (infoPtr->bAutoSize) {
2455         infoPtr->bAutoSize = FALSE;
2456         return 0;
2457     }
2458
2459     flags = (INT32) wParam;
2460
2461     /* FIXME for flags =
2462      * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
2463      */
2464
2465     TRACE (toolbar, "sizing toolbar!\n");
2466
2467     if (flags == SIZE_RESTORED) {
2468         /* width and height don't apply */
2469         parent = GetParent32 (wndPtr->hwndSelf);
2470         GetClientRect32(parent, &parent_rect);
2471
2472         if (wndPtr->dwStyle & CCS_NORESIZE) {
2473             uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
2474
2475             /* FIXME */
2476 //          infoPtr->nWidth = parent_rect.right - parent_rect.left;
2477             cy = infoPtr->nHeight;
2478             cx = infoPtr->nWidth;
2479             TOOLBAR_CalcToolbar (wndPtr);
2480             infoPtr->nWidth = cx;
2481             infoPtr->nHeight = cy;
2482         }
2483         else {
2484             infoPtr->nWidth = parent_rect.right - parent_rect.left;
2485             TOOLBAR_CalcToolbar (wndPtr);
2486             cy = infoPtr->nHeight;
2487             cx = infoPtr->nWidth;
2488         }
2489
2490         if (wndPtr->dwStyle & CCS_NOPARENTALIGN) {
2491             uPosFlags |= SWP_NOMOVE;
2492             cy = infoPtr->nHeight;
2493             cx = infoPtr->nWidth;
2494         }
2495
2496         if (!(wndPtr->dwStyle & CCS_NODIVIDER))
2497             cy += sysMetrics[SM_CYEDGE];
2498
2499         SetWindowPos32 (wndPtr->hwndSelf, 0, parent_rect.left, parent_rect.top,
2500                         cx, cy, uPosFlags | SWP_NOZORDER);
2501     }
2502     return 0;
2503 }
2504
2505
2506 static LRESULT
2507 TOOLBAR_StyleChanged (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2508 {
2509     HDC32 hdc;
2510
2511     TOOLBAR_AutoSize (wndPtr, wParam, lParam);
2512
2513     hdc = GetDC32 (wndPtr->hwndSelf);
2514     TOOLBAR_Refresh (wndPtr, hdc);
2515     ReleaseDC32 (wndPtr->hwndSelf, hdc);
2516
2517     return 0;
2518 }
2519
2520
2521
2522 LRESULT WINAPI
2523 ToolbarWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
2524 {
2525     WND *wndPtr = WIN_FindWndPtr(hwnd);
2526
2527     switch (uMsg)
2528     {
2529         case TB_ADDBITMAP:
2530             return TOOLBAR_AddBitmap (wndPtr, wParam, lParam);
2531
2532         case TB_ADDBUTTONS32A:
2533             return TOOLBAR_AddButtons32A (wndPtr, wParam, lParam);
2534
2535 //      case TB_ADDBUTTONS32W:
2536
2537         case TB_ADDSTRING32A:
2538             return TOOLBAR_AddString32A (wndPtr, wParam, lParam);
2539
2540 //      case TB_ADDSTRING32W:
2541
2542         case TB_AUTOSIZE:
2543             return TOOLBAR_AutoSize (wndPtr, wParam, lParam);
2544
2545         case TB_BUTTONCOUNT:
2546             return TOOLBAR_ButtonCount (wndPtr, wParam, lParam);
2547
2548         case TB_BUTTONSTRUCTSIZE:
2549             return TOOLBAR_ButtonStructSize (wndPtr, wParam, lParam);
2550
2551         case TB_CHANGEBITMAP:
2552             return TOOLBAR_ChangeBitmap (wndPtr, wParam, lParam);
2553
2554         case TB_CHECKBUTTON:
2555             return TOOLBAR_CheckButton (wndPtr, wParam, lParam);
2556
2557         case TB_COMMANDTOINDEX:
2558             return TOOLBAR_CommandToIndex (wndPtr, wParam, lParam);
2559
2560         case TB_CUSTOMIZE:
2561             return TOOLBAR_Customize (wndPtr);
2562
2563         case TB_DELETEBUTTON:
2564             return TOOLBAR_DeleteButton (wndPtr, wParam, lParam);
2565
2566         case TB_ENABLEBUTTON:
2567             return TOOLBAR_EnableButton (wndPtr, wParam, lParam);
2568
2569 //      case TB_GETANCHORHIGHLIGHT:             /* 4.71 */
2570
2571         case TB_GETBITMAP:
2572             return TOOLBAR_GetBitmap (wndPtr, wParam, lParam);
2573
2574         case TB_GETBITMAPFLAGS:
2575             return TOOLBAR_GetBitmapFlags (wndPtr, wParam, lParam);
2576
2577         case TB_GETBUTTON:
2578             return TOOLBAR_GetButton (wndPtr, wParam, lParam);
2579
2580         case TB_GETBUTTONINFO32A:
2581             return TOOLBAR_GetButtonInfo32A (wndPtr, wParam, lParam);
2582
2583 //      case TB_GETBUTTONINFO32W:               /* 4.71 */
2584
2585         case TB_GETBUTTONSIZE:
2586             return TOOLBAR_GetButtonSize (wndPtr);
2587
2588         case TB_GETBUTTONTEXT32A:
2589             return TOOLBAR_GetButtonText32A (wndPtr, wParam, lParam);
2590
2591 //      case TB_GETBUTTONTEXT32W:
2592 //      case TB_GETCOLORSCHEME:                 /* 4.71 */
2593
2594         case TB_GETDISABLEDIMAGELIST:
2595             return TOOLBAR_GetDisabledImageList (wndPtr, wParam, lParam);
2596
2597         case TB_GETEXTENDEDSTYLE:
2598             return TOOLBAR_GetExtendedStyle (wndPtr);
2599
2600         case TB_GETHOTIMAGELIST:
2601             return TOOLBAR_GetHotImageList (wndPtr, wParam, lParam);
2602
2603 //      case TB_GETHOTITEM:                     /* 4.71 */
2604
2605         case TB_GETIMAGELIST:
2606             return TOOLBAR_GetImageList (wndPtr, wParam, lParam);
2607
2608 //      case TB_GETINSERTMARK:                  /* 4.71 */
2609 //      case TB_GETINSERTMARKCOLOR:             /* 4.71 */
2610
2611         case TB_GETITEMRECT:
2612             return TOOLBAR_GetItemRect (wndPtr, wParam, lParam);
2613
2614         case TB_GETMAXSIZE:
2615             return TOOLBAR_GetMaxSize (wndPtr, wParam, lParam);
2616
2617 //      case TB_GETOBJECT:                      /* 4.71 */
2618 //      case TB_GETPADDING:                     /* 4.71 */
2619
2620         case TB_GETRECT:
2621             return TOOLBAR_GetRect (wndPtr, wParam, lParam);
2622
2623         case TB_GETROWS:
2624             return TOOLBAR_GetRows (wndPtr, wParam, lParam);
2625
2626         case TB_GETSTATE:
2627             return TOOLBAR_GetState (wndPtr, wParam, lParam);
2628
2629         case TB_GETSTYLE:
2630             return TOOLBAR_GetStyle (wndPtr, wParam, lParam);
2631
2632         case TB_GETTEXTROWS:
2633             return TOOLBAR_GetTextRows (wndPtr, wParam, lParam);
2634
2635         case TB_GETTOOLTIPS:
2636             return TOOLBAR_GetToolTips (wndPtr, wParam, lParam);
2637
2638         case TB_GETUNICODEFORMAT:
2639             return TOOLBAR_GetUnicodeFormat (wndPtr, wParam, lParam);
2640
2641         case TB_HIDEBUTTON:
2642             return TOOLBAR_HideButton (wndPtr, wParam, lParam);
2643
2644         case TB_HITTEST:
2645             return TOOLBAR_HitTest (wndPtr, wParam, lParam);
2646
2647         case TB_INDETERMINATE:
2648             return TOOLBAR_Indeterminate (wndPtr, wParam, lParam);
2649
2650         case TB_INSERTBUTTON32A:
2651             return TOOLBAR_InsertButton32A (wndPtr, wParam, lParam);
2652
2653 //      case TB_INSERTBUTTON32W:
2654 //      case TB_INSERTMARKHITTEST:              /* 4.71 */
2655
2656         case TB_ISBUTTONCHECKED:
2657             return TOOLBAR_IsButtonChecked (wndPtr, wParam, lParam);
2658
2659         case TB_ISBUTTONENABLED:
2660             return TOOLBAR_IsButtonEnabled (wndPtr, wParam, lParam);
2661
2662         case TB_ISBUTTONHIDDEN:
2663             return TOOLBAR_IsButtonHidden (wndPtr, wParam, lParam);
2664
2665         case TB_ISBUTTONHIGHLIGHTED:
2666             return TOOLBAR_IsButtonHighlighted (wndPtr, wParam, lParam);
2667
2668         case TB_ISBUTTONINDETERMINATE:
2669             return TOOLBAR_IsButtonIndeterminate (wndPtr, wParam, lParam);
2670
2671         case TB_ISBUTTONPRESSED:
2672             return TOOLBAR_IsButtonPressed (wndPtr, wParam, lParam);
2673
2674 //      case TB_LOADIMAGES:                     /* 4.70 */
2675 //      case TB_MAPACCELERATOR32A:              /* 4.71 */
2676 //      case TB_MAPACCELERATOR32W:              /* 4.71 */
2677 //      case TB_MARKBUTTON:                     /* 4.71 */
2678 //      case TB_MOVEBUTTON:                     /* 4.71 */
2679
2680         case TB_PRESSBUTTON:
2681             return TOOLBAR_PressButton (wndPtr, wParam, lParam);
2682
2683 //      case TB_REPLACEBITMAP:
2684
2685         case TB_SAVERESTORE32A:
2686             return TOOLBAR_SaveRestore32A (wndPtr, wParam, lParam);
2687
2688 //      case TB_SAVERESTORE32W:
2689 //      case TB_SETANCHORHIGHLIGHT:             /* 4.71 */
2690
2691         case TB_SETBITMAPSIZE:
2692             return TOOLBAR_SetBitmapSize (wndPtr, wParam, lParam);
2693
2694         case TB_SETBUTTONINFO32A:
2695             return TOOLBAR_SetButtonInfo32A (wndPtr, wParam, lParam);
2696
2697 //      case TB_SETBUTTONINFO32W:               /* 4.71 */
2698
2699         case TB_SETBUTTONSIZE:
2700             return TOOLBAR_SetButtonSize (wndPtr, wParam, lParam);
2701
2702         case TB_SETBUTTONWIDTH:
2703             return TOOLBAR_SetButtonWidth (wndPtr, wParam, lParam);
2704
2705         case TB_SETCMDID:
2706             return TOOLBAR_SetCmdId (wndPtr, wParam, lParam);
2707
2708 //      case TB_SETCOLORSCHEME:                 /* 4.71 */
2709
2710         case TB_SETDISABLEDIMAGELIST:
2711             return TOOLBAR_SetDisabledImageList (wndPtr, wParam, lParam);
2712
2713         case TB_SETDRAWTEXTFLAGS:
2714             return TOOLBAR_SetDrawTextFlags (wndPtr, wParam, lParam);
2715
2716         case TB_SETEXTENDEDSTYLE:
2717             return TOOLBAR_SetExtendedStyle (wndPtr, wParam, lParam);
2718
2719         case TB_SETHOTIMAGELIST:
2720             return TOOLBAR_SetHotImageList (wndPtr, wParam, lParam);
2721
2722 //      case TB_SETHOTITEM:                     /* 4.71 */
2723
2724         case TB_SETIMAGELIST:
2725             return TOOLBAR_SetImageList (wndPtr, wParam, lParam);
2726
2727         case TB_SETINDENT:
2728             return TOOLBAR_SetIndent (wndPtr, wParam, lParam);
2729
2730 //      case TB_SETINSERTMARK:                  /* 4.71 */
2731
2732         case TB_SETINSERTMARKCOLOR:
2733             return TOOLBAR_SetInsertMarkColor (wndPtr, wParam, lParam);
2734
2735         case TB_SETMAXTEXTROWS:
2736             return TOOLBAR_SetMaxTextRows (wndPtr, wParam, lParam);
2737
2738 //      case TB_SETPADDING:                     /* 4.71 */
2739
2740         case TB_SETPARENT:
2741             return TOOLBAR_SetParent (wndPtr, wParam, lParam);
2742
2743         case TB_SETROWS:
2744             return TOOLBAR_SetRows (wndPtr, wParam, lParam);
2745
2746         case TB_SETSTATE:
2747             return TOOLBAR_SetState (wndPtr, wParam, lParam);
2748
2749         case TB_SETSTYLE:
2750             return TOOLBAR_SetStyle (wndPtr, wParam, lParam);
2751
2752         case TB_SETTOOLTIPS:
2753             return TOOLBAR_SetToolTips (wndPtr, wParam, lParam);
2754
2755         case TB_SETUNICODEFORMAT:
2756             return TOOLBAR_SetUnicodeFormat (wndPtr, wParam, lParam);
2757
2758
2759 //      case WM_CHAR:
2760
2761         case WM_CREATE:
2762             return TOOLBAR_Create (wndPtr, wParam, lParam);
2763
2764         case WM_DESTROY:
2765             return TOOLBAR_Destroy (wndPtr, wParam, lParam);
2766
2767         case WM_ERASEBKGND:
2768             return TOOLBAR_EraseBackground (wndPtr, wParam, lParam);
2769
2770 //      case WM_GETFONT:
2771 //      case WM_KEYDOWN:
2772 //      case WM_KILLFOCUS:
2773
2774         case WM_LBUTTONDBLCLK:
2775             return TOOLBAR_LButtonDblClk (wndPtr, wParam, lParam);
2776
2777         case WM_LBUTTONDOWN:
2778             return TOOLBAR_LButtonDown (wndPtr, wParam, lParam);
2779
2780         case WM_LBUTTONUP:
2781             return TOOLBAR_LButtonUp (wndPtr, wParam, lParam);
2782
2783         case WM_MOUSEMOVE:
2784             return TOOLBAR_MouseMove (wndPtr, wParam, lParam);
2785
2786         case WM_NCACTIVATE:
2787             return TOOLBAR_NCActivate (wndPtr, wParam, lParam);
2788
2789         case WM_NCCALCSIZE:
2790             return TOOLBAR_NCCalcSize (wndPtr, wParam, lParam);
2791
2792         case WM_NCCREATE:
2793             return TOOLBAR_NCCreate (wndPtr, wParam, lParam);
2794
2795         case WM_NCPAINT:
2796             return TOOLBAR_NCPaint (wndPtr, wParam, lParam);
2797
2798         case WM_NOTIFY:
2799             return TOOLBAR_Notify (wndPtr, wParam, lParam);
2800
2801 //      case WM_NOTIFYFORMAT:
2802
2803         case WM_PAINT:
2804             return TOOLBAR_Paint (wndPtr, wParam);
2805
2806         case WM_SIZE:
2807             return TOOLBAR_Size (wndPtr, wParam, lParam);
2808
2809         case WM_STYLECHANGED:
2810             return TOOLBAR_StyleChanged (wndPtr, wParam, lParam);
2811
2812 //      case WM_SYSCOLORCHANGE:
2813
2814 //      case WM_WININICHANGE:
2815
2816         case WM_CHARTOITEM:
2817         case WM_COMMAND:
2818         case WM_DRAWITEM:
2819         case WM_MEASUREITEM:
2820         case WM_VKEYTOITEM:
2821             return SendMessage32A (GetParent32 (hwnd), uMsg, wParam, lParam);
2822
2823         default:
2824             if (uMsg >= WM_USER)
2825                 ERR (toolbar, "unknown msg %04x wp=%08x lp=%08lx\n",
2826                      uMsg, wParam, lParam);
2827             return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
2828     }
2829     return 0;
2830 }
2831
2832
2833 void TOOLBAR_Register (void)
2834 {
2835     WNDCLASS32A wndClass;
2836
2837     if (GlobalFindAtom32A (TOOLBARCLASSNAME32A)) return;
2838
2839     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
2840     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
2841     wndClass.lpfnWndProc   = (WNDPROC32)ToolbarWindowProc;
2842     wndClass.cbClsExtra    = 0;
2843     wndClass.cbWndExtra    = sizeof(TOOLBAR_INFO *);
2844     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
2845     wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
2846     wndClass.lpszClassName = TOOLBARCLASSNAME32A;
2847  
2848     RegisterClass32A (&wndClass);
2849 }