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"
45 #include "wine/winestring.h"
47 #include "imagelist.h"
49 #include "debugtools.h"
51 DEFAULT_DEBUG_CHANNEL(toolbar);
69 DWORD dwStructSize; /* size of TBBUTTON struct */
70 INT nHeight; /* height of the toolbar */
71 INT nWidth; /* width of the toolbar */
77 INT nRows; /* number of button rows */
78 INT nMaxTextRows; /* maximum number of text rows */
79 INT cxMin; /* minimum button width */
80 INT cxMax; /* maximum button width */
81 INT nNumButtons; /* number of buttons */
82 INT nNumBitmaps; /* number of bitmaps */
83 INT nNumStrings; /* number of strings */
84 BOOL bUnicode; /* ASCII (FALSE) or Unicode (TRUE)? */
85 BOOL bCaptured; /* mouse captured? */
88 INT nHotItem; /* index of the "hot" item */
89 HFONT hFont; /* text font */
90 HIMAGELIST himlInt; /* image list created internally */
91 HIMAGELIST himlDef; /* default image list */
92 HIMAGELIST himlHot; /* hot image list */
93 HIMAGELIST himlDis; /* disabled image list */
94 HWND hwndToolTip; /* handle to tool tip control */
95 HWND hwndNotify; /* handle to the window that gets notifications */
96 BOOL bTransparent; /* background transparency flag */
97 BOOL bAutoSize; /* auto size deadlock indicator */
98 BOOL bAnchor; /* anchor highlight enabled */
99 DWORD dwExStyle; /* extended toolbar style */
100 DWORD dwDTFlags; /* DrawText flags */
102 COLORREF clrInsertMark; /* insert mark color */
103 RECT rcBound; /* bounding rectangle */
106 TBUTTON_INFO *buttons; /* pointer to button array */
107 LPWSTR *strings; /* pointer to string array */
108 } TOOLBAR_INFO, *PTOOLBAR_INFO;
111 /* used by customization dialog */
114 PTOOLBAR_INFO tbInfo;
116 } CUSTDLG_INFO, *PCUSTDLG_INFO;
124 } CUSTOMBUTTON, *PCUSTOMBUTTON;
127 #define SEPARATOR_WIDTH 8
129 #define BOTTOM_BORDER 2
130 #define DDARROW_WIDTH 11
132 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
133 #define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE)
134 #define TOOLBAR_HasDropDownArrows(exStyle) ((exStyle & TBSTYLE_EX_DRAWDDARROWS) ? TRUE : FALSE)
137 TOOLBAR_GetText(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr)
139 LPWSTR lpText = NULL;
141 /* FIXME: iString == -1 is undocumented */
142 if ((HIWORD(btnPtr->iString) != 0) && (btnPtr->iString != -1))
143 lpText = (LPWSTR)btnPtr->iString;
144 else if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
145 lpText = infoPtr->strings[btnPtr->iString];
151 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index)
153 if ((index>=0) && (index < infoPtr->nNumBitmaps))
161 TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
163 INT x = (lpRect->left + lpRect->right) / 2 - 1;
164 INT yBottom = lpRect->bottom - 3;
165 INT yTop = lpRect->top + 1;
167 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
168 MoveToEx (hdc, x, yBottom, NULL);
169 LineTo (hdc, x, yTop);
171 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
172 MoveToEx (hdc, x, yBottom, NULL);
173 LineTo (hdc, x, yTop);
177 TOOLBAR_DrawArrow (HDC hdc, INT left, INT top, INT colorRef)
180 SelectObject ( hdc, GetSysColorPen (colorRef));
183 MoveToEx (hdc, x, y, NULL);
184 LineTo (hdc, x+5, y++); x++;
185 MoveToEx (hdc, x, y, NULL);
186 LineTo (hdc, x+3, y++); x++;
187 MoveToEx (hdc, x, y, NULL);
188 LineTo (hdc, x+1, y++);
192 * Draw the text string for this button.
193 * note: infoPtr->himlDis *SHOULD* be non-zero when infoPtr->himlDef
194 * is non-zero, so we can simply check himlDef to see if we have
198 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
199 HDC hdc, INT nState, DWORD dwStyle)
201 RECT rcText = btnPtr->rect;
205 LPWSTR lpText = NULL;
206 HIMAGELIST himl = infoPtr->himlDef;
208 TRACE ("iString: %x\n", btnPtr->iString);
210 /* get a pointer to the text */
211 lpText = TOOLBAR_GetText(infoPtr, btnPtr);
213 TRACE ("lpText: \"%s\"\n", debugstr_w(lpText));
218 InflateRect (&rcText, -3, -3);
220 if (himl && TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
221 if ((dwStyle & TBSTYLE_LIST) &&
222 ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
223 (btnPtr->iBitmap != I_IMAGENONE)) {
224 rcText.left += infoPtr->nBitmapWidth;
227 rcText.top += infoPtr->nBitmapHeight;
231 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
232 OffsetRect (&rcText, 1, 1);
234 hOldFont = SelectObject (hdc, infoPtr->hFont);
235 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
236 if (!(nState & TBSTATE_ENABLED)) {
237 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
238 OffsetRect (&rcText, 1, 1);
239 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
240 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
241 OffsetRect (&rcText, -1, -1);
242 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
244 else if (nState & TBSTATE_INDETERMINATE) {
245 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
246 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
249 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
250 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
253 SetTextColor (hdc, clrOld);
254 SelectObject (hdc, hOldFont);
255 if (nOldBkMode != TRANSPARENT)
256 SetBkMode (hdc, nOldBkMode);
262 TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
264 HBRUSH hbr = SelectObject (hdc, COMCTL32_hPattern55AABrush);
265 INT cx = lpRect->right - lpRect->left;
266 INT cy = lpRect->bottom - lpRect->top;
267 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
268 SelectObject (hdc, hbr);
273 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
274 HDC hdc, INT x, INT y)
276 /* FIXME: this function is a hack since it uses image list
277 internals directly */
279 HIMAGELIST himl = infoPtr->himlDef;
287 /* create new dc's */
288 hdcImageList = CreateCompatibleDC (0);
289 hdcMask = CreateCompatibleDC (0);
291 /* create new bitmap */
292 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
293 SelectObject (hdcMask, hbmMask);
295 /* copy the mask bitmap */
296 SelectObject (hdcImageList, himl->hbmMask);
297 SetBkColor (hdcImageList, RGB(255, 255, 255));
298 SetTextColor (hdcImageList, RGB(0, 0, 0));
299 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
300 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
302 /* draw the new mask */
303 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
304 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
305 hdcMask, 0, 0, 0xB8074A);
307 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
308 BitBlt (hdc, x, y, himl->cx, himl->cy,
309 hdcMask, 0, 0, 0xB8074A);
311 DeleteObject (hbmMask);
313 DeleteDC (hdcImageList);
318 TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
320 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
321 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
322 BOOL hasDropDownArrow = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) &&
323 (btnPtr->fsStyle & TBSTYLE_DROPDOWN);
324 RECT rc, rcArrow, rcBitmap;
326 if (btnPtr->fsState & TBSTATE_HIDDEN)
330 CopyRect (&rcArrow, &rc);
331 CopyRect(&rcBitmap, &rc);
333 FillRect( hdc, &rc, GetSysColorBrush(COLOR_BTNFACE));
335 if (hasDropDownArrow)
337 if (dwStyle & TBSTYLE_FLAT)
338 rc.right = max(rc.left, rc.right - DDARROW_WIDTH);
340 rc.right = max(rc.left, rc.right - DDARROW_WIDTH - 2);
341 rcArrow.left = rc.right;
344 /* Center the bitmap horizontally and vertically */
345 rcBitmap.left+=(infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2;
347 if(TOOLBAR_HasText(infoPtr, btnPtr))
348 rcBitmap.top+=2; /* this looks to be the correct value from vmware comparison - cmm */
350 rcBitmap.top+=(infoPtr->nButtonHeight - infoPtr->nBitmapHeight) / 2;
352 TRACE("iBitmap: %d\n", btnPtr->iBitmap);
355 if (btnPtr->fsStyle & TBSTYLE_SEP) {
356 /* with the FLAT style, iBitmap is the width and has already */
357 /* been taken into consideration in calculating the width */
358 /* so now we need to draw the vertical separator */
359 /* empirical tests show that iBitmap can/will be non-zero */
360 /* when drawing the vertical bar... */
361 if ((dwStyle & TBSTYLE_FLAT) /* && (btnPtr->iBitmap == 0) */)
362 TOOLBAR_DrawFlatSeparator (&rc, hdc);
367 if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
368 if (!(dwStyle & TBSTYLE_FLAT))
370 DrawEdge (hdc, &rc, EDGE_RAISED,
371 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
372 if (hasDropDownArrow)
373 DrawEdge (hdc, &rcArrow, EDGE_RAISED,
374 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
377 if (hasDropDownArrow)
379 TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top+1, COLOR_3DHIGHLIGHT);
380 TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_3DSHADOW);
383 if (infoPtr->himlDis &&
384 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
385 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
386 rcBitmap.left, rcBitmap.top, ILD_NORMAL);
388 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
390 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
394 /* pressed TBSTYLE_BUTTON */
395 if (btnPtr->fsState & TBSTATE_PRESSED) {
396 if (dwStyle & TBSTYLE_FLAT)
398 DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
399 if (hasDropDownArrow)
400 DrawEdge (hdc, &rcArrow, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
404 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
405 if (hasDropDownArrow)
406 DrawEdge (hdc, &rcArrow, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
409 if (hasDropDownArrow)
410 TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
412 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
413 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
414 rcBitmap.left + 1, rcBitmap.top + 1, ILD_NORMAL);
416 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
420 /* checked TBSTYLE_CHECK */
421 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
422 (btnPtr->fsState & TBSTATE_CHECKED)) {
423 if (dwStyle & TBSTYLE_FLAT)
424 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
425 BF_RECT | BF_MIDDLE | BF_ADJUST);
427 DrawEdge (hdc, &rc, EDGE_SUNKEN,
428 BF_RECT | BF_MIDDLE | BF_ADJUST);
430 TOOLBAR_DrawPattern (hdc, &rc);
432 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
433 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
434 rcBitmap.left + 1, rcBitmap.top + 1, ILD_NORMAL);
435 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
440 if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
441 DrawEdge (hdc, &rc, EDGE_RAISED,
442 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
444 TOOLBAR_DrawPattern (hdc, &rc);
445 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
446 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
451 if (dwStyle & TBSTYLE_FLAT)
455 DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
456 if (hasDropDownArrow)
457 DrawEdge (hdc, &rcArrow, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
461 FrameRect(hdc, &rc, GetSysColorBrush(COLOR_BTNFACE));
462 if (hasDropDownArrow)
463 FrameRect(hdc, &rcArrow, GetSysColorBrush(COLOR_BTNFACE));
466 if (hasDropDownArrow)
467 TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top, COLOR_WINDOWFRAME);
469 if (btnPtr->bHot && infoPtr->himlHot &&
470 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
471 ImageList_Draw (infoPtr->himlHot, btnPtr->iBitmap, hdc,
472 rcBitmap.left, rcBitmap.top, ILD_NORMAL);
473 else if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
474 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
475 rcBitmap.left, rcBitmap.top, ILD_NORMAL);
479 DrawEdge (hdc, &rc, EDGE_RAISED,
480 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
482 if (hasDropDownArrow)
484 DrawEdge (hdc, &rcArrow, EDGE_RAISED,
485 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
486 TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
489 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
490 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
491 rcBitmap.left, rcBitmap.top, ILD_NORMAL);
494 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
499 TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
501 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
502 TBUTTON_INFO *btnPtr;
506 /* redraw necessary buttons */
507 btnPtr = infoPtr->buttons;
508 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
510 if(IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect)))
511 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
516 TOOLBAR_MeasureString(HWND hwnd, INT index, LPSIZE lpSize)
518 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
519 TBUTTON_INFO *btnPtr;
526 hOldFont = SelectObject (hdc, infoPtr->hFont);
528 btnPtr = &infoPtr->buttons[index];
530 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
531 (btnPtr->iString > -1) &&
532 (btnPtr->iString < infoPtr->nNumStrings))
534 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
535 GetTextExtentPoint32W (hdc, lpText, lstrlenW (lpText), lpSize);
538 SelectObject (hdc, hOldFont);
541 TRACE("string size %ld x %ld!\n", lpSize->cx, lpSize->cy);
545 TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
547 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
548 TBUTTON_INFO *btnPtr;
556 btnPtr = infoPtr->buttons;
557 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
558 if(TOOLBAR_HasText(infoPtr, btnPtr))
560 TOOLBAR_MeasureString(hwnd,i,&sz);
561 if (sz.cx > lpSize->cx)
563 if (sz.cy > lpSize->cy)
568 TRACE("string size %ld x %ld!\n", lpSize->cx, lpSize->cy);
571 /***********************************************************************
572 * TOOLBAR_WrapToolbar
574 * This function walks through the buttons and seperators in the
575 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
576 * wrapping should occur based on the width of the toolbar window.
577 * It does *not* calculate button placement itself. That task
578 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
579 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
580 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
584 TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
586 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
587 TBUTTON_INFO *btnPtr;
590 BOOL bWrap, bButtonWrap;
592 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
593 /* no layout is necessary. Applications may use this style */
594 /* to perform their own layout on the toolbar. */
595 if( !(dwStyle & TBSTYLE_WRAPABLE) )
598 btnPtr = infoPtr->buttons;
599 x = infoPtr->nIndent;
601 /* this can get the parents width, to know how far we can extend
602 * this toolbar. We cannot use its height, as there may be multiple
603 * toolbars in a rebar control
605 GetClientRect( GetParent(hwnd), &rc );
606 infoPtr->nWidth = rc.right - rc.left;
609 for (i = 0; i < infoPtr->nNumButtons; i++ )
612 btnPtr[i].fsState &= ~TBSTATE_WRAP;
614 if (btnPtr[i].fsState & TBSTATE_HIDDEN)
617 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
618 /* it is the actual width of the separator. This is used for */
619 /* custom controls in toolbars. */
620 if (btnPtr[i].fsStyle & TBSTYLE_SEP)
621 cx = (btnPtr[i].iBitmap > 0) ?
622 btnPtr[i].iBitmap : SEPARATOR_WIDTH;
624 cx = infoPtr->nButtonWidth;
626 /* Two or more adjacent separators form a separator group. */
627 /* The first separator in a group should be wrapped to the */
628 /* next row if the previous wrapping is on a button. */
630 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
631 (i + 1 < infoPtr->nNumButtons ) &&
632 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
634 btnPtr[i].fsState |= TBSTATE_WRAP;
635 x = infoPtr->nIndent;
641 /* The layout makes sure the bitmap is visible, but not the button. */
642 if ( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
647 /* If the current button is a separator and not hidden, */
648 /* go to the next until it reaches a non separator. */
649 /* Wrap the last separator if it is before a button. */
650 while( ( (btnPtr[i].fsStyle & TBSTYLE_SEP) ||
651 (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
652 i < infoPtr->nNumButtons )
658 if( bFound && i < infoPtr->nNumButtons )
661 btnPtr[i].fsState |= TBSTATE_WRAP;
662 x = infoPtr->nIndent;
666 else if ( i >= infoPtr->nNumButtons)
669 /* If the current button is not a separator, find the last */
670 /* separator and wrap it. */
671 for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
673 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
674 !(btnPtr[j].fsState & TBSTATE_HIDDEN))
678 x = infoPtr->nIndent;
679 btnPtr[j].fsState |= TBSTATE_WRAP;
685 /* If no separator available for wrapping, wrap one of */
686 /* non-hidden previous button. */
690 j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
692 if (btnPtr[j].fsState & TBSTATE_HIDDEN)
697 x = infoPtr->nIndent;
698 btnPtr[j].fsState |= TBSTATE_WRAP;
704 /* If all above failed, wrap the current button. */
707 btnPtr[i].fsState |= TBSTATE_WRAP;
709 x = infoPtr->nIndent;
710 if (btnPtr[i].fsState & TBSTYLE_SEP )
722 /***********************************************************************
723 * TOOLBAR_CalcToolbar
725 * This function calculates button and separator placement. It first
726 * calculates the button sizes, gets the toolbar window width and then
727 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
728 * on. It assigns a new location to each item and sends this location to
729 * the tooltip window if appropriate. Finally, it updates the rcBound
730 * rect and calculates the new required toolbar window height.
734 TOOLBAR_CalcToolbar (HWND hwnd)
736 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
737 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
738 TBUTTON_INFO *btnPtr;
739 INT i, nRows, nSepRows;
743 BOOL usesBitmaps = FALSE;
744 BOOL hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle);
746 TOOLBAR_CalcStrings (hwnd, &sizeString);
748 if (dwStyle & TBSTYLE_LIST)
750 infoPtr->nButtonHeight = max(infoPtr->nBitmapHeight, sizeString.cy) + 6;
751 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + sizeString.cx + 6;
754 for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
756 if (TOOLBAR_IsValidBitmapIndex(infoPtr,infoPtr->buttons[i].iBitmap))
760 if (sizeString.cy > 0)
763 infoPtr->nButtonHeight = sizeString.cy +
764 infoPtr->nBitmapHeight + 6;
766 infoPtr->nButtonHeight = sizeString.cy + 6;
768 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
769 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
771 if (sizeString.cx > infoPtr->nBitmapWidth)
772 infoPtr->nButtonWidth = sizeString.cx + 6;
773 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
774 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
777 if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin )
778 infoPtr->nButtonWidth = infoPtr->cxMin;
779 if ( infoPtr->cxMax >= 0 && infoPtr->nButtonWidth > infoPtr->cxMax )
780 infoPtr->nButtonWidth = infoPtr->cxMax;
782 TOOLBAR_WrapToolbar( hwnd, dwStyle );
784 x = infoPtr->nIndent;
785 y = (dwStyle & TBSTYLE_FLAT) ? 0 : TOP_BORDER;
788 * We will set the height below, and we set the width on entry
789 * so we do not reset them here..
792 GetClientRect( hwnd, &rc );
793 /* get initial values for toolbar */
794 infoPtr->nWidth = rc.right - rc.left;
795 infoPtr->nHeight = rc.bottom - rc.top;
798 /* from above, minimum is a button, and possible text */
799 cx = infoPtr->nButtonWidth;
801 /* cannot use just ButtonHeight, we may have no buttons! */
802 if (infoPtr->nNumButtons > 0)
803 infoPtr->nHeight = infoPtr->nButtonHeight;
805 cy = infoPtr->nHeight;
807 nRows = nSepRows = 0;
809 infoPtr->rcBound.top = y;
810 infoPtr->rcBound.left = x;
811 infoPtr->rcBound.bottom = y + cy;
812 infoPtr->rcBound.right = x;
814 btnPtr = infoPtr->buttons;
816 /* do not base height/width on parent, if the parent is a */
817 /* rebar control it could have multiple rows of toolbars */
818 /* GetClientRect( GetParent(hwnd), &rc ); */
819 /* cx = rc.right - rc.left; */
820 /* cy = rc.bottom - rc.top; */
822 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
825 if (btnPtr->fsState & TBSTATE_HIDDEN)
827 SetRectEmpty (&btnPtr->rect);
831 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
832 /* it is the actual width of the separator. This is used for */
833 /* custom controls in toolbars. */
834 if (btnPtr->fsStyle & TBSTYLE_SEP)
835 cx = (btnPtr->iBitmap > 0) ?
836 btnPtr->iBitmap : SEPARATOR_WIDTH;
839 if (btnPtr->fsStyle & TBSTYLE_AUTOSIZE)
842 TOOLBAR_MeasureString(hwnd,i,&sz);
846 cx = infoPtr->nButtonWidth;
848 if (hasDropDownArrows && (btnPtr->fsStyle & TBSTYLE_DROPDOWN))
851 cy = infoPtr->nHeight;
853 if (btnPtr->fsState & TBSTATE_WRAP )
856 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
858 if (infoPtr->rcBound.left > x)
859 infoPtr->rcBound.left = x;
860 if (infoPtr->rcBound.right < x + cx)
861 infoPtr->rcBound.right = x + cx;
862 if (infoPtr->rcBound.bottom < y + cy)
863 infoPtr->rcBound.bottom = y + cy;
865 /* Set the toolTip only for non-hidden, non-separator button */
866 if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP ))
870 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
871 ti.cbSize = sizeof(TTTOOLINFOA);
873 ti.uId = btnPtr->idCommand;
874 ti.rect = btnPtr->rect;
875 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
879 /* btnPtr->nRow is zero based. The space between the rows is */
880 /* also considered as a row. */
881 btnPtr->nRow = nRows + nSepRows;
884 if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
888 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
889 /* it is the actual width of the separator. This is used for */
890 /* custom controls in toolbars. */
891 y += cy + ( (btnPtr->iBitmap > 0 ) ?
892 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
894 /* nSepRows is used to calculate the extra height follwoing */
898 x = infoPtr->nIndent;
905 /* infoPtr->nRows is the number of rows on the toolbar */
906 infoPtr->nRows = nRows + nSepRows + 1;
908 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
910 infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
911 nSepRows * (SEPARATOR_WIDTH * 2 / 3) +
912 nSepRows * (infoPtr->nBitmapHeight + 1) +
914 TRACE("toolbar height %d, button width %d\n", infoPtr->nHeight, infoPtr->nButtonWidth);
919 TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
921 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
922 TBUTTON_INFO *btnPtr;
925 btnPtr = infoPtr->buttons;
926 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
927 if (btnPtr->fsState & TBSTATE_HIDDEN)
930 if (btnPtr->fsStyle & TBSTYLE_SEP) {
931 if (PtInRect (&btnPtr->rect, *lpPt)) {
932 TRACE(" ON SEPARATOR %d!\n", i);
937 if (PtInRect (&btnPtr->rect, *lpPt)) {
938 TRACE(" ON BUTTON %d!\n", i);
944 TRACE(" NOWHERE!\n");
950 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
952 TBUTTON_INFO *btnPtr;
955 btnPtr = infoPtr->buttons;
956 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
957 if (btnPtr->idCommand == idCommand) {
958 TRACE("command=%d index=%d\n", idCommand, i);
962 TRACE("no index found for command=%d\n", idCommand);
968 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
970 TBUTTON_INFO *btnPtr;
973 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
976 /* check index button */
977 btnPtr = &infoPtr->buttons[nIndex];
978 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
979 if (btnPtr->fsState & TBSTATE_CHECKED)
983 /* check previous buttons */
984 nRunIndex = nIndex - 1;
985 while (nRunIndex >= 0) {
986 btnPtr = &infoPtr->buttons[nRunIndex];
987 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
988 if (btnPtr->fsState & TBSTATE_CHECKED)
996 /* check next buttons */
997 nRunIndex = nIndex + 1;
998 while (nRunIndex < infoPtr->nNumButtons) {
999 btnPtr = &infoPtr->buttons[nRunIndex];
1000 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
1001 if (btnPtr->fsState & TBSTATE_CHECKED)
1014 TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
1015 WPARAM wParam, LPARAM lParam)
1021 msg.wParam = wParam;
1022 msg.lParam = lParam;
1023 msg.time = GetMessageTime ();
1024 msg.pt.x = LOWORD(GetMessagePos ());
1025 msg.pt.y = HIWORD(GetMessagePos ());
1027 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
1031 /***********************************************************************
1032 * TOOLBAR_CustomizeDialogProc
1033 * This function implements the toolbar customization dialog.
1036 TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1038 PCUSTDLG_INFO custInfo = (PCUSTDLG_INFO)GetWindowLongA (hwnd, DWL_USER);
1039 PCUSTOMBUTTON btnInfo;
1045 custInfo = (PCUSTDLG_INFO)lParam;
1046 SetWindowLongA (hwnd, DWL_USER, (DWORD)custInfo);
1054 /* send TBN_QUERYINSERT notification */
1055 nmtb.hdr.hwndFrom = hwnd;
1056 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1057 nmtb.hdr.code = TBN_QUERYINSERT;
1058 nmtb.iItem = custInfo->tbInfo->nNumButtons;
1060 if (!SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1061 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1064 /* add items to 'toolbar buttons' list and check if removable */
1065 for (i = 0; i < custInfo->tbInfo->nNumButtons; i++)
1067 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1068 memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
1069 btnInfo->btn.fsStyle = TBSTYLE_SEP;
1070 btnInfo->bVirtual = FALSE;
1071 LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
1073 /* send TBN_QUERYDELETE notification */
1074 nmtb.hdr.hwndFrom = hwnd;
1075 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1076 nmtb.hdr.code = TBN_QUERYDELETE;
1079 btnInfo->bRemovable = SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1080 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
1082 index = (int)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, 0);
1083 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1086 /* insert separator button into 'available buttons' list */
1087 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1088 memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
1089 btnInfo->btn.fsStyle = TBSTYLE_SEP;
1090 btnInfo->bVirtual = FALSE;
1091 btnInfo->bRemovable = TRUE;
1092 LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
1093 index = (int)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
1094 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1096 /* insert all buttons into dsa */
1099 /* send TBN_GETBUTTONINFO notification */
1100 nmtb.hdr.hwndFrom = hwnd;
1101 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1102 nmtb.hdr.code = TBN_GETBUTTONINFOA;
1104 nmtb.pszText = Buffer;
1107 if (!SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1108 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1111 TRACE("style: %x\n", nmtb.tbButton.fsStyle);
1113 /* insert button into the apropriate list */
1114 index = TOOLBAR_GetButtonIndex (custInfo->tbInfo, nmtb.tbButton.idCommand);
1117 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1118 memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
1119 btnInfo->bVirtual = FALSE;
1120 btnInfo->bRemovable = TRUE;
1121 if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
1122 strcpy (btnInfo->text, nmtb.pszText);
1124 index = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, 0);
1125 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1129 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1130 memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
1131 if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
1132 strcpy (btnInfo->text, nmtb.pszText);
1134 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1138 /* select first item in the 'available' list */
1139 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, 0, 0);
1141 /* append 'virtual' separator button to the 'toolbar buttons' list */
1142 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1143 memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
1144 btnInfo->btn.fsStyle = TBSTYLE_SEP;
1145 btnInfo->bVirtual = TRUE;
1146 btnInfo->bRemovable = FALSE;
1147 LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
1148 index = (int)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
1149 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1151 /* select last item in the 'toolbar' list */
1152 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index, 0);
1153 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETTOPINDEX, index, 0);
1155 /* set focus and disable buttons */
1156 PostMessageA (hwnd, WM_USER, 0, 0);
1161 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1162 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1163 EnableWindow (GetDlgItem (hwnd,IDC_REMOVE_BTN), FALSE);
1164 SetFocus (GetDlgItem (hwnd, IDC_TOOLBARBTN_LBOX));
1168 EndDialog(hwnd, FALSE);
1172 switch (LOWORD(wParam))
1174 case IDC_TOOLBARBTN_LBOX:
1175 if (HIWORD(wParam) == LBN_SELCHANGE)
1177 PCUSTOMBUTTON btnInfo;
1182 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1183 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1185 /* send TBN_QUERYINSERT notification */
1186 nmtb.hdr.hwndFrom = hwnd;
1187 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1188 nmtb.hdr.code = TBN_QUERYINSERT;
1191 SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1192 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
1194 /* get list box item */
1195 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1197 if (index == (count - 1))
1199 /* last item (virtual separator) */
1200 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1201 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1203 else if (index == (count - 2))
1205 /* second last item (last non-virtual item) */
1206 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
1207 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1209 else if (index == 0)
1212 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1213 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
1217 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
1218 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
1221 EnableWindow (GetDlgItem (hwnd,IDC_REMOVE_BTN), btnInfo->bRemovable);
1225 case IDC_MOVEUP_BTN:
1227 PCUSTOMBUTTON btnInfo;
1231 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1232 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1233 TRACE("Move up: index %d\n", index);
1235 /* send TBN_QUERYINSERT notification */
1236 nmtb.hdr.hwndFrom = hwnd;
1237 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1238 nmtb.hdr.code = TBN_QUERYINSERT;
1241 if (SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1242 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1244 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1246 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_DELETESTRING, index, 0);
1247 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_INSERTSTRING, index-1, 0);
1248 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index-1, (LPARAM)btnInfo);
1249 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index-1 , 0);
1252 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1253 else if (index >= (count - 3))
1254 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
1256 SendMessageA (custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
1257 SendMessageA (custInfo->tbHwnd, TB_INSERTBUTTONA, index-1, (LPARAM)&(btnInfo->btn));
1262 case IDC_MOVEDN_BTN: /* move down */
1264 PCUSTOMBUTTON btnInfo;
1268 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1269 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1270 TRACE("Move up: index %d\n", index);
1272 /* send TBN_QUERYINSERT notification */
1273 nmtb.hdr.hwndFrom = hwnd;
1274 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1275 nmtb.hdr.code = TBN_QUERYINSERT;
1278 if (SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1279 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1281 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1283 /* move button down */
1284 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_DELETESTRING, index, 0);
1285 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_INSERTSTRING, index+1, 0);
1286 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index+1, (LPARAM)btnInfo);
1287 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index+1 , 0);
1290 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
1291 else if (index >= (count - 3))
1292 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1294 SendMessageA (custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
1295 SendMessageA (custInfo->tbHwnd, TB_INSERTBUTTONA, index+1, (LPARAM)&(btnInfo->btn));
1300 case IDC_REMOVE_BTN: /* remove button */
1302 PCUSTOMBUTTON btnInfo;
1305 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1306 TRACE("Remove: index %d\n", index);
1308 /* send TBN_QUERYDELETE notification */
1309 nmtb.hdr.hwndFrom = hwnd;
1310 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1311 nmtb.hdr.code = TBN_QUERYDELETE;
1314 if (SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1315 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1317 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1318 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_DELETESTRING, index, 0);
1319 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index , 0);
1321 SendMessageA (custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
1323 /* insert into 'available button' list */
1324 if (!(btnInfo->btn.fsStyle & TBSTYLE_SEP))
1326 index = (int)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, 0);
1327 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1330 COMCTL32_Free (btnInfo);
1335 case IDOK: /* Add button */
1340 count = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETCOUNT, 0, 0);
1341 index = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETCURSEL, 0, 0);
1342 TRACE("Add: index %d\n", index);
1344 /* send TBN_QUERYINSERT notification */
1345 nmtb.hdr.hwndFrom = hwnd;
1346 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1347 nmtb.hdr.code = TBN_QUERYINSERT;
1350 if (SendMessageA (custInfo->tbInfo->hwndNotify, WM_NOTIFY,
1351 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb))
1353 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, index, 0);
1357 /* remove from 'available buttons' list */
1358 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_DELETESTRING, index, 0);
1359 if (index == count-1)
1360 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, index-1 , 0);
1362 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, index , 0);
1366 PCUSTOMBUTTON btnNew;
1368 /* duplicate 'separator' button */
1369 btnNew = (PCUSTOMBUTTON)COMCTL32_Alloc (sizeof(CUSTOMBUTTON));
1370 memcpy (btnNew, btnInfo, sizeof(CUSTOMBUTTON));
1374 /* insert into 'toolbar button' list */
1375 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1376 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_INSERTSTRING, index, 0);
1377 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1379 SendMessageA (custInfo->tbHwnd, TB_INSERTBUTTONA, index, (LPARAM)&(btnInfo->btn));
1385 EndDialog(hwnd, FALSE);
1395 /* delete items from 'toolbar buttons' listbox*/
1396 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1397 for (i = 0; i < count; i++)
1399 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, i, 0);
1400 COMCTL32_Free(btnInfo);
1401 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, 0, 0);
1403 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_RESETCONTENT, 0, 0);
1406 /* delete items from 'available buttons' listbox*/
1407 count = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETCOUNT, 0, 0);
1408 for (i = 0; i < count; i++)
1410 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, i, 0);
1411 COMCTL32_Free(btnInfo);
1412 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, i, 0);
1414 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_RESETCONTENT, 0, 0);
1419 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1421 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
1426 COLORREF oldText = 0;
1430 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, wParam, LB_GETITEMDATA, (WPARAM)lpdis->itemID, 0);
1431 if (btnInfo == NULL)
1433 FIXME("btnInfo invalid!\n");
1437 /* set colors and select objects */
1438 oldBk = SetBkColor (lpdis->hDC, GetSysColor((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1439 if (btnInfo->bVirtual)
1440 oldText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_GRAYTEXT));
1442 oldText = SetTextColor (lpdis->hDC, GetSysColor((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHTTEXT:COLOR_WINDOWTEXT));
1443 hOldPen = SelectObject (lpdis->hDC, GetSysColorPen ((lpdis->itemState & ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1444 hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1446 /* fill background rectangle */
1447 Rectangle (lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
1448 lpdis->rcItem.right, lpdis->rcItem.bottom);
1450 /* calculate button and text rectangles */
1451 CopyRect (&rcButton, &lpdis->rcItem);
1452 InflateRect (&rcButton, -1, -1);
1453 CopyRect (&rcText, &rcButton);
1454 rcButton.right = rcButton.left + custInfo->tbInfo->nBitmapWidth + 6;
1455 rcText.left = rcButton.right + 2;
1457 /* draw focus rectangle */
1458 if (lpdis->itemState & ODS_FOCUS)
1459 DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
1462 DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
1464 /* draw image and text */
1465 if ((btnInfo->btn.fsStyle & TBSTYLE_SEP) == 0)
1466 ImageList_Draw (custInfo->tbInfo->himlDef, btnInfo->btn.iBitmap, lpdis->hDC,
1467 rcButton.left+3, rcButton.top+3, ILD_NORMAL);
1468 DrawTextA (lpdis->hDC, btnInfo->text, -1, &rcText,
1469 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1471 /* delete objects and reset colors */
1472 SelectObject (lpdis->hDC, hOldBrush);
1473 SelectObject (lpdis->hDC, hOldPen);
1474 SetBkColor (lpdis->hDC, oldBk);
1475 SetTextColor (lpdis->hDC, oldText);
1481 case WM_MEASUREITEM:
1482 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1484 MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*)lParam;
1486 if (custInfo && custInfo->tbInfo)
1487 lpmis->itemHeight = custInfo->tbInfo->nBitmapHeight + 8;
1489 lpmis->itemHeight = 15 + 8; /* default height */
1501 /***********************************************************************
1502 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1506 TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1508 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1509 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
1510 INT nIndex = 0, nButtons, nCount;
1513 TRACE("hwnd=%x wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
1517 if (lpAddBmp->hInst == HINST_COMMCTRL)
1519 if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR)
1521 else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR)
1523 else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR)
1528 TRACE ("adding %d internal bitmaps!\n", nButtons);
1530 /* Windows resize all the buttons to the size of a newly added standard image */
1531 if (lpAddBmp->nID & 1)
1534 /* FIXME: on windows the size of the images is 25x24 but the size of the bitmap
1535 * in rsrc is only 24x24. Fix the bitmap (how?) and then fix this
1537 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1538 MAKELPARAM((WORD)24, (WORD)24));
1539 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1540 MAKELPARAM((WORD)31, (WORD)30));
1545 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1546 MAKELPARAM((WORD)16, (WORD)16));
1547 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1548 MAKELPARAM((WORD)22, (WORD)22));
1553 nButtons = (INT)wParam;
1557 TRACE ("adding %d bitmaps!\n", nButtons);
1560 if (!(infoPtr->himlDef)) {
1561 /* create new default image list */
1562 TRACE ("creating default image list!\n");
1565 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
1566 ILC_COLOR | ILC_MASK, nButtons, 2);
1567 infoPtr->himlInt = infoPtr->himlDef;
1570 nCount = ImageList_GetImageCount(infoPtr->himlDef);
1572 /* Add bitmaps to the default image list */
1573 if (lpAddBmp->hInst == (HINSTANCE)0)
1576 ImageList_AddMasked (infoPtr->himlDef, (HBITMAP)lpAddBmp->nID,
1579 else if (lpAddBmp->hInst == HINST_COMMCTRL)
1581 /* Add system bitmaps */
1582 switch (lpAddBmp->nID)
1584 case IDB_STD_SMALL_COLOR:
1585 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1586 MAKEINTRESOURCEA(IDB_STD_SMALL));
1587 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1588 hbmLoad, CLR_DEFAULT);
1589 DeleteObject (hbmLoad);
1592 case IDB_STD_LARGE_COLOR:
1593 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1594 MAKEINTRESOURCEA(IDB_STD_LARGE));
1595 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1596 hbmLoad, CLR_DEFAULT);
1597 DeleteObject (hbmLoad);
1600 case IDB_VIEW_SMALL_COLOR:
1601 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1602 MAKEINTRESOURCEA(IDB_VIEW_SMALL));
1603 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1604 hbmLoad, CLR_DEFAULT);
1605 DeleteObject (hbmLoad);
1608 case IDB_VIEW_LARGE_COLOR:
1609 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1610 MAKEINTRESOURCEA(IDB_VIEW_LARGE));
1611 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1612 hbmLoad, CLR_DEFAULT);
1613 DeleteObject (hbmLoad);
1616 case IDB_HIST_SMALL_COLOR:
1617 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1618 MAKEINTRESOURCEA(IDB_HIST_SMALL));
1619 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1620 hbmLoad, CLR_DEFAULT);
1621 DeleteObject (hbmLoad);
1624 case IDB_HIST_LARGE_COLOR:
1625 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1626 MAKEINTRESOURCEA(IDB_HIST_LARGE));
1627 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1628 hbmLoad, CLR_DEFAULT);
1629 DeleteObject (hbmLoad);
1633 nIndex = ImageList_GetImageCount (infoPtr->himlDef);
1634 ERR ("invalid imagelist!\n");
1640 hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
1641 nIndex = ImageList_AddMasked (infoPtr->himlDef, hbmLoad, CLR_DEFAULT);
1642 DeleteObject (hbmLoad);
1647 INT imagecount = ImageList_GetImageCount(infoPtr->himlDef);
1649 if (infoPtr->nNumBitmaps + nButtons != imagecount)
1651 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",
1652 infoPtr->nNumBitmaps, nCount, imagecount - nCount,
1653 infoPtr->nNumBitmaps+nButtons,imagecount);
1655 infoPtr->nNumBitmaps = imagecount;
1658 infoPtr->nNumBitmaps += nButtons;
1661 InvalidateRect(hwnd, NULL, FALSE);
1668 TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1670 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1671 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1672 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1674 TRACE("adding %d buttons!\n", wParam);
1676 nAddButtons = (UINT)wParam;
1677 nOldButtons = infoPtr->nNumButtons;
1678 nNewButtons = nOldButtons + nAddButtons;
1680 if (infoPtr->nNumButtons == 0) {
1682 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1685 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1687 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1688 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1689 nOldButtons * sizeof(TBUTTON_INFO));
1690 COMCTL32_Free (oldButtons);
1693 infoPtr->nNumButtons = nNewButtons;
1695 /* insert new button data */
1696 for (nCount = 0; nCount < nAddButtons; nCount++) {
1697 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1698 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1699 btnPtr->idCommand = lpTbb[nCount].idCommand;
1700 btnPtr->fsState = lpTbb[nCount].fsState;
1701 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1702 btnPtr->dwData = lpTbb[nCount].dwData;
1703 btnPtr->iString = lpTbb[nCount].iString;
1704 btnPtr->bHot = FALSE;
1706 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1709 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1710 ti.cbSize = sizeof (TTTOOLINFOA);
1712 ti.uId = btnPtr->idCommand;
1714 ti.lpszText = LPSTR_TEXTCALLBACKA;
1716 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
1721 InvalidateRect(hwnd, NULL, FALSE);
1728 TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1730 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1731 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1732 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1734 TRACE("adding %d buttons!\n", wParam);
1736 nAddButtons = (UINT)wParam;
1737 nOldButtons = infoPtr->nNumButtons;
1738 nNewButtons = nOldButtons + nAddButtons;
1740 if (infoPtr->nNumButtons == 0) {
1742 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1745 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1747 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1748 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1749 nOldButtons * sizeof(TBUTTON_INFO));
1750 COMCTL32_Free (oldButtons);
1753 infoPtr->nNumButtons = nNewButtons;
1755 /* insert new button data */
1756 for (nCount = 0; nCount < nAddButtons; nCount++) {
1757 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1758 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1759 btnPtr->idCommand = lpTbb[nCount].idCommand;
1760 btnPtr->fsState = lpTbb[nCount].fsState;
1761 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1762 btnPtr->dwData = lpTbb[nCount].dwData;
1763 btnPtr->iString = lpTbb[nCount].iString;
1764 btnPtr->bHot = FALSE;
1766 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1769 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
1770 ti.cbSize = sizeof (TTTOOLINFOW);
1772 ti.uId = btnPtr->idCommand;
1774 ti.lpszText = LPSTR_TEXTCALLBACKW;
1776 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
1781 InvalidateRect(hwnd, NULL, FALSE);
1788 TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1790 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1793 if ((wParam) && (HIWORD(lParam) == 0)) {
1796 TRACE("adding string from resource!\n");
1798 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
1801 TRACE("len=%d \"%s\"\n", len, szString);
1802 nIndex = infoPtr->nNumStrings;
1803 if (infoPtr->nNumStrings == 0) {
1805 COMCTL32_Alloc (sizeof(LPWSTR));
1808 LPWSTR *oldStrings = infoPtr->strings;
1810 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1811 memcpy (&infoPtr->strings[0], &oldStrings[0],
1812 sizeof(LPWSTR) * infoPtr->nNumStrings);
1813 COMCTL32_Free (oldStrings);
1816 infoPtr->strings[infoPtr->nNumStrings] =
1817 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1818 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
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 infoPtr->strings[infoPtr->nNumStrings] =
1848 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1849 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
1850 infoPtr->nNumStrings++;
1861 TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1863 #define MAX_RESOURCE_STRING_LENGTH 512
1864 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1867 if ((wParam) && (HIWORD(lParam) == 0)) {
1868 WCHAR szString[MAX_RESOURCE_STRING_LENGTH];
1870 TRACE("adding string from resource!\n");
1872 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
1873 szString, MAX_RESOURCE_STRING_LENGTH);
1875 TRACE("len=%d \"%s\"\n", len, debugstr_w(szString));
1876 TRACE("First char: 0x%x\n", *szString);
1877 if (szString[0] == L'|')
1879 PWSTR p = szString + 1;
1881 nIndex = infoPtr->nNumStrings;
1882 while (*p != L'|') {
1884 if (infoPtr->nNumStrings == 0) {
1886 COMCTL32_Alloc (sizeof(LPWSTR));
1889 LPWSTR *oldStrings = infoPtr->strings;
1891 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1892 memcpy (&infoPtr->strings[0], &oldStrings[0],
1893 sizeof(LPWSTR) * infoPtr->nNumStrings);
1894 COMCTL32_Free (oldStrings);
1897 len = COMCTL32_StrChrW (p, L'|') - p;
1898 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1899 infoPtr->strings[infoPtr->nNumStrings] =
1900 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1901 lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len);
1902 infoPtr->nNumStrings++;
1909 nIndex = infoPtr->nNumStrings;
1910 if (infoPtr->nNumStrings == 0) {
1912 COMCTL32_Alloc (sizeof(LPWSTR));
1915 LPWSTR *oldStrings = infoPtr->strings;
1917 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1918 memcpy (&infoPtr->strings[0], &oldStrings[0],
1919 sizeof(LPWSTR) * infoPtr->nNumStrings);
1920 COMCTL32_Free (oldStrings);
1923 infoPtr->strings[infoPtr->nNumStrings] =
1924 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1925 strcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
1926 infoPtr->nNumStrings++;
1930 LPWSTR p = (LPWSTR)lParam;
1935 TRACE("adding string(s) from array!\n");
1936 nIndex = infoPtr->nNumStrings;
1940 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1941 if (infoPtr->nNumStrings == 0) {
1943 COMCTL32_Alloc (sizeof(LPWSTR));
1946 LPWSTR *oldStrings = infoPtr->strings;
1948 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1949 memcpy (&infoPtr->strings[0], &oldStrings[0],
1950 sizeof(LPWSTR) * infoPtr->nNumStrings);
1951 COMCTL32_Free (oldStrings);
1954 infoPtr->strings[infoPtr->nNumStrings] =
1955 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1956 strcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1957 infoPtr->nNumStrings++;
1968 TOOLBAR_AutoSize (HWND hwnd)
1970 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1971 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1977 UINT uPosFlags = SWP_NOZORDER;
1979 TRACE("resize forced, style=%lx!\n", dwStyle);
1981 parent = GetParent (hwnd);
1982 GetClientRect(parent, &parent_rect);
1984 x = parent_rect.left;
1985 y = parent_rect.top;
1987 /* FIXME: we should be able to early out if nothing */
1988 /* has changed with nWidth != parent_rect width */
1990 if (dwStyle & CCS_NORESIZE) {
1991 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
1996 infoPtr->nWidth = parent_rect.right - parent_rect.left;
1997 InvalidateRect( hwnd, NULL, TRUE );
1998 cy = infoPtr->nHeight;
1999 cx = infoPtr->nWidth;
2001 if (dwStyle & CCS_NOMOVEY) {
2002 GetWindowRect(hwnd, &window_rect);
2003 ScreenToClient(parent, (LPPOINT)&window_rect.left);
2004 y = window_rect.top;
2008 if (dwStyle & CCS_NOPARENTALIGN)
2009 uPosFlags |= SWP_NOMOVE;
2011 if (!(dwStyle & CCS_NODIVIDER))
2012 cy += GetSystemMetrics(SM_CYEDGE);
2014 if (dwStyle & WS_BORDER)
2017 cy += GetSystemMetrics(SM_CYEDGE);
2018 cx += GetSystemMetrics(SM_CYEDGE);
2021 infoPtr->bAutoSize = TRUE;
2022 SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
2024 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
2025 * the setwindowpos calls */
2026 infoPtr->bAutoSize = FALSE;
2033 TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
2035 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2037 return infoPtr->nNumButtons;
2042 TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2044 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2046 if (infoPtr == NULL) {
2047 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
2048 ERR("infoPtr == NULL!\n");
2052 infoPtr->dwStructSize = (DWORD)wParam;
2059 TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
2061 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2062 TBUTTON_INFO *btnPtr;
2065 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2069 btnPtr = &infoPtr->buttons[nIndex];
2070 btnPtr->iBitmap = LOWORD(lParam);
2072 /* we HAVE to erase the background, the new bitmap could be */
2074 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
2081 TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2083 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2084 TBUTTON_INFO *btnPtr;
2087 BOOL bChecked = FALSE;
2089 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2093 btnPtr = &infoPtr->buttons[nIndex];
2095 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
2098 bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
2100 if (LOWORD(lParam) == FALSE)
2101 btnPtr->fsState &= ~TBSTATE_CHECKED;
2103 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
2105 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
2106 if (nOldIndex == nIndex)
2108 if (nOldIndex != -1)
2109 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
2111 btnPtr->fsState |= TBSTATE_CHECKED;
2114 if( bChecked != LOWORD(lParam) )
2116 if (nOldIndex != -1)
2118 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
2119 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
2121 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
2124 /* FIXME: Send a WM_NOTIFY?? */
2131 TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
2133 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2135 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2140 TOOLBAR_Customize (HWND hwnd)
2142 CUSTDLG_INFO custInfo;
2148 custInfo.tbInfo = TOOLBAR_GetInfoPtr (hwnd);
2149 custInfo.tbHwnd = hwnd;
2151 /* send TBN_BEGINADJUST notification */
2152 nmhdr.hwndFrom = hwnd;
2153 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
2154 nmhdr.code = TBN_BEGINADJUST;
2156 SendMessageA (custInfo.tbInfo->hwndNotify, WM_NOTIFY,
2157 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
2159 if (!(hRes = FindResourceA (COMCTL32_hModule,
2160 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
2164 if(!(template = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
2167 ret = DialogBoxIndirectParamA (GetWindowLongA (hwnd, GWL_HINSTANCE),
2168 (LPDLGTEMPLATEA)template,
2170 (DLGPROC)TOOLBAR_CustomizeDialogProc,
2173 /* send TBN_ENDADJUST notification */
2174 nmhdr.code = TBN_ENDADJUST;
2175 SendMessageA (custInfo.tbInfo->hwndNotify, WM_NOTIFY,
2176 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
2183 TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2185 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2186 INT nIndex = (INT)wParam;
2188 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2191 if ((infoPtr->hwndToolTip) &&
2192 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
2195 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2196 ti.cbSize = sizeof (TTTOOLINFOA);
2198 ti.uId = infoPtr->buttons[nIndex].idCommand;
2200 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
2203 if (infoPtr->nNumButtons == 1) {
2204 TRACE(" simple delete!\n");
2205 COMCTL32_Free (infoPtr->buttons);
2206 infoPtr->buttons = NULL;
2207 infoPtr->nNumButtons = 0;
2210 TBUTTON_INFO *oldButtons = infoPtr->buttons;
2211 TRACE("complex delete! [nIndex=%d]\n", nIndex);
2213 infoPtr->nNumButtons--;
2214 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2216 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2217 nIndex * sizeof(TBUTTON_INFO));
2220 if (nIndex < infoPtr->nNumButtons) {
2221 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
2222 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
2225 COMCTL32_Free (oldButtons);
2228 InvalidateRect (hwnd, NULL, TRUE);
2235 TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2237 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2238 TBUTTON_INFO *btnPtr;
2242 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2246 btnPtr = &infoPtr->buttons[nIndex];
2248 bState = btnPtr->fsState & TBSTATE_ENABLED;
2250 /* update the toolbar button state */
2251 if(LOWORD(lParam) == FALSE) {
2252 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
2254 btnPtr->fsState |= TBSTATE_ENABLED;
2257 /* redraw the button only if the state of the button changed */
2258 if(bState != (btnPtr->fsState & TBSTATE_ENABLED))
2260 InvalidateRect(hwnd, &btnPtr->rect,
2261 TOOLBAR_HasText(infoPtr, btnPtr));
2268 static inline LRESULT
2269 TOOLBAR_GetAnchorHighlight (HWND hwnd)
2271 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2273 return infoPtr->bAnchor;
2278 TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
2280 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2283 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2287 return infoPtr->buttons[nIndex].iBitmap;
2291 static inline LRESULT
2292 TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
2294 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
2299 TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2301 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2302 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2303 INT nIndex = (INT)wParam;
2304 TBUTTON_INFO *btnPtr;
2306 if (infoPtr == NULL)
2312 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2315 btnPtr = &infoPtr->buttons[nIndex];
2316 lpTbb->iBitmap = btnPtr->iBitmap;
2317 lpTbb->idCommand = btnPtr->idCommand;
2318 lpTbb->fsState = btnPtr->fsState;
2319 lpTbb->fsStyle = btnPtr->fsStyle;
2320 lpTbb->dwData = btnPtr->dwData;
2321 lpTbb->iString = btnPtr->iString;
2328 TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2330 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2331 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
2332 TBUTTON_INFO *btnPtr;
2335 if (infoPtr == NULL)
2337 if (lpTbInfo == NULL)
2339 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOA))
2342 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2346 btnPtr = &infoPtr->buttons[nIndex];
2348 if (lpTbInfo->dwMask & TBIF_COMMAND)
2349 lpTbInfo->idCommand = btnPtr->idCommand;
2350 if (lpTbInfo->dwMask & TBIF_IMAGE)
2351 lpTbInfo->iImage = btnPtr->iBitmap;
2352 if (lpTbInfo->dwMask & TBIF_LPARAM)
2353 lpTbInfo->lParam = btnPtr->dwData;
2354 if (lpTbInfo->dwMask & TBIF_SIZE)
2355 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
2356 if (lpTbInfo->dwMask & TBIF_STATE)
2357 lpTbInfo->fsState = btnPtr->fsState;
2358 if (lpTbInfo->dwMask & TBIF_STYLE)
2359 lpTbInfo->fsStyle = btnPtr->fsStyle;
2360 if (lpTbInfo->dwMask & TBIF_TEXT) {
2361 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
2363 lstrcpynWtoA (lpTbInfo->pszText,
2364 (LPWSTR)infoPtr->strings[btnPtr->iString],
2367 else lpTbInfo->pszText[0]=0;
2374 TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2376 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2377 LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
2378 TBUTTON_INFO *btnPtr;
2381 if (infoPtr == NULL)
2383 if (lpTbInfo == NULL)
2385 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
2388 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2392 btnPtr = &infoPtr->buttons[nIndex];
2394 if (lpTbInfo->dwMask & TBIF_COMMAND)
2395 lpTbInfo->idCommand = btnPtr->idCommand;
2396 if (lpTbInfo->dwMask & TBIF_IMAGE)
2397 lpTbInfo->iImage = btnPtr->iBitmap;
2398 if (lpTbInfo->dwMask & TBIF_LPARAM)
2399 lpTbInfo->lParam = btnPtr->dwData;
2400 if (lpTbInfo->dwMask & TBIF_SIZE)
2401 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
2402 if (lpTbInfo->dwMask & TBIF_STATE)
2403 lpTbInfo->fsState = btnPtr->fsState;
2404 if (lpTbInfo->dwMask & TBIF_STYLE)
2405 lpTbInfo->fsStyle = btnPtr->fsStyle;
2406 if (lpTbInfo->dwMask & TBIF_TEXT) {
2407 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
2408 lstrcpynW (lpTbInfo->pszText,
2409 (LPWSTR)infoPtr->strings[btnPtr->iString],
2418 TOOLBAR_GetButtonSize (HWND hwnd)
2420 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2422 return MAKELONG((WORD)infoPtr->nButtonWidth,
2423 (WORD)infoPtr->nButtonHeight);
2428 TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2430 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2431 INT nIndex, nStringIndex;
2433 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2437 nStringIndex = infoPtr->buttons[nIndex].iString;
2439 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
2441 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2447 lstrcpyWtoA ((LPSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
2449 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
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 lstrlenW ((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 = lstrlenA((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);