Changed some treeview related definitions.
[wine] / dlls / comctl32 / toolbar.c
1 /*
2  * Toolbar control
3  *
4  * Copyright 1998 Eric Kohl
5  *
6  * TODO:
7  *   - A little bug in TOOLBAR_DrawMasked()
8  *   - Button wrapping (under construction).
9  *   - Messages.
10  *   - Notifications.
11  *   - Fix TB_SETROWS.
12  *   - Tooltip support (almost complete).
13  *   - Unicode suppport.
14  *   - Internal COMMCTL32 bitmaps.
15  *   - Fix TOOLBAR_SetButtonInfo32A.
16  *   - Fix TOOLBAR_Customize. (Customize dialog.)
17  *
18  * Testing:
19  *   - Run tests using Waite Group Windows95 API Bible Volume 2.
20  *     The second cdrom contains executables addstr.exe, btncount.exe,
21  *     btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
22  *     enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
23  *     indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
24  *     setparnt.exe, setrows.exe, toolwnd.exe.
25  *   - Microsofts controlspy examples.
26  */
27
28 #include "windows.h"
29 #include "commctrl.h"
30 #include "sysmetrics.h"
31 #include "cache.h"
32 #include "toolbar.h"
33 #include "win.h"
34 #include "debug.h"
35
36 /* #define __NEW_WRAP_CODE__ */
37
38 #define SEPARATOR_WIDTH    8
39 #define SEPARATOR_HEIGHT   5
40 #define TOP_BORDER         2
41 #define BOTTOM_BORDER      2
42
43
44
45 #define TOOLBAR_GetInfoPtr(wndPtr) ((TOOLBAR_INFO *)wndPtr->wExtra[0])
46
47
48 static void
49 TOOLBAR_DrawFlatSeparator (LPRECT32 lpRect, HDC32 hdc)
50 {
51     INT32 x = (lpRect->left + lpRect->right) / 2 - 1;
52     INT32 yBottom = lpRect->bottom - 3;
53     INT32 yTop = lpRect->top + 1;
54
55     SelectObject32 ( hdc, GetSysColorPen32 (COLOR_3DSHADOW));
56     MoveToEx32 (hdc, x, yBottom, NULL);
57     LineTo32 (hdc, x, yTop);
58     x++;
59     SelectObject32 ( hdc, GetSysColorPen32 (COLOR_3DHILIGHT));
60     MoveToEx32 (hdc, x, yBottom, NULL);
61     LineTo32 (hdc, x, yTop);
62 }
63
64
65 static void
66 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
67                     HDC32 hdc, INT32 nState)
68 {
69     RECT32   rcText = btnPtr->rect;
70     HFONT32  hOldFont;
71     INT32    nOldBkMode;
72     COLORREF clrOld;
73
74     /* draw text */
75     if ((btnPtr->iString > -1) && (btnPtr->iString < infoPtr->nNumStrings)) {
76         InflateRect32 (&rcText, -3, -3);
77         rcText.top += infoPtr->nBitmapHeight;
78         if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
79             OffsetRect32 (&rcText, 1, 1);
80
81         hOldFont = SelectObject32 (hdc, infoPtr->hFont);
82         nOldBkMode = SetBkMode32 (hdc, TRANSPARENT);
83         if (!(nState & TBSTATE_ENABLED)) {
84             clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_3DHILIGHT));
85             OffsetRect32 (&rcText, 1, 1);
86             DrawText32W (hdc, infoPtr->strings[btnPtr->iString], -1,
87                          &rcText, infoPtr->dwDTFlags);
88             SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW));
89             OffsetRect32 (&rcText, -1, -1);
90             DrawText32W (hdc, infoPtr->strings[btnPtr->iString], -1,
91                          &rcText, infoPtr->dwDTFlags);
92         }
93         else if (nState & TBSTATE_INDETERMINATE) {
94             clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_3DSHADOW));
95             DrawText32W (hdc, infoPtr->strings[btnPtr->iString], -1,
96                          &rcText, infoPtr->dwDTFlags);
97         }
98         else {
99             clrOld = SetTextColor32 (hdc, GetSysColor32 (COLOR_BTNTEXT));
100             DrawText32W (hdc, infoPtr->strings[btnPtr->iString], -1,
101                          &rcText, infoPtr->dwDTFlags);
102         }
103
104         SetTextColor32 (hdc, clrOld);
105         SelectObject32 (hdc, hOldFont);
106         if (nOldBkMode != TRANSPARENT)
107             SetBkMode32 (hdc, nOldBkMode);
108     }
109 }
110
111
112 static void
113 TOOLBAR_DrawPattern (HDC32 hdc, LPRECT32 lpRect)
114 {
115     HBRUSH32 hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ());
116     INT32 cx = lpRect->right - lpRect->left;
117     INT32 cy = lpRect->bottom - lpRect->top;
118     PatBlt32 (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
119     SelectObject32 (hdc, hbr);
120 }
121
122
123 static void
124 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
125                     HDC32 hdc, INT32 x, INT32 y)
126 {
127     /* FIXME: this function is a hack since it uses image list
128               internals directly */
129
130     HDC32 hdcImageList = CreateCompatibleDC32 (0);
131     HDC32 hdcMask = CreateCompatibleDC32 (0);
132     HIMAGELIST himl = infoPtr->himlStd;
133     HBITMAP32 hbmMask;
134
135     /* create new bitmap */
136     hbmMask = CreateBitmap32 (himl->cx, himl->cy, 1, 1, NULL);
137     SelectObject32 (hdcMask, hbmMask);
138
139     /* copy the mask bitmap */
140     SelectObject32 (hdcImageList, himl->hbmMask);
141     SetBkColor32 (hdcImageList, RGB(255, 255, 255));
142     SetTextColor32 (hdcImageList, RGB(0, 0, 0));
143     BitBlt32 (hdcMask, 0, 0, himl->cx, himl->cy,
144               hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
145
146 #if 0
147     /* add white mask from image */
148     SelectObject32 (hdcImageList, himl->hbmImage);
149     SetBkColor32 (hdcImageList, RGB(0, 0, 0));
150     BitBlt32 (hdcMask, 0, 0, himl->cx, himl->cy,
151               hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
152 #endif
153
154     /* draw the new mask */
155     SelectObject32 (hdc, GetSysColorBrush32 (COLOR_3DHILIGHT));
156     BitBlt32 (hdc, x+1, y+1, himl->cx, himl->cy,
157               hdcMask, 0, 0, 0xB8074A);
158
159     SelectObject32 (hdc, GetSysColorBrush32 (COLOR_3DSHADOW));
160     BitBlt32 (hdc, x, y, himl->cx, himl->cy,
161               hdcMask, 0, 0, 0xB8074A);
162
163     DeleteObject32 (hbmMask);
164     DeleteDC32 (hdcMask);
165     DeleteDC32 (hdcImageList);
166 }
167
168
169 static void
170 TOOLBAR_DrawButton (WND *wndPtr, TBUTTON_INFO *btnPtr, HDC32 hdc)
171 {
172     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
173     BOOL32 bFlat = (wndPtr->dwStyle & TBSTYLE_FLAT);
174     RECT32 rc;
175
176     if (btnPtr->fsState & TBSTATE_HIDDEN) return;
177
178     rc = btnPtr->rect;
179     if (btnPtr->fsStyle & TBSTYLE_SEP) {
180         if ((bFlat) && (btnPtr->idCommand == 0))
181             TOOLBAR_DrawFlatSeparator (&btnPtr->rect, hdc);
182         return;
183     }
184
185     /* disabled */
186     if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
187         DrawEdge32 (hdc, &rc, EDGE_RAISED,
188                     BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
189
190         if (bFlat) {
191 /*          if (infoPtr->himlDis) */
192                 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
193                                 rc.left+1, rc.top+1, ILD_NORMAL);
194 /*          else */
195 /*              TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1); */
196         }
197         else
198             TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
199
200         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
201         return;
202     }
203
204     /* pressed TBSTYLE_BUTTON */
205     if (btnPtr->fsState & TBSTATE_PRESSED) {
206         DrawEdge32 (hdc, &rc, EDGE_SUNKEN,
207                     BF_RECT | BF_MIDDLE | BF_ADJUST);
208         ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
209                         rc.left+2, rc.top+2, ILD_NORMAL);
210         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
211         return;
212     }
213
214     /* checked TBSTYLE_CHECK*/
215     if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
216         (btnPtr->fsState & TBSTATE_CHECKED)) {
217         if (bFlat)
218             DrawEdge32 (hdc, &rc, BDR_SUNKENOUTER,
219                         BF_RECT | BF_MIDDLE | BF_ADJUST);
220         else
221             DrawEdge32 (hdc, &rc, EDGE_SUNKEN,
222                         BF_RECT | BF_MIDDLE | BF_ADJUST);
223
224         TOOLBAR_DrawPattern (hdc, &rc);
225         if (bFlat)
226             ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
227                             rc.left+2, rc.top+2, ILD_NORMAL);
228         else
229             ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
230                             rc.left+2, rc.top+2, ILD_NORMAL);
231         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
232         return;
233     }
234
235     /* indeterminate */ 
236     if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
237         DrawEdge32 (hdc, &rc, EDGE_RAISED,
238                     BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
239
240         TOOLBAR_DrawPattern (hdc, &rc);
241         TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
242         TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
243         return;
244     }
245
246     /* normal state */
247     DrawEdge32 (hdc, &rc, EDGE_RAISED,
248                 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
249
250     if (bFlat)
251         ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
252                         rc.left+1, rc.top+1, ILD_NORMAL);
253     else
254         ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
255                         rc.left+1, rc.top+1, ILD_NORMAL);
256
257     TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
258 }
259
260
261 static void
262 TOOLBAR_Refresh (WND *wndPtr, HDC32 hdc)
263 {
264     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
265     TBUTTON_INFO *btnPtr;
266     INT32 i;
267
268     /* draw buttons */
269     btnPtr = infoPtr->buttons;
270     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
271         TOOLBAR_DrawButton (wndPtr, btnPtr, hdc);
272 }
273
274
275 static void
276 TOOLBAR_CalcStrings (WND *wndPtr, LPSIZE32 lpSize)
277 {
278     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
279     TBUTTON_INFO *btnPtr;
280     INT32 i;
281     HDC32 hdc;
282     HFONT32 hOldFont;
283     SIZE32 sz;
284
285     lpSize->cx = 0;
286     lpSize->cy = 0;
287     hdc = GetDC32 (0);
288     hOldFont = SelectObject32 (hdc, infoPtr->hFont);
289
290     btnPtr = infoPtr->buttons;
291     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
292         if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
293             (btnPtr->iString > -1) &&
294             (btnPtr->iString < infoPtr->nNumStrings)) {
295             LPWSTR lpText = infoPtr->strings[btnPtr->iString];
296             GetTextExtentPoint32W (hdc, lpText, lstrlen32W (lpText), &sz);
297             if (sz.cx > lpSize->cx)
298                 lpSize->cx = sz.cx;
299             if (sz.cy > lpSize->cy)
300                 lpSize->cy = sz.cy;
301         }
302     }
303
304     SelectObject32 (hdc, hOldFont);
305     ReleaseDC32 (0, hdc);
306
307     TRACE (toolbar, "string size %d x %d!\n", lpSize->cx, lpSize->cy);
308 }
309
310
311 static void
312 TOOLBAR_CalcToolbar (WND *wndPtr)
313 {
314     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
315     TBUTTON_INFO *btnPtr, *grpPtr;
316     INT32 i, j, nRows;
317     INT32 x, y, cx, cy;
318     BOOL32 bWrap;
319     SIZE32  sizeString;
320 /* --- new --- */
321     INT32  nGrpCount = 0;
322     INT32  grpX;
323 /* --- end new --- */
324
325     TOOLBAR_CalcStrings (wndPtr, &sizeString);
326
327     if (sizeString.cy > 0)
328         infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
329     else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
330         infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
331
332     if (sizeString.cx > infoPtr->nBitmapWidth)
333         infoPtr->nButtonWidth = sizeString.cx + 6;
334     else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
335         infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
336
337     x  = infoPtr->nIndent;
338     y  = TOP_BORDER;
339     cx = infoPtr->nButtonWidth;
340     cy = infoPtr->nButtonHeight;
341     nRows = 0;
342
343     /* calculate the size of each button according to it's style */
344 /*     TOOLBAR_CalcButtons (wndPtr); */
345
346     infoPtr->rcBound.top = y;
347     infoPtr->rcBound.left = x;
348     infoPtr->rcBound.bottom = y + cy;
349     infoPtr->rcBound.right = x;
350
351     btnPtr = infoPtr->buttons;
352     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
353         bWrap = FALSE;
354
355         if (btnPtr->fsState & TBSTATE_HIDDEN) {
356             SetRectEmpty32 (&btnPtr->rect);
357             continue;
358         }
359
360 #ifdef __NEW_WRAP_CODE__
361 /*#if 0 */
362         if (btnPtr->fsStyle & TBSTYLE_SEP) {
363             /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
364             /* it is the actual width of the separator. This is used for */
365             /* custom controls in toolbars.                              */
366             if ((wndPtr->dwStyle & TBSTYLE_WRAPABLE) &&
367                 (btnPtr->fsState & TBSTATE_WRAP)) {
368                 x = 0;
369                 y += cy;
370                 cx = infoPtr->nWidth;
371                 cy = ((btnPtr->iBitmap > 0) ?
372                      btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3;
373 /*              nRows++; */
374 /*              bWrap = TRUE; */
375             }
376             else
377                 cx = (btnPtr->iBitmap > 0) ?
378                      btnPtr->iBitmap : SEPARATOR_WIDTH;
379         }
380         else {
381             /* this must be a button */
382             cx = infoPtr->nButtonWidth;
383         }
384 /*#endif */
385
386 /* --- begin test --- */
387         if ((i >= nGrpCount) && (btnPtr->fsStyle & TBSTYLE_GROUP)) {
388             for (j = i, grpX = x, nGrpCount = 0; j < infoPtr->nNumButtons; j++) {
389                 grpPtr = &infoPtr->buttons[j];
390                 if (grpPtr->fsState & TBSTATE_HIDDEN)
391                     continue;
392
393                 grpX += cx;
394
395                 if ((grpPtr->fsStyle & TBSTYLE_SEP) ||
396                     !(grpPtr->fsStyle & TBSTYLE_GROUP) ||
397                     (grpX > infoPtr->nWidth)) {
398                     nGrpCount = j;
399                     break;
400                 }
401                 else if (grpX + x > infoPtr->nWidth) {
402                     bWrap = TRUE;
403                     nGrpCount = j;
404                     break;
405                 }
406             }
407         }
408
409         bWrap = ((bWrap || (x + cx > infoPtr->nWidth)) &&
410                  (wndPtr->dwStyle & TBSTYLE_WRAPABLE));
411         if (bWrap) {
412             nRows++;
413             y += cy;
414             x  = infoPtr->nIndent;
415             bWrap = FALSE;
416         }
417
418         SetRect32 (&btnPtr->rect, x, y, x + cx, y + cy);
419
420         btnPtr->nRow = nRows;
421         x += cx;
422
423         if (btnPtr->fsState & TBSTATE_WRAP) {
424             nRows++;
425             y += (cy + SEPARATOR_HEIGHT);
426             x  = infoPtr->nIndent;
427         }
428
429         infoPtr->nRows = nRows + 1;
430
431 /* --- end test --- */
432 #else
433         if (btnPtr->fsStyle & TBSTYLE_SEP) {
434             /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
435             /* it is the actual width of the separator. This is used for */
436             /* custom controls in toolbars.                              */
437             if ((wndPtr->dwStyle & TBSTYLE_WRAPABLE) &&
438                 (btnPtr->fsState & TBSTATE_WRAP)) {
439                 x = 0;
440                 y += cy;
441                 cx = infoPtr->nWidth;
442                 cy = ((btnPtr->iBitmap > 0) ?
443                      btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3;
444                 nRows++;
445                 bWrap = TRUE;
446             }
447             else
448                 cx = (btnPtr->iBitmap > 0) ?
449                      btnPtr->iBitmap : SEPARATOR_WIDTH;
450         }
451         else {
452             /* this must be a button */
453             cx = infoPtr->nButtonWidth;
454         }
455
456         btnPtr->rect.left   = x;
457         btnPtr->rect.top    = y;
458         btnPtr->rect.right  = x + cx;
459         btnPtr->rect.bottom = y + cy;
460
461         if (infoPtr->rcBound.left > x)
462             infoPtr->rcBound.left = x;
463         if (infoPtr->rcBound.right < x + cx)
464             infoPtr->rcBound.right = x + cx;
465         if (infoPtr->rcBound.bottom < y + cy)
466             infoPtr->rcBound.bottom = y + cy;
467
468         if (infoPtr->hwndToolTip) {
469             TTTOOLINFO32A ti;
470
471             ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
472             ti.cbSize = sizeof(TTTOOLINFO32A);
473             ti.hwnd = wndPtr->hwndSelf;
474             ti.uId = btnPtr->idCommand;
475             ti.rect = btnPtr->rect;
476             SendMessage32A (infoPtr->hwndToolTip, TTM_NEWTOOLRECT32A,
477                             0, (LPARAM)&ti);
478         }
479
480         if (bWrap) {
481             x = 0;
482             y += cy;
483             if (i < infoPtr->nNumButtons)
484                 nRows++;
485         }
486         else
487             x += cx;
488 #endif
489     }
490
491     infoPtr->nHeight = y + cy + BOTTOM_BORDER;
492     TRACE (toolbar, "toolbar height %d\n", infoPtr->nHeight);
493 }
494
495
496 static INT32
497 TOOLBAR_InternalHitTest (WND *wndPtr, LPPOINT32 lpPt)
498 {
499     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
500     TBUTTON_INFO *btnPtr;
501     INT32 i;
502     
503     btnPtr = infoPtr->buttons;
504     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
505         if (btnPtr->fsState & TBSTATE_HIDDEN)
506             continue;
507
508         if (btnPtr->fsStyle & TBSTYLE_SEP) {
509             if (PtInRect32 (&btnPtr->rect, *lpPt)) {
510                 TRACE (toolbar, " ON SEPARATOR %d!\n", i);
511                 return -i;
512             }
513         }
514         else {
515             if (PtInRect32 (&btnPtr->rect, *lpPt)) {
516                 TRACE (toolbar, " ON BUTTON %d!\n", i);
517                 return i;
518             }
519         }
520     }
521
522     TRACE (toolbar, " NOWHERE!\n");
523     return -1;
524 }
525
526
527 static INT32
528 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT32 idCommand)
529 {
530     TBUTTON_INFO *btnPtr;
531     INT32 i;
532
533     btnPtr = infoPtr->buttons;
534     for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
535         if (btnPtr->idCommand == idCommand) {
536             TRACE (toolbar, "command=%d index=%d\n", idCommand, i);
537             return i;
538         }
539     }
540     TRACE (toolbar, "no index found for command=%d\n", idCommand);
541     return -1;
542 }
543
544
545 static INT32
546 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT32 nIndex)
547 {
548     TBUTTON_INFO *btnPtr;
549     INT32 nRunIndex;
550
551     if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
552         return -1;
553
554     /* check index button */
555     btnPtr = &infoPtr->buttons[nIndex];
556     if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
557         if (btnPtr->fsState & TBSTATE_CHECKED)
558             return nIndex;
559     }
560
561     /* check previous buttons */
562     nRunIndex = nIndex - 1;
563     while (nRunIndex >= 0) {
564         btnPtr = &infoPtr->buttons[nRunIndex];
565         if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
566             if (btnPtr->fsState & TBSTATE_CHECKED)
567                 return nRunIndex;
568         }
569         else
570             break;
571         nRunIndex--;
572     }
573
574     /* check next buttons */
575     nRunIndex = nIndex + 1;
576     while (nRunIndex < infoPtr->nNumButtons) {
577         btnPtr = &infoPtr->buttons[nRunIndex];  
578         if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
579             if (btnPtr->fsState & TBSTATE_CHECKED)
580                 return nRunIndex;
581         }
582         else
583             break;
584         nRunIndex++;
585     }
586
587     return -1;
588 }
589
590
591 static VOID
592 TOOLBAR_RelayEvent (HWND32 hwndTip, HWND32 hwndMsg, UINT32 uMsg,
593                     WPARAM32 wParam, LPARAM lParam)
594 {
595     MSG32 msg;
596
597     msg.hwnd = hwndMsg;
598     msg.message = uMsg;
599     msg.wParam = wParam;
600     msg.lParam = lParam;
601     msg.time = GetMessageTime ();
602     msg.pt.x = LOWORD(GetMessagePos ());
603     msg.pt.y = HIWORD(GetMessagePos ());
604
605     SendMessage32A (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
606 }
607
608
609 static LRESULT
610 TOOLBAR_AddBitmap (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
611 {
612     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
613     LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
614     INT32 nIndex = 0;
615
616     if ((!lpAddBmp) || ((INT32)wParam <= 0))
617         return -1;
618
619     TRACE (toolbar, "adding %d bitmaps!\n", wParam);
620
621     if (!(infoPtr->himlDef)) {
622         /* create new default image list */
623         TRACE (toolbar, "creating default image list!\n");
624         infoPtr->himlStd =
625             ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
626                               ILC_COLOR | ILC_MASK, (INT32)wParam, 2);
627     }
628
629 #if 0
630     if (!(infoPtr->himlDis)) {
631         /* create new disabled image list */
632         TRACE (toolbar, "creating disabled image list!\n");
633         infoPtr->himlDis =
634             ImageList_Create (infoPtr->nBitmapWidth, 
635                               infoPtr->nBitmapHeight, ILC_COLOR | ILC_MASK,
636                               (INT32)wParam, 2);
637     }
638 #endif
639
640     /* Add bitmaps to the default image list */
641     if (lpAddBmp->hInst == (HINSTANCE32)0) {
642         nIndex = 
643             ImageList_AddMasked (infoPtr->himlStd, (HBITMAP32)lpAddBmp->nID,
644                                  CLR_DEFAULT);
645     }
646     else if (lpAddBmp->hInst == HINST_COMMCTRL) {
647         /* add internal bitmaps */
648         FIXME (toolbar, "internal bitmaps not supported!\n");
649
650         /* Hack to "add" some reserved images within the image list 
651            to get the right image indices */
652         nIndex = ImageList_GetImageCount (infoPtr->himlStd);
653         ImageList_SetImageCount (infoPtr->himlStd, nIndex + (INT32)wParam);
654     }
655     else {
656         HBITMAP32 hBmp =
657             LoadBitmap32A (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
658
659         nIndex = ImageList_AddMasked (infoPtr->himlStd, hBmp, CLR_DEFAULT);
660
661         DeleteObject32 (hBmp); 
662     }
663
664
665     infoPtr->nNumBitmaps += (INT32)wParam;
666
667     return nIndex;
668 }
669
670
671 static LRESULT
672 TOOLBAR_AddButtons32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
673 {
674     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
675     LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
676     INT32 nOldButtons, nNewButtons, nAddButtons, nCount;
677     HDC32 hdc;
678
679     TRACE (toolbar, "adding %d buttons!\n", wParam);
680
681     nAddButtons = (UINT32)wParam;
682     nOldButtons = infoPtr->nNumButtons;
683     nNewButtons = nOldButtons + nAddButtons;
684
685     if (infoPtr->nNumButtons == 0) {
686         infoPtr->buttons =
687             COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
688     }
689     else {
690         TBUTTON_INFO *oldButtons = infoPtr->buttons;
691         infoPtr->buttons =
692             COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
693         memcpy (&infoPtr->buttons[0], &oldButtons[0],
694                 nOldButtons * sizeof(TBUTTON_INFO));
695         COMCTL32_Free (oldButtons);
696     }
697
698     infoPtr->nNumButtons = nNewButtons;
699
700     /* insert new button data */
701     for (nCount = 0; nCount < nAddButtons; nCount++) {
702         TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
703         btnPtr->iBitmap   = lpTbb[nCount].iBitmap;
704         btnPtr->idCommand = lpTbb[nCount].idCommand;
705         btnPtr->fsState   = lpTbb[nCount].fsState;
706         btnPtr->fsStyle   = lpTbb[nCount].fsStyle;
707         btnPtr->dwData    = lpTbb[nCount].dwData;
708         btnPtr->iString   = lpTbb[nCount].iString;
709
710         if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
711             TTTOOLINFO32A ti;
712
713             ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
714             ti.cbSize   = sizeof (TTTOOLINFO32A);
715             ti.hwnd     = wndPtr->hwndSelf;
716             ti.uId      = btnPtr->idCommand;
717             ti.hinst    = 0;
718             ti.lpszText = LPSTR_TEXTCALLBACK32A;
719
720             SendMessage32A (infoPtr->hwndToolTip, TTM_ADDTOOL32A,
721                             0, (LPARAM)&ti);
722         }
723     }
724
725     TOOLBAR_CalcToolbar (wndPtr);
726
727     hdc = GetDC32 (wndPtr->hwndSelf);
728     TOOLBAR_Refresh (wndPtr, hdc);
729     ReleaseDC32 (wndPtr->hwndSelf, hdc);
730
731     return TRUE;
732 }
733
734
735 /* << TOOLBAR_AddButtons32W >> */
736
737
738 static LRESULT
739 TOOLBAR_AddString32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
740 {
741     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
742     INT32 nIndex;
743
744     if ((wParam) && (HIWORD(lParam) == 0)) {
745         char szString[256];
746         INT32 len;
747         TRACE (toolbar, "adding string from resource!\n");
748
749         len = LoadString32A ((HINSTANCE32)wParam, (UINT32)lParam,
750                              szString, 256);
751
752         TRACE (toolbar, "len=%d \"%s\"\n", len, szString);
753         nIndex = infoPtr->nNumStrings;
754         if (infoPtr->nNumStrings == 0) {
755             infoPtr->strings =
756                 COMCTL32_Alloc (sizeof(LPWSTR));
757         }
758         else {
759             LPWSTR *oldStrings = infoPtr->strings;
760             infoPtr->strings =
761                 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
762             memcpy (&infoPtr->strings[0], &oldStrings[0],
763                     sizeof(LPWSTR) * infoPtr->nNumStrings);
764             COMCTL32_Free (oldStrings);
765         }
766
767         infoPtr->strings[infoPtr->nNumStrings] =
768             COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
769         lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
770         infoPtr->nNumStrings++;
771     }
772     else {
773         LPSTR p = (LPSTR)lParam;
774         INT32 len;
775
776         if (p == NULL)
777             return -1;
778         TRACE (toolbar, "adding string(s) from array!\n");
779         nIndex = infoPtr->nNumStrings;
780         while (*p) {
781             len = lstrlen32A (p);
782             TRACE (toolbar, "len=%d \"%s\"\n", len, p);
783
784             if (infoPtr->nNumStrings == 0) {
785                 infoPtr->strings =
786                     COMCTL32_Alloc (sizeof(LPWSTR));
787             }
788             else {
789                 LPWSTR *oldStrings = infoPtr->strings;
790                 infoPtr->strings =
791                     COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
792                 memcpy (&infoPtr->strings[0], &oldStrings[0],
793                         sizeof(LPWSTR) * infoPtr->nNumStrings);
794                 COMCTL32_Free (oldStrings);
795             }
796
797             infoPtr->strings[infoPtr->nNumStrings] =
798                 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
799             lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
800             infoPtr->nNumStrings++;
801
802             p += (len+1);
803         }
804     }
805
806     return nIndex;
807 }
808
809
810 static LRESULT
811 TOOLBAR_AddString32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
812 {
813     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
814     INT32 nIndex;
815
816     if ((wParam) && (HIWORD(lParam) == 0)) {
817         WCHAR szString[256];
818         INT32 len;
819         TRACE (toolbar, "adding string from resource!\n");
820
821         len = LoadString32W ((HINSTANCE32)wParam, (UINT32)lParam,
822                              szString, 256);
823
824         TRACE (toolbar, "len=%d \"%s\"\n", len, debugstr_w(szString));
825         nIndex = infoPtr->nNumStrings;
826         if (infoPtr->nNumStrings == 0) {
827             infoPtr->strings =
828                 COMCTL32_Alloc (sizeof(LPWSTR));
829         }
830         else {
831             LPWSTR *oldStrings = infoPtr->strings;
832             infoPtr->strings =
833                 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
834             memcpy (&infoPtr->strings[0], &oldStrings[0],
835                     sizeof(LPWSTR) * infoPtr->nNumStrings);
836             COMCTL32_Free (oldStrings);
837         }
838
839         infoPtr->strings[infoPtr->nNumStrings] =
840             COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
841         lstrcpy32W (infoPtr->strings[infoPtr->nNumStrings], szString);
842         infoPtr->nNumStrings++;
843     }
844     else {
845         LPWSTR p = (LPWSTR)lParam;
846         INT32 len;
847
848         if (p == NULL)
849             return -1;
850         TRACE (toolbar, "adding string(s) from array!\n");
851         nIndex = infoPtr->nNumStrings;
852         while (*p) {
853             len = lstrlen32W (p);
854             TRACE (toolbar, "len=%d \"%s\"\n", len, debugstr_w(p));
855
856             if (infoPtr->nNumStrings == 0) {
857                 infoPtr->strings =
858                     COMCTL32_Alloc (sizeof(LPWSTR));
859             }
860             else {
861                 LPWSTR *oldStrings = infoPtr->strings;
862                 infoPtr->strings =
863                     COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
864                 memcpy (&infoPtr->strings[0], &oldStrings[0],
865                         sizeof(LPWSTR) * infoPtr->nNumStrings);
866                 COMCTL32_Free (oldStrings);
867             }
868
869             infoPtr->strings[infoPtr->nNumStrings] =
870                 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
871             lstrcpy32W (infoPtr->strings[infoPtr->nNumStrings], p);
872             infoPtr->nNumStrings++;
873
874             p += (len+1);
875         }
876     }
877
878     return nIndex;
879 }
880
881
882 static LRESULT
883 TOOLBAR_AutoSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
884 {
885     TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(wndPtr);
886     RECT32 parent_rect;
887     HWND32 parent;
888     INT32  x, y, 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, cx, cy;
2538     INT32  flags;
2539     UINT32 uPosFlags = 0;
2540
2541     /* Resize deadlock check */
2542     if (infoPtr->bAutoSize) {
2543         infoPtr->bAutoSize = FALSE;
2544         return 0;
2545     }
2546
2547     flags = (INT32) wParam;
2548
2549     /* FIXME for flags =
2550      * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
2551      */
2552
2553     TRACE (toolbar, "sizing toolbar!\n");
2554
2555     if (flags == SIZE_RESTORED) {
2556         /* width and height don't apply */
2557         parent = GetParent32 (wndPtr->hwndSelf);
2558         GetClientRect32(parent, &parent_rect);
2559
2560         if (wndPtr->dwStyle & CCS_NORESIZE) {
2561             uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
2562
2563             /* FIXME */
2564 /*          infoPtr->nWidth = parent_rect.right - parent_rect.left; */
2565             cy = infoPtr->nHeight;
2566             cx = infoPtr->nWidth;
2567             TOOLBAR_CalcToolbar (wndPtr);
2568             infoPtr->nWidth = cx;
2569             infoPtr->nHeight = cy;
2570         }
2571         else {
2572             infoPtr->nWidth = parent_rect.right - parent_rect.left;
2573             TOOLBAR_CalcToolbar (wndPtr);
2574             cy = infoPtr->nHeight;
2575             cx = infoPtr->nWidth;
2576         }
2577
2578         if (wndPtr->dwStyle & CCS_NOPARENTALIGN) {
2579             uPosFlags |= SWP_NOMOVE;
2580             cy = infoPtr->nHeight;
2581             cx = infoPtr->nWidth;
2582         }
2583
2584         if (!(wndPtr->dwStyle & CCS_NODIVIDER))
2585             cy += sysMetrics[SM_CYEDGE];
2586
2587         SetWindowPos32 (wndPtr->hwndSelf, 0, parent_rect.left, parent_rect.top,
2588                         cx, cy, uPosFlags | SWP_NOZORDER);
2589     }
2590     return 0;
2591 }
2592
2593
2594 static LRESULT
2595 TOOLBAR_StyleChanged (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
2596 {
2597     HDC32 hdc;
2598
2599     TOOLBAR_AutoSize (wndPtr, wParam, lParam);
2600
2601     hdc = GetDC32 (wndPtr->hwndSelf);
2602     TOOLBAR_Refresh (wndPtr, hdc);
2603     ReleaseDC32 (wndPtr->hwndSelf, hdc);
2604
2605     return 0;
2606 }
2607
2608
2609
2610 LRESULT WINAPI
2611 ToolbarWindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
2612 {
2613     WND *wndPtr = WIN_FindWndPtr(hwnd);
2614
2615     switch (uMsg)
2616     {
2617         case TB_ADDBITMAP:
2618             return TOOLBAR_AddBitmap (wndPtr, wParam, lParam);
2619
2620         case TB_ADDBUTTONS32A:
2621             return TOOLBAR_AddButtons32A (wndPtr, wParam, lParam);
2622
2623 /*      case TB_ADDBUTTONS32W: */
2624
2625         case TB_ADDSTRING32A:
2626             return TOOLBAR_AddString32A (wndPtr, wParam, lParam);
2627
2628         case TB_ADDSTRING32W:
2629             return TOOLBAR_AddString32W (wndPtr, wParam, lParam);
2630
2631         case TB_AUTOSIZE:
2632             return TOOLBAR_AutoSize (wndPtr, wParam, lParam);
2633
2634         case TB_BUTTONCOUNT:
2635             return TOOLBAR_ButtonCount (wndPtr, wParam, lParam);
2636
2637         case TB_BUTTONSTRUCTSIZE:
2638             return TOOLBAR_ButtonStructSize (wndPtr, wParam, lParam);
2639
2640         case TB_CHANGEBITMAP:
2641             return TOOLBAR_ChangeBitmap (wndPtr, wParam, lParam);
2642
2643         case TB_CHECKBUTTON:
2644             return TOOLBAR_CheckButton (wndPtr, wParam, lParam);
2645
2646         case TB_COMMANDTOINDEX:
2647             return TOOLBAR_CommandToIndex (wndPtr, wParam, lParam);
2648
2649         case TB_CUSTOMIZE:
2650             return TOOLBAR_Customize (wndPtr);
2651
2652         case TB_DELETEBUTTON:
2653             return TOOLBAR_DeleteButton (wndPtr, wParam, lParam);
2654
2655         case TB_ENABLEBUTTON:
2656             return TOOLBAR_EnableButton (wndPtr, wParam, lParam);
2657
2658 /*      case TB_GETANCHORHIGHLIGHT:             */ /* 4.71 */
2659
2660         case TB_GETBITMAP:
2661             return TOOLBAR_GetBitmap (wndPtr, wParam, lParam);
2662
2663         case TB_GETBITMAPFLAGS:
2664             return TOOLBAR_GetBitmapFlags (wndPtr, wParam, lParam);
2665
2666         case TB_GETBUTTON:
2667             return TOOLBAR_GetButton (wndPtr, wParam, lParam);
2668
2669         case TB_GETBUTTONINFO32A:
2670             return TOOLBAR_GetButtonInfo32A (wndPtr, wParam, lParam);
2671
2672 /*      case TB_GETBUTTONINFO32W:               */ /* 4.71 */
2673
2674         case TB_GETBUTTONSIZE:
2675             return TOOLBAR_GetButtonSize (wndPtr);
2676
2677         case TB_GETBUTTONTEXT32A:
2678             return TOOLBAR_GetButtonText32A (wndPtr, wParam, lParam);
2679
2680 /*      case TB_GETBUTTONTEXT32W: */
2681 /*      case TB_GETCOLORSCHEME:                 */ /* 4.71 */
2682
2683         case TB_GETDISABLEDIMAGELIST:
2684             return TOOLBAR_GetDisabledImageList (wndPtr, wParam, lParam);
2685
2686         case TB_GETEXTENDEDSTYLE:
2687             return TOOLBAR_GetExtendedStyle (wndPtr);
2688
2689         case TB_GETHOTIMAGELIST:
2690             return TOOLBAR_GetHotImageList (wndPtr, wParam, lParam);
2691
2692 /*      case TB_GETHOTITEM:                     */ /* 4.71 */
2693
2694         case TB_GETIMAGELIST:
2695             return TOOLBAR_GetImageList (wndPtr, wParam, lParam);
2696
2697 /*      case TB_GETINSERTMARK:                  */ /* 4.71 */
2698 /*      case TB_GETINSERTMARKCOLOR:             */ /* 4.71 */
2699
2700         case TB_GETITEMRECT:
2701             return TOOLBAR_GetItemRect (wndPtr, wParam, lParam);
2702
2703         case TB_GETMAXSIZE:
2704             return TOOLBAR_GetMaxSize (wndPtr, wParam, lParam);
2705
2706 /*      case TB_GETOBJECT:                      */ /* 4.71 */
2707 /*      case TB_GETPADDING:                     */ /* 4.71 */
2708
2709         case TB_GETRECT:
2710             return TOOLBAR_GetRect (wndPtr, wParam, lParam);
2711
2712         case TB_GETROWS:
2713             return TOOLBAR_GetRows (wndPtr, wParam, lParam);
2714
2715         case TB_GETSTATE:
2716             return TOOLBAR_GetState (wndPtr, wParam, lParam);
2717
2718         case TB_GETSTYLE:
2719             return TOOLBAR_GetStyle (wndPtr, wParam, lParam);
2720
2721         case TB_GETTEXTROWS:
2722             return TOOLBAR_GetTextRows (wndPtr, wParam, lParam);
2723
2724         case TB_GETTOOLTIPS:
2725             return TOOLBAR_GetToolTips (wndPtr, wParam, lParam);
2726
2727         case TB_GETUNICODEFORMAT:
2728             return TOOLBAR_GetUnicodeFormat (wndPtr, wParam, lParam);
2729
2730         case TB_HIDEBUTTON:
2731             return TOOLBAR_HideButton (wndPtr, wParam, lParam);
2732
2733         case TB_HITTEST:
2734             return TOOLBAR_HitTest (wndPtr, wParam, lParam);
2735
2736         case TB_INDETERMINATE:
2737             return TOOLBAR_Indeterminate (wndPtr, wParam, lParam);
2738
2739         case TB_INSERTBUTTON32A:
2740             return TOOLBAR_InsertButton32A (wndPtr, wParam, lParam);
2741
2742 /*      case TB_INSERTBUTTON32W: */
2743 /*      case TB_INSERTMARKHITTEST:              */ /* 4.71 */
2744
2745         case TB_ISBUTTONCHECKED:
2746             return TOOLBAR_IsButtonChecked (wndPtr, wParam, lParam);
2747
2748         case TB_ISBUTTONENABLED:
2749             return TOOLBAR_IsButtonEnabled (wndPtr, wParam, lParam);
2750
2751         case TB_ISBUTTONHIDDEN:
2752             return TOOLBAR_IsButtonHidden (wndPtr, wParam, lParam);
2753
2754         case TB_ISBUTTONHIGHLIGHTED:
2755             return TOOLBAR_IsButtonHighlighted (wndPtr, wParam, lParam);
2756
2757         case TB_ISBUTTONINDETERMINATE:
2758             return TOOLBAR_IsButtonIndeterminate (wndPtr, wParam, lParam);
2759
2760         case TB_ISBUTTONPRESSED:
2761             return TOOLBAR_IsButtonPressed (wndPtr, wParam, lParam);
2762
2763 /*      case TB_LOADIMAGES:                     */ /* 4.70 */
2764 /*      case TB_MAPACCELERATOR32A:              */ /* 4.71 */
2765 /*      case TB_MAPACCELERATOR32W:              */ /* 4.71 */
2766 /*      case TB_MARKBUTTON:                     */ /* 4.71 */
2767 /*      case TB_MOVEBUTTON:                     */ /* 4.71 */
2768
2769         case TB_PRESSBUTTON:
2770             return TOOLBAR_PressButton (wndPtr, wParam, lParam);
2771
2772 /*      case TB_REPLACEBITMAP: */
2773
2774         case TB_SAVERESTORE32A:
2775             return TOOLBAR_SaveRestore32A (wndPtr, wParam, lParam);
2776
2777 /*      case TB_SAVERESTORE32W: */
2778 /*      case TB_SETANCHORHIGHLIGHT:             */ /* 4.71 */
2779
2780         case TB_SETBITMAPSIZE:
2781             return TOOLBAR_SetBitmapSize (wndPtr, wParam, lParam);
2782
2783         case TB_SETBUTTONINFO32A:
2784             return TOOLBAR_SetButtonInfo32A (wndPtr, wParam, lParam);
2785
2786 /*      case TB_SETBUTTONINFO32W:               */ /* 4.71 */
2787
2788         case TB_SETBUTTONSIZE:
2789             return TOOLBAR_SetButtonSize (wndPtr, wParam, lParam);
2790
2791         case TB_SETBUTTONWIDTH:
2792             return TOOLBAR_SetButtonWidth (wndPtr, wParam, lParam);
2793
2794         case TB_SETCMDID:
2795             return TOOLBAR_SetCmdId (wndPtr, wParam, lParam);
2796
2797 /*      case TB_SETCOLORSCHEME:                 */ /* 4.71 */
2798
2799         case TB_SETDISABLEDIMAGELIST:
2800             return TOOLBAR_SetDisabledImageList (wndPtr, wParam, lParam);
2801
2802         case TB_SETDRAWTEXTFLAGS:
2803             return TOOLBAR_SetDrawTextFlags (wndPtr, wParam, lParam);
2804
2805         case TB_SETEXTENDEDSTYLE:
2806             return TOOLBAR_SetExtendedStyle (wndPtr, wParam, lParam);
2807
2808         case TB_SETHOTIMAGELIST:
2809             return TOOLBAR_SetHotImageList (wndPtr, wParam, lParam);
2810
2811 /*      case TB_SETHOTITEM:                     */ /* 4.71 */
2812
2813         case TB_SETIMAGELIST:
2814             return TOOLBAR_SetImageList (wndPtr, wParam, lParam);
2815
2816         case TB_SETINDENT:
2817             return TOOLBAR_SetIndent (wndPtr, wParam, lParam);
2818
2819 /*      case TB_SETINSERTMARK:                  */ /* 4.71 */
2820
2821         case TB_SETINSERTMARKCOLOR:
2822             return TOOLBAR_SetInsertMarkColor (wndPtr, wParam, lParam);
2823
2824         case TB_SETMAXTEXTROWS:
2825             return TOOLBAR_SetMaxTextRows (wndPtr, wParam, lParam);
2826
2827 /*      case TB_SETPADDING:                     */ /* 4.71 */
2828
2829         case TB_SETPARENT:
2830             return TOOLBAR_SetParent (wndPtr, wParam, lParam);
2831
2832         case TB_SETROWS:
2833             return TOOLBAR_SetRows (wndPtr, wParam, lParam);
2834
2835         case TB_SETSTATE:
2836             return TOOLBAR_SetState (wndPtr, wParam, lParam);
2837
2838         case TB_SETSTYLE:
2839             return TOOLBAR_SetStyle (wndPtr, wParam, lParam);
2840
2841         case TB_SETTOOLTIPS:
2842             return TOOLBAR_SetToolTips (wndPtr, wParam, lParam);
2843
2844         case TB_SETUNICODEFORMAT:
2845             return TOOLBAR_SetUnicodeFormat (wndPtr, wParam, lParam);
2846
2847
2848 /*      case WM_CHAR: */
2849
2850         case WM_CREATE:
2851             return TOOLBAR_Create (wndPtr, wParam, lParam);
2852
2853         case WM_DESTROY:
2854             return TOOLBAR_Destroy (wndPtr, wParam, lParam);
2855
2856         case WM_ERASEBKGND:
2857             return TOOLBAR_EraseBackground (wndPtr, wParam, lParam);
2858
2859 /*      case WM_GETFONT: */
2860 /*      case WM_KEYDOWN: */
2861 /*      case WM_KILLFOCUS: */
2862
2863         case WM_LBUTTONDBLCLK:
2864             return TOOLBAR_LButtonDblClk (wndPtr, wParam, lParam);
2865
2866         case WM_LBUTTONDOWN:
2867             return TOOLBAR_LButtonDown (wndPtr, wParam, lParam);
2868
2869         case WM_LBUTTONUP:
2870             return TOOLBAR_LButtonUp (wndPtr, wParam, lParam);
2871
2872         case WM_MOUSEMOVE:
2873             return TOOLBAR_MouseMove (wndPtr, wParam, lParam);
2874
2875         case WM_NCACTIVATE:
2876             return TOOLBAR_NCActivate (wndPtr, wParam, lParam);
2877
2878         case WM_NCCALCSIZE:
2879             return TOOLBAR_NCCalcSize (wndPtr, wParam, lParam);
2880
2881         case WM_NCCREATE:
2882             return TOOLBAR_NCCreate (wndPtr, wParam, lParam);
2883
2884         case WM_NCPAINT:
2885             return TOOLBAR_NCPaint (wndPtr, wParam, lParam);
2886
2887         case WM_NOTIFY:
2888             return TOOLBAR_Notify (wndPtr, wParam, lParam);
2889
2890 /*      case WM_NOTIFYFORMAT: */
2891
2892         case WM_PAINT:
2893             return TOOLBAR_Paint (wndPtr, wParam);
2894
2895         case WM_SIZE:
2896             return TOOLBAR_Size (wndPtr, wParam, lParam);
2897
2898         case WM_STYLECHANGED:
2899             return TOOLBAR_StyleChanged (wndPtr, wParam, lParam);
2900
2901 /*      case WM_SYSCOLORCHANGE: */
2902
2903 /*      case WM_WININICHANGE: */
2904
2905         case WM_CHARTOITEM:
2906         case WM_COMMAND:
2907         case WM_DRAWITEM:
2908         case WM_MEASUREITEM:
2909         case WM_VKEYTOITEM:
2910             return SendMessage32A (GetParent32 (hwnd), uMsg, wParam, lParam);
2911
2912         default:
2913             if (uMsg >= WM_USER)
2914                 ERR (toolbar, "unknown msg %04x wp=%08x lp=%08lx\n",
2915                      uMsg, wParam, lParam);
2916             return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
2917     }
2918     return 0;
2919 }
2920
2921
2922 VOID
2923 TOOLBAR_Register (VOID)
2924 {
2925     WNDCLASS32A wndClass;
2926
2927     if (GlobalFindAtom32A (TOOLBARCLASSNAME32A)) return;
2928
2929     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
2930     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
2931     wndClass.lpfnWndProc   = (WNDPROC32)ToolbarWindowProc;
2932     wndClass.cbClsExtra    = 0;
2933     wndClass.cbWndExtra    = sizeof(TOOLBAR_INFO *);
2934     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
2935     wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
2936     wndClass.lpszClassName = TOOLBARCLASSNAME32A;
2937  
2938     RegisterClass32A (&wndClass);
2939 }
2940
2941
2942 VOID
2943 TOOLBAR_Unregister (VOID)
2944 {
2945     if (GlobalFindAtom32A (TOOLBARCLASSNAME32A))
2946         UnregisterClass32A (TOOLBARCLASSNAME32A, (HINSTANCE32)NULL);
2947 }
2948