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