4 * Copyright 1998,1999 Eric Kohl
7 * - A little bug in TOOLBAR_DrawMasked()
8 * - Button wrapping (under construction).
10 * - Notifications (under construction).
12 * - Tooltip support (almost complete).
13 * - Unicode suppport (under construction).
14 * - Fix TOOLBAR_SetButtonInfo32A/W.
15 * - Customize dialog (under construction).
16 * - TBSTYLE_AUTOSIZE for toolbar and buttons.
17 * - I_IMAGECALLBACK support.
20 * - Run tests using Waite Group Windows95 API Bible Volume 2.
21 * The second cdrom contains executables addstr.exe, btncount.exe,
22 * btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
23 * enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
24 * indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
25 * setparnt.exe, setrows.exe, toolwnd.exe.
26 * - Microsofts controlspy examples.
39 #include "debugtools.h"
41 DEFAULT_DEBUG_CHANNEL(toolbar)
43 #define SEPARATOR_WIDTH 8
45 #define BOTTOM_BORDER 2
47 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
50 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index)
52 if ((index>=0) && (index < infoPtr->nNumBitmaps))
60 TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
62 INT x = (lpRect->left + lpRect->right) / 2 - 1;
63 INT yBottom = lpRect->bottom - 3;
64 INT yTop = lpRect->top + 1;
66 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
67 MoveToEx (hdc, x, yBottom, NULL);
68 LineTo (hdc, x, yTop);
70 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
71 MoveToEx (hdc, x, yBottom, NULL);
72 LineTo (hdc, x, yTop);
76 * Draw the text string for this button.
77 * note: himl is not used, except to determine whether this button has
78 * an associated bitmap. If so, the text is drawn below it, otherwise
79 * the text is drawn within the rectangle of the button itself.
82 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
83 HDC hdc, INT nState, DWORD dwStyle, HIMAGELIST himl)
85 RECT rcText = btnPtr->rect;
91 TRACE ("iString: %x\n", btnPtr->iString);
93 /* get a pointer to the text */
94 if (btnPtr->iString == -1)
95 FIXME("Undocumented Index -1\n");
96 else if (HIWORD(btnPtr->iString) != 0)
97 lpText = (LPWSTR)btnPtr->iString;
98 else if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
99 lpText = infoPtr->strings[btnPtr->iString];
101 TRACE ("lpText: \"%s\"\n", debugstr_w(lpText));
106 InflateRect (&rcText, -3, -3);
108 if (himl && TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
109 if ((dwStyle & TBSTYLE_LIST) &&
110 ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
111 (btnPtr->iBitmap != I_IMAGENONE)) {
112 rcText.left += infoPtr->nBitmapWidth;
115 rcText.top += infoPtr->nBitmapHeight;
119 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
120 OffsetRect (&rcText, 1, 1);
122 hOldFont = SelectObject (hdc, infoPtr->hFont);
123 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
124 if (!(nState & TBSTATE_ENABLED)) {
125 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
126 OffsetRect (&rcText, 1, 1);
127 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
128 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
129 OffsetRect (&rcText, -1, -1);
130 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
132 else if (nState & TBSTATE_INDETERMINATE) {
133 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
134 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
137 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
138 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
141 SetTextColor (hdc, clrOld);
142 SelectObject (hdc, hOldFont);
143 if (nOldBkMode != TRANSPARENT)
144 SetBkMode (hdc, nOldBkMode);
150 TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
152 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
153 INT cx = lpRect->right - lpRect->left;
154 INT cy = lpRect->bottom - lpRect->top;
155 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
156 SelectObject (hdc, hbr);
161 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
162 HDC hdc, INT x, INT y)
164 /* FIXME: this function is a hack since it uses image list
165 internals directly */
167 HIMAGELIST himl = infoPtr->himlDef;
175 /* create new dc's */
176 hdcImageList = CreateCompatibleDC (0);
177 hdcMask = CreateCompatibleDC (0);
179 /* create new bitmap */
180 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
181 SelectObject (hdcMask, hbmMask);
183 /* copy the mask bitmap */
184 SelectObject (hdcImageList, himl->hbmMask);
185 SetBkColor (hdcImageList, RGB(255, 255, 255));
186 SetTextColor (hdcImageList, RGB(0, 0, 0));
187 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
188 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
191 /* add white mask from image */
192 SelectObject (hdcImageList, himl->hbmImage);
193 SetBkColor (hdcImageList, RGB(0, 0, 0));
194 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
195 hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
198 /* draw the new mask */
199 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
200 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
201 hdcMask, 0, 0, 0xB8074A);
203 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
204 BitBlt (hdc, x, y, himl->cx, himl->cy,
205 hdcMask, 0, 0, 0xB8074A);
207 DeleteObject (hbmMask);
209 DeleteDC (hdcImageList);
214 TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
216 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
217 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
220 if (btnPtr->fsState & TBSTATE_HIDDEN)
225 TRACE("iBitmap: %d\n", btnPtr->iBitmap);
228 if (btnPtr->fsStyle & TBSTYLE_SEP) {
229 if ((dwStyle & TBSTYLE_FLAT) && (btnPtr->iBitmap == 0))
230 TOOLBAR_DrawFlatSeparator (&rc, hdc);
235 if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
236 if (!(dwStyle & TBSTYLE_FLAT))
237 DrawEdge (hdc, &rc, EDGE_RAISED,
238 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
240 if (infoPtr->himlDis &&
241 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
242 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
243 rc.left+1, rc.top+1, ILD_NORMAL);
245 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
247 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle,
252 /* pressed TBSTYLE_BUTTON */
253 if (btnPtr->fsState & TBSTATE_PRESSED) {
254 if (dwStyle & TBSTYLE_FLAT)
255 DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
257 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
258 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
259 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
260 rc.left+2, rc.top+2, ILD_NORMAL);
261 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle,
266 /* checked TBSTYLE_CHECK */
267 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
268 (btnPtr->fsState & TBSTATE_CHECKED)) {
269 if (dwStyle & TBSTYLE_FLAT)
270 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
271 BF_RECT | BF_MIDDLE | BF_ADJUST);
273 DrawEdge (hdc, &rc, EDGE_SUNKEN,
274 BF_RECT | BF_MIDDLE | BF_ADJUST);
276 TOOLBAR_DrawPattern (hdc, &rc);
278 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
279 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
280 rc.left+2, rc.top+2, ILD_NORMAL);
282 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle,
288 if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
289 DrawEdge (hdc, &rc, EDGE_RAISED,
290 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
292 TOOLBAR_DrawPattern (hdc, &rc);
293 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
294 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle,
300 if (dwStyle & TBSTYLE_FLAT)
303 DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
304 if (btnPtr->bHot && infoPtr->himlHot &&
305 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
306 ImageList_Draw (infoPtr->himlHot, btnPtr->iBitmap, hdc,
307 rc.left +2, rc.top +2, ILD_NORMAL);
308 else if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
309 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
310 rc.left +2, rc.top +2, ILD_NORMAL);
314 DrawEdge (hdc, &rc, EDGE_RAISED,
315 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
317 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
318 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
319 rc.left+1, rc.top+1, ILD_NORMAL);
322 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle,
328 TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
330 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
331 TBUTTON_INFO *btnPtr;
335 /* redraw necessary buttons */
336 btnPtr = infoPtr->buttons;
337 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
339 if(IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect)))
340 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
345 TOOLBAR_MeasureString(HWND hwnd, INT index, LPSIZE lpSize)
347 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
348 TBUTTON_INFO *btnPtr;
355 hOldFont = SelectObject (hdc, infoPtr->hFont);
357 btnPtr = &infoPtr->buttons[index];
359 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
360 (btnPtr->iString > -1) &&
361 (btnPtr->iString < infoPtr->nNumStrings))
363 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
364 GetTextExtentPoint32W (hdc, lpText, lstrlenW (lpText), lpSize);
367 SelectObject (hdc, hOldFont);
370 TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
374 TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
376 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
377 TBUTTON_INFO *btnPtr;
385 btnPtr = infoPtr->buttons;
386 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
387 TOOLBAR_MeasureString(hwnd,i,&sz);
388 if (sz.cx > lpSize->cx)
390 if (sz.cy > lpSize->cy)
394 TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
397 /***********************************************************************
398 * TOOLBAR_WrapToolbar
400 * This function walks through the buttons and seperators in the
401 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
402 * wrapping should occur based on the width of the toolbar window.
403 * It does *not* calculate button placement itself. That task
404 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
405 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
406 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
410 TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
412 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
413 TBUTTON_INFO *btnPtr;
416 BOOL bWrap, bButtonWrap;
418 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
419 /* no layout is necessary. Applications may use this style */
420 /* to perform their own layout on the toolbar. */
421 if( !(dwStyle & TBSTYLE_WRAPABLE) )
424 btnPtr = infoPtr->buttons;
425 x = infoPtr->nIndent;
427 /* this can get the parents width, to know how far we can extend
428 * this toolbar. We cannot use its height, as there may be multiple
429 * toolbars in a rebar control
431 GetClientRect( GetParent(hwnd), &rc );
432 infoPtr->nWidth = rc.right - rc.left;
435 for (i = 0; i < infoPtr->nNumButtons; i++ )
438 btnPtr[i].fsState &= ~TBSTATE_WRAP;
440 if (btnPtr[i].fsState & TBSTATE_HIDDEN)
443 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
444 /* it is the actual width of the separator. This is used for */
445 /* custom controls in toolbars. */
446 if (btnPtr[i].fsStyle & TBSTYLE_SEP)
447 cx = (btnPtr[i].iBitmap > 0) ?
448 btnPtr[i].iBitmap : SEPARATOR_WIDTH;
450 cx = infoPtr->nButtonWidth;
452 /* Two or more adjacent separators form a separator group. */
453 /* The first separator in a group should be wrapped to the */
454 /* next row if the previous wrapping is on a button. */
456 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
457 (i + 1 < infoPtr->nNumButtons ) &&
458 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
460 btnPtr[i].fsState |= TBSTATE_WRAP;
461 x = infoPtr->nIndent;
467 /* The layout makes sure the bitmap is visible, but not the button. */
468 if ( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
473 /* If the current button is a separator and not hidden, */
474 /* go to the next until it reaches a non separator. */
475 /* Wrap the last separator if it is before a button. */
476 while( ( (btnPtr[i].fsStyle & TBSTYLE_SEP) ||
477 (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
478 i < infoPtr->nNumButtons )
484 if( bFound && i < infoPtr->nNumButtons )
487 btnPtr[i].fsState |= TBSTATE_WRAP;
488 x = infoPtr->nIndent;
492 else if ( i >= infoPtr->nNumButtons)
495 /* If the current button is not a separator, find the last */
496 /* separator and wrap it. */
497 for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
499 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
500 !(btnPtr[j].fsState & TBSTATE_HIDDEN))
504 x = infoPtr->nIndent;
505 btnPtr[j].fsState |= TBSTATE_WRAP;
511 /* If no separator available for wrapping, wrap one of */
512 /* non-hidden previous button. */
516 j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
518 if (btnPtr[j].fsState & TBSTATE_HIDDEN)
523 x = infoPtr->nIndent;
524 btnPtr[j].fsState |= TBSTATE_WRAP;
530 /* If all above failed, wrap the current button. */
533 btnPtr[i].fsState |= TBSTATE_WRAP;
535 x = infoPtr->nIndent;
536 if (btnPtr[i].fsState & TBSTYLE_SEP )
547 /***********************************************************************
548 * TOOLBAR_CalcToolbar
550 * This function calculates button and separator placement. It first
551 * calculates the button sizes, gets the toolbar window width and then
552 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
553 * on. It assigns a new location to each item and sends this location to
554 * the tooltip window if appropriate. Finally, it updates the rcBound
555 * rect and calculates the new required toolbar window height.
559 TOOLBAR_CalcToolbar (HWND hwnd)
561 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
562 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
563 TBUTTON_INFO *btnPtr;
564 INT i, nRows, nSepRows;
569 TOOLBAR_CalcStrings (hwnd, &sizeString);
571 if (dwStyle & TBSTYLE_LIST) {
572 infoPtr->nButtonHeight = max(infoPtr->nBitmapHeight, sizeString.cy) + 6;
573 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + sizeString.cx + 6;
576 BOOL usesBitmaps = FALSE;
579 for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
580 if (TOOLBAR_IsValidBitmapIndex(infoPtr,infoPtr->buttons[i].iBitmap))
583 if (sizeString.cy > 0) {
585 infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
587 infoPtr->nButtonHeight = sizeString.cy + 6;
589 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
590 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
592 if (sizeString.cx > infoPtr->nBitmapWidth)
593 infoPtr->nButtonWidth = sizeString.cx + 6;
594 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
595 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
598 if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin )
599 infoPtr->nButtonWidth = infoPtr->cxMin;
600 if ( infoPtr->cxMax >= 0 && infoPtr->nButtonWidth > infoPtr->cxMax )
601 infoPtr->nButtonWidth = infoPtr->cxMax;
603 TOOLBAR_WrapToolbar( hwnd, dwStyle );
605 x = infoPtr->nIndent;
606 y = (dwStyle & TBSTYLE_FLAT) ? 0 : TOP_BORDER;
609 * We wills et the height below, and we set the width on entry
610 * so we do not reset them here..
613 GetClientRect( hwnd, &rc );
614 /* get initial values for toolbar */
615 infoPtr->nWidth = rc.right - rc.left;
616 infoPtr->nHeight = rc.bottom - rc.top;
619 /* from above, minimum is a button, and possible text */
620 cx = infoPtr->nButtonWidth;
621 /* cannot use just ButtonHeight, we may have no buttons! */
622 if (infoPtr->nNumButtons > 0)
623 infoPtr->nHeight = infoPtr->nButtonHeight;
624 cy = infoPtr->nHeight;
626 nRows = nSepRows = 0;
628 infoPtr->rcBound.top = y;
629 infoPtr->rcBound.left = x;
630 infoPtr->rcBound.bottom = y + cy;
631 infoPtr->rcBound.right = x;
633 btnPtr = infoPtr->buttons;
635 /* do not base height/width on parent, if the parent is a */
636 /* rebar control it could have multiple rows of toolbars */
637 /* GetClientRect( GetParent(hwnd), &rc ); */
638 /* cx = rc.right - rc.left; */
639 /* cy = rc.bottom - rc.top; */
641 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
644 if (btnPtr->fsState & TBSTATE_HIDDEN)
646 SetRectEmpty (&btnPtr->rect);
650 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
651 /* it is the actual width of the separator. This is used for */
652 /* custom controls in toolbars. */
653 if (btnPtr->fsStyle & TBSTYLE_SEP)
654 cx = (btnPtr->iBitmap > 0) ?
655 btnPtr->iBitmap : SEPARATOR_WIDTH;
657 if (btnPtr->fsStyle & TBSTYLE_AUTOSIZE)
660 TOOLBAR_MeasureString(hwnd,i,&sz);
664 cx = infoPtr->nButtonWidth;
666 cy = infoPtr->nHeight;
668 if (btnPtr->fsState & TBSTATE_WRAP )
671 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
673 if (infoPtr->rcBound.left > x)
674 infoPtr->rcBound.left = x;
675 if (infoPtr->rcBound.right < x + cx)
676 infoPtr->rcBound.right = x + cx;
677 if (infoPtr->rcBound.bottom < y + cy)
678 infoPtr->rcBound.bottom = y + cy;
680 /* Set the toolTip only for non-hidden, non-separator button */
681 if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP ))
685 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
686 ti.cbSize = sizeof(TTTOOLINFOA);
688 ti.uId = btnPtr->idCommand;
689 ti.rect = btnPtr->rect;
690 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
694 /* btnPtr->nRow is zero based. The space between the rows is */
695 /* also considered as a row. */
696 btnPtr->nRow = nRows + nSepRows;
699 if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
703 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
704 /* it is the actual width of the separator. This is used for */
705 /* custom controls in toolbars. */
706 y += cy + ( (btnPtr->iBitmap > 0 ) ?
707 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
709 /* nSepRows is used to calculate the extra height follwoing */
713 x = infoPtr->nIndent;
720 /* infoPtr->nRows is the number of rows on the toolbar */
721 infoPtr->nRows = nRows + nSepRows + 1;
723 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
725 infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
726 nSepRows * (SEPARATOR_WIDTH * 2 / 3) +
727 nSepRows * (infoPtr->nBitmapHeight + 1) +
729 TRACE("toolbar height %d\n", infoPtr->nHeight);
734 TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
736 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
737 TBUTTON_INFO *btnPtr;
740 btnPtr = infoPtr->buttons;
741 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
742 if (btnPtr->fsState & TBSTATE_HIDDEN)
745 if (btnPtr->fsStyle & TBSTYLE_SEP) {
746 if (PtInRect (&btnPtr->rect, *lpPt)) {
747 TRACE(" ON SEPARATOR %d!\n", i);
752 if (PtInRect (&btnPtr->rect, *lpPt)) {
753 TRACE(" ON BUTTON %d!\n", i);
759 TRACE(" NOWHERE!\n");
765 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
767 TBUTTON_INFO *btnPtr;
770 btnPtr = infoPtr->buttons;
771 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
772 if (btnPtr->idCommand == idCommand) {
773 TRACE("command=%d index=%d\n", idCommand, i);
777 TRACE("no index found for command=%d\n", idCommand);
783 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
785 TBUTTON_INFO *btnPtr;
788 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
791 /* check index button */
792 btnPtr = &infoPtr->buttons[nIndex];
793 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
794 if (btnPtr->fsState & TBSTATE_CHECKED)
798 /* check previous buttons */
799 nRunIndex = nIndex - 1;
800 while (nRunIndex >= 0) {
801 btnPtr = &infoPtr->buttons[nRunIndex];
802 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
803 if (btnPtr->fsState & TBSTATE_CHECKED)
811 /* check next buttons */
812 nRunIndex = nIndex + 1;
813 while (nRunIndex < infoPtr->nNumButtons) {
814 btnPtr = &infoPtr->buttons[nRunIndex];
815 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
816 if (btnPtr->fsState & TBSTATE_CHECKED)
829 TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
830 WPARAM wParam, LPARAM lParam)
838 msg.time = GetMessageTime ();
839 msg.pt.x = LOWORD(GetMessagePos ());
840 msg.pt.y = HIWORD(GetMessagePos ());
842 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
846 /***********************************************************************
847 * TOOLBAR_CustomizeDialogProc
848 * This function implements the toolbar customization dialog.
851 TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
853 TOOLBAR_INFO *infoPtr = (TOOLBAR_INFO *)GetWindowLongA (hwnd, DWL_USER);
854 static HDSA hDsa = NULL;
859 infoPtr = (TOOLBAR_INFO *)lParam;
860 SetWindowLongA (hwnd, DWL_USER, (DWORD)infoPtr);
862 hDsa = DSA_Create (sizeof(TBUTTON_INFO), 5);
866 TBUTTON_INFO *btnPtr;
869 /* insert 'virtual' separator button into 'available buttons' list */
870 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
872 /* copy all buttons and append them to the right listbox */
873 btnPtr = infoPtr->buttons;
874 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
876 DSA_InsertItem (hDsa, i, btnPtr);
878 /* FIXME: hidden buttons appear in the 'toolbar buttons' list too */
879 if (btnPtr->fsState & TBSTATE_HIDDEN)
881 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
885 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
889 /* append 'virtual' separator button to the 'toolbar buttons' list */
895 EndDialog(hwnd, FALSE);
899 switch (LOWORD(wParam))
902 EndDialog(hwnd, FALSE);
913 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
915 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
921 COLORREF oldText = 0;
924 FIXME("action: %x itemState: %x\n",
925 lpdis->itemAction, lpdis->itemState);
927 DSA_GetItem (hDsa, 0 /*lpdis->itemID*/, &btnPtr);
929 if (lpdis->itemState & ODS_FOCUS)
931 oldBk = SetBkColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
932 oldText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
935 hOldPen = SelectObject (lpdis->hDC, GetSysColorPen ((lpdis->itemState & ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
936 hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
938 /* fill background rectangle */
939 Rectangle (lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
940 lpdis->rcItem.right, lpdis->rcItem.bottom);
942 /* calculate button and text rectangles */
943 CopyRect (&rcButton, &lpdis->rcItem);
944 InflateRect (&rcButton, -1, -1);
945 CopyRect (&rcText, &rcButton);
946 rcButton.right = rcButton.left + infoPtr->nBitmapWidth + 6;
947 rcText.left = rcButton.right + 2;
949 /* draw focus rectangle */
950 if (lpdis->itemState & ODS_FOCUS)
951 DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
954 DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
956 /* draw image and text */
957 if (wParam == IDC_AVAILBTN_LBOX && lpdis->itemID == 0)
959 /* virtual separator in the 'available' list */
960 DrawTextA (lpdis->hDC, "Separator", -1, &rcText,
961 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
967 ImageList_Draw (infoPtr->himlDef, btnPtr.iBitmap, lpdis->hDC,
968 rcButton.left+1, rcButton.top+1, ILD_NORMAL);
970 DrawTextW (lpdis->hDC, infoPtr->strings[btnPtr.iString], -1, &rcText,
971 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
975 if (lpdis->itemState & ODS_FOCUS)
977 SetBkColor (lpdis->hDC, oldBk);
978 SetTextColor (lpdis->hDC, oldText);
981 SelectObject (lpdis->hDC, hOldBrush);
982 SelectObject (lpdis->hDC, hOldPen);
989 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
991 MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*)lParam;
994 lpmis->itemHeight = infoPtr->nBitmapHeight + 8;
996 lpmis->itemHeight = 15 + 8; /* default height */
1008 /***********************************************************************
1009 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1013 TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1015 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1016 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
1017 INT nIndex = 0, nButtons, nCount;
1020 TRACE("hwnd=%x wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
1024 if (lpAddBmp->hInst == HINST_COMMCTRL)
1026 if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR)
1028 else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR)
1030 else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR)
1035 TRACE ("adding %d internal bitmaps!\n", nButtons);
1037 /* Windows resize all the buttons to the size of a newly added standard image */
1038 if (lpAddBmp->nID & 1)
1041 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1042 MAKELPARAM((WORD)26, (WORD)26));
1043 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1044 MAKELPARAM((WORD)33, (WORD)33));
1049 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1050 MAKELPARAM((WORD)16, (WORD)16));
1051 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1052 MAKELPARAM((WORD)22, (WORD)22));
1055 TOOLBAR_CalcToolbar (hwnd);
1059 nButtons = (INT)wParam;
1063 TRACE ("adding %d bitmaps!\n", nButtons);
1066 if (!(infoPtr->himlDef)) {
1067 /* create new default image list */
1068 TRACE ("creating default image list!\n");
1071 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
1072 ILC_COLOR | ILC_MASK, nButtons, 2);
1073 infoPtr->himlInt = infoPtr->himlDef;
1076 nCount = ImageList_GetImageCount(infoPtr->himlDef);
1078 /* Add bitmaps to the default image list */
1079 if (lpAddBmp->hInst == (HINSTANCE)0)
1082 ImageList_AddMasked (infoPtr->himlDef, (HBITMAP)lpAddBmp->nID,
1085 else if (lpAddBmp->hInst == HINST_COMMCTRL)
1087 /* Add system bitmaps */
1088 switch (lpAddBmp->nID)
1090 case IDB_STD_SMALL_COLOR:
1091 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1092 MAKEINTRESOURCEA(IDB_STD_SMALL));
1093 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1094 hbmLoad, CLR_DEFAULT);
1095 DeleteObject (hbmLoad);
1098 case IDB_STD_LARGE_COLOR:
1099 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1100 MAKEINTRESOURCEA(IDB_STD_LARGE));
1101 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1102 hbmLoad, CLR_DEFAULT);
1103 DeleteObject (hbmLoad);
1106 case IDB_VIEW_SMALL_COLOR:
1107 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1108 MAKEINTRESOURCEA(IDB_VIEW_SMALL));
1109 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1110 hbmLoad, CLR_DEFAULT);
1111 DeleteObject (hbmLoad);
1114 case IDB_VIEW_LARGE_COLOR:
1115 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1116 MAKEINTRESOURCEA(IDB_VIEW_LARGE));
1117 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1118 hbmLoad, CLR_DEFAULT);
1119 DeleteObject (hbmLoad);
1122 case IDB_HIST_SMALL_COLOR:
1123 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1124 MAKEINTRESOURCEA(IDB_HIST_SMALL));
1125 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1126 hbmLoad, CLR_DEFAULT);
1127 DeleteObject (hbmLoad);
1130 case IDB_HIST_LARGE_COLOR:
1131 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1132 MAKEINTRESOURCEA(IDB_HIST_LARGE));
1133 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1134 hbmLoad, CLR_DEFAULT);
1135 DeleteObject (hbmLoad);
1139 nIndex = ImageList_GetImageCount (infoPtr->himlDef);
1140 ERR ("invalid imagelist!\n");
1146 hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
1147 nIndex = ImageList_AddMasked (infoPtr->himlDef, hbmLoad, CLR_DEFAULT);
1148 DeleteObject (hbmLoad);
1153 INT imagecount = ImageList_GetImageCount(infoPtr->himlDef);
1155 if (infoPtr->nNumBitmaps + nButtons != imagecount)
1157 WARN("Desired images do not match recieved images : Previous image number %i Previous images in list %i added %i expecting total %i, Images in list %i\n",
1158 infoPtr->nNumBitmaps, nCount, imagecount - nCount,
1159 infoPtr->nNumBitmaps+nButtons,imagecount);
1161 infoPtr->nNumBitmaps = imagecount;
1164 infoPtr->nNumBitmaps += nButtons;
1172 TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1174 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1175 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1176 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1178 TRACE("adding %d buttons!\n", wParam);
1180 nAddButtons = (UINT)wParam;
1181 nOldButtons = infoPtr->nNumButtons;
1182 nNewButtons = nOldButtons + nAddButtons;
1184 if (infoPtr->nNumButtons == 0) {
1186 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1189 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1191 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1192 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1193 nOldButtons * sizeof(TBUTTON_INFO));
1194 COMCTL32_Free (oldButtons);
1197 infoPtr->nNumButtons = nNewButtons;
1199 /* insert new button data */
1200 for (nCount = 0; nCount < nAddButtons; nCount++) {
1201 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1202 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1203 btnPtr->idCommand = lpTbb[nCount].idCommand;
1204 btnPtr->fsState = lpTbb[nCount].fsState;
1205 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1206 btnPtr->dwData = lpTbb[nCount].dwData;
1207 btnPtr->iString = lpTbb[nCount].iString;
1208 btnPtr->bHot = FALSE;
1210 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1213 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1214 ti.cbSize = sizeof (TTTOOLINFOA);
1216 ti.uId = btnPtr->idCommand;
1218 ti.lpszText = LPSTR_TEXTCALLBACKA;
1220 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
1225 TOOLBAR_CalcToolbar (hwnd);
1227 InvalidateRect(hwnd, NULL, FALSE);
1234 TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1236 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1237 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1238 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1240 TRACE("adding %d buttons!\n", wParam);
1242 nAddButtons = (UINT)wParam;
1243 nOldButtons = infoPtr->nNumButtons;
1244 nNewButtons = nOldButtons + nAddButtons;
1246 if (infoPtr->nNumButtons == 0) {
1248 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1251 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1253 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1254 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1255 nOldButtons * sizeof(TBUTTON_INFO));
1256 COMCTL32_Free (oldButtons);
1259 infoPtr->nNumButtons = nNewButtons;
1261 /* insert new button data */
1262 for (nCount = 0; nCount < nAddButtons; nCount++) {
1263 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1264 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1265 btnPtr->idCommand = lpTbb[nCount].idCommand;
1266 btnPtr->fsState = lpTbb[nCount].fsState;
1267 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1268 btnPtr->dwData = lpTbb[nCount].dwData;
1269 btnPtr->iString = lpTbb[nCount].iString;
1270 btnPtr->bHot = FALSE;
1272 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1275 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
1276 ti.cbSize = sizeof (TTTOOLINFOW);
1278 ti.uId = btnPtr->idCommand;
1280 ti.lpszText = LPSTR_TEXTCALLBACKW;
1282 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
1287 TOOLBAR_CalcToolbar (hwnd);
1289 InvalidateRect(hwnd, NULL, FALSE);
1296 TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1298 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1301 if ((wParam) && (HIWORD(lParam) == 0)) {
1304 TRACE("adding string from resource!\n");
1306 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
1309 TRACE("len=%d \"%s\"\n", len, szString);
1310 nIndex = infoPtr->nNumStrings;
1311 if (infoPtr->nNumStrings == 0) {
1313 COMCTL32_Alloc (sizeof(LPWSTR));
1316 LPWSTR *oldStrings = infoPtr->strings;
1318 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1319 memcpy (&infoPtr->strings[0], &oldStrings[0],
1320 sizeof(LPWSTR) * infoPtr->nNumStrings);
1321 COMCTL32_Free (oldStrings);
1324 infoPtr->strings[infoPtr->nNumStrings] =
1325 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1326 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
1327 infoPtr->nNumStrings++;
1330 LPSTR p = (LPSTR)lParam;
1335 TRACE("adding string(s) from array!\n");
1337 nIndex = infoPtr->nNumStrings;
1340 TRACE("len=%d \"%s\"\n", len, p);
1342 if (infoPtr->nNumStrings == 0) {
1344 COMCTL32_Alloc (sizeof(LPWSTR));
1347 LPWSTR *oldStrings = infoPtr->strings;
1349 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1350 memcpy (&infoPtr->strings[0], &oldStrings[0],
1351 sizeof(LPWSTR) * infoPtr->nNumStrings);
1352 COMCTL32_Free (oldStrings);
1355 infoPtr->strings[infoPtr->nNumStrings] =
1356 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1357 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
1358 infoPtr->nNumStrings++;
1369 TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1371 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1374 if ((wParam) && (HIWORD(lParam) == 0)) {
1375 WCHAR szString[256];
1377 TRACE("adding string from resource!\n");
1379 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
1382 TRACE("len=%d \"%s\"\n", len, debugstr_w(szString));
1383 TRACE("First char: 0x%x\n", *szString);
1384 if (szString[0] == L'|')
1386 PWSTR p = szString + 1;
1388 nIndex = infoPtr->nNumStrings;
1389 while (*p != L'|') {
1391 if (infoPtr->nNumStrings == 0) {
1393 COMCTL32_Alloc (sizeof(LPWSTR));
1396 LPWSTR *oldStrings = infoPtr->strings;
1398 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1399 memcpy (&infoPtr->strings[0], &oldStrings[0],
1400 sizeof(LPWSTR) * infoPtr->nNumStrings);
1401 COMCTL32_Free (oldStrings);
1404 len = COMCTL32_StrChrW (p, L'|') - p;
1405 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1406 infoPtr->strings[infoPtr->nNumStrings] =
1407 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1408 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1409 infoPtr->nNumStrings++;
1416 nIndex = infoPtr->nNumStrings;
1417 if (infoPtr->nNumStrings == 0) {
1419 COMCTL32_Alloc (sizeof(LPWSTR));
1422 LPWSTR *oldStrings = infoPtr->strings;
1424 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1425 memcpy (&infoPtr->strings[0], &oldStrings[0],
1426 sizeof(LPWSTR) * infoPtr->nNumStrings);
1427 COMCTL32_Free (oldStrings);
1430 infoPtr->strings[infoPtr->nNumStrings] =
1431 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1432 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
1433 infoPtr->nNumStrings++;
1437 LPWSTR p = (LPWSTR)lParam;
1442 TRACE("adding string(s) from array!\n");
1443 nIndex = infoPtr->nNumStrings;
1447 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1448 if (infoPtr->nNumStrings == 0) {
1450 COMCTL32_Alloc (sizeof(LPWSTR));
1453 LPWSTR *oldStrings = infoPtr->strings;
1455 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1456 memcpy (&infoPtr->strings[0], &oldStrings[0],
1457 sizeof(LPWSTR) * infoPtr->nNumStrings);
1458 COMCTL32_Free (oldStrings);
1461 infoPtr->strings[infoPtr->nNumStrings] =
1462 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1463 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1464 infoPtr->nNumStrings++;
1475 TOOLBAR_AutoSize (HWND hwnd)
1477 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1478 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1484 UINT uPosFlags = SWP_NOZORDER;
1486 TRACE("resize forced, style=%lx!\n", dwStyle);
1488 parent = GetParent (hwnd);
1489 GetClientRect(parent, &parent_rect);
1491 x = parent_rect.left;
1492 y = parent_rect.top;
1494 if (dwStyle & CCS_NORESIZE) {
1495 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
1500 infoPtr->nWidth = parent_rect.right - parent_rect.left;
1501 TOOLBAR_CalcToolbar (hwnd);
1502 InvalidateRect( hwnd, NULL, TRUE );
1503 cy = infoPtr->nHeight;
1504 cx = infoPtr->nWidth;
1506 if (dwStyle & CCS_NOMOVEY) {
1507 GetWindowRect(hwnd, &window_rect);
1508 ScreenToClient(parent, (LPPOINT)&window_rect.left);
1509 y = window_rect.top;
1513 if (dwStyle & CCS_NOPARENTALIGN)
1514 uPosFlags |= SWP_NOMOVE;
1516 if (!(dwStyle & CCS_NODIVIDER))
1517 cy += GetSystemMetrics(SM_CYEDGE);
1519 if (dwStyle & WS_BORDER)
1522 cy += GetSystemMetrics(SM_CYEDGE);
1523 cx += GetSystemMetrics(SM_CYEDGE);
1526 infoPtr->bAutoSize = TRUE;
1527 SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
1529 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
1530 * the setwindowpos calls */
1531 infoPtr->bAutoSize = FALSE;
1538 TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
1540 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1542 return infoPtr->nNumButtons;
1547 TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1549 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1551 if (infoPtr == NULL) {
1552 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
1553 ERR("infoPtr == NULL!\n");
1557 infoPtr->dwStructSize = (DWORD)wParam;
1564 TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1566 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1567 TBUTTON_INFO *btnPtr;
1570 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1574 btnPtr = &infoPtr->buttons[nIndex];
1575 btnPtr->iBitmap = LOWORD(lParam);
1577 RedrawWindow(hwnd,&btnPtr->rect,0,RDW_ERASE|RDW_INVALIDATE);
1584 TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1586 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1587 TBUTTON_INFO *btnPtr;
1590 BOOL bChecked = FALSE;
1592 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1596 btnPtr = &infoPtr->buttons[nIndex];
1598 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
1601 bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
1603 if (LOWORD(lParam) == FALSE)
1604 btnPtr->fsState &= ~TBSTATE_CHECKED;
1606 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
1608 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
1609 if (nOldIndex == nIndex)
1611 if (nOldIndex != -1)
1612 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
1614 btnPtr->fsState |= TBSTATE_CHECKED;
1617 if( bChecked != LOWORD(lParam) )
1619 if (nOldIndex != -1)
1620 RedrawWindow(hwnd,&infoPtr->buttons[nOldIndex].rect,(HRGN)NULL,
1621 RDW_ERASE|RDW_INVALIDATE);
1622 RedrawWindow(hwnd,&btnPtr->rect,0,RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
1625 /* FIXME: Send a WM_NOTIFY?? */
1632 TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
1634 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1636 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1641 TOOLBAR_Customize (HWND hwnd)
1643 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1649 /* send TBN_BEGINADJUST notification */
1650 nmhdr.hwndFrom = hwnd;
1651 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1652 nmhdr.code = TBN_BEGINADJUST;
1654 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1655 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1657 if (!(hRes = FindResourceA (COMCTL32_hModule,
1658 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
1662 if(!(template = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
1665 ret = DialogBoxIndirectParamA (GetWindowLongA (hwnd, GWL_HINSTANCE),
1666 (LPDLGTEMPLATEA)template,
1668 (DLGPROC)TOOLBAR_CustomizeDialogProc,
1671 /* send TBN_ENDADJUST notification */
1672 nmhdr.code = TBN_ENDADJUST;
1674 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1675 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1682 TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1684 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1685 INT nIndex = (INT)wParam;
1687 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1690 if ((infoPtr->hwndToolTip) &&
1691 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
1694 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1695 ti.cbSize = sizeof (TTTOOLINFOA);
1697 ti.uId = infoPtr->buttons[nIndex].idCommand;
1699 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
1702 if (infoPtr->nNumButtons == 1) {
1703 TRACE(" simple delete!\n");
1704 COMCTL32_Free (infoPtr->buttons);
1705 infoPtr->buttons = NULL;
1706 infoPtr->nNumButtons = 0;
1709 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1710 TRACE("complex delete! [nIndex=%d]\n", nIndex);
1712 infoPtr->nNumButtons--;
1713 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
1715 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1716 nIndex * sizeof(TBUTTON_INFO));
1719 if (nIndex < infoPtr->nNumButtons) {
1720 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
1721 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
1724 COMCTL32_Free (oldButtons);
1727 TOOLBAR_CalcToolbar (hwnd);
1729 InvalidateRect (hwnd, NULL, TRUE);
1736 TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1738 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1739 TBUTTON_INFO *btnPtr;
1743 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1747 btnPtr = &infoPtr->buttons[nIndex];
1749 bState = btnPtr->fsState & TBSTATE_ENABLED;
1751 /* update the toolbar button state */
1752 if(LOWORD(lParam) == FALSE) {
1753 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
1755 btnPtr->fsState |= TBSTATE_ENABLED;
1758 /* redraw the button only if the state of the button changed */
1759 if(bState != (btnPtr->fsState & TBSTATE_ENABLED)) {
1760 RedrawWindow(hwnd,&btnPtr->rect,0,RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
1767 static inline LRESULT
1768 TOOLBAR_GetAnchorHighlight (HWND hwnd)
1770 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1772 return infoPtr->bAnchor;
1777 TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1779 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1782 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1786 return infoPtr->buttons[nIndex].iBitmap;
1790 static inline LRESULT
1791 TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
1793 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
1798 TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1800 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1801 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1802 INT nIndex = (INT)wParam;
1803 TBUTTON_INFO *btnPtr;
1805 if (infoPtr == NULL)
1811 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1814 btnPtr = &infoPtr->buttons[nIndex];
1815 lpTbb->iBitmap = btnPtr->iBitmap;
1816 lpTbb->idCommand = btnPtr->idCommand;
1817 lpTbb->fsState = btnPtr->fsState;
1818 lpTbb->fsStyle = btnPtr->fsStyle;
1819 lpTbb->dwData = btnPtr->dwData;
1820 lpTbb->iString = btnPtr->iString;
1827 TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1829 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1830 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
1831 TBUTTON_INFO *btnPtr;
1834 if (infoPtr == NULL)
1836 if (lpTbInfo == NULL)
1838 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOA))
1841 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1845 btnPtr = &infoPtr->buttons[nIndex];
1847 if (lpTbInfo->dwMask & TBIF_COMMAND)
1848 lpTbInfo->idCommand = btnPtr->idCommand;
1849 if (lpTbInfo->dwMask & TBIF_IMAGE)
1850 lpTbInfo->iImage = btnPtr->iBitmap;
1851 if (lpTbInfo->dwMask & TBIF_LPARAM)
1852 lpTbInfo->lParam = btnPtr->dwData;
1853 if (lpTbInfo->dwMask & TBIF_SIZE)
1854 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1855 if (lpTbInfo->dwMask & TBIF_STATE)
1856 lpTbInfo->fsState = btnPtr->fsState;
1857 if (lpTbInfo->dwMask & TBIF_STYLE)
1858 lpTbInfo->fsStyle = btnPtr->fsStyle;
1859 if (lpTbInfo->dwMask & TBIF_TEXT) {
1860 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
1862 lstrcpynWtoA (lpTbInfo->pszText,
1863 (LPWSTR)infoPtr->strings[btnPtr->iString],
1866 else lpTbInfo->pszText[0]=0;
1873 TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1875 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1876 LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
1877 TBUTTON_INFO *btnPtr;
1880 if (infoPtr == NULL)
1882 if (lpTbInfo == NULL)
1884 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
1887 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1891 btnPtr = &infoPtr->buttons[nIndex];
1893 if (lpTbInfo->dwMask & TBIF_COMMAND)
1894 lpTbInfo->idCommand = btnPtr->idCommand;
1895 if (lpTbInfo->dwMask & TBIF_IMAGE)
1896 lpTbInfo->iImage = btnPtr->iBitmap;
1897 if (lpTbInfo->dwMask & TBIF_LPARAM)
1898 lpTbInfo->lParam = btnPtr->dwData;
1899 if (lpTbInfo->dwMask & TBIF_SIZE)
1900 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1901 if (lpTbInfo->dwMask & TBIF_STATE)
1902 lpTbInfo->fsState = btnPtr->fsState;
1903 if (lpTbInfo->dwMask & TBIF_STYLE)
1904 lpTbInfo->fsStyle = btnPtr->fsStyle;
1905 if (lpTbInfo->dwMask & TBIF_TEXT) {
1906 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
1907 lstrcpynW (lpTbInfo->pszText,
1908 (LPWSTR)infoPtr->strings[btnPtr->iString],
1917 TOOLBAR_GetButtonSize (HWND hwnd)
1919 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1921 return MAKELONG((WORD)infoPtr->nButtonWidth,
1922 (WORD)infoPtr->nButtonHeight);
1927 TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1929 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1930 INT nIndex, nStringIndex;
1932 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1936 nStringIndex = infoPtr->buttons[nIndex].iString;
1938 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
1940 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
1946 lstrcpyWtoA ((LPSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
1948 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
1953 TOOLBAR_GetButtonTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1955 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1956 INT nIndex, nStringIndex;
1958 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1962 nStringIndex = infoPtr->buttons[nIndex].iString;
1964 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
1966 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
1972 lstrcpyW ((LPWSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
1974 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
1978 /* << TOOLBAR_GetColorScheme >> */
1982 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1984 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1986 return (LRESULT)infoPtr->himlDis;
1990 inline static LRESULT
1991 TOOLBAR_GetExtendedStyle (HWND hwnd)
1993 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1995 return infoPtr->dwExStyle;
2000 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2002 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2004 return (LRESULT)infoPtr->himlHot;
2009 TOOLBAR_GetHotItem (HWND hwnd)
2011 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2013 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2016 if (infoPtr->nHotItem < 0)
2019 return (LRESULT)infoPtr->nHotItem;
2024 TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2026 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2028 return (LRESULT)infoPtr->himlDef;
2032 /* << TOOLBAR_GetInsertMark >> */
2033 /* << TOOLBAR_GetInsertMarkColor >> */
2037 TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2039 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2040 TBUTTON_INFO *btnPtr;
2044 if (infoPtr == NULL)
2046 nIndex = (INT)wParam;
2047 btnPtr = &infoPtr->buttons[nIndex];
2048 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2050 lpRect = (LPRECT)lParam;
2053 if (btnPtr->fsState & TBSTATE_HIDDEN)
2056 TOOLBAR_CalcToolbar( hwnd );
2058 lpRect->left = btnPtr->rect.left;
2059 lpRect->right = btnPtr->rect.right;
2060 lpRect->bottom = btnPtr->rect.bottom;
2061 lpRect->top = btnPtr->rect.top;
2068 TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2070 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2071 LPSIZE lpSize = (LPSIZE)lParam;
2076 lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
2077 lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
2079 TRACE("maximum size %d x %d\n",
2080 infoPtr->rcBound.right - infoPtr->rcBound.left,
2081 infoPtr->rcBound.bottom - infoPtr->rcBound.top);
2087 /* << TOOLBAR_GetObject >> */
2088 /* << TOOLBAR_GetPadding >> */
2092 TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2094 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2095 TBUTTON_INFO *btnPtr;
2099 if (infoPtr == NULL)
2101 nIndex = (INT)wParam;
2102 btnPtr = &infoPtr->buttons[nIndex];
2103 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2105 lpRect = (LPRECT)lParam;
2109 lpRect->left = btnPtr->rect.left;
2110 lpRect->right = btnPtr->rect.right;
2111 lpRect->bottom = btnPtr->rect.bottom;
2112 lpRect->top = btnPtr->rect.top;
2119 TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2121 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2123 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
2124 return infoPtr->nRows;
2131 TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2133 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2136 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2140 return infoPtr->buttons[nIndex].fsState;
2145 TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2147 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2150 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2154 return infoPtr->buttons[nIndex].fsStyle;
2159 TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2161 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2163 if (infoPtr == NULL)
2166 return infoPtr->nMaxTextRows;
2171 TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
2173 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2175 if (infoPtr == NULL)
2177 return infoPtr->hwndToolTip;
2182 TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2184 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2186 TRACE("%s hwnd=0x%x stub!\n",
2187 infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
2189 return infoPtr->bUnicode;
2193 inline static LRESULT
2194 TOOLBAR_GetVersion (HWND hwnd)
2196 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2197 return infoPtr->iVersion;
2202 TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2204 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2205 TBUTTON_INFO *btnPtr;
2208 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2212 btnPtr = &infoPtr->buttons[nIndex];
2213 if (LOWORD(lParam) == FALSE)
2214 btnPtr->fsState &= ~TBSTATE_HIDDEN;
2216 btnPtr->fsState |= TBSTATE_HIDDEN;
2218 TOOLBAR_CalcToolbar (hwnd);
2220 InvalidateRect (hwnd, NULL, TRUE);
2226 inline static LRESULT
2227 TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2229 return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
2234 TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2236 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2237 TBUTTON_INFO *btnPtr;
2240 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2244 btnPtr = &infoPtr->buttons[nIndex];
2245 if (LOWORD(lParam) == FALSE)
2246 btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
2248 btnPtr->fsState |= TBSTATE_INDETERMINATE;
2250 RedrawWindow(hwnd,&btnPtr->rect,0,
2251 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
2258 TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2260 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2261 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2262 INT nIndex = (INT)wParam;
2263 TBUTTON_INFO *oldButtons;
2269 /* EPP: this seems to be an undocumented call (from my IE4)
2270 * I assume in that case that:
2271 * - lpTbb->iString is a string pointer (not a string index in strings[] table
2272 * - index of insertion is at the end of existing buttons
2273 * I only see this happen with nIndex == -1, but it could have a special
2274 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
2279 if(lpTbb->iString) {
2280 len = lstrlenA((char*)lpTbb->iString) + 2;
2281 ptr = COMCTL32_Alloc(len);
2282 nIndex = infoPtr->nNumButtons;
2283 strcpy(ptr, (char*)lpTbb->iString);
2284 ptr[len - 1] = 0; /* ended by two '\0' */
2285 lpTbb->iString = TOOLBAR_AddStringA(hwnd, 0, (LPARAM)ptr);
2289 ERR("lpTbb->iString is NULL\n");
2293 } else if (nIndex < 0)
2296 TRACE("inserting button index=%d\n", nIndex);
2297 if (nIndex > infoPtr->nNumButtons) {
2298 nIndex = infoPtr->nNumButtons;
2299 TRACE("adjust index=%d\n", nIndex);
2302 oldButtons = infoPtr->buttons;
2303 infoPtr->nNumButtons++;
2304 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2305 /* pre insert copy */
2307 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2308 nIndex * sizeof(TBUTTON_INFO));
2311 /* insert new button */
2312 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2313 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2314 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2315 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2316 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2317 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2319 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2322 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2323 ti.cbSize = sizeof (TTTOOLINFOA);
2325 ti.uId = lpTbb->idCommand;
2327 ti.lpszText = LPSTR_TEXTCALLBACKA;
2329 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
2333 /* post insert copy */
2334 if (nIndex < infoPtr->nNumButtons - 1) {
2335 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2336 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2339 COMCTL32_Free (oldButtons);
2341 TOOLBAR_CalcToolbar (hwnd);
2343 InvalidateRect (hwnd, NULL, FALSE);
2350 TOOLBAR_InsertButtonW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2352 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2353 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2354 INT nIndex = (INT)wParam;
2355 TBUTTON_INFO *oldButtons;
2362 TRACE("inserting button index=%d\n", nIndex);
2363 if (nIndex > infoPtr->nNumButtons) {
2364 nIndex = infoPtr->nNumButtons;
2365 TRACE("adjust index=%d\n", nIndex);
2368 oldButtons = infoPtr->buttons;
2369 infoPtr->nNumButtons++;
2370 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2371 /* pre insert copy */
2373 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2374 nIndex * sizeof(TBUTTON_INFO));
2377 /* insert new button */
2378 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2379 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2380 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2381 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2382 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2383 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2385 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2388 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
2389 ti.cbSize = sizeof (TTTOOLINFOW);
2391 ti.uId = lpTbb->idCommand;
2393 ti.lpszText = LPSTR_TEXTCALLBACKW;
2395 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
2399 /* post insert copy */
2400 if (nIndex < infoPtr->nNumButtons - 1) {
2401 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2402 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2405 COMCTL32_Free (oldButtons);
2407 TOOLBAR_CalcToolbar (hwnd);
2409 InvalidateRect (hwnd, NULL, FALSE);
2415 /* << TOOLBAR_InsertMarkHitTest >> */
2419 TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
2421 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2424 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2428 return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
2433 TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
2435 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2438 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2442 return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
2447 TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
2449 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2452 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2456 return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
2461 TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
2463 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2466 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2470 return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
2475 TOOLBAR_IsButtonIndeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2477 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2480 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2484 return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
2489 TOOLBAR_IsButtonPressed (HWND hwnd, WPARAM wParam, LPARAM lParam)
2491 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2494 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2498 return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
2502 /* << TOOLBAR_LoadImages >> */
2503 /* << TOOLBAR_MapAccelerator >> */
2504 /* << TOOLBAR_MarkButton >> */
2505 /* << TOOLBAR_MoveButton >> */
2509 TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2511 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2512 TBUTTON_INFO *btnPtr;
2515 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2519 btnPtr = &infoPtr->buttons[nIndex];
2520 if (LOWORD(lParam) == FALSE)
2521 btnPtr->fsState &= ~TBSTATE_PRESSED;
2523 btnPtr->fsState |= TBSTATE_PRESSED;
2525 RedrawWindow(hwnd,&btnPtr->rect,0,
2526 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
2532 /* << TOOLBAR_ReplaceBitmap >> */
2536 TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2539 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2540 LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
2542 if (lpSave == NULL) return 0;
2545 /* save toolbar information */
2546 FIXME("save to \"%s\" \"%s\"\n",
2547 lpSave->pszSubKey, lpSave->pszValueName);
2552 /* restore toolbar information */
2554 FIXME("restore from \"%s\" \"%s\"\n",
2555 lpSave->pszSubKey, lpSave->pszValueName);
2566 TOOLBAR_SaveRestoreW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2569 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2570 LPTBSAVEPARAMSW lpSave = (LPTBSAVEPARAMSW)lParam;
2576 /* save toolbar information */
2577 FIXME("save to \"%s\" \"%s\"\n",
2578 lpSave->pszSubKey, lpSave->pszValueName);
2583 /* restore toolbar information */
2585 FIXME("restore from \"%s\" \"%s\"\n",
2586 lpSave->pszSubKey, lpSave->pszValueName);
2597 TOOLBAR_SetAnchorHighlight (HWND hwnd, WPARAM wParam)
2599 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2600 BOOL bOldAnchor = infoPtr->bAnchor;
2602 infoPtr->bAnchor = (BOOL)wParam;
2604 return (LRESULT)bOldAnchor;
2609 TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2611 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2613 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
2616 if (infoPtr->nNumButtons > 0)
2617 WARN("%d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n",
2618 infoPtr->nNumButtons,
2619 infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
2620 LOWORD(lParam), HIWORD(lParam));
2622 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
2623 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
2625 /* uses image list internals directly */
2626 if (infoPtr->himlDef) {
2627 infoPtr->himlDef->cx = infoPtr->nBitmapWidth;
2628 infoPtr->himlDef->cy = infoPtr->nBitmapHeight;
2636 TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2638 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2639 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
2640 TBUTTON_INFO *btnPtr;
2645 if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
2648 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2652 btnPtr = &infoPtr->buttons[nIndex];
2653 if (lptbbi->dwMask & TBIF_COMMAND)
2654 btnPtr->idCommand = lptbbi->idCommand;
2655 if (lptbbi->dwMask & TBIF_IMAGE)
2656 btnPtr->iBitmap = lptbbi->iImage;
2657 if (lptbbi->dwMask & TBIF_LPARAM)
2658 btnPtr->dwData = lptbbi->lParam;
2659 /* if (lptbbi->dwMask & TBIF_SIZE) */
2660 /* btnPtr->cx = lptbbi->cx; */
2661 if (lptbbi->dwMask & TBIF_STATE)
2662 btnPtr->fsState = lptbbi->fsState;
2663 if (lptbbi->dwMask & TBIF_STYLE)
2664 btnPtr->fsStyle = lptbbi->fsStyle;
2666 if (lptbbi->dwMask & TBIF_TEXT) {
2667 if ((btnPtr->iString >= 0) ||
2668 (btnPtr->iString < infoPtr->nNumStrings)) {
2669 TRACE("Ooooooch\n");
2671 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2672 INT len = lstrlenA (lptbbi->pszText);
2673 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
2676 /* this is the ultimate sollution */
2677 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2686 TOOLBAR_SetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2688 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2689 LPTBBUTTONINFOW lptbbi = (LPTBBUTTONINFOW)lParam;
2690 TBUTTON_INFO *btnPtr;
2695 if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
2698 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2702 btnPtr = &infoPtr->buttons[nIndex];
2703 if (lptbbi->dwMask & TBIF_COMMAND)
2704 btnPtr->idCommand = lptbbi->idCommand;
2705 if (lptbbi->dwMask & TBIF_IMAGE)
2706 btnPtr->iBitmap = lptbbi->iImage;
2707 if (lptbbi->dwMask & TBIF_LPARAM)
2708 btnPtr->dwData = lptbbi->lParam;
2709 /* if (lptbbi->dwMask & TBIF_SIZE) */
2710 /* btnPtr->cx = lptbbi->cx; */
2711 if (lptbbi->dwMask & TBIF_STATE)
2712 btnPtr->fsState = lptbbi->fsState;
2713 if (lptbbi->dwMask & TBIF_STYLE)
2714 btnPtr->fsStyle = lptbbi->fsStyle;
2716 if (lptbbi->dwMask & TBIF_TEXT) {
2717 if ((btnPtr->iString >= 0) ||
2718 (btnPtr->iString < infoPtr->nNumStrings)) {
2720 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2721 INT len = lstrlenW (lptbbi->pszText);
2722 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
2725 /* this is the ultimate sollution */
2726 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2735 TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2737 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2739 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
2741 ERR("invalid parameter\n");
2745 /* Button size can only be set before adding any button to the toolbar
2746 according to the documentation. */
2747 /* this appears to be wrong. WINZIP32.EXE (ver 8) calls this on
2748 one of its buttons after adding it to the toolbar, and it
2749 checks that the return value is nonzero - mjm */
2750 if( infoPtr->nNumButtons != 0 )
2752 FIXME("Button size set after button in toolbar\n");
2756 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
2757 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
2763 TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
2765 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2767 if (infoPtr == NULL)
2770 infoPtr->cxMin = (INT)LOWORD(lParam);
2771 infoPtr->cxMax = (INT)HIWORD(lParam);
2778 TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
2780 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2781 INT nIndex = (INT)wParam;
2783 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2786 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
2788 if (infoPtr->hwndToolTip) {
2790 FIXME("change tool tip!\n");
2798 /* << TOOLBAR_SetColorScheme >> */
2802 TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2804 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2805 HIMAGELIST himlTemp;
2808 himlTemp = infoPtr->himlDis;
2809 infoPtr->himlDis = (HIMAGELIST)lParam;
2811 /* FIXME: redraw ? */
2813 return (LRESULT)himlTemp;
2818 TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
2820 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2823 dwTemp = infoPtr->dwDTFlags;
2824 infoPtr->dwDTFlags =
2825 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
2827 return (LRESULT)dwTemp;
2832 TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2834 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2837 dwTemp = infoPtr->dwExStyle;
2838 infoPtr->dwExStyle = (DWORD)lParam;
2840 return (LRESULT)dwTemp;
2845 TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2847 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2848 HIMAGELIST himlTemp;
2850 himlTemp = infoPtr->himlHot;
2851 infoPtr->himlHot = (HIMAGELIST)lParam;
2853 /* FIXME: redraw ? */
2855 return (LRESULT)himlTemp;
2860 TOOLBAR_SetHotItem (HWND hwnd, WPARAM wParam)
2862 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2863 INT nOldHotItem = infoPtr->nHotItem;
2865 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
2867 infoPtr->nHotItem = (INT)wParam;
2869 /* FIXME: What else must be done ??? */
2873 if (nOldHotItem < 0)
2876 return (LRESULT)nOldHotItem;
2881 TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2883 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2884 HIMAGELIST himlTemp;
2886 himlTemp = infoPtr->himlDef;
2887 infoPtr->himlDef = (HIMAGELIST)lParam;
2889 infoPtr->nNumBitmaps = ImageList_GetImageCount(infoPtr->himlDef);
2890 /* FIXME: redraw ? */
2892 return (LRESULT)himlTemp;
2897 TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2899 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2901 infoPtr->nIndent = (INT)wParam;
2903 TOOLBAR_CalcToolbar (hwnd);
2905 InvalidateRect(hwnd, NULL, FALSE);
2911 /* << TOOLBAR_SetInsertMark >> */
2915 TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2917 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2919 infoPtr->clrInsertMark = (COLORREF)lParam;
2921 /* FIXME : redraw ??*/
2928 TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2930 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2932 if (infoPtr == NULL)
2935 infoPtr->nMaxTextRows = (INT)wParam;
2941 /* << TOOLBAR_SetPadding >> */
2945 TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2947 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2950 if (infoPtr == NULL)
2952 hwndOldNotify = infoPtr->hwndNotify;
2953 infoPtr->hwndNotify = (HWND)wParam;
2955 return hwndOldNotify;
2960 TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2962 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2963 LPRECT lprc = (LPRECT)lParam;
2965 if (LOWORD(wParam) > 1) {
2967 FIXME("multiple rows not supported!\n");
2971 /* recalculate toolbar */
2972 TOOLBAR_CalcToolbar (hwnd);
2974 /* return bounding rectangle */
2976 lprc->left = infoPtr->rcBound.left;
2977 lprc->right = infoPtr->rcBound.right;
2978 lprc->top = infoPtr->rcBound.top;
2979 lprc->bottom = infoPtr->rcBound.bottom;
2982 /* repaint toolbar */
2983 InvalidateRect(hwnd, NULL, FALSE);
2990 TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2992 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2993 TBUTTON_INFO *btnPtr;
2996 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3000 btnPtr = &infoPtr->buttons[nIndex];
3001 btnPtr->fsState = LOWORD(lParam);
3003 RedrawWindow(hwnd,&btnPtr->rect,0,
3004 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3011 TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3013 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3014 TBUTTON_INFO *btnPtr;
3017 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3021 btnPtr = &infoPtr->buttons[nIndex];
3022 btnPtr->fsStyle = LOWORD(lParam);
3024 RedrawWindow(hwnd,&btnPtr->rect,0,
3025 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3027 if (infoPtr->hwndToolTip) {
3029 FIXME("change tool tip!\n");
3037 inline static LRESULT
3038 TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
3040 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3042 if (infoPtr == NULL)
3044 infoPtr->hwndToolTip = (HWND)wParam;
3050 TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
3052 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3055 TRACE("%s hwnd=0x%04x stub!\n",
3056 ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
3058 bTemp = infoPtr->bUnicode;
3059 infoPtr->bUnicode = (BOOL)wParam;
3066 TOOLBAR_SetVersion (HWND hwnd, INT iVersion)
3068 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3069 INT iOldVersion = infoPtr->iVersion;
3071 infoPtr->iVersion = iVersion;
3078 TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
3080 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3081 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3084 /* initialize info structure */
3085 infoPtr->nButtonHeight = 22;
3086 infoPtr->nButtonWidth = 24;
3087 infoPtr->nBitmapHeight = 15;
3088 infoPtr->nBitmapWidth = 16;
3090 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
3092 infoPtr->nMaxTextRows = 1;
3093 infoPtr->cxMin = -1;
3094 infoPtr->cxMax = -1;
3095 infoPtr->nNumBitmaps = 0;
3096 infoPtr->nNumStrings = 0;
3098 infoPtr->bCaptured = FALSE;
3099 infoPtr->bUnicode = IsWindowUnicode (hwnd);
3100 infoPtr->nButtonDown = -1;
3101 infoPtr->nOldHit = -1;
3102 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3103 infoPtr->hwndNotify = GetParent (hwnd);
3104 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
3105 infoPtr->dwDTFlags = (dwStyle & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE : DT_CENTER;
3106 infoPtr->bAnchor = FALSE; /* no anchor highlighting */
3107 infoPtr->iVersion = 0;
3109 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
3110 infoPtr->hFont = CreateFontIndirectA (&logFont);
3112 if (dwStyle & TBSTYLE_TOOLTIPS) {
3113 /* Create tooltip control */
3114 infoPtr->hwndToolTip =
3115 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
3116 CW_USEDEFAULT, CW_USEDEFAULT,
3117 CW_USEDEFAULT, CW_USEDEFAULT,
3120 /* Send NM_TOOLTIPSCREATED notification */
3121 if (infoPtr->hwndToolTip) {
3122 NMTOOLTIPSCREATED nmttc;
3124 nmttc.hdr.hwndFrom = hwnd;
3125 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3126 nmttc.hdr.code = NM_TOOLTIPSCREATED;
3127 nmttc.hwndToolTips = infoPtr->hwndToolTip;
3129 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3130 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
3139 TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
3141 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3143 /* delete tooltip control */
3144 if (infoPtr->hwndToolTip)
3145 DestroyWindow (infoPtr->hwndToolTip);
3147 /* delete button data */
3148 if (infoPtr->buttons)
3149 COMCTL32_Free (infoPtr->buttons);
3151 /* delete strings */
3152 if (infoPtr->strings) {
3154 for (i = 0; i < infoPtr->nNumStrings; i++)
3155 if (infoPtr->strings[i])
3156 COMCTL32_Free (infoPtr->strings[i]);
3158 COMCTL32_Free (infoPtr->strings);
3161 /* destroy internal image list */
3162 if (infoPtr->himlInt)
3163 ImageList_Destroy (infoPtr->himlInt);
3165 /* delete default font */
3167 DeleteObject (infoPtr->hFont);
3169 /* free toolbar info data */
3170 COMCTL32_Free (infoPtr);
3171 SetWindowLongA (hwnd, 0, 0);
3178 TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
3180 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3182 if (infoPtr->bTransparent)
3183 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
3185 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
3190 TOOLBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
3192 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3194 return infoPtr->hFont;
3199 TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
3201 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3202 TBUTTON_INFO *btnPtr;
3206 pt.x = (INT)LOWORD(lParam);
3207 pt.y = (INT)HIWORD(lParam);
3208 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3211 btnPtr = &infoPtr->buttons[nHit];
3212 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3215 infoPtr->bCaptured = TRUE;
3216 infoPtr->nButtonDown = nHit;
3218 btnPtr->fsState |= TBSTATE_PRESSED;
3220 RedrawWindow(hwnd,&btnPtr->rect,0,
3221 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3223 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
3224 TOOLBAR_Customize (hwnd);
3231 TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
3233 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3234 TBUTTON_INFO *btnPtr;
3238 if (infoPtr->hwndToolTip)
3239 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3240 WM_LBUTTONDOWN, wParam, lParam);
3242 pt.x = (INT)LOWORD(lParam);
3243 pt.y = (INT)HIWORD(lParam);
3244 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3247 btnPtr = &infoPtr->buttons[nHit];
3248 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3251 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN)
3255 nmtb.hdr.hwndFrom = hwnd;
3256 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3257 nmtb.hdr.code = TBN_DROPDOWN;
3258 nmtb.iItem = btnPtr->idCommand;
3260 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3261 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3265 infoPtr->bCaptured = TRUE;
3266 infoPtr->nButtonDown = nHit;
3267 infoPtr->nOldHit = nHit;
3269 btnPtr->fsState |= TBSTATE_PRESSED;
3270 btnPtr->bHot = FALSE;
3272 RedrawWindow(hwnd,&btnPtr->rect,0,
3273 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3280 TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
3282 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3283 TBUTTON_INFO *btnPtr;
3287 BOOL bSendMessage = TRUE;
3289 if (infoPtr->hwndToolTip)
3290 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3291 WM_LBUTTONUP, wParam, lParam);
3293 pt.x = (INT)LOWORD(lParam);
3294 pt.y = (INT)HIWORD(lParam);
3295 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3297 /* restore hot effect to hot button disabled by TOOLBAR_LButtonDown() */
3298 if(infoPtr->nHotItem >= 0)
3299 infoPtr->buttons[infoPtr->nHotItem].bHot = TRUE;
3301 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
3302 infoPtr->bCaptured = FALSE;
3304 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3305 btnPtr->fsState &= ~TBSTATE_PRESSED;
3307 if (nHit == infoPtr->nButtonDown) {
3308 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
3309 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
3310 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
3311 infoPtr->nButtonDown);
3312 if (nOldIndex == infoPtr->nButtonDown)
3313 bSendMessage = FALSE;
3314 if ((nOldIndex != infoPtr->nButtonDown) &&
3316 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
3317 btnPtr->fsState |= TBSTATE_CHECKED;
3320 if (btnPtr->fsState & TBSTATE_CHECKED)
3321 btnPtr->fsState &= ~TBSTATE_CHECKED;
3323 btnPtr->fsState |= TBSTATE_CHECKED;
3328 bSendMessage = FALSE;
3330 if (nOldIndex != -1)
3331 RedrawWindow(hwnd,&infoPtr->buttons[nOldIndex].rect,0,
3332 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3333 RedrawWindow(hwnd,&btnPtr->rect,0,
3334 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3337 SendMessageA (GetParent(hwnd), WM_COMMAND,
3338 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
3340 // if ((GetWindowLongA(hwnd, GWL_STYLE) & TBSTYLE_DROPDOWN) ||
3341 // (btnPtr->fsStyle & 0x08/* BTNS_DROPDOWN */)) {
3343 * This appears to be an error. Instead of checking the style of the
3344 * button in question wine was checking the style of the toolbar
3345 * itself. This caused a number of strange behaviors. In my
3346 * invistigation i think the whole dropdown thing is still fairly
3347 * broken. but this helps fix some of the problems.
3350 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN) {
3353 nmtb.hdr.hwndFrom = hwnd;
3354 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3355 nmtb.hdr.code = TBN_DROPDOWN;
3357 /* nmtb.tbButton not used with TBN_DROPDOWN */
3358 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings)) {
3359 nmtb.pszText = infoPtr->strings[btnPtr->iString];
3360 nmtb.cchText = lstrlenW(nmtb.pszText);
3362 nmtb.pszText = NULL;
3365 nmtb.rcButton = btnPtr->rect;
3367 SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
3368 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3371 infoPtr->nButtonDown = -1;
3372 infoPtr->nOldHit = -1;
3379 TOOLBAR_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam)
3381 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3382 TBUTTON_INFO *hotBtnPtr;
3384 if (infoPtr->nOldHit < 0)
3387 hotBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3389 /* Redraw the button if the last button we were over is the hot button and it
3391 if((infoPtr->nOldHit == infoPtr->nHotItem) && (hotBtnPtr->fsState & TBSTATE_ENABLED))
3393 hotBtnPtr->bHot = FALSE;
3395 InvalidateRect (hwnd, &hotBtnPtr->rect, TRUE);
3398 infoPtr->nOldHit = -1; /* reset the old hit index as we've left the toolbar */
3399 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3405 TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
3407 TBUTTON_INFO *btnPtr, *oldBtnPtr;
3408 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3411 TRACKMOUSEEVENT trackinfo;
3413 /* fill in the TRACKMOUSEEVENT struct */
3414 trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
3415 trackinfo.dwFlags = TME_QUERY;
3416 trackinfo.hwndTrack = hwnd;
3417 trackinfo.dwHoverTime = HOVER_DEFAULT;
3419 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
3420 _TrackMouseEvent(&trackinfo);
3422 /* Make sure tracking is enabled so we recieve a WM_MOUSELEAVE message */
3423 if(!(trackinfo.dwFlags & TME_LEAVE)) {
3424 trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
3426 /* call TRACKMOUSEEVENT so we recieve a WM_MOUSELEAVE message */
3427 /* and can properly deactivate the hot toolbar button */
3428 _TrackMouseEvent(&trackinfo);
3431 if (infoPtr->hwndToolTip)
3432 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3433 WM_MOUSEMOVE, wParam, lParam);
3435 pt.x = (INT)LOWORD(lParam);
3436 pt.y = (INT)HIWORD(lParam);
3438 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3440 if (infoPtr->nOldHit != nHit)
3442 /* Remove the effect of an old hot button if the button was enabled and was
3443 drawn with the hot button effect */
3444 if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem &&
3445 (infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED))
3447 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3448 oldBtnPtr->bHot = FALSE;
3450 InvalidateRect (hwnd, &oldBtnPtr->rect, TRUE);
3453 /* It's not a separator or in nowhere. It's a hot button. */
3456 btnPtr = &infoPtr->buttons[nHit];
3457 btnPtr->bHot = TRUE;
3459 infoPtr->nHotItem = nHit;
3461 /* only enabled buttons show hot effect */
3462 if(infoPtr->buttons[nHit].fsState & TBSTATE_ENABLED)
3464 RedrawWindow(hwnd,&btnPtr->rect,0,
3465 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3469 if (infoPtr->bCaptured) {
3470 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3471 if (infoPtr->nOldHit == infoPtr->nButtonDown) {
3472 btnPtr->fsState &= ~TBSTATE_PRESSED;
3473 RedrawWindow(hwnd,&btnPtr->rect,0,
3474 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3476 else if (nHit == infoPtr->nButtonDown) {
3477 btnPtr->fsState |= TBSTATE_PRESSED;
3478 RedrawWindow(hwnd,&btnPtr->rect,0,
3479 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3482 infoPtr->nOldHit = nHit;
3488 inline static LRESULT
3489 TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3491 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
3492 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
3494 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
3498 inline static LRESULT
3499 TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3501 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
3502 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
3504 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
3509 TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3511 TOOLBAR_INFO *infoPtr;
3513 /* allocate memory for info structure */
3514 infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
3515 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
3518 infoPtr->dwStructSize = sizeof(TBBUTTON);
3520 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
3521 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
3522 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
3523 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
3526 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
3531 TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3533 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3537 if (dwStyle & WS_MINIMIZE)
3538 return 0; /* Nothing to do */
3540 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
3542 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
3545 if (!(dwStyle & CCS_NODIVIDER))
3547 GetWindowRect (hwnd, &rcWindow);
3548 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3549 if( dwStyle & WS_BORDER )
3550 OffsetRect (&rcWindow, 1, 1);
3551 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
3554 ReleaseDC( hwnd, hdc );
3560 inline static LRESULT
3561 TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
3563 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3564 LPNMHDR lpnmh = (LPNMHDR)lParam;
3566 TRACE("passing WM_NOTIFY!\n");
3568 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
3569 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
3572 if (lpnmh->code == TTN_GETDISPINFOA) {
3573 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
3575 FIXME("retrieving ASCII string\n");
3578 else if (lpnmh->code == TTN_GETDISPINFOW) {
3579 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
3581 FIXME("retrieving UNICODE string\n");
3592 TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
3594 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3598 /* fill ps.rcPaint with a default rect */
3599 memcpy(&(ps.rcPaint), &(infoPtr->rcBound), sizeof(infoPtr->rcBound));
3601 TOOLBAR_CalcToolbar( hwnd );
3602 hdc = wParam==0 ? BeginPaint(hwnd, &ps) : (HDC)wParam;
3603 TOOLBAR_Refresh (hwnd, hdc, &ps);
3604 if (!wParam) EndPaint (hwnd, &ps);
3611 TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
3613 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3614 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3623 /* Resize deadlock check */
3624 if (infoPtr->bAutoSize) {
3625 infoPtr->bAutoSize = FALSE;
3629 flags = (INT) wParam;
3631 /* FIXME for flags =
3632 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
3635 TRACE("sizing toolbar!\n");
3637 if (flags == SIZE_RESTORED) {
3638 /* width and height don't apply */
3639 parent = GetParent (hwnd);
3640 GetClientRect(parent, &parent_rect);
3641 x = parent_rect.left;
3642 y = parent_rect.top;
3644 if (dwStyle & CCS_NORESIZE) {
3645 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
3648 * this sets the working width of the toolbar, and
3649 * Calc Toolbar will not adjust it, only the height
3651 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3652 cy = infoPtr->nHeight;
3653 cx = infoPtr->nWidth;
3654 TOOLBAR_CalcToolbar (hwnd);
3655 infoPtr->nWidth = cx;
3656 infoPtr->nHeight = cy;
3659 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3660 TOOLBAR_CalcToolbar (hwnd);
3661 cy = infoPtr->nHeight;
3662 cx = infoPtr->nWidth;
3664 if (dwStyle & CCS_NOMOVEY) {
3665 GetWindowRect(hwnd, &window_rect);
3666 ScreenToClient(parent, (LPPOINT)&window_rect.left);
3667 y = window_rect.top;
3671 if (dwStyle & CCS_NOPARENTALIGN) {
3672 uPosFlags |= SWP_NOMOVE;
3673 cy = infoPtr->nHeight;
3674 cx = infoPtr->nWidth;
3677 if (!(dwStyle & CCS_NODIVIDER))
3678 cy += GetSystemMetrics(SM_CYEDGE);
3680 if (dwStyle & WS_BORDER)
3683 cy += GetSystemMetrics(SM_CYEDGE);
3684 cx += GetSystemMetrics(SM_CYEDGE);
3687 SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
3688 cx, cy, uPosFlags | SWP_NOZORDER);
3695 TOOLBAR_StyleChanged (HWND hwnd, INT nType, LPSTYLESTRUCT lpStyle)
3697 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3699 if (nType == GWL_STYLE) {
3700 if (lpStyle->styleNew & TBSTYLE_LIST) {
3701 infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
3704 infoPtr->dwDTFlags = DT_CENTER;
3708 TOOLBAR_AutoSize (hwnd);
3710 InvalidateRect(hwnd, NULL, FALSE);
3717 static LRESULT WINAPI
3718 ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3724 return TOOLBAR_Destroy (hwnd, wParam, lParam);
3727 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
3730 if (!TOOLBAR_GetInfoPtr (hwnd))
3732 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3738 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
3740 case TB_ADDBUTTONSA:
3741 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
3743 case TB_ADDBUTTONSW:
3744 return TOOLBAR_AddButtonsW (hwnd, wParam, lParam);
3747 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
3750 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
3753 return TOOLBAR_AutoSize (hwnd);
3755 case TB_BUTTONCOUNT:
3756 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
3758 case TB_BUTTONSTRUCTSIZE:
3759 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
3761 case TB_CHANGEBITMAP:
3762 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
3764 case TB_CHECKBUTTON:
3765 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
3767 case TB_COMMANDTOINDEX:
3768 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
3771 return TOOLBAR_Customize (hwnd);
3773 case TB_DELETEBUTTON:
3774 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
3776 case TB_ENABLEBUTTON:
3777 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
3779 case TB_GETANCHORHIGHLIGHT:
3780 return TOOLBAR_GetAnchorHighlight (hwnd);
3783 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
3785 case TB_GETBITMAPFLAGS:
3786 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
3789 return TOOLBAR_GetButton (hwnd, wParam, lParam);
3791 case TB_GETBUTTONINFOA:
3792 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
3794 case TB_GETBUTTONINFOW:
3795 return TOOLBAR_GetButtonInfoW (hwnd, wParam, lParam);
3797 case TB_GETBUTTONSIZE:
3798 return TOOLBAR_GetButtonSize (hwnd);
3800 case TB_GETBUTTONTEXTA:
3801 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
3803 case TB_GETBUTTONTEXTW:
3804 return TOOLBAR_GetButtonTextW (hwnd, wParam, lParam);
3806 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
3808 case TB_GETDISABLEDIMAGELIST:
3809 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
3811 case TB_GETEXTENDEDSTYLE:
3812 return TOOLBAR_GetExtendedStyle (hwnd);
3814 case TB_GETHOTIMAGELIST:
3815 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
3818 return TOOLBAR_GetHotItem (hwnd);
3820 case TB_GETIMAGELIST:
3821 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
3823 /* case TB_GETINSERTMARK: */ /* 4.71 */
3824 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
3826 case TB_GETITEMRECT:
3827 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
3830 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
3832 /* case TB_GETOBJECT: */ /* 4.71 */
3833 /* case TB_GETPADDING: */ /* 4.71 */
3836 return TOOLBAR_GetRect (hwnd, wParam, lParam);
3839 return TOOLBAR_GetRows (hwnd, wParam, lParam);
3842 return TOOLBAR_GetState (hwnd, wParam, lParam);
3845 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
3847 case TB_GETTEXTROWS:
3848 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
3850 case TB_GETTOOLTIPS:
3851 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
3853 case TB_GETUNICODEFORMAT:
3854 return TOOLBAR_GetUnicodeFormat (hwnd, wParam, lParam);
3856 case CCM_GETVERSION:
3857 return TOOLBAR_GetVersion (hwnd);
3860 return TOOLBAR_HideButton (hwnd, wParam, lParam);
3863 return TOOLBAR_HitTest (hwnd, wParam, lParam);
3865 case TB_INDETERMINATE:
3866 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
3868 case TB_INSERTBUTTONA:
3869 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
3871 case TB_INSERTBUTTONW:
3872 return TOOLBAR_InsertButtonW (hwnd, wParam, lParam);
3874 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
3876 case TB_ISBUTTONCHECKED:
3877 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
3879 case TB_ISBUTTONENABLED:
3880 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
3882 case TB_ISBUTTONHIDDEN:
3883 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
3885 case TB_ISBUTTONHIGHLIGHTED:
3886 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
3888 case TB_ISBUTTONINDETERMINATE:
3889 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
3891 case TB_ISBUTTONPRESSED:
3892 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
3894 case TB_LOADIMAGES: /* 4.70 */
3895 FIXME("missing standard imagelists\n");
3898 /* case TB_MAPACCELERATORA: */ /* 4.71 */
3899 /* case TB_MAPACCELERATORW: */ /* 4.71 */
3900 /* case TB_MARKBUTTON: */ /* 4.71 */
3901 /* case TB_MOVEBUTTON: */ /* 4.71 */
3903 case TB_PRESSBUTTON:
3904 return TOOLBAR_PressButton (hwnd, wParam, lParam);
3906 /* case TB_REPLACEBITMAP: */
3908 case TB_SAVERESTOREA:
3909 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
3911 case TB_SAVERESTOREW:
3912 return TOOLBAR_SaveRestoreW (hwnd, wParam, lParam);
3914 case TB_SETANCHORHIGHLIGHT:
3915 return TOOLBAR_SetAnchorHighlight (hwnd, wParam);
3917 case TB_SETBITMAPSIZE:
3918 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
3920 case TB_SETBUTTONINFOA:
3921 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
3923 case TB_SETBUTTONINFOW:
3924 return TOOLBAR_SetButtonInfoW (hwnd, wParam, lParam);
3926 case TB_SETBUTTONSIZE:
3927 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
3929 case TB_SETBUTTONWIDTH:
3930 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
3933 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
3935 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
3937 case TB_SETDISABLEDIMAGELIST:
3938 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
3940 case TB_SETDRAWTEXTFLAGS:
3941 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
3943 case TB_SETEXTENDEDSTYLE:
3944 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
3946 case TB_SETHOTIMAGELIST:
3947 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
3950 return TOOLBAR_SetHotItem (hwnd, wParam);
3952 case TB_SETIMAGELIST:
3953 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
3956 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
3958 /* case TB_SETINSERTMARK: */ /* 4.71 */
3960 case TB_SETINSERTMARKCOLOR:
3961 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
3963 case TB_SETMAXTEXTROWS:
3964 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
3966 /* case TB_SETPADDING: */ /* 4.71 */
3969 return TOOLBAR_SetParent (hwnd, wParam, lParam);
3972 return TOOLBAR_SetRows (hwnd, wParam, lParam);
3975 return TOOLBAR_SetState (hwnd, wParam, lParam);
3978 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
3980 case TB_SETTOOLTIPS:
3981 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
3983 case TB_SETUNICODEFORMAT:
3984 return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
3986 case CCM_SETVERSION:
3987 return TOOLBAR_SetVersion (hwnd, (INT)wParam);
3993 return TOOLBAR_Create (hwnd, wParam, lParam);
3996 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
3999 return TOOLBAR_GetFont (hwnd, wParam, lParam);
4001 /* case WM_KEYDOWN: */
4002 /* case WM_KILLFOCUS: */
4004 case WM_LBUTTONDBLCLK:
4005 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
4007 case WM_LBUTTONDOWN:
4008 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
4011 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
4014 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
4017 return TOOLBAR_MouseLeave (hwnd, wParam, lParam);
4020 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
4023 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
4026 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
4029 return TOOLBAR_Notify (hwnd, wParam, lParam);
4031 /* case WM_NOTIFYFORMAT: */
4034 return TOOLBAR_Paint (hwnd, wParam);
4037 return TOOLBAR_Size (hwnd, wParam, lParam);
4039 case WM_STYLECHANGED:
4040 return TOOLBAR_StyleChanged (hwnd, (INT)wParam, (LPSTYLESTRUCT)lParam);
4042 /* case WM_SYSCOLORCHANGE: */
4044 /* case WM_WININICHANGE: */
4049 case WM_MEASUREITEM:
4051 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
4054 if (uMsg >= WM_USER)
4055 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
4056 uMsg, wParam, lParam);
4057 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
4064 TOOLBAR_Register (void)
4068 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
4069 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
4070 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
4071 wndClass.cbClsExtra = 0;
4072 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
4073 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
4074 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
4075 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
4077 RegisterClassA (&wndClass);
4082 TOOLBAR_Unregister (void)
4084 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);