4 * Copyright 1998,1999 Eric Kohl
5 * Copyright 2000 Eric Kohl for CodeWeavers
8 * - A little bug in TOOLBAR_DrawMasked()
9 * - Button wrapping (under construction).
11 * - Notifications (under construction).
13 * - Tooltip support (almost complete).
14 * - Unicode suppport (under construction).
15 * - Fix TOOLBAR_SetButtonInfo32A/W.
16 * - TBSTYLE_AUTOSIZE for toolbar and buttons.
17 * - I_IMAGECALLBACK support.
18 * - iString of -1 is undocumented
19 * - Customization dialog:
21 * - Minor buglet in 'available buttons' list:
22 * Buttons are not listed in M$-like order. M$ seems to use a single
23 * internal list to store the button information of both listboxes.
24 * - Drag list support.
25 * - Help and Reset button support.
28 * - Run tests using Waite Group Windows95 API Bible Volume 2.
29 * The second cdrom contains executables addstr.exe, btncount.exe,
30 * btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
31 * enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
32 * indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
33 * setparnt.exe, setrows.exe, toolwnd.exe.
34 * - Microsofts controlspy examples.
35 * - Charles Petzold's 'Programming Windows': gadgets.exe
44 #include "wine/unicode.h"
46 #include "imagelist.h"
48 #include "debugtools.h"
50 DEFAULT_DEBUG_CHANNEL(toolbar);
68 DWORD dwStructSize; /* size of TBBUTTON struct */
69 INT nHeight; /* height of the toolbar */
70 INT nWidth; /* width of the toolbar */
76 INT nRows; /* number of button rows */
77 INT nMaxTextRows; /* maximum number of text rows */
78 INT cxMin; /* minimum button width */
79 INT cxMax; /* maximum button width */
80 INT nNumButtons; /* number of buttons */
81 INT nNumBitmaps; /* number of bitmaps */
82 INT nNumStrings; /* number of strings */
83 BOOL bUnicode; /* ASCII (FALSE) or Unicode (TRUE)? */
84 BOOL bCaptured; /* mouse captured? */
87 INT nHotItem; /* index of the "hot" item */
88 HFONT hFont; /* text font */
89 HIMAGELIST himlInt; /* image list created internally */
90 HIMAGELIST himlDef; /* default image list */
91 HIMAGELIST himlHot; /* hot image list */
92 HIMAGELIST himlDis; /* disabled image list */
93 HWND hwndToolTip; /* handle to tool tip control */
94 HWND hwndNotify; /* handle to the window that gets notifications */
95 BOOL bTransparent; /* background transparency flag */
96 BOOL bAutoSize; /* auto size deadlock indicator */
97 BOOL bAnchor; /* anchor highlight enabled */
98 DWORD dwExStyle; /* extended toolbar style */
99 DWORD dwDTFlags; /* DrawText flags */
101 COLORREF clrInsertMark; /* insert mark color */
102 RECT rcBound; /* bounding rectangle */
105 TBUTTON_INFO *buttons; /* pointer to button array */
106 LPWSTR *strings; /* pointer to string array */
107 } TOOLBAR_INFO, *PTOOLBAR_INFO;
110 /* used by customization dialog */
113 PTOOLBAR_INFO tbInfo;
115 } CUSTDLG_INFO, *PCUSTDLG_INFO;
123 } CUSTOMBUTTON, *PCUSTOMBUTTON;
126 #define SEPARATOR_WIDTH 8
128 #define BOTTOM_BORDER 2
129 #define DDARROW_WIDTH 11
131 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
132 #define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE)
133 #define TOOLBAR_HasDropDownArrows(exStyle) ((exStyle & TBSTYLE_EX_DRAWDDARROWS) ? TRUE : FALSE)
136 TOOLBAR_GetText(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr)
138 LPWSTR lpText = NULL;
140 /* FIXME: iString == -1 is undocumented */
141 if ((HIWORD(btnPtr->iString) != 0) && (btnPtr->iString != -1))
142 lpText = (LPWSTR)btnPtr->iString;
143 else if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
144 lpText = infoPtr->strings[btnPtr->iString];
150 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index)
152 if ((index>=0) && (index < infoPtr->nNumBitmaps))
160 TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
162 INT x = (lpRect->left + lpRect->right) / 2 - 1;
163 INT yBottom = lpRect->bottom - 3;
164 INT yTop = lpRect->top + 1;
166 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
167 MoveToEx (hdc, x, yBottom, NULL);
168 LineTo (hdc, x, yTop);
170 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
171 MoveToEx (hdc, x, yBottom, NULL);
172 LineTo (hdc, x, yTop);
176 TOOLBAR_DrawArrow (HDC hdc, INT left, INT top, INT colorRef)
179 SelectObject ( hdc, GetSysColorPen (colorRef));
182 MoveToEx (hdc, x, y, NULL);
183 LineTo (hdc, x+5, y++); x++;
184 MoveToEx (hdc, x, y, NULL);
185 LineTo (hdc, x+3, y++); x++;
186 MoveToEx (hdc, x, y, NULL);
187 LineTo (hdc, x+1, y++);
191 * Draw the text string for this button.
192 * note: infoPtr->himlDis *SHOULD* be non-zero when infoPtr->himlDef
193 * is non-zero, so we can simply check himlDef to see if we have
197 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
198 HDC hdc, INT nState, DWORD dwStyle)
200 RECT rcText = btnPtr->rect;
204 LPWSTR lpText = NULL;
205 HIMAGELIST himl = infoPtr->himlDef;
207 TRACE ("iString: %x\n", btnPtr->iString);
209 /* get a pointer to the text */
210 lpText = TOOLBAR_GetText(infoPtr, btnPtr);
212 TRACE ("lpText: \"%s\"\n", debugstr_w(lpText));
217 InflateRect (&rcText, -3, -3);
219 if (himl && TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
220 if ((dwStyle & TBSTYLE_LIST) &&
221 ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
222 (btnPtr->iBitmap != I_IMAGENONE)) {
223 rcText.left += infoPtr->nBitmapWidth;
226 rcText.top += infoPtr->nBitmapHeight;
230 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
231 OffsetRect (&rcText, 1, 1);
233 hOldFont = SelectObject (hdc, infoPtr->hFont);
234 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
235 if (!(nState & TBSTATE_ENABLED)) {
236 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
237 OffsetRect (&rcText, 1, 1);
238 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
239 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
240 OffsetRect (&rcText, -1, -1);
241 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
243 else if (nState & TBSTATE_INDETERMINATE) {
244 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
245 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
248 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
249 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
252 SetTextColor (hdc, clrOld);
253 SelectObject (hdc, hOldFont);
254 if (nOldBkMode != TRANSPARENT)
255 SetBkMode (hdc, nOldBkMode);
261 TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
263 HBRUSH hbr = SelectObject (hdc, COMCTL32_hPattern55AABrush);
264 INT cx = lpRect->right - lpRect->left;
265 INT cy = lpRect->bottom - lpRect->top;
266 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
267 SelectObject (hdc, hbr);
272 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
273 HDC hdc, INT x, INT y)
275 /* FIXME: this function is a hack since it uses image list
276 internals directly */
278 HIMAGELIST himl = infoPtr->himlDef;
286 /* create new dc's */
287 hdcImageList = CreateCompatibleDC (0);
288 hdcMask = CreateCompatibleDC (0);
290 /* create new bitmap */
291 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
292 SelectObject (hdcMask, hbmMask);
294 /* copy the mask bitmap */
295 SelectObject (hdcImageList, himl->hbmMask);
296 SetBkColor (hdcImageList, RGB(255, 255, 255));
297 SetTextColor (hdcImageList, RGB(0, 0, 0));
298 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
299 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
301 /* draw the new mask */
302 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
303 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
304 hdcMask, 0, 0, 0xB8074A);
306 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
307 BitBlt (hdc, x, y, himl->cx, himl->cy,
308 hdcMask, 0, 0, 0xB8074A);
310 DeleteObject (hbmMask);
312 DeleteDC (hdcImageList);
317 TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
319 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
320 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
321 BOOL hasDropDownArrow = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) &&
322 (btnPtr->fsStyle & TBSTYLE_DROPDOWN);
323 RECT rc, rcArrow, rcBitmap;
325 if (btnPtr->fsState & TBSTATE_HIDDEN)
329 CopyRect (&rcArrow, &rc);
330 CopyRect(&rcBitmap, &rc);
332 FillRect( hdc, &rc, GetSysColorBrush(COLOR_BTNFACE));
334 if (hasDropDownArrow)
336 if (dwStyle & TBSTYLE_FLAT)
337 rc.right = max(rc.left, rc.right - DDARROW_WIDTH);
339 rc.right = max(rc.left, rc.right - DDARROW_WIDTH - 2);
340 rcArrow.left = rc.right;
343 /* Center the bitmap horizontally and vertically */
344 rcBitmap.left+=(infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2;
346 if(TOOLBAR_HasText(infoPtr, btnPtr))
347 rcBitmap.top+=2; /* this looks to be the correct value from vmware comparison - cmm */
349 rcBitmap.top+=(infoPtr->nButtonHeight - infoPtr->nBitmapHeight) / 2;
351 TRACE("iBitmap: %d\n", btnPtr->iBitmap);
354 if (btnPtr->fsStyle & TBSTYLE_SEP) {
355 /* with the FLAT style, iBitmap is the width and has already */
356 /* been taken into consideration in calculating the width */
357 /* so now we need to draw the vertical separator */
358 /* empirical tests show that iBitmap can/will be non-zero */
359 /* when drawing the vertical bar... */
360 if ((dwStyle & TBSTYLE_FLAT) /* && (btnPtr->iBitmap == 0) */)
361 TOOLBAR_DrawFlatSeparator (&rc, hdc);
366 if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
367 if (!(dwStyle & TBSTYLE_FLAT))
369 DrawEdge (hdc, &rc, EDGE_RAISED,
370 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
371 if (hasDropDownArrow)
372 DrawEdge (hdc, &rcArrow, EDGE_RAISED,
373 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
376 if (hasDropDownArrow)
378 TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top+1, COLOR_3DHIGHLIGHT);
379 TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_3DSHADOW);
382 if (infoPtr->himlDis &&
383 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
384 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
385 rcBitmap.left, rcBitmap.top, ILD_NORMAL);
387 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
389 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
393 /* pressed TBSTYLE_BUTTON */
394 if (btnPtr->fsState & TBSTATE_PRESSED) {
395 if (dwStyle & TBSTYLE_FLAT)
397 DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
398 if (hasDropDownArrow)
399 DrawEdge (hdc, &rcArrow, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
403 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
404 if (hasDropDownArrow)
405 DrawEdge (hdc, &rcArrow, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
408 if (hasDropDownArrow)
409 TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
411 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
412 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
413 rcBitmap.left + 1, rcBitmap.top + 1, ILD_NORMAL);
415 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
419 /* checked TBSTYLE_CHECK */
420 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
421 (btnPtr->fsState & TBSTATE_CHECKED)) {
422 if (dwStyle & TBSTYLE_FLAT)
423 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
424 BF_RECT | BF_MIDDLE | BF_ADJUST);
426 DrawEdge (hdc, &rc, EDGE_SUNKEN,
427 BF_RECT | BF_MIDDLE | BF_ADJUST);
429 TOOLBAR_DrawPattern (hdc, &rc);
431 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
432 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
433 rcBitmap.left + 1, rcBitmap.top + 1, ILD_NORMAL);
434 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
439 if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
440 DrawEdge (hdc, &rc, EDGE_RAISED,
441 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
443 TOOLBAR_DrawPattern (hdc, &rc);
444 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
445 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
450 if (dwStyle & TBSTYLE_FLAT)
454 DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
455 if (hasDropDownArrow)
456 DrawEdge (hdc, &rcArrow, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
460 FrameRect(hdc, &rc, GetSysColorBrush(COLOR_BTNFACE));
461 if (hasDropDownArrow)
462 FrameRect(hdc, &rcArrow, GetSysColorBrush(COLOR_BTNFACE));
465 if (hasDropDownArrow)
466 TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top, COLOR_WINDOWFRAME);
468 if (btnPtr->bHot && infoPtr->himlHot &&
469 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
470 ImageList_Draw (infoPtr->himlHot, btnPtr->iBitmap, hdc,
471 rcBitmap.left, rcBitmap.top, ILD_NORMAL);
472 else if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
473 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
474 rcBitmap.left, rcBitmap.top, ILD_NORMAL);
478 DrawEdge (hdc, &rc, EDGE_RAISED,
479 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
481 if (hasDropDownArrow)
483 DrawEdge (hdc, &rcArrow, EDGE_RAISED,
484 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
485 TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
488 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
489 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
490 rcBitmap.left, rcBitmap.top, ILD_NORMAL);
493 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
498 TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
500 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
501 TBUTTON_INFO *btnPtr;
505 /* redraw necessary buttons */
506 btnPtr = infoPtr->buttons;
507 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
509 if(IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect)))
510 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
515 TOOLBAR_MeasureString(HWND hwnd, INT index, LPSIZE lpSize)
517 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
518 TBUTTON_INFO *btnPtr;
525 hOldFont = SelectObject (hdc, infoPtr->hFont);
527 btnPtr = &infoPtr->buttons[index];
529 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
530 (btnPtr->iString > -1) &&
531 (btnPtr->iString < infoPtr->nNumStrings))
533 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
534 GetTextExtentPoint32W (hdc, lpText, strlenW (lpText), lpSize);
537 SelectObject (hdc, hOldFont);
540 TRACE("string size %ld x %ld!\n", lpSize->cx, lpSize->cy);
544 TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
546 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
547 TBUTTON_INFO *btnPtr;
555 btnPtr = infoPtr->buttons;
556 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
557 if(TOOLBAR_HasText(infoPtr, btnPtr))
559 TOOLBAR_MeasureString(hwnd,i,&sz);
560 if (sz.cx > lpSize->cx)
562 if (sz.cy > lpSize->cy)
567 TRACE("string size %ld x %ld!\n", lpSize->cx, lpSize->cy);
570 /***********************************************************************
571 * TOOLBAR_WrapToolbar
573 * This function walks through the buttons and seperators in the
574 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
575 * wrapping should occur based on the width of the toolbar window.
576 * It does *not* calculate button placement itself. That task
577 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
578 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
579 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
583 TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
585 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
586 TBUTTON_INFO *btnPtr;
589 BOOL bWrap, bButtonWrap;
591 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
592 /* no layout is necessary. Applications may use this style */
593 /* to perform their own layout on the toolbar. */
594 if( !(dwStyle & TBSTYLE_WRAPABLE) )
597 btnPtr = infoPtr->buttons;
598 x = infoPtr->nIndent;
600 /* this can get the parents width, to know how far we can extend
601 * this toolbar. We cannot use its height, as there may be multiple
602 * toolbars in a rebar control
604 GetClientRect( GetParent(hwnd), &rc );
605 infoPtr->nWidth = rc.right - rc.left;
608 for (i = 0; i < infoPtr->nNumButtons; i++ )
611 btnPtr[i].fsState &= ~TBSTATE_WRAP;
613 if (btnPtr[i].fsState & TBSTATE_HIDDEN)
616 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
617 /* it is the actual width of the separator. This is used for */
618 /* custom controls in toolbars. */
619 if (btnPtr[i].fsStyle & TBSTYLE_SEP)
620 cx = (btnPtr[i].iBitmap > 0) ?
621 btnPtr[i].iBitmap : SEPARATOR_WIDTH;
623 cx = infoPtr->nButtonWidth;
625 /* Two or more adjacent separators form a separator group. */
626 /* The first separator in a group should be wrapped to the */
627 /* next row if the previous wrapping is on a button. */
629 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
630 (i + 1 < infoPtr->nNumButtons ) &&
631 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
633 btnPtr[i].fsState |= TBSTATE_WRAP;
634 x = infoPtr->nIndent;
640 /* The layout makes sure the bitmap is visible, but not the button. */
641 if ( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
646 /* If the current button is a separator and not hidden, */
647 /* go to the next until it reaches a non separator. */
648 /* Wrap the last separator if it is before a button. */
649 while( ( (btnPtr[i].fsStyle & TBSTYLE_SEP) ||
650 (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
651 i < infoPtr->nNumButtons )
657 if( bFound && i < infoPtr->nNumButtons )
660 btnPtr[i].fsState |= TBSTATE_WRAP;
661 x = infoPtr->nIndent;
665 else if ( i >= infoPtr->nNumButtons)
668 /* If the current button is not a separator, find the last */
669 /* separator and wrap it. */
670 for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
672 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
673 !(btnPtr[j].fsState & TBSTATE_HIDDEN))
677 x = infoPtr->nIndent;
678 btnPtr[j].fsState |= TBSTATE_WRAP;
684 /* If no separator available for wrapping, wrap one of */
685 /* non-hidden previous button. */
689 j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
691 if (btnPtr[j].fsState & TBSTATE_HIDDEN)
696 x = infoPtr->nIndent;
697 btnPtr[j].fsState |= TBSTATE_WRAP;
703 /* If all above failed, wrap the current button. */
706 btnPtr[i].fsState |= TBSTATE_WRAP;
708 x = infoPtr->nIndent;
709 if (btnPtr[i].fsState & TBSTYLE_SEP )
721 /***********************************************************************
722 * TOOLBAR_CalcToolbar
724 * This function calculates button and separator placement. It first
725 * calculates the button sizes, gets the toolbar window width and then
726 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
727 * on. It assigns a new location to each item and sends this location to
728 * the tooltip window if appropriate. Finally, it updates the rcBound
729 * rect and calculates the new required toolbar window height.
733 TOOLBAR_CalcToolbar (HWND hwnd)
735 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
736 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
737 TBUTTON_INFO *btnPtr;
738 INT i, nRows, nSepRows;
742 BOOL usesBitmaps = FALSE;
743 BOOL hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle);
745 TOOLBAR_CalcStrings (hwnd, &sizeString);
747 if (dwStyle & TBSTYLE_LIST)
749 infoPtr->nButtonHeight = max(infoPtr->nBitmapHeight, sizeString.cy) + 6;
750 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + sizeString.cx + 6;
753 for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
755 if (TOOLBAR_IsValidBitmapIndex(infoPtr,infoPtr->buttons[i].iBitmap))
759 if (sizeString.cy > 0)
762 infoPtr->nButtonHeight = sizeString.cy +
763 infoPtr->nBitmapHeight + 6;
765 infoPtr->nButtonHeight = sizeString.cy + 6;
767 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
768 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
770 if (sizeString.cx > infoPtr->nBitmapWidth)
771 infoPtr->nButtonWidth = sizeString.cx + 6;
772 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
773 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
776 if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin )
777 infoPtr->nButtonWidth = infoPtr->cxMin;
778 if ( infoPtr->cxMax >= 0 && infoPtr->nButtonWidth > infoPtr->cxMax )
779 infoPtr->nButtonWidth = infoPtr->cxMax;
781 TOOLBAR_WrapToolbar( hwnd, dwStyle );
783 x = infoPtr->nIndent;
784 y = (dwStyle & TBSTYLE_FLAT) ? 0 : TOP_BORDER;
787 * We will set the height below, and we set the width on entry
788 * so we do not reset them here..
791 GetClientRect( hwnd, &rc );
792 /* get initial values for toolbar */
793 infoPtr->nWidth = rc.right - rc.left;
794 infoPtr->nHeight = rc.bottom - rc.top;
797 /* from above, minimum is a button, and possible text */
798 cx = infoPtr->nButtonWidth;
800 /* cannot use just ButtonHeight, we may have no buttons! */
801 if (infoPtr->nNumButtons > 0)
802 infoPtr->nHeight = infoPtr->nButtonHeight;
804 cy = infoPtr->nHeight;
806 nRows = nSepRows = 0;
808 infoPtr->rcBound.top = y;
809 infoPtr->rcBound.left = x;
810 infoPtr->rcBound.bottom = y + cy;
811 infoPtr->rcBound.right = x;
813 btnPtr = infoPtr->buttons;
815 /* do not base height/width on parent, if the parent is a */
816 /* rebar control it could have multiple rows of toolbars */
817 /* GetClientRect( GetParent(hwnd), &rc ); */
818 /* cx = rc.right - rc.left; */
819 /* cy = rc.bottom - rc.top; */
821 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
824 if (btnPtr->fsState & TBSTATE_HIDDEN)
826 SetRectEmpty (&btnPtr->rect);
830 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
831 /* it is the actual width of the separator. This is used for */
832 /* custom controls in toolbars. */
833 if (btnPtr->fsStyle & TBSTYLE_SEP)
834 cx = (btnPtr->iBitmap > 0) ?
835 btnPtr->iBitmap : SEPARATOR_WIDTH;
838 if (btnPtr->fsStyle & TBSTYLE_AUTOSIZE)
841 TOOLBAR_MeasureString(hwnd,i,&sz);
845 cx = infoPtr->nButtonWidth;
847 if (hasDropDownArrows && (btnPtr->fsStyle & TBSTYLE_DROPDOWN))
850 cy = infoPtr->nHeight;
852 if (btnPtr->fsState & TBSTATE_WRAP )
855 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
857 if (infoPtr->rcBound.left > x)
858 infoPtr->rcBound.left = x;
859 if (infoPtr->rcBound.right < x + cx)
860 infoPtr->rcBound.right = x + cx;
861 if (infoPtr->rcBound.bottom < y + cy)
862 infoPtr->rcBound.bottom = y + cy;
864 /* Set the toolTip only for non-hidden, non-separator button */
865 if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP ))
869 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
870 ti.cbSize = sizeof(TTTOOLINFOA);
872 ti.uId = btnPtr->idCommand;
873 ti.rect = btnPtr->rect;
874 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
878 /* btnPtr->nRow is zero based. The space between the rows is */
879 /* also considered as a row. */
880 btnPtr->nRow = nRows + nSepRows;
883 if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
887 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
888 /* it is the actual width of the separator. This is used for */
889 /* custom controls in toolbars. */
890 y += cy + ( (btnPtr->iBitmap > 0 ) ?
891 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
893 /* nSepRows is used to calculate the extra height follwoing */
897 x = infoPtr->nIndent;
904 /* infoPtr->nRows is the number of rows on the toolbar */
905 infoPtr->nRows = nRows + nSepRows + 1;
907 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
909 infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
910 nSepRows * (SEPARATOR_WIDTH * 2 / 3) +
911 nSepRows * (infoPtr->nBitmapHeight + 1) +
913 TRACE("toolbar height %d, button width %d\n", infoPtr->nHeight, infoPtr->nButtonWidth);
918 TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
920 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
921 TBUTTON_INFO *btnPtr;
924 btnPtr = infoPtr->buttons;
925 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
926 if (btnPtr->fsState & TBSTATE_HIDDEN)
929 if (btnPtr->fsStyle & TBSTYLE_SEP) {
930 if (PtInRect (&btnPtr->rect, *lpPt)) {
931 TRACE(" ON SEPARATOR %d!\n", i);
936 if (PtInRect (&btnPtr->rect, *lpPt)) {
937 TRACE(" ON BUTTON %d!\n", i);
943 TRACE(" NOWHERE!\n");
949 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
951 TBUTTON_INFO *btnPtr;
954 btnPtr = infoPtr->buttons;
955 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
956 if (btnPtr->idCommand == idCommand) {
957 TRACE("command=%d index=%d\n", idCommand, i);
961 TRACE("no index found for command=%d\n", idCommand);
967 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
969 TBUTTON_INFO *btnPtr;
972 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
975 /* check index button */
976 btnPtr = &infoPtr->buttons[nIndex];
977 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
978 if (btnPtr->fsState & TBSTATE_CHECKED)
982 /* check previous buttons */
983 nRunIndex = nIndex - 1;
984 while (nRunIndex >= 0) {
985 btnPtr = &infoPtr->buttons[nRunIndex];
986 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
987 if (btnPtr->fsState & TBSTATE_CHECKED)
995 /* check next buttons */
996 nRunIndex = nIndex + 1;
997 while (nRunIndex < infoPtr->nNumButtons) {
998 btnPtr = &infoPtr->buttons[nRunIndex];
999 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
1000 if (btnPtr->fsState & TBSTATE_CHECKED)
1013 TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
1014 WPARAM wParam, LPARAM lParam)
1020 msg.wParam = wParam;
1021 msg.lParam = lParam;
1022 msg.time = GetMessageTime ();
1023 msg.pt.x = LOWORD(GetMessagePos ());
1024 msg.pt.y = HIWORD(GetMessagePos ());
1026 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
1030 /***********************************************************************
1031 * TOOLBAR_CustomizeDialogProc
1032 * This function implements the toolbar customization dialog.
1035 TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1037 PCUSTDLG_INFO custInfo = (PCUSTDLG_INFO)GetWindowLongA (hwnd, DWL_USER);
1038 PCUSTOMBUTTON btnInfo;
1044 custInfo = (PCUSTDLG_INFO)lParam;
1045 SetWindowLongA (hwnd, DWL_USER, (DWORD)custInfo);
1053 /* send TBN_QUERYINSERT notification */
1054 nmtb.hdr.hwndFrom = hwnd;
1055 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1056 nmtb.hdr.code = TBN_QUERYINSERT;
1057 nmtb.iItem = custInfo->tbInfo->nNumButtons;
1059 if (!SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1060 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1063 /* add items to 'toolbar buttons' list and check if removable */
1064 for (i = 0; i < custInfo->tbInfo->nNumButtons; i++)
1066 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1067 memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
1068 btnInfo->btn.fsStyle = TBSTYLE_SEP;
1069 btnInfo->bVirtual = FALSE;
1070 LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
1072 /* send TBN_QUERYDELETE notification */
1073 nmtb.hdr.hwndFrom = hwnd;
1074 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1075 nmtb.hdr.code = TBN_QUERYDELETE;
1078 btnInfo->bRemovable = SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1079 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
1081 index = (int)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, 0);
1082 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1085 /* insert separator button into 'available buttons' list */
1086 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1087 memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
1088 btnInfo->btn.fsStyle = TBSTYLE_SEP;
1089 btnInfo->bVirtual = FALSE;
1090 btnInfo->bRemovable = TRUE;
1091 LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
1092 index = (int)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
1093 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1095 /* insert all buttons into dsa */
1098 /* send TBN_GETBUTTONINFO notification */
1099 nmtb.hdr.hwndFrom = hwnd;
1100 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1101 nmtb.hdr.code = TBN_GETBUTTONINFOA;
1103 nmtb.pszText = Buffer;
1106 if (!SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1107 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1110 TRACE("style: %x\n", nmtb.tbButton.fsStyle);
1112 /* insert button into the apropriate list */
1113 index = TOOLBAR_GetButtonIndex (custInfo->tbInfo, nmtb.tbButton.idCommand);
1116 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1117 memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
1118 btnInfo->bVirtual = FALSE;
1119 btnInfo->bRemovable = TRUE;
1120 if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
1121 strcpy (btnInfo->text, nmtb.pszText);
1123 index = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, 0);
1124 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1128 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1129 memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
1130 if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
1131 strcpy (btnInfo->text, nmtb.pszText);
1133 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1137 /* select first item in the 'available' list */
1138 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, 0, 0);
1140 /* append 'virtual' separator button to the 'toolbar buttons' list */
1141 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1142 memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
1143 btnInfo->btn.fsStyle = TBSTYLE_SEP;
1144 btnInfo->bVirtual = TRUE;
1145 btnInfo->bRemovable = FALSE;
1146 LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
1147 index = (int)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
1148 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1150 /* select last item in the 'toolbar' list */
1151 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index, 0);
1152 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETTOPINDEX, index, 0);
1154 /* set focus and disable buttons */
1155 PostMessageA (hwnd, WM_USER, 0, 0);
1160 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1161 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1162 EnableWindow (GetDlgItem (hwnd,IDC_REMOVE_BTN), FALSE);
1163 SetFocus (GetDlgItem (hwnd, IDC_TOOLBARBTN_LBOX));
1167 EndDialog(hwnd, FALSE);
1171 switch (LOWORD(wParam))
1173 case IDC_TOOLBARBTN_LBOX:
1174 if (HIWORD(wParam) == LBN_SELCHANGE)
1176 PCUSTOMBUTTON btnInfo;
1181 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1182 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1184 /* send TBN_QUERYINSERT notification */
1185 nmtb.hdr.hwndFrom = hwnd;
1186 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1187 nmtb.hdr.code = TBN_QUERYINSERT;
1190 SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1191 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
1193 /* get list box item */
1194 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1196 if (index == (count - 1))
1198 /* last item (virtual separator) */
1199 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1200 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1202 else if (index == (count - 2))
1204 /* second last item (last non-virtual item) */
1205 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
1206 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1208 else if (index == 0)
1211 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1212 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
1216 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
1217 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
1220 EnableWindow (GetDlgItem (hwnd,IDC_REMOVE_BTN), btnInfo->bRemovable);
1224 case IDC_MOVEUP_BTN:
1226 PCUSTOMBUTTON btnInfo;
1230 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1231 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1232 TRACE("Move up: index %d\n", index);
1234 /* send TBN_QUERYINSERT notification */
1235 nmtb.hdr.hwndFrom = hwnd;
1236 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1237 nmtb.hdr.code = TBN_QUERYINSERT;
1240 if (SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1241 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1243 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1245 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_DELETESTRING, index, 0);
1246 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_INSERTSTRING, index-1, 0);
1247 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index-1, (LPARAM)btnInfo);
1248 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index-1 , 0);
1251 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1252 else if (index >= (count - 3))
1253 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
1255 SendMessageA (custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
1256 SendMessageA (custInfo->tbHwnd, TB_INSERTBUTTONA, index-1, (LPARAM)&(btnInfo->btn));
1261 case IDC_MOVEDN_BTN: /* move down */
1263 PCUSTOMBUTTON btnInfo;
1267 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1268 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1269 TRACE("Move up: index %d\n", index);
1271 /* send TBN_QUERYINSERT notification */
1272 nmtb.hdr.hwndFrom = hwnd;
1273 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1274 nmtb.hdr.code = TBN_QUERYINSERT;
1277 if (SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1278 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1280 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1282 /* move button down */
1283 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_DELETESTRING, index, 0);
1284 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_INSERTSTRING, index+1, 0);
1285 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index+1, (LPARAM)btnInfo);
1286 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index+1 , 0);
1289 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
1290 else if (index >= (count - 3))
1291 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1293 SendMessageA (custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
1294 SendMessageA (custInfo->tbHwnd, TB_INSERTBUTTONA, index+1, (LPARAM)&(btnInfo->btn));
1299 case IDC_REMOVE_BTN: /* remove button */
1301 PCUSTOMBUTTON btnInfo;
1304 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1305 TRACE("Remove: index %d\n", index);
1307 /* send TBN_QUERYDELETE notification */
1308 nmtb.hdr.hwndFrom = hwnd;
1309 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1310 nmtb.hdr.code = TBN_QUERYDELETE;
1313 if (SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1314 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1316 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1317 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_DELETESTRING, index, 0);
1318 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index , 0);
1320 SendMessageA (custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
1322 /* insert into 'available button' list */
1323 if (!(btnInfo->btn.fsStyle & TBSTYLE_SEP))
1325 index = (int)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, 0);
1326 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1329 COMCTL32_Free (btnInfo);
1334 case IDOK: /* Add button */
1339 count = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETCOUNT, 0, 0);
1340 index = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETCURSEL, 0, 0);
1341 TRACE("Add: index %d\n", index);
1343 /* send TBN_QUERYINSERT notification */
1344 nmtb.hdr.hwndFrom = hwnd;
1345 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1346 nmtb.hdr.code = TBN_QUERYINSERT;
1349 if (SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1350 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1352 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, index, 0);
1356 /* remove from 'available buttons' list */
1357 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_DELETESTRING, index, 0);
1358 if (index == count-1)
1359 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, index-1 , 0);
1361 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, index , 0);
1365 PCUSTOMBUTTON btnNew;
1367 /* duplicate 'separator' button */
1368 btnNew = (PCUSTOMBUTTON)COMCTL32_Alloc (sizeof(CUSTOMBUTTON));
1369 memcpy (btnNew, btnInfo, sizeof(CUSTOMBUTTON));
1373 /* insert into 'toolbar button' list */
1374 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1375 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_INSERTSTRING, index, 0);
1376 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1378 SendMessageA (custInfo->tbHwnd, TB_INSERTBUTTONA, index, (LPARAM)&(btnInfo->btn));
1384 EndDialog(hwnd, FALSE);
1394 /* delete items from 'toolbar buttons' listbox*/
1395 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1396 for (i = 0; i < count; i++)
1398 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, i, 0);
1399 COMCTL32_Free(btnInfo);
1400 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, 0, 0);
1402 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_RESETCONTENT, 0, 0);
1405 /* delete items from 'available buttons' listbox*/
1406 count = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETCOUNT, 0, 0);
1407 for (i = 0; i < count; i++)
1409 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, i, 0);
1410 COMCTL32_Free(btnInfo);
1411 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, i, 0);
1413 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_RESETCONTENT, 0, 0);
1418 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1420 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
1425 COLORREF oldText = 0;
1429 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, wParam, LB_GETITEMDATA, (WPARAM)lpdis->itemID, 0);
1430 if (btnInfo == NULL)
1432 FIXME("btnInfo invalid!\n");
1436 /* set colors and select objects */
1437 oldBk = SetBkColor (lpdis->hDC, GetSysColor((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1438 if (btnInfo->bVirtual)
1439 oldText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_GRAYTEXT));
1441 oldText = SetTextColor (lpdis->hDC, GetSysColor((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHTTEXT:COLOR_WINDOWTEXT));
1442 hOldPen = SelectObject (lpdis->hDC, GetSysColorPen ((lpdis->itemState & ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1443 hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1445 /* fill background rectangle */
1446 Rectangle (lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
1447 lpdis->rcItem.right, lpdis->rcItem.bottom);
1449 /* calculate button and text rectangles */
1450 CopyRect (&rcButton, &lpdis->rcItem);
1451 InflateRect (&rcButton, -1, -1);
1452 CopyRect (&rcText, &rcButton);
1453 rcButton.right = rcButton.left + custInfo->tbInfo->nBitmapWidth + 6;
1454 rcText.left = rcButton.right + 2;
1456 /* draw focus rectangle */
1457 if (lpdis->itemState & ODS_FOCUS)
1458 DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
1461 DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
1463 /* draw image and text */
1464 if ((btnInfo->btn.fsStyle & TBSTYLE_SEP) == 0)
1465 ImageList_Draw (custInfo->tbInfo->himlDef, btnInfo->btn.iBitmap, lpdis->hDC,
1466 rcButton.left+3, rcButton.top+3, ILD_NORMAL);
1467 DrawTextA (lpdis->hDC, btnInfo->text, -1, &rcText,
1468 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1470 /* delete objects and reset colors */
1471 SelectObject (lpdis->hDC, hOldBrush);
1472 SelectObject (lpdis->hDC, hOldPen);
1473 SetBkColor (lpdis->hDC, oldBk);
1474 SetTextColor (lpdis->hDC, oldText);
1480 case WM_MEASUREITEM:
1481 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1483 MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*)lParam;
1485 if (custInfo && custInfo->tbInfo)
1486 lpmis->itemHeight = custInfo->tbInfo->nBitmapHeight + 8;
1488 lpmis->itemHeight = 15 + 8; /* default height */
1500 /***********************************************************************
1501 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1505 TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1507 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1508 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
1509 INT nIndex = 0, nButtons, nCount;
1512 TRACE("hwnd=%x wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
1516 if (lpAddBmp->hInst == HINST_COMMCTRL)
1518 if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR)
1520 else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR)
1522 else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR)
1527 TRACE ("adding %d internal bitmaps!\n", nButtons);
1529 /* Windows resize all the buttons to the size of a newly added standard image */
1530 if (lpAddBmp->nID & 1)
1533 /* FIXME: on windows the size of the images is 25x24 but the size of the bitmap
1534 * in rsrc is only 24x24. Fix the bitmap (how?) and then fix this
1536 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1537 MAKELPARAM((WORD)24, (WORD)24));
1538 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1539 MAKELPARAM((WORD)31, (WORD)30));
1544 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1545 MAKELPARAM((WORD)16, (WORD)16));
1546 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1547 MAKELPARAM((WORD)22, (WORD)22));
1552 nButtons = (INT)wParam;
1556 TRACE ("adding %d bitmaps!\n", nButtons);
1559 if (!(infoPtr->himlDef)) {
1560 /* create new default image list */
1561 TRACE ("creating default image list!\n");
1564 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
1565 ILC_COLOR | ILC_MASK, nButtons, 2);
1566 infoPtr->himlInt = infoPtr->himlDef;
1569 nCount = ImageList_GetImageCount(infoPtr->himlDef);
1571 /* Add bitmaps to the default image list */
1572 if (lpAddBmp->hInst == (HINSTANCE)0)
1575 ImageList_AddMasked (infoPtr->himlDef, (HBITMAP)lpAddBmp->nID,
1578 else if (lpAddBmp->hInst == HINST_COMMCTRL)
1580 /* Add system bitmaps */
1581 switch (lpAddBmp->nID)
1583 case IDB_STD_SMALL_COLOR:
1584 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1585 MAKEINTRESOURCEA(IDB_STD_SMALL));
1586 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1587 hbmLoad, CLR_DEFAULT);
1588 DeleteObject (hbmLoad);
1591 case IDB_STD_LARGE_COLOR:
1592 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1593 MAKEINTRESOURCEA(IDB_STD_LARGE));
1594 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1595 hbmLoad, CLR_DEFAULT);
1596 DeleteObject (hbmLoad);
1599 case IDB_VIEW_SMALL_COLOR:
1600 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1601 MAKEINTRESOURCEA(IDB_VIEW_SMALL));
1602 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1603 hbmLoad, CLR_DEFAULT);
1604 DeleteObject (hbmLoad);
1607 case IDB_VIEW_LARGE_COLOR:
1608 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1609 MAKEINTRESOURCEA(IDB_VIEW_LARGE));
1610 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1611 hbmLoad, CLR_DEFAULT);
1612 DeleteObject (hbmLoad);
1615 case IDB_HIST_SMALL_COLOR:
1616 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1617 MAKEINTRESOURCEA(IDB_HIST_SMALL));
1618 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1619 hbmLoad, CLR_DEFAULT);
1620 DeleteObject (hbmLoad);
1623 case IDB_HIST_LARGE_COLOR:
1624 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1625 MAKEINTRESOURCEA(IDB_HIST_LARGE));
1626 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1627 hbmLoad, CLR_DEFAULT);
1628 DeleteObject (hbmLoad);
1632 nIndex = ImageList_GetImageCount (infoPtr->himlDef);
1633 ERR ("invalid imagelist!\n");
1639 hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
1640 nIndex = ImageList_AddMasked (infoPtr->himlDef, hbmLoad, CLR_DEFAULT);
1641 DeleteObject (hbmLoad);
1646 INT imagecount = ImageList_GetImageCount(infoPtr->himlDef);
1648 if (infoPtr->nNumBitmaps + nButtons != imagecount)
1650 WARN("Desired images do not match received images : Previous image number %i Previous images in list %i added %i expecting total %i, Images in list %i\n",
1651 infoPtr->nNumBitmaps, nCount, imagecount - nCount,
1652 infoPtr->nNumBitmaps+nButtons,imagecount);
1654 infoPtr->nNumBitmaps = imagecount;
1657 infoPtr->nNumBitmaps += nButtons;
1660 InvalidateRect(hwnd, NULL, FALSE);
1667 TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1669 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1670 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1671 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1673 TRACE("adding %d buttons!\n", wParam);
1675 nAddButtons = (UINT)wParam;
1676 nOldButtons = infoPtr->nNumButtons;
1677 nNewButtons = nOldButtons + nAddButtons;
1679 if (infoPtr->nNumButtons == 0) {
1681 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1684 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1686 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1687 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1688 nOldButtons * sizeof(TBUTTON_INFO));
1689 COMCTL32_Free (oldButtons);
1692 infoPtr->nNumButtons = nNewButtons;
1694 /* insert new button data */
1695 for (nCount = 0; nCount < nAddButtons; nCount++) {
1696 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1697 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1698 btnPtr->idCommand = lpTbb[nCount].idCommand;
1699 btnPtr->fsState = lpTbb[nCount].fsState;
1700 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1701 btnPtr->dwData = lpTbb[nCount].dwData;
1702 btnPtr->iString = lpTbb[nCount].iString;
1703 btnPtr->bHot = FALSE;
1705 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1708 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1709 ti.cbSize = sizeof (TTTOOLINFOA);
1711 ti.uId = btnPtr->idCommand;
1713 ti.lpszText = LPSTR_TEXTCALLBACKA;
1715 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
1720 InvalidateRect(hwnd, NULL, FALSE);
1727 TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1729 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1730 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1731 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1733 TRACE("adding %d buttons!\n", wParam);
1735 nAddButtons = (UINT)wParam;
1736 nOldButtons = infoPtr->nNumButtons;
1737 nNewButtons = nOldButtons + nAddButtons;
1739 if (infoPtr->nNumButtons == 0) {
1741 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1744 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1746 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1747 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1748 nOldButtons * sizeof(TBUTTON_INFO));
1749 COMCTL32_Free (oldButtons);
1752 infoPtr->nNumButtons = nNewButtons;
1754 /* insert new button data */
1755 for (nCount = 0; nCount < nAddButtons; nCount++) {
1756 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1757 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1758 btnPtr->idCommand = lpTbb[nCount].idCommand;
1759 btnPtr->fsState = lpTbb[nCount].fsState;
1760 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1761 btnPtr->dwData = lpTbb[nCount].dwData;
1762 btnPtr->iString = lpTbb[nCount].iString;
1763 btnPtr->bHot = FALSE;
1765 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1768 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
1769 ti.cbSize = sizeof (TTTOOLINFOW);
1771 ti.uId = btnPtr->idCommand;
1773 ti.lpszText = LPSTR_TEXTCALLBACKW;
1775 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
1780 InvalidateRect(hwnd, NULL, FALSE);
1787 TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1789 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1792 if ((wParam) && (HIWORD(lParam) == 0)) {
1795 TRACE("adding string from resource!\n");
1797 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
1800 TRACE("len=%d \"%s\"\n", len, szString);
1801 nIndex = infoPtr->nNumStrings;
1802 if (infoPtr->nNumStrings == 0) {
1804 COMCTL32_Alloc (sizeof(LPWSTR));
1807 LPWSTR *oldStrings = infoPtr->strings;
1809 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1810 memcpy (&infoPtr->strings[0], &oldStrings[0],
1811 sizeof(LPWSTR) * infoPtr->nNumStrings);
1812 COMCTL32_Free (oldStrings);
1815 lenW = MultiByteToWideChar( CP_ACP, 0, szString, -1, NULL, 0 );
1816 infoPtr->strings[infoPtr->nNumStrings] = COMCTL32_Alloc (sizeof(WCHAR)*lenW);
1817 MultiByteToWideChar( CP_ACP, 0, szString, -1,
1818 infoPtr->strings[infoPtr->nNumStrings], lenW );
1819 infoPtr->nNumStrings++;
1822 LPSTR p = (LPSTR)lParam;
1827 TRACE("adding string(s) from array!\n");
1829 nIndex = infoPtr->nNumStrings;
1832 TRACE("len=%d \"%s\"\n", len, p);
1834 if (infoPtr->nNumStrings == 0) {
1836 COMCTL32_Alloc (sizeof(LPWSTR));
1839 LPWSTR *oldStrings = infoPtr->strings;
1841 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1842 memcpy (&infoPtr->strings[0], &oldStrings[0],
1843 sizeof(LPWSTR) * infoPtr->nNumStrings);
1844 COMCTL32_Free (oldStrings);
1847 lenW = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
1848 infoPtr->strings[infoPtr->nNumStrings] = COMCTL32_Alloc (sizeof(WCHAR)*lenW);
1849 MultiByteToWideChar( CP_ACP, 0, p, -1,
1850 infoPtr->strings[infoPtr->nNumStrings], lenW );
1851 infoPtr->nNumStrings++;
1862 TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1864 #define MAX_RESOURCE_STRING_LENGTH 512
1865 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1868 if ((wParam) && (HIWORD(lParam) == 0)) {
1869 WCHAR szString[MAX_RESOURCE_STRING_LENGTH];
1871 TRACE("adding string from resource!\n");
1873 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
1874 szString, MAX_RESOURCE_STRING_LENGTH);
1876 TRACE("len=%d \"%s\"\n", len, debugstr_w(szString));
1877 TRACE("First char: 0x%x\n", *szString);
1878 if (szString[0] == L'|')
1880 PWSTR p = szString + 1;
1882 nIndex = infoPtr->nNumStrings;
1883 while (*p != L'|') {
1885 if (infoPtr->nNumStrings == 0) {
1887 COMCTL32_Alloc (sizeof(LPWSTR));
1890 LPWSTR *oldStrings = infoPtr->strings;
1892 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1893 memcpy (&infoPtr->strings[0], &oldStrings[0],
1894 sizeof(LPWSTR) * infoPtr->nNumStrings);
1895 COMCTL32_Free (oldStrings);
1898 len = COMCTL32_StrChrW (p, L'|') - p;
1899 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1900 infoPtr->strings[infoPtr->nNumStrings] =
1901 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1902 lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len);
1903 infoPtr->nNumStrings++;
1910 nIndex = infoPtr->nNumStrings;
1911 if (infoPtr->nNumStrings == 0) {
1913 COMCTL32_Alloc (sizeof(LPWSTR));
1916 LPWSTR *oldStrings = infoPtr->strings;
1918 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1919 memcpy (&infoPtr->strings[0], &oldStrings[0],
1920 sizeof(LPWSTR) * infoPtr->nNumStrings);
1921 COMCTL32_Free (oldStrings);
1924 infoPtr->strings[infoPtr->nNumStrings] =
1925 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1926 strcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
1927 infoPtr->nNumStrings++;
1931 LPWSTR p = (LPWSTR)lParam;
1936 TRACE("adding string(s) from array!\n");
1937 nIndex = infoPtr->nNumStrings;
1941 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1942 if (infoPtr->nNumStrings == 0) {
1944 COMCTL32_Alloc (sizeof(LPWSTR));
1947 LPWSTR *oldStrings = infoPtr->strings;
1949 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1950 memcpy (&infoPtr->strings[0], &oldStrings[0],
1951 sizeof(LPWSTR) * infoPtr->nNumStrings);
1952 COMCTL32_Free (oldStrings);
1955 infoPtr->strings[infoPtr->nNumStrings] =
1956 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1957 strcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1958 infoPtr->nNumStrings++;
1969 TOOLBAR_AutoSize (HWND hwnd)
1971 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1972 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1978 UINT uPosFlags = SWP_NOZORDER;
1980 TRACE("resize forced, style=%lx!\n", dwStyle);
1982 parent = GetParent (hwnd);
1983 GetClientRect(parent, &parent_rect);
1985 x = parent_rect.left;
1986 y = parent_rect.top;
1988 /* FIXME: we should be able to early out if nothing */
1989 /* has changed with nWidth != parent_rect width */
1991 if (dwStyle & CCS_NORESIZE) {
1992 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
1997 infoPtr->nWidth = parent_rect.right - parent_rect.left;
1998 InvalidateRect( hwnd, NULL, TRUE );
1999 cy = infoPtr->nHeight;
2000 cx = infoPtr->nWidth;
2002 if (dwStyle & CCS_NOMOVEY) {
2003 GetWindowRect(hwnd, &window_rect);
2004 ScreenToClient(parent, (LPPOINT)&window_rect.left);
2005 y = window_rect.top;
2009 if (dwStyle & CCS_NOPARENTALIGN)
2010 uPosFlags |= SWP_NOMOVE;
2012 if (!(dwStyle & CCS_NODIVIDER))
2013 cy += GetSystemMetrics(SM_CYEDGE);
2015 if (dwStyle & WS_BORDER)
2018 cy += GetSystemMetrics(SM_CYEDGE);
2019 cx += GetSystemMetrics(SM_CYEDGE);
2022 infoPtr->bAutoSize = TRUE;
2023 SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
2025 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
2026 * the setwindowpos calls */
2027 infoPtr->bAutoSize = FALSE;
2034 TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
2036 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2038 return infoPtr->nNumButtons;
2043 TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2045 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2047 if (infoPtr == NULL) {
2048 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
2049 ERR("infoPtr == NULL!\n");
2053 infoPtr->dwStructSize = (DWORD)wParam;
2060 TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
2062 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2063 TBUTTON_INFO *btnPtr;
2066 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2070 btnPtr = &infoPtr->buttons[nIndex];
2071 btnPtr->iBitmap = LOWORD(lParam);
2073 /* we HAVE to erase the background, the new bitmap could be */
2075 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
2082 TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2084 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2085 TBUTTON_INFO *btnPtr;
2088 BOOL bChecked = FALSE;
2090 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2094 btnPtr = &infoPtr->buttons[nIndex];
2096 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
2099 bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
2101 if (LOWORD(lParam) == FALSE)
2102 btnPtr->fsState &= ~TBSTATE_CHECKED;
2104 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
2106 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
2107 if (nOldIndex == nIndex)
2109 if (nOldIndex != -1)
2110 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
2112 btnPtr->fsState |= TBSTATE_CHECKED;
2115 if( bChecked != LOWORD(lParam) )
2117 if (nOldIndex != -1)
2119 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
2120 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
2122 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
2125 /* FIXME: Send a WM_NOTIFY?? */
2132 TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
2134 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2136 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2141 TOOLBAR_Customize (HWND hwnd)
2143 CUSTDLG_INFO custInfo;
2149 custInfo.tbInfo = TOOLBAR_GetInfoPtr (hwnd);
2150 custInfo.tbHwnd = hwnd;
2152 /* send TBN_BEGINADJUST notification */
2153 nmhdr.hwndFrom = hwnd;
2154 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
2155 nmhdr.code = TBN_BEGINADJUST;
2157 SendMessageA (custInfo.tbInfo->hwndNotify, WM_NOTIFY,
2158 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
2160 if (!(hRes = FindResourceA (COMCTL32_hModule,
2161 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
2165 if(!(template = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
2168 ret = DialogBoxIndirectParamA (GetWindowLongA (hwnd, GWL_HINSTANCE),
2169 (LPDLGTEMPLATEA)template,
2171 (DLGPROC)TOOLBAR_CustomizeDialogProc,
2174 /* send TBN_ENDADJUST notification */
2175 nmhdr.code = TBN_ENDADJUST;
2176 SendMessageA (custInfo.tbInfo->hwndNotify, WM_NOTIFY,
2177 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
2184 TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2186 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2187 INT nIndex = (INT)wParam;
2189 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2192 if ((infoPtr->hwndToolTip) &&
2193 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
2196 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2197 ti.cbSize = sizeof (TTTOOLINFOA);
2199 ti.uId = infoPtr->buttons[nIndex].idCommand;
2201 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
2204 if (infoPtr->nNumButtons == 1) {
2205 TRACE(" simple delete!\n");
2206 COMCTL32_Free (infoPtr->buttons);
2207 infoPtr->buttons = NULL;
2208 infoPtr->nNumButtons = 0;
2211 TBUTTON_INFO *oldButtons = infoPtr->buttons;
2212 TRACE("complex delete! [nIndex=%d]\n", nIndex);
2214 infoPtr->nNumButtons--;
2215 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2217 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2218 nIndex * sizeof(TBUTTON_INFO));
2221 if (nIndex < infoPtr->nNumButtons) {
2222 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
2223 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
2226 COMCTL32_Free (oldButtons);
2229 InvalidateRect (hwnd, NULL, TRUE);
2236 TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2238 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2239 TBUTTON_INFO *btnPtr;
2243 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2247 btnPtr = &infoPtr->buttons[nIndex];
2249 bState = btnPtr->fsState & TBSTATE_ENABLED;
2251 /* update the toolbar button state */
2252 if(LOWORD(lParam) == FALSE) {
2253 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
2255 btnPtr->fsState |= TBSTATE_ENABLED;
2258 /* redraw the button only if the state of the button changed */
2259 if(bState != (btnPtr->fsState & TBSTATE_ENABLED))
2261 InvalidateRect(hwnd, &btnPtr->rect,
2262 TOOLBAR_HasText(infoPtr, btnPtr));
2269 static inline LRESULT
2270 TOOLBAR_GetAnchorHighlight (HWND hwnd)
2272 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2274 return infoPtr->bAnchor;
2279 TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
2281 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2284 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2288 return infoPtr->buttons[nIndex].iBitmap;
2292 static inline LRESULT
2293 TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
2295 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
2300 TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2302 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2303 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2304 INT nIndex = (INT)wParam;
2305 TBUTTON_INFO *btnPtr;
2307 if (infoPtr == NULL)
2313 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2316 btnPtr = &infoPtr->buttons[nIndex];
2317 lpTbb->iBitmap = btnPtr->iBitmap;
2318 lpTbb->idCommand = btnPtr->idCommand;
2319 lpTbb->fsState = btnPtr->fsState;
2320 lpTbb->fsStyle = btnPtr->fsStyle;
2321 lpTbb->dwData = btnPtr->dwData;
2322 lpTbb->iString = btnPtr->iString;
2329 TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2331 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2332 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
2333 TBUTTON_INFO *btnPtr;
2336 if (infoPtr == NULL)
2338 if (lpTbInfo == NULL)
2340 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOA))
2343 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2347 btnPtr = &infoPtr->buttons[nIndex];
2349 if (lpTbInfo->dwMask & TBIF_COMMAND)
2350 lpTbInfo->idCommand = btnPtr->idCommand;
2351 if (lpTbInfo->dwMask & TBIF_IMAGE)
2352 lpTbInfo->iImage = btnPtr->iBitmap;
2353 if (lpTbInfo->dwMask & TBIF_LPARAM)
2354 lpTbInfo->lParam = btnPtr->dwData;
2355 if (lpTbInfo->dwMask & TBIF_SIZE)
2356 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
2357 if (lpTbInfo->dwMask & TBIF_STATE)
2358 lpTbInfo->fsState = btnPtr->fsState;
2359 if (lpTbInfo->dwMask & TBIF_STYLE)
2360 lpTbInfo->fsStyle = btnPtr->fsStyle;
2361 if (lpTbInfo->dwMask & TBIF_TEXT) {
2362 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
2364 if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)infoPtr->strings[btnPtr->iString], -1,
2365 lpTbInfo->pszText, lpTbInfo->cchText, NULL, NULL ))
2366 lpTbInfo->pszText[lpTbInfo->cchText-1] = 0;
2368 else lpTbInfo->pszText[0]=0;
2375 TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2377 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2378 LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
2379 TBUTTON_INFO *btnPtr;
2382 if (infoPtr == NULL)
2384 if (lpTbInfo == NULL)
2386 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
2389 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2393 btnPtr = &infoPtr->buttons[nIndex];
2395 if (lpTbInfo->dwMask & TBIF_COMMAND)
2396 lpTbInfo->idCommand = btnPtr->idCommand;
2397 if (lpTbInfo->dwMask & TBIF_IMAGE)
2398 lpTbInfo->iImage = btnPtr->iBitmap;
2399 if (lpTbInfo->dwMask & TBIF_LPARAM)
2400 lpTbInfo->lParam = btnPtr->dwData;
2401 if (lpTbInfo->dwMask & TBIF_SIZE)
2402 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
2403 if (lpTbInfo->dwMask & TBIF_STATE)
2404 lpTbInfo->fsState = btnPtr->fsState;
2405 if (lpTbInfo->dwMask & TBIF_STYLE)
2406 lpTbInfo->fsStyle = btnPtr->fsStyle;
2407 if (lpTbInfo->dwMask & TBIF_TEXT) {
2408 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
2409 lstrcpynW (lpTbInfo->pszText,
2410 (LPWSTR)infoPtr->strings[btnPtr->iString],
2419 TOOLBAR_GetButtonSize (HWND hwnd)
2421 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2423 return MAKELONG((WORD)infoPtr->nButtonWidth,
2424 (WORD)infoPtr->nButtonHeight);
2429 TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2431 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2432 INT nIndex, nStringIndex;
2434 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2438 nStringIndex = infoPtr->buttons[nIndex].iString;
2440 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
2442 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2448 return WideCharToMultiByte( CP_ACP, 0, (LPWSTR)infoPtr->strings[nStringIndex], -1,
2449 (LPSTR)lParam, 0x7fffffff, NULL, NULL ) - 1;
2454 TOOLBAR_GetButtonTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2456 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2457 INT nIndex, nStringIndex;
2459 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2463 nStringIndex = infoPtr->buttons[nIndex].iString;
2465 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
2467 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2473 strcpyW ((LPWSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
2475 return strlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
2479 /* << TOOLBAR_GetColorScheme >> */
2483 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2485 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2487 return (LRESULT)infoPtr->himlDis;
2491 inline static LRESULT
2492 TOOLBAR_GetExtendedStyle (HWND hwnd)
2494 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2496 return infoPtr->dwExStyle;
2501 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2503 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2505 return (LRESULT)infoPtr->himlHot;
2510 TOOLBAR_GetHotItem (HWND hwnd)
2512 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2514 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2517 if (infoPtr->nHotItem < 0)
2520 return (LRESULT)infoPtr->nHotItem;
2525 TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2527 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2529 return (LRESULT)infoPtr->himlDef;
2533 /* << TOOLBAR_GetInsertMark >> */
2534 /* << TOOLBAR_GetInsertMarkColor >> */
2538 TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2540 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2541 TBUTTON_INFO *btnPtr;
2545 if (infoPtr == NULL)
2547 nIndex = (INT)wParam;
2548 btnPtr = &infoPtr->buttons[nIndex];
2549 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2551 lpRect = (LPRECT)lParam;
2554 if (btnPtr->fsState & TBSTATE_HIDDEN)
2557 lpRect->left = btnPtr->rect.left;
2558 lpRect->right = btnPtr->rect.right;
2559 lpRect->bottom = btnPtr->rect.bottom;
2560 lpRect->top = btnPtr->rect.top;
2567 TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2569 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2570 LPSIZE lpSize = (LPSIZE)lParam;
2575 lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
2576 lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
2578 TRACE("maximum size %d x %d\n",
2579 infoPtr->rcBound.right - infoPtr->rcBound.left,
2580 infoPtr->rcBound.bottom - infoPtr->rcBound.top);
2586 /* << TOOLBAR_GetObject >> */
2587 /* << TOOLBAR_GetPadding >> */
2591 TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2593 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2594 TBUTTON_INFO *btnPtr;
2598 if (infoPtr == NULL)
2600 nIndex = (INT)wParam;
2601 btnPtr = &infoPtr->buttons[nIndex];
2602 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2604 lpRect = (LPRECT)lParam;
2608 lpRect->left = btnPtr->rect.left;
2609 lpRect->right = btnPtr->rect.right;
2610 lpRect->bottom = btnPtr->rect.bottom;
2611 lpRect->top = btnPtr->rect.top;
2618 TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2620 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2622 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
2623 return infoPtr->nRows;
2630 TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2632 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2635 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2639 return infoPtr->buttons[nIndex].fsState;
2644 TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2646 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2649 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2653 return infoPtr->buttons[nIndex].fsStyle;
2658 TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2660 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2662 if (infoPtr == NULL)
2665 return infoPtr->nMaxTextRows;
2670 TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
2672 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2674 if (infoPtr == NULL)
2676 return infoPtr->hwndToolTip;
2681 TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2683 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2685 TRACE("%s hwnd=0x%x stub!\n",
2686 infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
2688 return infoPtr->bUnicode;
2692 inline static LRESULT
2693 TOOLBAR_GetVersion (HWND hwnd)
2695 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2696 return infoPtr->iVersion;
2701 TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2703 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2704 TBUTTON_INFO *btnPtr;
2709 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2713 btnPtr = &infoPtr->buttons[nIndex];
2714 if (LOWORD(lParam) == FALSE)
2715 btnPtr->fsState &= ~TBSTATE_HIDDEN;
2717 btnPtr->fsState |= TBSTATE_HIDDEN;
2719 InvalidateRect (hwnd, NULL, TRUE);
2725 inline static LRESULT
2726 TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2728 return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
2733 TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2735 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2736 TBUTTON_INFO *btnPtr;
2739 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2743 btnPtr = &infoPtr->buttons[nIndex];
2744 if (LOWORD(lParam) == FALSE)
2745 btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
2747 btnPtr->fsState |= TBSTATE_INDETERMINATE;
2749 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
2756 TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2758 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2759 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2760 INT nIndex = (INT)wParam;
2761 TBUTTON_INFO *oldButtons;
2767 /* EPP: this seems to be an undocumented call (from my IE4)
2768 * I assume in that case that:
2769 * - lpTbb->iString is a string pointer (not a string index in strings[] table
2770 * - index of insertion is at the end of existing buttons
2771 * I only see this happen with nIndex == -1, but it could have a special
2772 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
2777 if(lpTbb->iString) {
2778 len = strlen((char*)lpTbb->iString) + 2;
2779 ptr = COMCTL32_Alloc(len);
2780 nIndex = infoPtr->nNumButtons;
2781 strcpy(ptr, (char*)lpTbb->iString);
2782 ptr[len - 1] = 0; /* ended by two '\0' */
2783 lpTbb->iString = TOOLBAR_AddStringA(hwnd, 0, (LPARAM)ptr);
2787 ERR("lpTbb->iString is NULL\n");
2791 } else if (nIndex < 0)
2794 TRACE("inserting button index=%d\n", nIndex);
2795 if (nIndex > infoPtr->nNumButtons) {
2796 nIndex = infoPtr->nNumButtons;
2797 TRACE("adjust index=%d\n", nIndex);
2800 oldButtons = infoPtr->buttons;
2801 infoPtr->nNumButtons++;
2802 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2803 /* pre insert copy */
2805 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2806 nIndex * sizeof(TBUTTON_INFO));
2809 /* insert new button */
2810 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2811 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2812 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2813 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2814 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2815 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2817 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2820 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2821 ti.cbSize = sizeof (TTTOOLINFOA);
2823 ti.uId = lpTbb->idCommand;
2825 ti.lpszText = LPSTR_TEXTCALLBACKA;
2827 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
2831 /* post insert copy */
2832 if (nIndex < infoPtr->nNumButtons - 1) {
2833 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2834 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2837 COMCTL32_Free (oldButtons);
2839 InvalidateRect (hwnd, NULL, FALSE);
2846 TOOLBAR_InsertButtonW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2848 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2849 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2850 INT nIndex = (INT)wParam;
2851 TBUTTON_INFO *oldButtons;
2858 TRACE("inserting button index=%d\n", nIndex);
2859 if (nIndex > infoPtr->nNumButtons) {
2860 nIndex = infoPtr->nNumButtons;
2861 TRACE("adjust index=%d\n", nIndex);
2864 oldButtons = infoPtr->buttons;
2865 infoPtr->nNumButtons++;
2866 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2867 /* pre insert copy */
2869 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2870 nIndex * sizeof(TBUTTON_INFO));
2873 /* insert new button */
2874 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2875 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2876 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2877 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2878 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2879 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2881 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2884 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
2885 ti.cbSize = sizeof (TTTOOLINFOW);
2887 ti.uId = lpTbb->idCommand;
2889 ti.lpszText = LPSTR_TEXTCALLBACKW;
2891 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
2895 /* post insert copy */
2896 if (nIndex < infoPtr->nNumButtons - 1) {
2897 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2898 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2901 COMCTL32_Free (oldButtons);
2903 InvalidateRect (hwnd, NULL, FALSE);
2909 /* << TOOLBAR_InsertMarkHitTest >> */
2913 TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
2915 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2918 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2922 return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
2927 TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
2929 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2932 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2936 return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
2941 TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
2943 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2946 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2950 return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
2955 TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
2957 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2960 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2964 return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
2969 TOOLBAR_IsButtonIndeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2971 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2974 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2978 return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
2983 TOOLBAR_IsButtonPressed (HWND hwnd, WPARAM wParam, LPARAM lParam)
2985 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2988 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2992 return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
2996 /* << TOOLBAR_LoadImages >> */
2997 /* << TOOLBAR_MapAccelerator >> */
2998 /* << TOOLBAR_MarkButton >> */
2999 /* << TOOLBAR_MoveButton >> */
3003 TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
3005 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3006 TBUTTON_INFO *btnPtr;
3009 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3013 btnPtr = &infoPtr->buttons[nIndex];
3014 if (LOWORD(lParam) == FALSE)
3015 btnPtr->fsState &= ~TBSTATE_PRESSED;
3017 btnPtr->fsState |= TBSTATE_PRESSED;
3019 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
3025 /* << TOOLBAR_ReplaceBitmap >> */
3029 TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
3032 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3033 LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
3035 if (lpSave == NULL) return 0;
3038 /* save toolbar information */
3039 FIXME("save to \"%s\" \"%s\"\n",
3040 lpSave->pszSubKey, lpSave->pszValueName);
3045 /* restore toolbar information */
3047 FIXME("restore from \"%s\" \"%s\"\n",
3048 lpSave->pszSubKey, lpSave->pszValueName);
3059 TOOLBAR_SaveRestoreW (HWND hwnd, WPARAM wParam, LPARAM lParam)
3062 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3063 LPTBSAVEPARAMSW lpSave = (LPTBSAVEPARAMSW)lParam;
3069 /* save toolbar information */
3070 FIXME("save to \"%s\" \"%s\"\n",
3071 lpSave->pszSubKey, lpSave->pszValueName);
3076 /* restore toolbar information */
3078 FIXME("restore from \"%s\" \"%s\"\n",
3079 lpSave->pszSubKey, lpSave->pszValueName);
3090 TOOLBAR_SetAnchorHighlight (HWND hwnd, WPARAM wParam)
3092 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3093 BOOL bOldAnchor = infoPtr->bAnchor;
3095 infoPtr->bAnchor = (BOOL)wParam;
3097 return (LRESULT)bOldAnchor;
3102 TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3104 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3106 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
3109 if (infoPtr->nNumButtons > 0)
3110 WARN("%d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n",
3111 infoPtr->nNumButtons,
3112 infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
3113 LOWORD(lParam), HIWORD(lParam));
3115 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
3116 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
3118 /* uses image list internals directly */
3119 if (infoPtr->himlDef) {
3120 infoPtr->himlDef->cx = infoPtr->nBitmapWidth;
3121 infoPtr->himlDef->cy = infoPtr->nBitmapHeight;
3129 TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
3131 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3132 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
3133 TBUTTON_INFO *btnPtr;
3138 if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
3141 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3145 btnPtr = &infoPtr->buttons[nIndex];
3146 if (lptbbi->dwMask & TBIF_COMMAND)
3147 btnPtr->idCommand = lptbbi->idCommand;
3148 if (lptbbi->dwMask & TBIF_IMAGE)
3149 btnPtr->iBitmap = lptbbi->iImage;
3150 if (lptbbi->dwMask & TBIF_LPARAM)
3151 btnPtr->dwData = lptbbi->lParam;
3152 /* if (lptbbi->dwMask & TBIF_SIZE) */
3153 /* btnPtr->cx = lptbbi->cx; */
3154 if (lptbbi->dwMask & TBIF_STATE)
3155 btnPtr->fsState = lptbbi->fsState;
3156 if (lptbbi->dwMask & TBIF_STYLE)
3157 btnPtr->fsStyle = lptbbi->fsStyle;
3159 if (lptbbi->dwMask & TBIF_TEXT) {
3160 if ((btnPtr->iString >= 0) ||
3161 (btnPtr->iString < infoPtr->nNumStrings)) {
3162 TRACE("Ooooooch\n");
3164 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
3165 INT len = lstrlenA (lptbbi->pszText);
3166 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
3169 /* this is the ultimate sollution */
3170 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3179 TOOLBAR_SetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
3181 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3182 LPTBBUTTONINFOW lptbbi = (LPTBBUTTONINFOW)lParam;
3183 TBUTTON_INFO *btnPtr;
3188 if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
3191 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3195 btnPtr = &infoPtr->buttons[nIndex];
3196 if (lptbbi->dwMask & TBIF_COMMAND)
3197 btnPtr->idCommand = lptbbi->idCommand;
3198 if (lptbbi->dwMask & TBIF_IMAGE)
3199 btnPtr->iBitmap = lptbbi->iImage;
3200 if (lptbbi->dwMask & TBIF_LPARAM)
3201 btnPtr->dwData = lptbbi->lParam;
3202 /* if (lptbbi->dwMask & TBIF_SIZE) */
3203 /* btnPtr->cx = lptbbi->cx; */
3204 if (lptbbi->dwMask & TBIF_STATE)
3205 btnPtr->fsState = lptbbi->fsState;
3206 if (lptbbi->dwMask & TBIF_STYLE)
3207 btnPtr->fsStyle = lptbbi->fsStyle;
3209 if (lptbbi->dwMask & TBIF_TEXT) {
3210 if ((btnPtr->iString >= 0) ||
3211 (btnPtr->iString < infoPtr->nNumStrings)) {
3213 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
3214 INT len = lstrlenW (lptbbi->pszText);
3215 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
3218 /* this is the ultimate solution */
3219 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3228 TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3230 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3232 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
3234 ERR("invalid parameter\n");
3238 /* Button size can only be set before adding any button to the toolbar
3239 according to the documentation. */
3240 /* this appears to be wrong. WINZIP32.EXE (ver 8) calls this on
3241 one of its buttons after adding it to the toolbar, and it
3242 checks that the return value is nonzero - mjm */
3243 if( infoPtr->nNumButtons != 0 )
3245 WARN("Button size set after button in toolbar\n");
3249 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
3250 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
3256 TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
3258 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3260 if (infoPtr == NULL)
3263 infoPtr->cxMin = (INT)LOWORD(lParam);
3264 infoPtr->cxMax = (INT)HIWORD(lParam);
3271 TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
3273 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3274 INT nIndex = (INT)wParam;
3276 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
3279 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
3281 if (infoPtr->hwndToolTip) {
3283 FIXME("change tool tip!\n");
3291 /* << TOOLBAR_SetColorScheme >> */
3295 TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3297 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3298 HIMAGELIST himlTemp;
3301 himlTemp = infoPtr->himlDis;
3302 infoPtr->himlDis = (HIMAGELIST)lParam;
3304 /* FIXME: redraw ? */
3306 return (LRESULT)himlTemp;
3311 TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
3313 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3316 dwTemp = infoPtr->dwDTFlags;
3317 infoPtr->dwDTFlags =
3318 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
3320 return (LRESULT)dwTemp;
3325 TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3327 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3330 dwTemp = infoPtr->dwExStyle;
3331 infoPtr->dwExStyle = (DWORD)lParam;
3333 return (LRESULT)dwTemp;
3338 TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3340 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3341 HIMAGELIST himlTemp;
3343 himlTemp = infoPtr->himlHot;
3344 infoPtr->himlHot = (HIMAGELIST)lParam;
3346 /* FIXME: redraw ? */
3348 return (LRESULT)himlTemp;
3353 TOOLBAR_SetHotItem (HWND hwnd, WPARAM wParam)
3355 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3356 INT nOldHotItem = infoPtr->nHotItem;
3358 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
3360 infoPtr->nHotItem = (INT)wParam;
3362 /* FIXME: What else must be done ??? */
3366 if (nOldHotItem < 0)
3369 return (LRESULT)nOldHotItem;
3374 TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3376 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3377 HIMAGELIST himlTemp;
3379 himlTemp = infoPtr->himlDef;
3380 infoPtr->himlDef = (HIMAGELIST)lParam;
3382 infoPtr->nNumBitmaps = ImageList_GetImageCount(infoPtr->himlDef);
3383 /* FIXME: redraw ? */
3385 return (LRESULT)himlTemp;
3390 TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3392 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3394 infoPtr->nIndent = (INT)wParam;
3398 /* process only on indent changing */
3399 if(infoPtr->nIndent != (INT)wParam)
3401 infoPtr->nIndent = (INT)wParam;
3402 InvalidateRect(hwnd, NULL, FALSE);
3409 /* << TOOLBAR_SetInsertMark >> */
3413 TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
3415 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3417 infoPtr->clrInsertMark = (COLORREF)lParam;
3419 /* FIXME : redraw ??*/
3426 TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3428 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3430 if (infoPtr == NULL)
3433 infoPtr->nMaxTextRows = (INT)wParam;
3439 /* << TOOLBAR_SetPadding >> */
3443 TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3445 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3450 if (infoPtr == NULL)
3452 hwndOldNotify = infoPtr->hwndNotify;
3453 infoPtr->hwndNotify = (HWND)wParam;
3455 return hwndOldNotify;
3460 TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3462 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3463 LPRECT lprc = (LPRECT)lParam;
3467 if (LOWORD(wParam) > 1) {
3468 FIXME("multiple rows not supported!\n");
3471 if(infoPtr->nRows != LOWORD(wParam))
3473 infoPtr->nRows = LOWORD(wParam);
3475 /* repaint toolbar */
3476 InvalidateRect(hwnd, NULL, FALSE);
3479 /* return bounding rectangle */
3481 lprc->left = infoPtr->rcBound.left;
3482 lprc->right = infoPtr->rcBound.right;
3483 lprc->top = infoPtr->rcBound.top;
3484 lprc->bottom = infoPtr->rcBound.bottom;
3492 TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
3494 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3495 TBUTTON_INFO *btnPtr;
3498 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3502 btnPtr = &infoPtr->buttons[nIndex];
3504 /* process state changing if current state doesn't match new state */
3505 if(btnPtr->fsState != LOWORD(lParam))
3507 btnPtr->fsState = LOWORD(lParam);
3508 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3517 TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3519 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3520 TBUTTON_INFO *btnPtr;
3523 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3527 btnPtr = &infoPtr->buttons[nIndex];
3529 /* process style change if current style doesn't match new style */
3530 if(btnPtr->fsStyle != LOWORD(lParam))
3532 btnPtr->fsStyle = LOWORD(lParam);
3533 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3536 if (infoPtr->hwndToolTip) {
3537 FIXME("change tool tip!\n");
3545 inline static LRESULT
3546 TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
3548 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3550 if (infoPtr == NULL)
3552 infoPtr->hwndToolTip = (HWND)wParam;
3558 TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
3560 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3563 TRACE("%s hwnd=0x%04x stub!\n",
3564 ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
3566 bTemp = infoPtr->bUnicode;
3567 infoPtr->bUnicode = (BOOL)wParam;
3574 TOOLBAR_SetVersion (HWND hwnd, INT iVersion)
3576 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3577 INT iOldVersion = infoPtr->iVersion;
3579 infoPtr->iVersion = iVersion;
3586 TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
3588 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3589 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3592 /* initialize info structure */
3593 infoPtr->nButtonHeight = 22;
3594 infoPtr->nButtonWidth = 24;
3595 infoPtr->nBitmapHeight = 15;
3596 infoPtr->nBitmapWidth = 16;
3598 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
3600 infoPtr->nMaxTextRows = 1;
3601 infoPtr->cxMin = -1;
3602 infoPtr->cxMax = -1;
3603 infoPtr->nNumBitmaps = 0;
3604 infoPtr->nNumStrings = 0;
3606 infoPtr->bCaptured = FALSE;
3607 infoPtr->bUnicode = IsWindowUnicode (hwnd);
3608 infoPtr->nButtonDown = -1;
3609 infoPtr->nOldHit = -1;
3610 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3611 infoPtr->hwndNotify = GetParent (hwnd);
3612 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
3613 infoPtr->dwDTFlags = (dwStyle & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE : DT_CENTER;
3614 infoPtr->bAnchor = FALSE; /* no anchor highlighting */
3615 infoPtr->iVersion = 0;
3617 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
3618 infoPtr->hFont = CreateFontIndirectA (&logFont);
3620 if (dwStyle & TBSTYLE_TOOLTIPS) {
3621 /* Create tooltip control */
3622 infoPtr->hwndToolTip =
3623 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
3624 CW_USEDEFAULT, CW_USEDEFAULT,
3625 CW_USEDEFAULT, CW_USEDEFAULT,
3628 /* Send NM_TOOLTIPSCREATED notification */
3629 if (infoPtr->hwndToolTip) {
3630 NMTOOLTIPSCREATED nmttc;
3632 nmttc.hdr.hwndFrom = hwnd;
3633 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3634 nmttc.hdr.code = NM_TOOLTIPSCREATED;
3635 nmttc.hwndToolTips = infoPtr->hwndToolTip;
3637 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3638 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
3646 TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
3648 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3650 /* delete tooltip control */
3651 if (infoPtr->hwndToolTip)
3652 DestroyWindow (infoPtr->hwndToolTip);
3654 /* delete button data */
3655 if (infoPtr->buttons)
3656 COMCTL32_Free (infoPtr->buttons);
3658 /* delete strings */
3659 if (infoPtr->strings) {
3661 for (i = 0; i < infoPtr->nNumStrings; i++)
3662 if (infoPtr->strings[i])
3663 COMCTL32_Free (infoPtr->strings[i]);
3665 COMCTL32_Free (infoPtr->strings);
3668 /* destroy internal image list */
3669 if (infoPtr->himlInt)
3670 ImageList_Destroy (infoPtr->himlInt);
3672 /* delete default font */
3674 DeleteObject (infoPtr->hFont);
3676 /* free toolbar info data */
3677 COMCTL32_Free (infoPtr);
3678 SetWindowLongA (hwnd, 0, 0);
3685 TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
3687 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3689 if (infoPtr->bTransparent)
3690 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
3692 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
3697 TOOLBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
3699 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3701 return infoPtr->hFont;
3706 TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
3708 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3709 TBUTTON_INFO *btnPtr;
3713 pt.x = (INT)LOWORD(lParam);
3714 pt.y = (INT)HIWORD(lParam);
3715 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3718 btnPtr = &infoPtr->buttons[nHit];
3719 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3722 infoPtr->bCaptured = TRUE;
3723 infoPtr->nButtonDown = nHit;
3725 btnPtr->fsState |= TBSTATE_PRESSED;
3727 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3730 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
3731 TOOLBAR_Customize (hwnd);
3738 TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
3740 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3741 TBUTTON_INFO *btnPtr;
3745 if (infoPtr->hwndToolTip)
3746 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3747 WM_LBUTTONDOWN, wParam, lParam);
3749 pt.x = (INT)LOWORD(lParam);
3750 pt.y = (INT)HIWORD(lParam);
3751 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3755 btnPtr = &infoPtr->buttons[nHit];
3756 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3760 infoPtr->bCaptured = TRUE;
3761 infoPtr->nButtonDown = nHit;
3762 infoPtr->nOldHit = nHit;
3764 btnPtr->fsState |= TBSTATE_PRESSED;
3765 btnPtr->bHot = FALSE;
3767 CopyRect(&arrowRect, &btnPtr->rect);
3768 arrowRect.left = max(btnPtr->rect.left, btnPtr->rect.right - DDARROW_WIDTH);
3770 /* for EX_DRAWDDARROWS style, click must be in the drop-down arrow rect */
3771 if ((btnPtr->fsStyle & TBSTYLE_DROPDOWN) &&
3772 !(TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) && !PtInRect(&arrowRect, pt)))
3776 * this time we must force a Redraw, so the btn is
3777 * painted down before CaptureChanged repaints it up
3779 RedrawWindow(hwnd,&btnPtr->rect,0,
3780 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3782 nmtb.hdr.hwndFrom = hwnd;
3783 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3784 nmtb.hdr.code = TBN_DROPDOWN;
3785 nmtb.iItem = btnPtr->idCommand;
3787 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3788 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3791 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3799 TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
3801 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3802 TBUTTON_INFO *btnPtr;
3806 BOOL bSendMessage = TRUE;
3808 if (infoPtr->hwndToolTip)
3809 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3810 WM_LBUTTONUP, wParam, lParam);
3812 pt.x = (INT)LOWORD(lParam);
3813 pt.y = (INT)HIWORD(lParam);
3814 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3816 /* restore hot effect to hot button disabled by TOOLBAR_LButtonDown() */
3817 /* if the cursor is still inside of the toolbar */
3818 if((infoPtr->nHotItem >= 0) && (nHit != -1))
3819 infoPtr->buttons[infoPtr->nHotItem].bHot = TRUE;
3821 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
3822 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3823 btnPtr->fsState &= ~TBSTATE_PRESSED;
3825 if (nHit == infoPtr->nButtonDown) {
3826 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
3827 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
3828 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
3829 infoPtr->nButtonDown);
3830 if (nOldIndex == infoPtr->nButtonDown)
3831 bSendMessage = FALSE;
3832 if ((nOldIndex != infoPtr->nButtonDown) &&
3834 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
3835 btnPtr->fsState |= TBSTATE_CHECKED;
3838 if (btnPtr->fsState & TBSTATE_CHECKED)
3839 btnPtr->fsState &= ~TBSTATE_CHECKED;
3841 btnPtr->fsState |= TBSTATE_CHECKED;
3846 bSendMessage = FALSE;
3848 if (nOldIndex != -1)
3850 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
3851 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
3855 * now we can ReleaseCapture, which triggers CAPTURECHANGED msg,
3856 * that resets bCaptured and btn TBSTATE_PRESSED flags,
3857 * and obliterates nButtonDown and nOldHit (see TOOLBAR_CaptureChanged)
3862 SendMessageA (GetParent(hwnd), WM_COMMAND,
3863 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
3870 TOOLBAR_CaptureChanged(HWND hwnd)
3872 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3873 TBUTTON_INFO *btnPtr;
3875 infoPtr->bCaptured = FALSE;
3877 if (infoPtr->nButtonDown >= 0)
3879 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3880 btnPtr->fsState &= ~TBSTATE_PRESSED;
3882 infoPtr->nButtonDown = -1;
3883 infoPtr->nOldHit = -1;
3885 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3892 TOOLBAR_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam)
3894 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3895 TBUTTON_INFO *hotBtnPtr, *btnPtr;
3897 if (infoPtr->nOldHit < 0)
3900 hotBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3902 /* Redraw the button if the last button we were over is the hot button and it
3904 if((infoPtr->nOldHit == infoPtr->nHotItem) && (hotBtnPtr->fsState & TBSTATE_ENABLED))
3906 hotBtnPtr->bHot = FALSE;
3908 InvalidateRect (hwnd, &hotBtnPtr->rect, TOOLBAR_HasText(infoPtr,
3912 /* If the last button we were over is depressed then make it not */
3913 /* depressed and redraw it */
3914 if(infoPtr->nOldHit == infoPtr->nButtonDown)
3916 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3918 btnPtr->fsState &= ~TBSTATE_PRESSED;
3920 InvalidateRect (hwnd, &(btnPtr->rect), TRUE);
3923 infoPtr->nOldHit = -1; /* reset the old hit index as we've left the toolbar */
3924 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3930 TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
3932 TBUTTON_INFO *btnPtr, *oldBtnPtr;
3933 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3936 TRACKMOUSEEVENT trackinfo;
3938 /* fill in the TRACKMOUSEEVENT struct */
3939 trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
3940 trackinfo.dwFlags = TME_QUERY;
3941 trackinfo.hwndTrack = hwnd;
3942 trackinfo.dwHoverTime = HOVER_DEFAULT;
3944 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
3945 _TrackMouseEvent(&trackinfo);
3947 /* Make sure tracking is enabled so we recieve a WM_MOUSELEAVE message */
3948 if(!(trackinfo.dwFlags & TME_LEAVE)) {
3949 trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
3951 /* call TRACKMOUSEEVENT so we recieve a WM_MOUSELEAVE message */
3952 /* and can properly deactivate the hot toolbar button */
3953 _TrackMouseEvent(&trackinfo);
3956 if (infoPtr->hwndToolTip)
3957 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3958 WM_MOUSEMOVE, wParam, lParam);
3960 pt.x = (INT)LOWORD(lParam);
3961 pt.y = (INT)HIWORD(lParam);
3963 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3965 if (infoPtr->nOldHit != nHit)
3967 /* Remove the effect of an old hot button if the button was enabled and was
3968 drawn with the hot button effect */
3969 if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem &&
3970 (infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED))
3972 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3973 oldBtnPtr->bHot = FALSE;
3975 InvalidateRect (hwnd, &oldBtnPtr->rect,
3976 TOOLBAR_HasText(infoPtr, oldBtnPtr));
3979 /* It's not a separator or in nowhere. It's a hot button. */
3982 btnPtr = &infoPtr->buttons[nHit];
3983 btnPtr->bHot = TRUE;
3985 infoPtr->nHotItem = nHit;
3987 /* only enabled buttons show hot effect */
3988 if(infoPtr->buttons[nHit].fsState & TBSTATE_ENABLED)
3990 InvalidateRect(hwnd, &btnPtr->rect,
3991 TOOLBAR_HasText(infoPtr, btnPtr));
3996 if (infoPtr->bCaptured) {
3997 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3998 if (infoPtr->nOldHit == infoPtr->nButtonDown) {
3999 btnPtr->fsState &= ~TBSTATE_PRESSED;
4000 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
4002 else if (nHit == infoPtr->nButtonDown) {
4003 btnPtr->fsState |= TBSTATE_PRESSED;
4004 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
4007 infoPtr->nOldHit = nHit;
4013 inline static LRESULT
4014 TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
4016 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
4017 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
4019 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
4023 inline static LRESULT
4024 TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
4026 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
4027 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
4029 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
4034 TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
4036 TOOLBAR_INFO *infoPtr;
4038 /* allocate memory for info structure */
4039 infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
4040 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
4043 infoPtr->dwStructSize = sizeof(TBBUTTON);
4045 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
4046 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
4047 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
4048 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
4051 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
4056 TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
4058 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
4062 if (dwStyle & WS_MINIMIZE)
4063 return 0; /* Nothing to do */
4065 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
4067 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
4070 if (!(dwStyle & CCS_NODIVIDER))
4072 GetWindowRect (hwnd, &rcWindow);
4073 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
4074 if( dwStyle & WS_BORDER )
4075 OffsetRect (&rcWindow, 1, 1);
4076 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
4079 ReleaseDC( hwnd, hdc );
4085 inline static LRESULT
4086 TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
4088 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4089 LPNMHDR lpnmh = (LPNMHDR)lParam;
4091 TRACE("passing WM_NOTIFY!\n");
4093 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
4094 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
4097 if (lpnmh->code == TTN_GETDISPINFOA) {
4098 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
4100 FIXME("retrieving ASCII string\n");
4103 else if (lpnmh->code == TTN_GETDISPINFOW) {
4104 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
4106 FIXME("retrieving UNICODE string\n");
4117 TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
4119 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
4125 TOOLBAR_CalcToolbar( hwnd );
4127 /* fill ps.rcPaint with a default rect */
4128 memcpy(&(ps.rcPaint), &(infoPtr->rcBound), sizeof(infoPtr->rcBound));
4130 hdc = wParam==0 ? BeginPaint(hwnd, &ps) : (HDC)wParam;
4131 TOOLBAR_Refresh (hwnd, hdc, &ps);
4132 if (!wParam) EndPaint (hwnd, &ps);
4139 TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
4141 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4142 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
4151 /* Resize deadlock check */
4152 if (infoPtr->bAutoSize) {
4153 infoPtr->bAutoSize = FALSE;
4157 /* FIXME: optimize to only update size if the new size doesn't */
4158 /* match the current size */
4160 flags = (INT) wParam;
4162 /* FIXME for flags =
4163 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
4166 TRACE("sizing toolbar!\n");
4168 if (flags == SIZE_RESTORED) {
4169 /* width and height don't apply */
4170 parent = GetParent (hwnd);
4171 GetClientRect(parent, &parent_rect);
4172 x = parent_rect.left;
4173 y = parent_rect.top;
4175 if (dwStyle & CCS_NORESIZE) {
4176 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
4179 * this sets the working width of the toolbar, and
4180 * Calc Toolbar will not adjust it, only the height
4182 infoPtr->nWidth = parent_rect.right - parent_rect.left;
4183 cy = infoPtr->nHeight;
4184 cx = infoPtr->nWidth;
4185 TOOLBAR_CalcToolbar (hwnd);
4186 infoPtr->nWidth = cx;
4187 infoPtr->nHeight = cy;
4190 infoPtr->nWidth = parent_rect.right - parent_rect.left;
4191 TOOLBAR_CalcToolbar (hwnd);
4192 cy = infoPtr->nHeight;
4193 cx = infoPtr->nWidth;
4195 if (dwStyle & CCS_NOMOVEY) {
4196 GetWindowRect(hwnd, &window_rect);
4197 ScreenToClient(parent, (LPPOINT)&window_rect.left);
4198 y = window_rect.top;
4202 if (dwStyle & CCS_NOPARENTALIGN) {
4203 uPosFlags |= SWP_NOMOVE;
4204 cy = infoPtr->nHeight;
4205 cx = infoPtr->nWidth;
4208 if (!(dwStyle & CCS_NODIVIDER))
4209 cy += GetSystemMetrics(SM_CYEDGE);
4211 if (dwStyle & WS_BORDER)
4214 cy += GetSystemMetrics(SM_CYEDGE);
4215 cx += GetSystemMetrics(SM_CYEDGE);
4218 SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
4219 cx, cy, uPosFlags | SWP_NOZORDER);
4226 TOOLBAR_StyleChanged (HWND hwnd, INT nType, LPSTYLESTRUCT lpStyle)
4228 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4230 if (nType == GWL_STYLE) {
4231 if (lpStyle->styleNew & TBSTYLE_LIST) {
4232 infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
4235 infoPtr->dwDTFlags = DT_CENTER;
4239 TOOLBAR_AutoSize (hwnd);
4241 InvalidateRect(hwnd, NULL, FALSE);
4248 static LRESULT WINAPI
4249 ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
4255 return TOOLBAR_Destroy (hwnd, wParam, lParam);
4258 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
4261 if (!TOOLBAR_GetInfoPtr (hwnd))
4263 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
4269 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
4271 case TB_ADDBUTTONSA:
4272 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
4274 case TB_ADDBUTTONSW:
4275 return TOOLBAR_AddButtonsW (hwnd, wParam, lParam);
4278 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
4281 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
4284 return TOOLBAR_AutoSize (hwnd);
4286 case TB_BUTTONCOUNT:
4287 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
4289 case TB_BUTTONSTRUCTSIZE:
4290 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
4292 case TB_CHANGEBITMAP:
4293 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
4295 case TB_CHECKBUTTON:
4296 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
4298 case TB_COMMANDTOINDEX:
4299 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
4302 return TOOLBAR_Customize (hwnd);
4304 case TB_DELETEBUTTON:
4305 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
4307 case TB_ENABLEBUTTON:
4308 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
4310 case TB_GETANCHORHIGHLIGHT:
4311 return TOOLBAR_GetAnchorHighlight (hwnd);
4314 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
4316 case TB_GETBITMAPFLAGS:
4317 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
4320 return TOOLBAR_GetButton (hwnd, wParam, lParam);
4322 case TB_GETBUTTONINFOA:
4323 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
4325 case TB_GETBUTTONINFOW:
4326 return TOOLBAR_GetButtonInfoW (hwnd, wParam, lParam);
4328 case TB_GETBUTTONSIZE:
4329 return TOOLBAR_GetButtonSize (hwnd);
4331 case TB_GETBUTTONTEXTA:
4332 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
4334 case TB_GETBUTTONTEXTW:
4335 return TOOLBAR_GetButtonTextW (hwnd, wParam, lParam);
4337 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
4339 case TB_GETDISABLEDIMAGELIST:
4340 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
4342 case TB_GETEXTENDEDSTYLE:
4343 return TOOLBAR_GetExtendedStyle (hwnd);
4345 case TB_GETHOTIMAGELIST:
4346 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
4349 return TOOLBAR_GetHotItem (hwnd);
4351 case TB_GETIMAGELIST:
4352 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
4354 /* case TB_GETINSERTMARK: */ /* 4.71 */
4355 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
4357 case TB_GETITEMRECT:
4358 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
4361 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
4363 /* case TB_GETOBJECT: */ /* 4.71 */
4364 /* case TB_GETPADDING: */ /* 4.71 */
4367 return TOOLBAR_GetRect (hwnd, wParam, lParam);
4370 return TOOLBAR_GetRows (hwnd, wParam, lParam);
4373 return TOOLBAR_GetState (hwnd, wParam, lParam);
4376 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
4378 case TB_GETTEXTROWS:
4379 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
4381 case TB_GETTOOLTIPS:
4382 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
4384 case TB_GETUNICODEFORMAT:
4385 return TOOLBAR_GetUnicodeFormat (hwnd, wParam, lParam);
4387 case CCM_GETVERSION:
4388 return TOOLBAR_GetVersion (hwnd);
4391 return TOOLBAR_HideButton (hwnd, wParam, lParam);
4394 return TOOLBAR_HitTest (hwnd, wParam, lParam);
4396 case TB_INDETERMINATE:
4397 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
4399 case TB_INSERTBUTTONA:
4400 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
4402 case TB_INSERTBUTTONW:
4403 return TOOLBAR_InsertButtonW (hwnd, wParam, lParam);
4405 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
4407 case TB_ISBUTTONCHECKED:
4408 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
4410 case TB_ISBUTTONENABLED:
4411 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
4413 case TB_ISBUTTONHIDDEN:
4414 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
4416 case TB_ISBUTTONHIGHLIGHTED:
4417 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
4419 case TB_ISBUTTONINDETERMINATE:
4420 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
4422 case TB_ISBUTTONPRESSED:
4423 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
4425 case TB_LOADIMAGES: /* 4.70 */
4426 FIXME("missing standard imagelists\n");
4429 /* case TB_MAPACCELERATORA: */ /* 4.71 */
4430 /* case TB_MAPACCELERATORW: */ /* 4.71 */
4431 /* case TB_MARKBUTTON: */ /* 4.71 */
4432 /* case TB_MOVEBUTTON: */ /* 4.71 */
4434 case TB_PRESSBUTTON:
4435 return TOOLBAR_PressButton (hwnd, wParam, lParam);
4437 /* case TB_REPLACEBITMAP: */
4439 case TB_SAVERESTOREA:
4440 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
4442 case TB_SAVERESTOREW:
4443 return TOOLBAR_SaveRestoreW (hwnd, wParam, lParam);
4445 case TB_SETANCHORHIGHLIGHT:
4446 return TOOLBAR_SetAnchorHighlight (hwnd, wParam);
4448 case TB_SETBITMAPSIZE:
4449 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
4451 case TB_SETBUTTONINFOA:
4452 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
4454 case TB_SETBUTTONINFOW:
4455 return TOOLBAR_SetButtonInfoW (hwnd, wParam, lParam);
4457 case TB_SETBUTTONSIZE:
4458 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
4460 case TB_SETBUTTONWIDTH:
4461 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
4464 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
4466 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
4468 case TB_SETDISABLEDIMAGELIST:
4469 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
4471 case TB_SETDRAWTEXTFLAGS:
4472 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
4474 case TB_SETEXTENDEDSTYLE:
4475 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
4477 case TB_SETHOTIMAGELIST:
4478 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
4481 return TOOLBAR_SetHotItem (hwnd, wParam);
4483 case TB_SETIMAGELIST:
4484 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
4487 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
4489 /* case TB_SETINSERTMARK: */ /* 4.71 */
4491 case TB_SETINSERTMARKCOLOR:
4492 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
4494 case TB_SETMAXTEXTROWS:
4495 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
4497 /* case TB_SETPADDING: */ /* 4.71 */
4500 return TOOLBAR_SetParent (hwnd, wParam, lParam);
4503 return TOOLBAR_SetRows (hwnd, wParam, lParam);
4506 return TOOLBAR_SetState (hwnd, wParam, lParam);
4509 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
4511 case TB_SETTOOLTIPS:
4512 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
4514 case TB_SETUNICODEFORMAT:
4515 return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
4517 case CCM_SETVERSION:
4518 return TOOLBAR_SetVersion (hwnd, (INT)wParam);
4524 return TOOLBAR_Create (hwnd, wParam, lParam);
4527 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
4530 return TOOLBAR_GetFont (hwnd, wParam, lParam);
4532 /* case WM_KEYDOWN: */
4533 /* case WM_KILLFOCUS: */
4535 case WM_LBUTTONDBLCLK:
4536 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
4538 case WM_LBUTTONDOWN:
4539 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
4542 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
4545 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
4548 return TOOLBAR_MouseLeave (hwnd, wParam, lParam);
4550 case WM_CAPTURECHANGED:
4551 return TOOLBAR_CaptureChanged(hwnd);
4554 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
4557 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
4560 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
4563 return TOOLBAR_Notify (hwnd, wParam, lParam);
4565 /* case WM_NOTIFYFORMAT: */
4568 return TOOLBAR_Paint (hwnd, wParam);
4571 return TOOLBAR_Size (hwnd, wParam, lParam);
4573 case WM_STYLECHANGED:
4574 return TOOLBAR_StyleChanged (hwnd, (INT)wParam, (LPSTYLESTRUCT)lParam);
4576 /* case WM_SYSCOLORCHANGE: */
4578 /* case WM_WININICHANGE: */
4583 case WM_MEASUREITEM:
4585 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
4588 if (uMsg >= WM_USER)
4589 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
4590 uMsg, wParam, lParam);
4591 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
4598 TOOLBAR_Register (void)
4602 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
4603 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
4604 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
4605 wndClass.cbClsExtra = 0;
4606 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
4607 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
4608 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
4609 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
4611 RegisterClassA (&wndClass);
4616 TOOLBAR_Unregister (void)
4618 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);