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.
35 #include "wine/unicode.h"
37 #include "imagelist.h"
40 #include "debugtools.h"
42 DEFAULT_DEBUG_CHANNEL(toolbar);
60 DWORD dwStructSize; /* size of TBBUTTON struct */
61 INT nHeight; /* height of the toolbar */
62 INT nWidth; /* width of the toolbar */
68 INT nRows; /* number of button rows */
69 INT nMaxTextRows; /* maximum number of text rows */
70 INT cxMin; /* minimum button width */
71 INT cxMax; /* maximum button width */
72 INT nNumButtons; /* number of buttons */
73 INT nNumBitmaps; /* number of bitmaps */
74 INT nNumStrings; /* number of strings */
75 BOOL bUnicode; /* ASCII (FALSE) or Unicode (TRUE)? */
76 BOOL bCaptured; /* mouse captured? */
79 INT nHotItem; /* index of the "hot" item */
80 HFONT hFont; /* text font */
81 HIMAGELIST himlInt; /* image list created internally */
82 HIMAGELIST himlDef; /* default image list */
83 HIMAGELIST himlHot; /* hot image list */
84 HIMAGELIST himlDis; /* disabled image list */
85 HWND hwndToolTip; /* handle to tool tip control */
86 HWND hwndNotify; /* handle to the window that gets notifications */
87 BOOL bTransparent; /* background transparency flag */
88 BOOL bAutoSize; /* auto size deadlock indicator */
89 BOOL bAnchor; /* anchor highlight enabled */
90 DWORD dwExStyle; /* extended toolbar style */
91 DWORD dwDTFlags; /* DrawText flags */
93 COLORREF clrInsertMark; /* insert mark color */
94 RECT rcBound; /* bounding rectangle */
97 TBUTTON_INFO *buttons; /* pointer to button array */
98 LPWSTR *strings; /* pointer to string array */
101 #define SEPARATOR_WIDTH 8
103 #define BOTTOM_BORDER 2
105 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
108 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index)
110 if ((index>=0) && (index < infoPtr->nNumBitmaps))
118 TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
120 INT x = (lpRect->left + lpRect->right) / 2 - 1;
121 INT yBottom = lpRect->bottom - 3;
122 INT yTop = lpRect->top + 1;
124 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
125 MoveToEx (hdc, x, yBottom, NULL);
126 LineTo (hdc, x, yTop);
128 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
129 MoveToEx (hdc, x, yBottom, NULL);
130 LineTo (hdc, x, yTop);
134 * Draw the text string for this button.
135 * note: infoPtr->himlDis *SHOULD* be non-zero when infoPtr->himlDef
136 * is non-zero, so we can simply check himlDef to see if we have
140 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
141 HDC hdc, INT nState, DWORD dwStyle)
143 RECT rcText = btnPtr->rect;
147 LPWSTR lpText = NULL;
148 HIMAGELIST himl = infoPtr->himlDef;
150 TRACE ("iString: %x\n", btnPtr->iString);
152 /* get a pointer to the text */
153 if (btnPtr->iString == -1)
154 FIXME("Undocumented Index -1\n");
155 else if (HIWORD(btnPtr->iString) != 0)
156 lpText = (LPWSTR)btnPtr->iString;
157 else if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
158 lpText = infoPtr->strings[btnPtr->iString];
160 TRACE ("lpText: \"%s\"\n", debugstr_w(lpText));
165 InflateRect (&rcText, -3, -3);
167 if (himl && TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
168 if ((dwStyle & TBSTYLE_LIST) &&
169 ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
170 (btnPtr->iBitmap != I_IMAGENONE)) {
171 rcText.left += infoPtr->nBitmapWidth;
174 rcText.top += infoPtr->nBitmapHeight;
178 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
179 OffsetRect (&rcText, 1, 1);
181 hOldFont = SelectObject (hdc, infoPtr->hFont);
182 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
183 if (!(nState & TBSTATE_ENABLED)) {
184 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
185 OffsetRect (&rcText, 1, 1);
186 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
187 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
188 OffsetRect (&rcText, -1, -1);
189 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
191 else if (nState & TBSTATE_INDETERMINATE) {
192 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
193 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
196 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
197 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
200 SetTextColor (hdc, clrOld);
201 SelectObject (hdc, hOldFont);
202 if (nOldBkMode != TRANSPARENT)
203 SetBkMode (hdc, nOldBkMode);
209 TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
211 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
212 INT cx = lpRect->right - lpRect->left;
213 INT cy = lpRect->bottom - lpRect->top;
214 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
215 SelectObject (hdc, hbr);
220 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
221 HDC hdc, INT x, INT y)
223 /* FIXME: this function is a hack since it uses image list
224 internals directly */
226 HIMAGELIST himl = infoPtr->himlDef;
234 /* create new dc's */
235 hdcImageList = CreateCompatibleDC (0);
236 hdcMask = CreateCompatibleDC (0);
238 /* create new bitmap */
239 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
240 SelectObject (hdcMask, hbmMask);
242 /* copy the mask bitmap */
243 SelectObject (hdcImageList, himl->hbmMask);
244 SetBkColor (hdcImageList, RGB(255, 255, 255));
245 SetTextColor (hdcImageList, RGB(0, 0, 0));
246 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
247 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
250 /* add white mask from image */
251 SelectObject (hdcImageList, himl->hbmImage);
252 SetBkColor (hdcImageList, RGB(0, 0, 0));
253 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
254 hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
257 /* draw the new mask */
258 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
259 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
260 hdcMask, 0, 0, 0xB8074A);
262 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
263 BitBlt (hdc, x, y, himl->cx, himl->cy,
264 hdcMask, 0, 0, 0xB8074A);
266 DeleteObject (hbmMask);
268 DeleteDC (hdcImageList);
273 TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
275 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
276 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
279 if (btnPtr->fsState & TBSTATE_HIDDEN)
284 TRACE("iBitmap: %d\n", btnPtr->iBitmap);
287 if (btnPtr->fsStyle & TBSTYLE_SEP) {
288 /* with the FLAT style, iBitmap is the width and has already */
289 /* been taken into consideration in calculating the width */
290 /* so now we need to draw the vertical separator */
291 /* empirical tests show that iBitmap can/will be non-zero */
292 /* when drawing the vertical bar... */
293 if ((dwStyle & TBSTYLE_FLAT) /* && (btnPtr->iBitmap == 0) */)
294 TOOLBAR_DrawFlatSeparator (&rc, hdc);
299 if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
300 if (!(dwStyle & TBSTYLE_FLAT))
301 DrawEdge (hdc, &rc, EDGE_RAISED,
302 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
304 if (infoPtr->himlDis &&
305 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
306 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
307 rc.left+1, rc.top+1, ILD_NORMAL);
309 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
311 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
315 /* pressed TBSTYLE_BUTTON */
316 if (btnPtr->fsState & TBSTATE_PRESSED) {
317 if (dwStyle & TBSTYLE_FLAT)
318 DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
320 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
321 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
322 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
323 rc.left+2, rc.top+2, ILD_NORMAL);
324 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
328 /* checked TBSTYLE_CHECK */
329 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
330 (btnPtr->fsState & TBSTATE_CHECKED)) {
331 if (dwStyle & TBSTYLE_FLAT)
332 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
333 BF_RECT | BF_MIDDLE | BF_ADJUST);
335 DrawEdge (hdc, &rc, EDGE_SUNKEN,
336 BF_RECT | BF_MIDDLE | BF_ADJUST);
338 TOOLBAR_DrawPattern (hdc, &rc);
340 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
341 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
342 rc.left+2, rc.top+2, ILD_NORMAL);
344 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
349 if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
350 DrawEdge (hdc, &rc, EDGE_RAISED,
351 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
353 TOOLBAR_DrawPattern (hdc, &rc);
354 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
355 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
360 if (dwStyle & TBSTYLE_FLAT)
363 DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
364 if (btnPtr->bHot && infoPtr->himlHot &&
365 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
366 ImageList_Draw (infoPtr->himlHot, btnPtr->iBitmap, hdc,
367 rc.left +2, rc.top +2, ILD_NORMAL);
368 else if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
369 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
370 rc.left +2, rc.top +2, ILD_NORMAL);
374 DrawEdge (hdc, &rc, EDGE_RAISED,
375 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
377 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
378 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
379 rc.left+1, rc.top+1, ILD_NORMAL);
382 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
387 TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
389 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
390 TBUTTON_INFO *btnPtr;
394 /* redraw necessary buttons */
395 btnPtr = infoPtr->buttons;
396 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
398 if(IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect)))
399 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
404 TOOLBAR_MeasureString(HWND hwnd, INT index, LPSIZE lpSize)
406 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
407 TBUTTON_INFO *btnPtr;
414 hOldFont = SelectObject (hdc, infoPtr->hFont);
416 btnPtr = &infoPtr->buttons[index];
418 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
419 (btnPtr->iString > -1) &&
420 (btnPtr->iString < infoPtr->nNumStrings))
422 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
423 GetTextExtentPoint32W (hdc, lpText, lstrlenW (lpText), lpSize);
426 SelectObject (hdc, hOldFont);
429 TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
433 TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
435 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
436 TBUTTON_INFO *btnPtr;
444 btnPtr = infoPtr->buttons;
445 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
446 TOOLBAR_MeasureString(hwnd,i,&sz);
447 if (sz.cx > lpSize->cx)
449 if (sz.cy > lpSize->cy)
453 TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
456 /***********************************************************************
457 * TOOLBAR_WrapToolbar
459 * This function walks through the buttons and seperators in the
460 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
461 * wrapping should occur based on the width of the toolbar window.
462 * It does *not* calculate button placement itself. That task
463 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
464 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
465 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
469 TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
471 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
472 TBUTTON_INFO *btnPtr;
475 BOOL bWrap, bButtonWrap;
477 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
478 /* no layout is necessary. Applications may use this style */
479 /* to perform their own layout on the toolbar. */
480 if( !(dwStyle & TBSTYLE_WRAPABLE) )
483 btnPtr = infoPtr->buttons;
484 x = infoPtr->nIndent;
486 /* this can get the parents width, to know how far we can extend
487 * this toolbar. We cannot use its height, as there may be multiple
488 * toolbars in a rebar control
490 GetClientRect( GetParent(hwnd), &rc );
491 infoPtr->nWidth = rc.right - rc.left;
494 for (i = 0; i < infoPtr->nNumButtons; i++ )
497 btnPtr[i].fsState &= ~TBSTATE_WRAP;
499 if (btnPtr[i].fsState & TBSTATE_HIDDEN)
502 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
503 /* it is the actual width of the separator. This is used for */
504 /* custom controls in toolbars. */
505 if (btnPtr[i].fsStyle & TBSTYLE_SEP)
506 cx = (btnPtr[i].iBitmap > 0) ?
507 btnPtr[i].iBitmap : SEPARATOR_WIDTH;
509 cx = infoPtr->nButtonWidth;
511 /* Two or more adjacent separators form a separator group. */
512 /* The first separator in a group should be wrapped to the */
513 /* next row if the previous wrapping is on a button. */
515 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
516 (i + 1 < infoPtr->nNumButtons ) &&
517 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
519 btnPtr[i].fsState |= TBSTATE_WRAP;
520 x = infoPtr->nIndent;
526 /* The layout makes sure the bitmap is visible, but not the button. */
527 if ( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
532 /* If the current button is a separator and not hidden, */
533 /* go to the next until it reaches a non separator. */
534 /* Wrap the last separator if it is before a button. */
535 while( ( (btnPtr[i].fsStyle & TBSTYLE_SEP) ||
536 (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
537 i < infoPtr->nNumButtons )
543 if( bFound && i < infoPtr->nNumButtons )
546 btnPtr[i].fsState |= TBSTATE_WRAP;
547 x = infoPtr->nIndent;
551 else if ( i >= infoPtr->nNumButtons)
554 /* If the current button is not a separator, find the last */
555 /* separator and wrap it. */
556 for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
558 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
559 !(btnPtr[j].fsState & TBSTATE_HIDDEN))
563 x = infoPtr->nIndent;
564 btnPtr[j].fsState |= TBSTATE_WRAP;
570 /* If no separator available for wrapping, wrap one of */
571 /* non-hidden previous button. */
575 j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
577 if (btnPtr[j].fsState & TBSTATE_HIDDEN)
582 x = infoPtr->nIndent;
583 btnPtr[j].fsState |= TBSTATE_WRAP;
589 /* If all above failed, wrap the current button. */
592 btnPtr[i].fsState |= TBSTATE_WRAP;
594 x = infoPtr->nIndent;
595 if (btnPtr[i].fsState & TBSTYLE_SEP )
606 /***********************************************************************
607 * TOOLBAR_CalcToolbar
609 * This function calculates button and separator placement. It first
610 * calculates the button sizes, gets the toolbar window width and then
611 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
612 * on. It assigns a new location to each item and sends this location to
613 * the tooltip window if appropriate. Finally, it updates the rcBound
614 * rect and calculates the new required toolbar window height.
618 TOOLBAR_CalcToolbar (HWND hwnd)
620 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
621 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
622 TBUTTON_INFO *btnPtr;
623 INT i, nRows, nSepRows;
628 TOOLBAR_CalcStrings (hwnd, &sizeString);
630 if (dwStyle & TBSTYLE_LIST) {
631 infoPtr->nButtonHeight = max(infoPtr->nBitmapHeight, sizeString.cy) + 6;
632 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + sizeString.cx + 6;
635 BOOL usesBitmaps = FALSE;
638 for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
639 if (TOOLBAR_IsValidBitmapIndex(infoPtr,infoPtr->buttons[i].iBitmap))
642 if (sizeString.cy > 0) {
644 infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
646 infoPtr->nButtonHeight = sizeString.cy + 6;
648 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
649 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
651 if (sizeString.cx > infoPtr->nBitmapWidth)
652 infoPtr->nButtonWidth = sizeString.cx + 6;
653 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
654 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
657 if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin )
658 infoPtr->nButtonWidth = infoPtr->cxMin;
659 if ( infoPtr->cxMax >= 0 && infoPtr->nButtonWidth > infoPtr->cxMax )
660 infoPtr->nButtonWidth = infoPtr->cxMax;
662 TOOLBAR_WrapToolbar( hwnd, dwStyle );
664 x = infoPtr->nIndent;
665 y = (dwStyle & TBSTYLE_FLAT) ? 0 : TOP_BORDER;
668 * We wills et the height below, and we set the width on entry
669 * so we do not reset them here..
672 GetClientRect( hwnd, &rc );
673 /* get initial values for toolbar */
674 infoPtr->nWidth = rc.right - rc.left;
675 infoPtr->nHeight = rc.bottom - rc.top;
678 /* from above, minimum is a button, and possible text */
679 cx = infoPtr->nButtonWidth;
680 /* cannot use just ButtonHeight, we may have no buttons! */
681 if (infoPtr->nNumButtons > 0)
682 infoPtr->nHeight = infoPtr->nButtonHeight;
683 cy = infoPtr->nHeight;
685 nRows = nSepRows = 0;
687 infoPtr->rcBound.top = y;
688 infoPtr->rcBound.left = x;
689 infoPtr->rcBound.bottom = y + cy;
690 infoPtr->rcBound.right = x;
692 btnPtr = infoPtr->buttons;
694 /* do not base height/width on parent, if the parent is a */
695 /* rebar control it could have multiple rows of toolbars */
696 /* GetClientRect( GetParent(hwnd), &rc ); */
697 /* cx = rc.right - rc.left; */
698 /* cy = rc.bottom - rc.top; */
700 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
703 if (btnPtr->fsState & TBSTATE_HIDDEN)
705 SetRectEmpty (&btnPtr->rect);
709 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
710 /* it is the actual width of the separator. This is used for */
711 /* custom controls in toolbars. */
712 if (btnPtr->fsStyle & TBSTYLE_SEP)
713 cx = (btnPtr->iBitmap > 0) ?
714 btnPtr->iBitmap : SEPARATOR_WIDTH;
716 if (btnPtr->fsStyle & TBSTYLE_AUTOSIZE)
719 TOOLBAR_MeasureString(hwnd,i,&sz);
723 cx = infoPtr->nButtonWidth;
725 cy = infoPtr->nHeight;
727 if (btnPtr->fsState & TBSTATE_WRAP )
730 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
732 if (infoPtr->rcBound.left > x)
733 infoPtr->rcBound.left = x;
734 if (infoPtr->rcBound.right < x + cx)
735 infoPtr->rcBound.right = x + cx;
736 if (infoPtr->rcBound.bottom < y + cy)
737 infoPtr->rcBound.bottom = y + cy;
739 /* Set the toolTip only for non-hidden, non-separator button */
740 if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP ))
744 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
745 ti.cbSize = sizeof(TTTOOLINFOA);
747 ti.uId = btnPtr->idCommand;
748 ti.rect = btnPtr->rect;
749 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
753 /* btnPtr->nRow is zero based. The space between the rows is */
754 /* also considered as a row. */
755 btnPtr->nRow = nRows + nSepRows;
758 if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
762 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
763 /* it is the actual width of the separator. This is used for */
764 /* custom controls in toolbars. */
765 y += cy + ( (btnPtr->iBitmap > 0 ) ?
766 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
768 /* nSepRows is used to calculate the extra height follwoing */
772 x = infoPtr->nIndent;
779 /* infoPtr->nRows is the number of rows on the toolbar */
780 infoPtr->nRows = nRows + nSepRows + 1;
782 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
784 infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
785 nSepRows * (SEPARATOR_WIDTH * 2 / 3) +
786 nSepRows * (infoPtr->nBitmapHeight + 1) +
788 TRACE("toolbar height %d\n", infoPtr->nHeight);
793 TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
795 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
796 TBUTTON_INFO *btnPtr;
799 btnPtr = infoPtr->buttons;
800 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
801 if (btnPtr->fsState & TBSTATE_HIDDEN)
804 if (btnPtr->fsStyle & TBSTYLE_SEP) {
805 if (PtInRect (&btnPtr->rect, *lpPt)) {
806 TRACE(" ON SEPARATOR %d!\n", i);
811 if (PtInRect (&btnPtr->rect, *lpPt)) {
812 TRACE(" ON BUTTON %d!\n", i);
818 TRACE(" NOWHERE!\n");
824 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
826 TBUTTON_INFO *btnPtr;
829 btnPtr = infoPtr->buttons;
830 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
831 if (btnPtr->idCommand == idCommand) {
832 TRACE("command=%d index=%d\n", idCommand, i);
836 TRACE("no index found for command=%d\n", idCommand);
842 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
844 TBUTTON_INFO *btnPtr;
847 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
850 /* check index button */
851 btnPtr = &infoPtr->buttons[nIndex];
852 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
853 if (btnPtr->fsState & TBSTATE_CHECKED)
857 /* check previous buttons */
858 nRunIndex = nIndex - 1;
859 while (nRunIndex >= 0) {
860 btnPtr = &infoPtr->buttons[nRunIndex];
861 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
862 if (btnPtr->fsState & TBSTATE_CHECKED)
870 /* check next buttons */
871 nRunIndex = nIndex + 1;
872 while (nRunIndex < infoPtr->nNumButtons) {
873 btnPtr = &infoPtr->buttons[nRunIndex];
874 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
875 if (btnPtr->fsState & TBSTATE_CHECKED)
888 TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
889 WPARAM wParam, LPARAM lParam)
897 msg.time = GetMessageTime ();
898 msg.pt.x = LOWORD(GetMessagePos ());
899 msg.pt.y = HIWORD(GetMessagePos ());
901 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
905 /***********************************************************************
906 * TOOLBAR_CustomizeDialogProc
907 * This function implements the toolbar customization dialog.
910 TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
912 TOOLBAR_INFO *infoPtr = (TOOLBAR_INFO *)GetWindowLongA (hwnd, DWL_USER);
913 static HDSA hDsa = NULL;
918 infoPtr = (TOOLBAR_INFO *)lParam;
919 SetWindowLongA (hwnd, DWL_USER, (DWORD)infoPtr);
921 hDsa = DSA_Create (sizeof(TBUTTON_INFO), 5);
925 TBUTTON_INFO *btnPtr;
928 /* insert 'virtual' separator button into 'available buttons' list */
929 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
931 /* copy all buttons and append them to the right listbox */
932 btnPtr = infoPtr->buttons;
933 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
935 DSA_InsertItem (hDsa, i, btnPtr);
937 /* FIXME: hidden buttons appear in the 'toolbar buttons' list too */
938 if (btnPtr->fsState & TBSTATE_HIDDEN)
940 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
944 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
948 /* append 'virtual' separator button to the 'toolbar buttons' list */
954 EndDialog(hwnd, FALSE);
958 switch (LOWORD(wParam))
961 EndDialog(hwnd, FALSE);
972 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
974 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
980 COLORREF oldText = 0;
983 FIXME("action: %x itemState: %x\n",
984 lpdis->itemAction, lpdis->itemState);
986 DSA_GetItem (hDsa, 0 /*lpdis->itemID*/, &btnPtr);
988 if (lpdis->itemState & ODS_FOCUS)
990 oldBk = SetBkColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
991 oldText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
994 hOldPen = SelectObject (lpdis->hDC, GetSysColorPen ((lpdis->itemState & ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
995 hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
997 /* fill background rectangle */
998 Rectangle (lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
999 lpdis->rcItem.right, lpdis->rcItem.bottom);
1001 /* calculate button and text rectangles */
1002 CopyRect (&rcButton, &lpdis->rcItem);
1003 InflateRect (&rcButton, -1, -1);
1004 CopyRect (&rcText, &rcButton);
1005 rcButton.right = rcButton.left + infoPtr->nBitmapWidth + 6;
1006 rcText.left = rcButton.right + 2;
1008 /* draw focus rectangle */
1009 if (lpdis->itemState & ODS_FOCUS)
1010 DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
1013 DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
1015 /* draw image and text */
1016 if (wParam == IDC_AVAILBTN_LBOX && lpdis->itemID == 0)
1018 /* virtual separator in the 'available' list */
1019 DrawTextA (lpdis->hDC, "Separator", -1, &rcText,
1020 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1026 ImageList_Draw (infoPtr->himlDef, btnPtr.iBitmap, lpdis->hDC,
1027 rcButton.left+1, rcButton.top+1, ILD_NORMAL);
1029 DrawTextW (lpdis->hDC, infoPtr->strings[btnPtr.iString], -1, &rcText,
1030 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1034 if (lpdis->itemState & ODS_FOCUS)
1036 SetBkColor (lpdis->hDC, oldBk);
1037 SetTextColor (lpdis->hDC, oldText);
1040 SelectObject (lpdis->hDC, hOldBrush);
1041 SelectObject (lpdis->hDC, hOldPen);
1047 case WM_MEASUREITEM:
1048 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1050 MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*)lParam;
1053 lpmis->itemHeight = infoPtr->nBitmapHeight + 8;
1055 lpmis->itemHeight = 15 + 8; /* default height */
1067 /***********************************************************************
1068 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1072 TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1074 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1075 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
1076 INT nIndex = 0, nButtons, nCount;
1079 TRACE("hwnd=%x wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
1083 if (lpAddBmp->hInst == HINST_COMMCTRL)
1085 if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR)
1087 else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR)
1089 else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR)
1094 TRACE ("adding %d internal bitmaps!\n", nButtons);
1096 /* Windows resize all the buttons to the size of a newly added standard image */
1097 if (lpAddBmp->nID & 1)
1100 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1101 MAKELPARAM((WORD)26, (WORD)26));
1102 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1103 MAKELPARAM((WORD)33, (WORD)33));
1108 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1109 MAKELPARAM((WORD)16, (WORD)16));
1110 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1111 MAKELPARAM((WORD)22, (WORD)22));
1114 TOOLBAR_CalcToolbar (hwnd);
1118 nButtons = (INT)wParam;
1122 TRACE ("adding %d bitmaps!\n", nButtons);
1125 if (!(infoPtr->himlDef)) {
1126 /* create new default image list */
1127 TRACE ("creating default image list!\n");
1130 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
1131 ILC_COLOR | ILC_MASK, nButtons, 2);
1132 infoPtr->himlInt = infoPtr->himlDef;
1135 nCount = ImageList_GetImageCount(infoPtr->himlDef);
1137 /* Add bitmaps to the default image list */
1138 if (lpAddBmp->hInst == (HINSTANCE)0)
1141 ImageList_AddMasked (infoPtr->himlDef, (HBITMAP)lpAddBmp->nID,
1144 else if (lpAddBmp->hInst == HINST_COMMCTRL)
1146 /* Add system bitmaps */
1147 switch (lpAddBmp->nID)
1149 case IDB_STD_SMALL_COLOR:
1150 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1151 MAKEINTRESOURCEA(IDB_STD_SMALL));
1152 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1153 hbmLoad, CLR_DEFAULT);
1154 DeleteObject (hbmLoad);
1157 case IDB_STD_LARGE_COLOR:
1158 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1159 MAKEINTRESOURCEA(IDB_STD_LARGE));
1160 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1161 hbmLoad, CLR_DEFAULT);
1162 DeleteObject (hbmLoad);
1165 case IDB_VIEW_SMALL_COLOR:
1166 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1167 MAKEINTRESOURCEA(IDB_VIEW_SMALL));
1168 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1169 hbmLoad, CLR_DEFAULT);
1170 DeleteObject (hbmLoad);
1173 case IDB_VIEW_LARGE_COLOR:
1174 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1175 MAKEINTRESOURCEA(IDB_VIEW_LARGE));
1176 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1177 hbmLoad, CLR_DEFAULT);
1178 DeleteObject (hbmLoad);
1181 case IDB_HIST_SMALL_COLOR:
1182 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1183 MAKEINTRESOURCEA(IDB_HIST_SMALL));
1184 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1185 hbmLoad, CLR_DEFAULT);
1186 DeleteObject (hbmLoad);
1189 case IDB_HIST_LARGE_COLOR:
1190 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1191 MAKEINTRESOURCEA(IDB_HIST_LARGE));
1192 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1193 hbmLoad, CLR_DEFAULT);
1194 DeleteObject (hbmLoad);
1198 nIndex = ImageList_GetImageCount (infoPtr->himlDef);
1199 ERR ("invalid imagelist!\n");
1205 hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
1206 nIndex = ImageList_AddMasked (infoPtr->himlDef, hbmLoad, CLR_DEFAULT);
1207 DeleteObject (hbmLoad);
1212 INT imagecount = ImageList_GetImageCount(infoPtr->himlDef);
1214 if (infoPtr->nNumBitmaps + nButtons != imagecount)
1216 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",
1217 infoPtr->nNumBitmaps, nCount, imagecount - nCount,
1218 infoPtr->nNumBitmaps+nButtons,imagecount);
1220 infoPtr->nNumBitmaps = imagecount;
1223 infoPtr->nNumBitmaps += nButtons;
1231 TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1233 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1234 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1235 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1237 TRACE("adding %d buttons!\n", wParam);
1239 nAddButtons = (UINT)wParam;
1240 nOldButtons = infoPtr->nNumButtons;
1241 nNewButtons = nOldButtons + nAddButtons;
1243 if (infoPtr->nNumButtons == 0) {
1245 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1248 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1250 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1251 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1252 nOldButtons * sizeof(TBUTTON_INFO));
1253 COMCTL32_Free (oldButtons);
1256 infoPtr->nNumButtons = nNewButtons;
1258 /* insert new button data */
1259 for (nCount = 0; nCount < nAddButtons; nCount++) {
1260 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1261 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1262 btnPtr->idCommand = lpTbb[nCount].idCommand;
1263 btnPtr->fsState = lpTbb[nCount].fsState;
1264 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1265 btnPtr->dwData = lpTbb[nCount].dwData;
1266 btnPtr->iString = lpTbb[nCount].iString;
1267 btnPtr->bHot = FALSE;
1269 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1272 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1273 ti.cbSize = sizeof (TTTOOLINFOA);
1275 ti.uId = btnPtr->idCommand;
1277 ti.lpszText = LPSTR_TEXTCALLBACKA;
1279 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
1284 TOOLBAR_CalcToolbar (hwnd);
1286 InvalidateRect(hwnd, NULL, FALSE);
1293 TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1295 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1296 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1297 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1299 TRACE("adding %d buttons!\n", wParam);
1301 nAddButtons = (UINT)wParam;
1302 nOldButtons = infoPtr->nNumButtons;
1303 nNewButtons = nOldButtons + nAddButtons;
1305 if (infoPtr->nNumButtons == 0) {
1307 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1310 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1312 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1313 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1314 nOldButtons * sizeof(TBUTTON_INFO));
1315 COMCTL32_Free (oldButtons);
1318 infoPtr->nNumButtons = nNewButtons;
1320 /* insert new button data */
1321 for (nCount = 0; nCount < nAddButtons; nCount++) {
1322 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1323 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1324 btnPtr->idCommand = lpTbb[nCount].idCommand;
1325 btnPtr->fsState = lpTbb[nCount].fsState;
1326 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1327 btnPtr->dwData = lpTbb[nCount].dwData;
1328 btnPtr->iString = lpTbb[nCount].iString;
1329 btnPtr->bHot = FALSE;
1331 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1334 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
1335 ti.cbSize = sizeof (TTTOOLINFOW);
1337 ti.uId = btnPtr->idCommand;
1339 ti.lpszText = LPSTR_TEXTCALLBACKW;
1341 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
1346 TOOLBAR_CalcToolbar (hwnd);
1348 InvalidateRect(hwnd, NULL, FALSE);
1355 TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1357 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1360 if ((wParam) && (HIWORD(lParam) == 0)) {
1363 TRACE("adding string from resource!\n");
1365 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
1368 TRACE("len=%d \"%s\"\n", len, szString);
1369 nIndex = infoPtr->nNumStrings;
1370 if (infoPtr->nNumStrings == 0) {
1372 COMCTL32_Alloc (sizeof(LPWSTR));
1375 LPWSTR *oldStrings = infoPtr->strings;
1377 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1378 memcpy (&infoPtr->strings[0], &oldStrings[0],
1379 sizeof(LPWSTR) * infoPtr->nNumStrings);
1380 COMCTL32_Free (oldStrings);
1383 infoPtr->strings[infoPtr->nNumStrings] =
1384 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1385 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
1386 infoPtr->nNumStrings++;
1389 LPSTR p = (LPSTR)lParam;
1394 TRACE("adding string(s) from array!\n");
1396 nIndex = infoPtr->nNumStrings;
1399 TRACE("len=%d \"%s\"\n", len, p);
1401 if (infoPtr->nNumStrings == 0) {
1403 COMCTL32_Alloc (sizeof(LPWSTR));
1406 LPWSTR *oldStrings = infoPtr->strings;
1408 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1409 memcpy (&infoPtr->strings[0], &oldStrings[0],
1410 sizeof(LPWSTR) * infoPtr->nNumStrings);
1411 COMCTL32_Free (oldStrings);
1414 infoPtr->strings[infoPtr->nNumStrings] =
1415 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1416 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
1417 infoPtr->nNumStrings++;
1428 TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1430 #define MAX_RESOURCE_STRING_LENGTH 512
1431 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1434 if ((wParam) && (HIWORD(lParam) == 0)) {
1435 WCHAR szString[MAX_RESOURCE_STRING_LENGTH];
1437 TRACE("adding string from resource!\n");
1439 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
1440 szString, MAX_RESOURCE_STRING_LENGTH);
1442 TRACE("len=%d \"%s\"\n", len, debugstr_w(szString));
1443 TRACE("First char: 0x%x\n", *szString);
1444 if (szString[0] == L'|')
1446 PWSTR p = szString + 1;
1448 nIndex = infoPtr->nNumStrings;
1449 while (*p != L'|') {
1451 if (infoPtr->nNumStrings == 0) {
1453 COMCTL32_Alloc (sizeof(LPWSTR));
1456 LPWSTR *oldStrings = infoPtr->strings;
1458 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1459 memcpy (&infoPtr->strings[0], &oldStrings[0],
1460 sizeof(LPWSTR) * infoPtr->nNumStrings);
1461 COMCTL32_Free (oldStrings);
1464 len = COMCTL32_StrChrW (p, L'|') - p;
1465 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1466 infoPtr->strings[infoPtr->nNumStrings] =
1467 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1468 lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len);
1469 infoPtr->nNumStrings++;
1476 nIndex = infoPtr->nNumStrings;
1477 if (infoPtr->nNumStrings == 0) {
1479 COMCTL32_Alloc (sizeof(LPWSTR));
1482 LPWSTR *oldStrings = infoPtr->strings;
1484 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1485 memcpy (&infoPtr->strings[0], &oldStrings[0],
1486 sizeof(LPWSTR) * infoPtr->nNumStrings);
1487 COMCTL32_Free (oldStrings);
1490 infoPtr->strings[infoPtr->nNumStrings] =
1491 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1492 strcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
1493 infoPtr->nNumStrings++;
1497 LPWSTR p = (LPWSTR)lParam;
1502 TRACE("adding string(s) from array!\n");
1503 nIndex = infoPtr->nNumStrings;
1507 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1508 if (infoPtr->nNumStrings == 0) {
1510 COMCTL32_Alloc (sizeof(LPWSTR));
1513 LPWSTR *oldStrings = infoPtr->strings;
1515 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1516 memcpy (&infoPtr->strings[0], &oldStrings[0],
1517 sizeof(LPWSTR) * infoPtr->nNumStrings);
1518 COMCTL32_Free (oldStrings);
1521 infoPtr->strings[infoPtr->nNumStrings] =
1522 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1523 strcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1524 infoPtr->nNumStrings++;
1535 TOOLBAR_AutoSize (HWND hwnd)
1537 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1538 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1544 UINT uPosFlags = SWP_NOZORDER;
1546 TRACE("resize forced, style=%lx!\n", dwStyle);
1548 parent = GetParent (hwnd);
1549 GetClientRect(parent, &parent_rect);
1551 x = parent_rect.left;
1552 y = parent_rect.top;
1554 if (dwStyle & CCS_NORESIZE) {
1555 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
1560 infoPtr->nWidth = parent_rect.right - parent_rect.left;
1561 TOOLBAR_CalcToolbar (hwnd);
1562 InvalidateRect( hwnd, NULL, TRUE );
1563 cy = infoPtr->nHeight;
1564 cx = infoPtr->nWidth;
1566 if (dwStyle & CCS_NOMOVEY) {
1567 GetWindowRect(hwnd, &window_rect);
1568 ScreenToClient(parent, (LPPOINT)&window_rect.left);
1569 y = window_rect.top;
1573 if (dwStyle & CCS_NOPARENTALIGN)
1574 uPosFlags |= SWP_NOMOVE;
1576 if (!(dwStyle & CCS_NODIVIDER))
1577 cy += GetSystemMetrics(SM_CYEDGE);
1579 if (dwStyle & WS_BORDER)
1582 cy += GetSystemMetrics(SM_CYEDGE);
1583 cx += GetSystemMetrics(SM_CYEDGE);
1586 infoPtr->bAutoSize = TRUE;
1587 SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
1589 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
1590 * the setwindowpos calls */
1591 infoPtr->bAutoSize = FALSE;
1598 TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
1600 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1602 return infoPtr->nNumButtons;
1607 TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1609 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1611 if (infoPtr == NULL) {
1612 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
1613 ERR("infoPtr == NULL!\n");
1617 infoPtr->dwStructSize = (DWORD)wParam;
1624 TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1626 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1627 TBUTTON_INFO *btnPtr;
1630 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1634 btnPtr = &infoPtr->buttons[nIndex];
1635 btnPtr->iBitmap = LOWORD(lParam);
1637 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
1644 TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1646 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1647 TBUTTON_INFO *btnPtr;
1650 BOOL bChecked = FALSE;
1652 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1656 btnPtr = &infoPtr->buttons[nIndex];
1658 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
1661 bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
1663 if (LOWORD(lParam) == FALSE)
1664 btnPtr->fsState &= ~TBSTATE_CHECKED;
1666 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
1668 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
1669 if (nOldIndex == nIndex)
1671 if (nOldIndex != -1)
1672 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
1674 btnPtr->fsState |= TBSTATE_CHECKED;
1677 if( bChecked != LOWORD(lParam) )
1679 if (nOldIndex != -1)
1680 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect, TRUE);
1681 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
1684 /* FIXME: Send a WM_NOTIFY?? */
1691 TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
1693 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1695 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1700 TOOLBAR_Customize (HWND hwnd)
1702 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1708 /* send TBN_BEGINADJUST notification */
1709 nmhdr.hwndFrom = hwnd;
1710 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1711 nmhdr.code = TBN_BEGINADJUST;
1713 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1714 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1716 if (!(hRes = FindResourceA (COMCTL32_hModule,
1717 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
1721 if(!(template = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
1724 ret = DialogBoxIndirectParamA (GetWindowLongA (hwnd, GWL_HINSTANCE),
1725 (LPDLGTEMPLATEA)template,
1727 (DLGPROC)TOOLBAR_CustomizeDialogProc,
1730 /* send TBN_ENDADJUST notification */
1731 nmhdr.code = TBN_ENDADJUST;
1733 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1734 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1741 TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1743 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1744 INT nIndex = (INT)wParam;
1746 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1749 if ((infoPtr->hwndToolTip) &&
1750 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
1753 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1754 ti.cbSize = sizeof (TTTOOLINFOA);
1756 ti.uId = infoPtr->buttons[nIndex].idCommand;
1758 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
1761 if (infoPtr->nNumButtons == 1) {
1762 TRACE(" simple delete!\n");
1763 COMCTL32_Free (infoPtr->buttons);
1764 infoPtr->buttons = NULL;
1765 infoPtr->nNumButtons = 0;
1768 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1769 TRACE("complex delete! [nIndex=%d]\n", nIndex);
1771 infoPtr->nNumButtons--;
1772 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
1774 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1775 nIndex * sizeof(TBUTTON_INFO));
1778 if (nIndex < infoPtr->nNumButtons) {
1779 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
1780 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
1783 COMCTL32_Free (oldButtons);
1786 TOOLBAR_CalcToolbar (hwnd);
1788 InvalidateRect (hwnd, NULL, TRUE);
1795 TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1797 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1798 TBUTTON_INFO *btnPtr;
1802 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1806 btnPtr = &infoPtr->buttons[nIndex];
1808 bState = btnPtr->fsState & TBSTATE_ENABLED;
1810 /* update the toolbar button state */
1811 if(LOWORD(lParam) == FALSE) {
1812 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
1814 btnPtr->fsState |= TBSTATE_ENABLED;
1817 /* redraw the button only if the state of the button changed */
1818 if(bState != (btnPtr->fsState & TBSTATE_ENABLED))
1819 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
1825 static inline LRESULT
1826 TOOLBAR_GetAnchorHighlight (HWND hwnd)
1828 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1830 return infoPtr->bAnchor;
1835 TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1837 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1840 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1844 return infoPtr->buttons[nIndex].iBitmap;
1848 static inline LRESULT
1849 TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
1851 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
1856 TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1858 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1859 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1860 INT nIndex = (INT)wParam;
1861 TBUTTON_INFO *btnPtr;
1863 if (infoPtr == NULL)
1869 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1872 btnPtr = &infoPtr->buttons[nIndex];
1873 lpTbb->iBitmap = btnPtr->iBitmap;
1874 lpTbb->idCommand = btnPtr->idCommand;
1875 lpTbb->fsState = btnPtr->fsState;
1876 lpTbb->fsStyle = btnPtr->fsStyle;
1877 lpTbb->dwData = btnPtr->dwData;
1878 lpTbb->iString = btnPtr->iString;
1885 TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1887 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1888 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
1889 TBUTTON_INFO *btnPtr;
1892 if (infoPtr == NULL)
1894 if (lpTbInfo == NULL)
1896 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOA))
1899 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1903 btnPtr = &infoPtr->buttons[nIndex];
1905 if (lpTbInfo->dwMask & TBIF_COMMAND)
1906 lpTbInfo->idCommand = btnPtr->idCommand;
1907 if (lpTbInfo->dwMask & TBIF_IMAGE)
1908 lpTbInfo->iImage = btnPtr->iBitmap;
1909 if (lpTbInfo->dwMask & TBIF_LPARAM)
1910 lpTbInfo->lParam = btnPtr->dwData;
1911 if (lpTbInfo->dwMask & TBIF_SIZE)
1912 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1913 if (lpTbInfo->dwMask & TBIF_STATE)
1914 lpTbInfo->fsState = btnPtr->fsState;
1915 if (lpTbInfo->dwMask & TBIF_STYLE)
1916 lpTbInfo->fsStyle = btnPtr->fsStyle;
1917 if (lpTbInfo->dwMask & TBIF_TEXT) {
1918 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
1920 lstrcpynWtoA (lpTbInfo->pszText,
1921 (LPWSTR)infoPtr->strings[btnPtr->iString],
1924 else lpTbInfo->pszText[0]=0;
1931 TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1933 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1934 LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
1935 TBUTTON_INFO *btnPtr;
1938 if (infoPtr == NULL)
1940 if (lpTbInfo == NULL)
1942 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
1945 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1949 btnPtr = &infoPtr->buttons[nIndex];
1951 if (lpTbInfo->dwMask & TBIF_COMMAND)
1952 lpTbInfo->idCommand = btnPtr->idCommand;
1953 if (lpTbInfo->dwMask & TBIF_IMAGE)
1954 lpTbInfo->iImage = btnPtr->iBitmap;
1955 if (lpTbInfo->dwMask & TBIF_LPARAM)
1956 lpTbInfo->lParam = btnPtr->dwData;
1957 if (lpTbInfo->dwMask & TBIF_SIZE)
1958 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1959 if (lpTbInfo->dwMask & TBIF_STATE)
1960 lpTbInfo->fsState = btnPtr->fsState;
1961 if (lpTbInfo->dwMask & TBIF_STYLE)
1962 lpTbInfo->fsStyle = btnPtr->fsStyle;
1963 if (lpTbInfo->dwMask & TBIF_TEXT) {
1964 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
1965 lstrcpynW (lpTbInfo->pszText,
1966 (LPWSTR)infoPtr->strings[btnPtr->iString],
1975 TOOLBAR_GetButtonSize (HWND hwnd)
1977 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1979 return MAKELONG((WORD)infoPtr->nButtonWidth,
1980 (WORD)infoPtr->nButtonHeight);
1985 TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1987 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1988 INT nIndex, nStringIndex;
1990 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1994 nStringIndex = infoPtr->buttons[nIndex].iString;
1996 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
1998 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2004 lstrcpyWtoA ((LPSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
2006 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
2011 TOOLBAR_GetButtonTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2013 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2014 INT nIndex, nStringIndex;
2016 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2020 nStringIndex = infoPtr->buttons[nIndex].iString;
2022 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
2024 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2030 strcpyW ((LPWSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
2032 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
2036 /* << TOOLBAR_GetColorScheme >> */
2040 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2042 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2044 return (LRESULT)infoPtr->himlDis;
2048 inline static LRESULT
2049 TOOLBAR_GetExtendedStyle (HWND hwnd)
2051 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2053 return infoPtr->dwExStyle;
2058 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2060 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2062 return (LRESULT)infoPtr->himlHot;
2067 TOOLBAR_GetHotItem (HWND hwnd)
2069 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2071 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2074 if (infoPtr->nHotItem < 0)
2077 return (LRESULT)infoPtr->nHotItem;
2082 TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2084 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2086 return (LRESULT)infoPtr->himlDef;
2090 /* << TOOLBAR_GetInsertMark >> */
2091 /* << TOOLBAR_GetInsertMarkColor >> */
2095 TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2097 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2098 TBUTTON_INFO *btnPtr;
2102 if (infoPtr == NULL)
2104 nIndex = (INT)wParam;
2105 btnPtr = &infoPtr->buttons[nIndex];
2106 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2108 lpRect = (LPRECT)lParam;
2111 if (btnPtr->fsState & TBSTATE_HIDDEN)
2114 TOOLBAR_CalcToolbar( hwnd );
2116 lpRect->left = btnPtr->rect.left;
2117 lpRect->right = btnPtr->rect.right;
2118 lpRect->bottom = btnPtr->rect.bottom;
2119 lpRect->top = btnPtr->rect.top;
2126 TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2128 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2129 LPSIZE lpSize = (LPSIZE)lParam;
2134 lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
2135 lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
2137 TRACE("maximum size %d x %d\n",
2138 infoPtr->rcBound.right - infoPtr->rcBound.left,
2139 infoPtr->rcBound.bottom - infoPtr->rcBound.top);
2145 /* << TOOLBAR_GetObject >> */
2146 /* << TOOLBAR_GetPadding >> */
2150 TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2152 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2153 TBUTTON_INFO *btnPtr;
2157 if (infoPtr == NULL)
2159 nIndex = (INT)wParam;
2160 btnPtr = &infoPtr->buttons[nIndex];
2161 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2163 lpRect = (LPRECT)lParam;
2167 lpRect->left = btnPtr->rect.left;
2168 lpRect->right = btnPtr->rect.right;
2169 lpRect->bottom = btnPtr->rect.bottom;
2170 lpRect->top = btnPtr->rect.top;
2177 TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2179 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2181 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
2182 return infoPtr->nRows;
2189 TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2191 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2194 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2198 return infoPtr->buttons[nIndex].fsState;
2203 TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2205 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2208 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2212 return infoPtr->buttons[nIndex].fsStyle;
2217 TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2219 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2221 if (infoPtr == NULL)
2224 return infoPtr->nMaxTextRows;
2229 TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
2231 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2233 if (infoPtr == NULL)
2235 return infoPtr->hwndToolTip;
2240 TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2242 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2244 TRACE("%s hwnd=0x%x stub!\n",
2245 infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
2247 return infoPtr->bUnicode;
2251 inline static LRESULT
2252 TOOLBAR_GetVersion (HWND hwnd)
2254 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2255 return infoPtr->iVersion;
2260 TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2262 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2263 TBUTTON_INFO *btnPtr;
2266 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2270 btnPtr = &infoPtr->buttons[nIndex];
2271 if (LOWORD(lParam) == FALSE)
2272 btnPtr->fsState &= ~TBSTATE_HIDDEN;
2274 btnPtr->fsState |= TBSTATE_HIDDEN;
2276 TOOLBAR_CalcToolbar (hwnd);
2278 InvalidateRect (hwnd, NULL, TRUE);
2284 inline static LRESULT
2285 TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2287 return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
2292 TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2294 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2295 TBUTTON_INFO *btnPtr;
2298 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2302 btnPtr = &infoPtr->buttons[nIndex];
2303 if (LOWORD(lParam) == FALSE)
2304 btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
2306 btnPtr->fsState |= TBSTATE_INDETERMINATE;
2308 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
2315 TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2317 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2318 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2319 INT nIndex = (INT)wParam;
2320 TBUTTON_INFO *oldButtons;
2326 /* EPP: this seems to be an undocumented call (from my IE4)
2327 * I assume in that case that:
2328 * - lpTbb->iString is a string pointer (not a string index in strings[] table
2329 * - index of insertion is at the end of existing buttons
2330 * I only see this happen with nIndex == -1, but it could have a special
2331 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
2336 if(lpTbb->iString) {
2337 len = lstrlenA((char*)lpTbb->iString) + 2;
2338 ptr = COMCTL32_Alloc(len);
2339 nIndex = infoPtr->nNumButtons;
2340 strcpy(ptr, (char*)lpTbb->iString);
2341 ptr[len - 1] = 0; /* ended by two '\0' */
2342 lpTbb->iString = TOOLBAR_AddStringA(hwnd, 0, (LPARAM)ptr);
2346 ERR("lpTbb->iString is NULL\n");
2350 } else if (nIndex < 0)
2353 TRACE("inserting button index=%d\n", nIndex);
2354 if (nIndex > infoPtr->nNumButtons) {
2355 nIndex = infoPtr->nNumButtons;
2356 TRACE("adjust index=%d\n", nIndex);
2359 oldButtons = infoPtr->buttons;
2360 infoPtr->nNumButtons++;
2361 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2362 /* pre insert copy */
2364 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2365 nIndex * sizeof(TBUTTON_INFO));
2368 /* insert new button */
2369 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2370 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2371 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2372 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2373 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2374 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2376 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2379 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2380 ti.cbSize = sizeof (TTTOOLINFOA);
2382 ti.uId = lpTbb->idCommand;
2384 ti.lpszText = LPSTR_TEXTCALLBACKA;
2386 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
2390 /* post insert copy */
2391 if (nIndex < infoPtr->nNumButtons - 1) {
2392 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2393 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2396 COMCTL32_Free (oldButtons);
2398 TOOLBAR_CalcToolbar (hwnd);
2400 InvalidateRect (hwnd, NULL, FALSE);
2407 TOOLBAR_InsertButtonW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2409 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2410 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2411 INT nIndex = (INT)wParam;
2412 TBUTTON_INFO *oldButtons;
2419 TRACE("inserting button index=%d\n", nIndex);
2420 if (nIndex > infoPtr->nNumButtons) {
2421 nIndex = infoPtr->nNumButtons;
2422 TRACE("adjust index=%d\n", nIndex);
2425 oldButtons = infoPtr->buttons;
2426 infoPtr->nNumButtons++;
2427 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2428 /* pre insert copy */
2430 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2431 nIndex * sizeof(TBUTTON_INFO));
2434 /* insert new button */
2435 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2436 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2437 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2438 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2439 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2440 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2442 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2445 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
2446 ti.cbSize = sizeof (TTTOOLINFOW);
2448 ti.uId = lpTbb->idCommand;
2450 ti.lpszText = LPSTR_TEXTCALLBACKW;
2452 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
2456 /* post insert copy */
2457 if (nIndex < infoPtr->nNumButtons - 1) {
2458 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2459 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2462 COMCTL32_Free (oldButtons);
2464 TOOLBAR_CalcToolbar (hwnd);
2466 InvalidateRect (hwnd, NULL, FALSE);
2472 /* << TOOLBAR_InsertMarkHitTest >> */
2476 TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
2478 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2481 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2485 return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
2490 TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
2492 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2495 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2499 return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
2504 TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
2506 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2509 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2513 return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
2518 TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
2520 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2523 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2527 return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
2532 TOOLBAR_IsButtonIndeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2534 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2537 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2541 return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
2546 TOOLBAR_IsButtonPressed (HWND hwnd, WPARAM wParam, LPARAM lParam)
2548 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2551 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2555 return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
2559 /* << TOOLBAR_LoadImages >> */
2560 /* << TOOLBAR_MapAccelerator >> */
2561 /* << TOOLBAR_MarkButton >> */
2562 /* << TOOLBAR_MoveButton >> */
2566 TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2568 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2569 TBUTTON_INFO *btnPtr;
2572 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2576 btnPtr = &infoPtr->buttons[nIndex];
2577 if (LOWORD(lParam) == FALSE)
2578 btnPtr->fsState &= ~TBSTATE_PRESSED;
2580 btnPtr->fsState |= TBSTATE_PRESSED;
2582 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
2588 /* << TOOLBAR_ReplaceBitmap >> */
2592 TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2595 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2596 LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
2598 if (lpSave == NULL) return 0;
2601 /* save toolbar information */
2602 FIXME("save to \"%s\" \"%s\"\n",
2603 lpSave->pszSubKey, lpSave->pszValueName);
2608 /* restore toolbar information */
2610 FIXME("restore from \"%s\" \"%s\"\n",
2611 lpSave->pszSubKey, lpSave->pszValueName);
2622 TOOLBAR_SaveRestoreW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2625 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2626 LPTBSAVEPARAMSW lpSave = (LPTBSAVEPARAMSW)lParam;
2632 /* save toolbar information */
2633 FIXME("save to \"%s\" \"%s\"\n",
2634 lpSave->pszSubKey, lpSave->pszValueName);
2639 /* restore toolbar information */
2641 FIXME("restore from \"%s\" \"%s\"\n",
2642 lpSave->pszSubKey, lpSave->pszValueName);
2653 TOOLBAR_SetAnchorHighlight (HWND hwnd, WPARAM wParam)
2655 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2656 BOOL bOldAnchor = infoPtr->bAnchor;
2658 infoPtr->bAnchor = (BOOL)wParam;
2660 return (LRESULT)bOldAnchor;
2665 TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2667 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2669 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
2672 if (infoPtr->nNumButtons > 0)
2673 WARN("%d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n",
2674 infoPtr->nNumButtons,
2675 infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
2676 LOWORD(lParam), HIWORD(lParam));
2678 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
2679 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
2681 /* uses image list internals directly */
2682 if (infoPtr->himlDef) {
2683 infoPtr->himlDef->cx = infoPtr->nBitmapWidth;
2684 infoPtr->himlDef->cy = infoPtr->nBitmapHeight;
2692 TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2694 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2695 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
2696 TBUTTON_INFO *btnPtr;
2701 if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
2704 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2708 btnPtr = &infoPtr->buttons[nIndex];
2709 if (lptbbi->dwMask & TBIF_COMMAND)
2710 btnPtr->idCommand = lptbbi->idCommand;
2711 if (lptbbi->dwMask & TBIF_IMAGE)
2712 btnPtr->iBitmap = lptbbi->iImage;
2713 if (lptbbi->dwMask & TBIF_LPARAM)
2714 btnPtr->dwData = lptbbi->lParam;
2715 /* if (lptbbi->dwMask & TBIF_SIZE) */
2716 /* btnPtr->cx = lptbbi->cx; */
2717 if (lptbbi->dwMask & TBIF_STATE)
2718 btnPtr->fsState = lptbbi->fsState;
2719 if (lptbbi->dwMask & TBIF_STYLE)
2720 btnPtr->fsStyle = lptbbi->fsStyle;
2722 if (lptbbi->dwMask & TBIF_TEXT) {
2723 if ((btnPtr->iString >= 0) ||
2724 (btnPtr->iString < infoPtr->nNumStrings)) {
2725 TRACE("Ooooooch\n");
2727 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2728 INT len = lstrlenA (lptbbi->pszText);
2729 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
2732 /* this is the ultimate sollution */
2733 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2742 TOOLBAR_SetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2744 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2745 LPTBBUTTONINFOW lptbbi = (LPTBBUTTONINFOW)lParam;
2746 TBUTTON_INFO *btnPtr;
2751 if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
2754 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2758 btnPtr = &infoPtr->buttons[nIndex];
2759 if (lptbbi->dwMask & TBIF_COMMAND)
2760 btnPtr->idCommand = lptbbi->idCommand;
2761 if (lptbbi->dwMask & TBIF_IMAGE)
2762 btnPtr->iBitmap = lptbbi->iImage;
2763 if (lptbbi->dwMask & TBIF_LPARAM)
2764 btnPtr->dwData = lptbbi->lParam;
2765 /* if (lptbbi->dwMask & TBIF_SIZE) */
2766 /* btnPtr->cx = lptbbi->cx; */
2767 if (lptbbi->dwMask & TBIF_STATE)
2768 btnPtr->fsState = lptbbi->fsState;
2769 if (lptbbi->dwMask & TBIF_STYLE)
2770 btnPtr->fsStyle = lptbbi->fsStyle;
2772 if (lptbbi->dwMask & TBIF_TEXT) {
2773 if ((btnPtr->iString >= 0) ||
2774 (btnPtr->iString < infoPtr->nNumStrings)) {
2776 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2777 INT len = lstrlenW (lptbbi->pszText);
2778 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
2781 /* this is the ultimate sollution */
2782 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2791 TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2793 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2795 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
2797 ERR("invalid parameter\n");
2801 /* Button size can only be set before adding any button to the toolbar
2802 according to the documentation. */
2803 /* this appears to be wrong. WINZIP32.EXE (ver 8) calls this on
2804 one of its buttons after adding it to the toolbar, and it
2805 checks that the return value is nonzero - mjm */
2806 if( infoPtr->nNumButtons != 0 )
2808 FIXME("Button size set after button in toolbar\n");
2812 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
2813 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
2819 TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
2821 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2823 if (infoPtr == NULL)
2826 infoPtr->cxMin = (INT)LOWORD(lParam);
2827 infoPtr->cxMax = (INT)HIWORD(lParam);
2834 TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
2836 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2837 INT nIndex = (INT)wParam;
2839 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2842 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
2844 if (infoPtr->hwndToolTip) {
2846 FIXME("change tool tip!\n");
2854 /* << TOOLBAR_SetColorScheme >> */
2858 TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2860 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2861 HIMAGELIST himlTemp;
2864 himlTemp = infoPtr->himlDis;
2865 infoPtr->himlDis = (HIMAGELIST)lParam;
2867 /* FIXME: redraw ? */
2869 return (LRESULT)himlTemp;
2874 TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
2876 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2879 dwTemp = infoPtr->dwDTFlags;
2880 infoPtr->dwDTFlags =
2881 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
2883 return (LRESULT)dwTemp;
2888 TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2890 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2893 dwTemp = infoPtr->dwExStyle;
2894 infoPtr->dwExStyle = (DWORD)lParam;
2896 return (LRESULT)dwTemp;
2901 TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2903 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2904 HIMAGELIST himlTemp;
2906 himlTemp = infoPtr->himlHot;
2907 infoPtr->himlHot = (HIMAGELIST)lParam;
2909 /* FIXME: redraw ? */
2911 return (LRESULT)himlTemp;
2916 TOOLBAR_SetHotItem (HWND hwnd, WPARAM wParam)
2918 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2919 INT nOldHotItem = infoPtr->nHotItem;
2921 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
2923 infoPtr->nHotItem = (INT)wParam;
2925 /* FIXME: What else must be done ??? */
2929 if (nOldHotItem < 0)
2932 return (LRESULT)nOldHotItem;
2937 TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2939 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2940 HIMAGELIST himlTemp;
2942 himlTemp = infoPtr->himlDef;
2943 infoPtr->himlDef = (HIMAGELIST)lParam;
2945 infoPtr->nNumBitmaps = ImageList_GetImageCount(infoPtr->himlDef);
2946 /* FIXME: redraw ? */
2948 return (LRESULT)himlTemp;
2953 TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2955 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2957 infoPtr->nIndent = (INT)wParam;
2959 TOOLBAR_CalcToolbar (hwnd);
2961 InvalidateRect(hwnd, NULL, FALSE);
2967 /* << TOOLBAR_SetInsertMark >> */
2971 TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2973 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2975 infoPtr->clrInsertMark = (COLORREF)lParam;
2977 /* FIXME : redraw ??*/
2984 TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2986 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2988 if (infoPtr == NULL)
2991 infoPtr->nMaxTextRows = (INT)wParam;
2997 /* << TOOLBAR_SetPadding >> */
3001 TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3003 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3006 if (infoPtr == NULL)
3008 hwndOldNotify = infoPtr->hwndNotify;
3009 infoPtr->hwndNotify = (HWND)wParam;
3011 return hwndOldNotify;
3016 TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3018 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3019 LPRECT lprc = (LPRECT)lParam;
3021 if (LOWORD(wParam) > 1) {
3023 FIXME("multiple rows not supported!\n");
3027 /* recalculate toolbar */
3028 TOOLBAR_CalcToolbar (hwnd);
3030 /* return bounding rectangle */
3032 lprc->left = infoPtr->rcBound.left;
3033 lprc->right = infoPtr->rcBound.right;
3034 lprc->top = infoPtr->rcBound.top;
3035 lprc->bottom = infoPtr->rcBound.bottom;
3038 /* repaint toolbar */
3039 InvalidateRect(hwnd, NULL, FALSE);
3046 TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
3048 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3049 TBUTTON_INFO *btnPtr;
3052 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3056 btnPtr = &infoPtr->buttons[nIndex];
3057 btnPtr->fsState = LOWORD(lParam);
3059 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3066 TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3068 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3069 TBUTTON_INFO *btnPtr;
3072 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3076 btnPtr = &infoPtr->buttons[nIndex];
3077 btnPtr->fsStyle = LOWORD(lParam);
3079 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3081 if (infoPtr->hwndToolTip) {
3082 FIXME("change tool tip!\n");
3089 inline static LRESULT
3090 TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
3092 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3094 if (infoPtr == NULL)
3096 infoPtr->hwndToolTip = (HWND)wParam;
3102 TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
3104 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3107 TRACE("%s hwnd=0x%04x stub!\n",
3108 ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
3110 bTemp = infoPtr->bUnicode;
3111 infoPtr->bUnicode = (BOOL)wParam;
3118 TOOLBAR_SetVersion (HWND hwnd, INT iVersion)
3120 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3121 INT iOldVersion = infoPtr->iVersion;
3123 infoPtr->iVersion = iVersion;
3130 TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
3132 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3133 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3136 /* initialize info structure */
3137 infoPtr->nButtonHeight = 22;
3138 infoPtr->nButtonWidth = 24;
3139 infoPtr->nBitmapHeight = 15;
3140 infoPtr->nBitmapWidth = 16;
3142 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
3144 infoPtr->nMaxTextRows = 1;
3145 infoPtr->cxMin = -1;
3146 infoPtr->cxMax = -1;
3147 infoPtr->nNumBitmaps = 0;
3148 infoPtr->nNumStrings = 0;
3150 infoPtr->bCaptured = FALSE;
3151 infoPtr->bUnicode = IsWindowUnicode (hwnd);
3152 infoPtr->nButtonDown = -1;
3153 infoPtr->nOldHit = -1;
3154 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3155 infoPtr->hwndNotify = GetParent (hwnd);
3156 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
3157 infoPtr->dwDTFlags = (dwStyle & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE : DT_CENTER;
3158 infoPtr->bAnchor = FALSE; /* no anchor highlighting */
3159 infoPtr->iVersion = 0;
3161 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
3162 infoPtr->hFont = CreateFontIndirectA (&logFont);
3164 if (dwStyle & TBSTYLE_TOOLTIPS) {
3165 /* Create tooltip control */
3166 infoPtr->hwndToolTip =
3167 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
3168 CW_USEDEFAULT, CW_USEDEFAULT,
3169 CW_USEDEFAULT, CW_USEDEFAULT,
3172 /* Send NM_TOOLTIPSCREATED notification */
3173 if (infoPtr->hwndToolTip) {
3174 NMTOOLTIPSCREATED nmttc;
3176 nmttc.hdr.hwndFrom = hwnd;
3177 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3178 nmttc.hdr.code = NM_TOOLTIPSCREATED;
3179 nmttc.hwndToolTips = infoPtr->hwndToolTip;
3181 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3182 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
3191 TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
3193 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3195 /* delete tooltip control */
3196 if (infoPtr->hwndToolTip)
3197 DestroyWindow (infoPtr->hwndToolTip);
3199 /* delete button data */
3200 if (infoPtr->buttons)
3201 COMCTL32_Free (infoPtr->buttons);
3203 /* delete strings */
3204 if (infoPtr->strings) {
3206 for (i = 0; i < infoPtr->nNumStrings; i++)
3207 if (infoPtr->strings[i])
3208 COMCTL32_Free (infoPtr->strings[i]);
3210 COMCTL32_Free (infoPtr->strings);
3213 /* destroy internal image list */
3214 if (infoPtr->himlInt)
3215 ImageList_Destroy (infoPtr->himlInt);
3217 /* delete default font */
3219 DeleteObject (infoPtr->hFont);
3221 /* free toolbar info data */
3222 COMCTL32_Free (infoPtr);
3223 SetWindowLongA (hwnd, 0, 0);
3230 TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
3232 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3234 if (infoPtr->bTransparent)
3235 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
3237 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
3242 TOOLBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
3244 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3246 return infoPtr->hFont;
3251 TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
3253 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3254 TBUTTON_INFO *btnPtr;
3258 pt.x = (INT)LOWORD(lParam);
3259 pt.y = (INT)HIWORD(lParam);
3260 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3263 btnPtr = &infoPtr->buttons[nHit];
3264 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3267 infoPtr->bCaptured = TRUE;
3268 infoPtr->nButtonDown = nHit;
3270 btnPtr->fsState |= TBSTATE_PRESSED;
3272 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3274 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
3275 TOOLBAR_Customize (hwnd);
3282 TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
3284 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3285 TBUTTON_INFO *btnPtr;
3289 if (infoPtr->hwndToolTip)
3290 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3291 WM_LBUTTONDOWN, wParam, lParam);
3293 pt.x = (INT)LOWORD(lParam);
3294 pt.y = (INT)HIWORD(lParam);
3295 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3298 btnPtr = &infoPtr->buttons[nHit];
3299 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3302 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN)
3306 nmtb.hdr.hwndFrom = hwnd;
3307 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3308 nmtb.hdr.code = TBN_DROPDOWN;
3309 nmtb.iItem = btnPtr->idCommand;
3311 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3312 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3316 infoPtr->bCaptured = TRUE;
3317 infoPtr->nButtonDown = nHit;
3318 infoPtr->nOldHit = nHit;
3320 btnPtr->fsState |= TBSTATE_PRESSED;
3321 btnPtr->bHot = FALSE;
3323 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3330 TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
3332 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3333 TBUTTON_INFO *btnPtr;
3337 BOOL bSendMessage = TRUE;
3339 if (infoPtr->hwndToolTip)
3340 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3341 WM_LBUTTONUP, wParam, lParam);
3343 pt.x = (INT)LOWORD(lParam);
3344 pt.y = (INT)HIWORD(lParam);
3345 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3347 /* restore hot effect to hot button disabled by TOOLBAR_LButtonDown() */
3348 if(infoPtr->nHotItem >= 0)
3349 infoPtr->buttons[infoPtr->nHotItem].bHot = TRUE;
3351 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
3352 infoPtr->bCaptured = FALSE;
3354 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3355 btnPtr->fsState &= ~TBSTATE_PRESSED;
3357 if (nHit == infoPtr->nButtonDown) {
3358 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
3359 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
3360 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
3361 infoPtr->nButtonDown);
3362 if (nOldIndex == infoPtr->nButtonDown)
3363 bSendMessage = FALSE;
3364 if ((nOldIndex != infoPtr->nButtonDown) &&
3366 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
3367 btnPtr->fsState |= TBSTATE_CHECKED;
3370 if (btnPtr->fsState & TBSTATE_CHECKED)
3371 btnPtr->fsState &= ~TBSTATE_CHECKED;
3373 btnPtr->fsState |= TBSTATE_CHECKED;
3378 bSendMessage = FALSE;
3380 if (nOldIndex != -1)
3381 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect, TRUE);
3383 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3386 SendMessageA (GetParent(hwnd), WM_COMMAND,
3387 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
3389 // if ((GetWindowLongA(hwnd, GWL_STYLE) & TBSTYLE_DROPDOWN) ||
3390 // (btnPtr->fsStyle & 0x08/* BTNS_DROPDOWN */)) {
3392 * This appears to be an error. Instead of checking the style of the
3393 * button in question wine was checking the style of the toolbar
3394 * itself. This caused a number of strange behaviors. In my
3395 * invistigation i think the whole dropdown thing is still fairly
3396 * broken. but this helps fix some of the problems.
3399 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN) {
3402 nmtb.hdr.hwndFrom = hwnd;
3403 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3404 nmtb.hdr.code = TBN_DROPDOWN;
3406 /* nmtb.tbButton not used with TBN_DROPDOWN */
3407 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings)) {
3408 nmtb.pszText = infoPtr->strings[btnPtr->iString];
3409 nmtb.cchText = lstrlenW(nmtb.pszText);
3411 nmtb.pszText = NULL;
3414 nmtb.rcButton = btnPtr->rect;
3416 SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
3417 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3420 infoPtr->nButtonDown = -1;
3421 infoPtr->nOldHit = -1;
3428 TOOLBAR_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam)
3430 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3431 TBUTTON_INFO *hotBtnPtr;
3433 if (infoPtr->nOldHit < 0)
3436 hotBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3438 /* Redraw the button if the last button we were over is the hot button and it
3440 if((infoPtr->nOldHit == infoPtr->nHotItem) && (hotBtnPtr->fsState & TBSTATE_ENABLED))
3442 hotBtnPtr->bHot = FALSE;
3444 InvalidateRect (hwnd, &hotBtnPtr->rect, TRUE);
3447 infoPtr->nOldHit = -1; /* reset the old hit index as we've left the toolbar */
3448 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3454 TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
3456 TBUTTON_INFO *btnPtr, *oldBtnPtr;
3457 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3460 TRACKMOUSEEVENT trackinfo;
3462 /* fill in the TRACKMOUSEEVENT struct */
3463 trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
3464 trackinfo.dwFlags = TME_QUERY;
3465 trackinfo.hwndTrack = hwnd;
3466 trackinfo.dwHoverTime = HOVER_DEFAULT;
3468 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
3469 _TrackMouseEvent(&trackinfo);
3471 /* Make sure tracking is enabled so we recieve a WM_MOUSELEAVE message */
3472 if(!(trackinfo.dwFlags & TME_LEAVE)) {
3473 trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
3475 /* call TRACKMOUSEEVENT so we recieve a WM_MOUSELEAVE message */
3476 /* and can properly deactivate the hot toolbar button */
3477 _TrackMouseEvent(&trackinfo);
3480 if (infoPtr->hwndToolTip)
3481 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3482 WM_MOUSEMOVE, wParam, lParam);
3484 pt.x = (INT)LOWORD(lParam);
3485 pt.y = (INT)HIWORD(lParam);
3487 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3489 if (infoPtr->nOldHit != nHit)
3491 /* Remove the effect of an old hot button if the button was enabled and was
3492 drawn with the hot button effect */
3493 if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem &&
3494 (infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED))
3496 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3497 oldBtnPtr->bHot = FALSE;
3499 InvalidateRect (hwnd, &oldBtnPtr->rect, TRUE);
3502 /* It's not a separator or in nowhere. It's a hot button. */
3505 btnPtr = &infoPtr->buttons[nHit];
3506 btnPtr->bHot = TRUE;
3508 infoPtr->nHotItem = nHit;
3510 /* only enabled buttons show hot effect */
3511 if(infoPtr->buttons[nHit].fsState & TBSTATE_ENABLED)
3512 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3515 if (infoPtr->bCaptured) {
3516 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3517 if (infoPtr->nOldHit == infoPtr->nButtonDown) {
3518 btnPtr->fsState &= ~TBSTATE_PRESSED;
3519 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3521 else if (nHit == infoPtr->nButtonDown) {
3522 btnPtr->fsState |= TBSTATE_PRESSED;
3523 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3526 infoPtr->nOldHit = nHit;
3532 inline static LRESULT
3533 TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3535 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
3536 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
3538 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
3542 inline static LRESULT
3543 TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3545 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
3546 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
3548 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
3553 TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3555 TOOLBAR_INFO *infoPtr;
3557 /* allocate memory for info structure */
3558 infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
3559 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
3562 infoPtr->dwStructSize = sizeof(TBBUTTON);
3564 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
3565 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
3566 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
3567 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
3570 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
3575 TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3577 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3581 if (dwStyle & WS_MINIMIZE)
3582 return 0; /* Nothing to do */
3584 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
3586 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
3589 if (!(dwStyle & CCS_NODIVIDER))
3591 GetWindowRect (hwnd, &rcWindow);
3592 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3593 if( dwStyle & WS_BORDER )
3594 OffsetRect (&rcWindow, 1, 1);
3595 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
3598 ReleaseDC( hwnd, hdc );
3604 inline static LRESULT
3605 TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
3607 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3608 LPNMHDR lpnmh = (LPNMHDR)lParam;
3610 TRACE("passing WM_NOTIFY!\n");
3612 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
3613 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
3616 if (lpnmh->code == TTN_GETDISPINFOA) {
3617 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
3619 FIXME("retrieving ASCII string\n");
3622 else if (lpnmh->code == TTN_GETDISPINFOW) {
3623 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
3625 FIXME("retrieving UNICODE string\n");
3636 TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
3638 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3642 /* fill ps.rcPaint with a default rect */
3643 memcpy(&(ps.rcPaint), &(infoPtr->rcBound), sizeof(infoPtr->rcBound));
3645 TOOLBAR_CalcToolbar( hwnd );
3646 hdc = wParam==0 ? BeginPaint(hwnd, &ps) : (HDC)wParam;
3647 TOOLBAR_Refresh (hwnd, hdc, &ps);
3648 if (!wParam) EndPaint (hwnd, &ps);
3655 TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
3657 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3658 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3667 /* Resize deadlock check */
3668 if (infoPtr->bAutoSize) {
3669 infoPtr->bAutoSize = FALSE;
3673 flags = (INT) wParam;
3675 /* FIXME for flags =
3676 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
3679 TRACE("sizing toolbar!\n");
3681 if (flags == SIZE_RESTORED) {
3682 /* width and height don't apply */
3683 parent = GetParent (hwnd);
3684 GetClientRect(parent, &parent_rect);
3685 x = parent_rect.left;
3686 y = parent_rect.top;
3688 if (dwStyle & CCS_NORESIZE) {
3689 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
3692 * this sets the working width of the toolbar, and
3693 * Calc Toolbar will not adjust it, only the height
3695 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3696 cy = infoPtr->nHeight;
3697 cx = infoPtr->nWidth;
3698 TOOLBAR_CalcToolbar (hwnd);
3699 infoPtr->nWidth = cx;
3700 infoPtr->nHeight = cy;
3703 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3704 TOOLBAR_CalcToolbar (hwnd);
3705 cy = infoPtr->nHeight;
3706 cx = infoPtr->nWidth;
3708 if (dwStyle & CCS_NOMOVEY) {
3709 GetWindowRect(hwnd, &window_rect);
3710 ScreenToClient(parent, (LPPOINT)&window_rect.left);
3711 y = window_rect.top;
3715 if (dwStyle & CCS_NOPARENTALIGN) {
3716 uPosFlags |= SWP_NOMOVE;
3717 cy = infoPtr->nHeight;
3718 cx = infoPtr->nWidth;
3721 if (!(dwStyle & CCS_NODIVIDER))
3722 cy += GetSystemMetrics(SM_CYEDGE);
3724 if (dwStyle & WS_BORDER)
3727 cy += GetSystemMetrics(SM_CYEDGE);
3728 cx += GetSystemMetrics(SM_CYEDGE);
3731 SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
3732 cx, cy, uPosFlags | SWP_NOZORDER);
3739 TOOLBAR_StyleChanged (HWND hwnd, INT nType, LPSTYLESTRUCT lpStyle)
3741 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3743 if (nType == GWL_STYLE) {
3744 if (lpStyle->styleNew & TBSTYLE_LIST) {
3745 infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
3748 infoPtr->dwDTFlags = DT_CENTER;
3752 TOOLBAR_AutoSize (hwnd);
3754 InvalidateRect(hwnd, NULL, FALSE);
3761 static LRESULT WINAPI
3762 ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3768 return TOOLBAR_Destroy (hwnd, wParam, lParam);
3771 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
3774 if (!TOOLBAR_GetInfoPtr (hwnd))
3776 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3782 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
3784 case TB_ADDBUTTONSA:
3785 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
3787 case TB_ADDBUTTONSW:
3788 return TOOLBAR_AddButtonsW (hwnd, wParam, lParam);
3791 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
3794 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
3797 return TOOLBAR_AutoSize (hwnd);
3799 case TB_BUTTONCOUNT:
3800 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
3802 case TB_BUTTONSTRUCTSIZE:
3803 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
3805 case TB_CHANGEBITMAP:
3806 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
3808 case TB_CHECKBUTTON:
3809 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
3811 case TB_COMMANDTOINDEX:
3812 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
3815 return TOOLBAR_Customize (hwnd);
3817 case TB_DELETEBUTTON:
3818 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
3820 case TB_ENABLEBUTTON:
3821 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
3823 case TB_GETANCHORHIGHLIGHT:
3824 return TOOLBAR_GetAnchorHighlight (hwnd);
3827 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
3829 case TB_GETBITMAPFLAGS:
3830 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
3833 return TOOLBAR_GetButton (hwnd, wParam, lParam);
3835 case TB_GETBUTTONINFOA:
3836 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
3838 case TB_GETBUTTONINFOW:
3839 return TOOLBAR_GetButtonInfoW (hwnd, wParam, lParam);
3841 case TB_GETBUTTONSIZE:
3842 return TOOLBAR_GetButtonSize (hwnd);
3844 case TB_GETBUTTONTEXTA:
3845 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
3847 case TB_GETBUTTONTEXTW:
3848 return TOOLBAR_GetButtonTextW (hwnd, wParam, lParam);
3850 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
3852 case TB_GETDISABLEDIMAGELIST:
3853 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
3855 case TB_GETEXTENDEDSTYLE:
3856 return TOOLBAR_GetExtendedStyle (hwnd);
3858 case TB_GETHOTIMAGELIST:
3859 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
3862 return TOOLBAR_GetHotItem (hwnd);
3864 case TB_GETIMAGELIST:
3865 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
3867 /* case TB_GETINSERTMARK: */ /* 4.71 */
3868 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
3870 case TB_GETITEMRECT:
3871 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
3874 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
3876 /* case TB_GETOBJECT: */ /* 4.71 */
3877 /* case TB_GETPADDING: */ /* 4.71 */
3880 return TOOLBAR_GetRect (hwnd, wParam, lParam);
3883 return TOOLBAR_GetRows (hwnd, wParam, lParam);
3886 return TOOLBAR_GetState (hwnd, wParam, lParam);
3889 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
3891 case TB_GETTEXTROWS:
3892 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
3894 case TB_GETTOOLTIPS:
3895 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
3897 case TB_GETUNICODEFORMAT:
3898 return TOOLBAR_GetUnicodeFormat (hwnd, wParam, lParam);
3900 case CCM_GETVERSION:
3901 return TOOLBAR_GetVersion (hwnd);
3904 return TOOLBAR_HideButton (hwnd, wParam, lParam);
3907 return TOOLBAR_HitTest (hwnd, wParam, lParam);
3909 case TB_INDETERMINATE:
3910 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
3912 case TB_INSERTBUTTONA:
3913 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
3915 case TB_INSERTBUTTONW:
3916 return TOOLBAR_InsertButtonW (hwnd, wParam, lParam);
3918 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
3920 case TB_ISBUTTONCHECKED:
3921 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
3923 case TB_ISBUTTONENABLED:
3924 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
3926 case TB_ISBUTTONHIDDEN:
3927 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
3929 case TB_ISBUTTONHIGHLIGHTED:
3930 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
3932 case TB_ISBUTTONINDETERMINATE:
3933 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
3935 case TB_ISBUTTONPRESSED:
3936 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
3938 case TB_LOADIMAGES: /* 4.70 */
3939 FIXME("missing standard imagelists\n");
3942 /* case TB_MAPACCELERATORA: */ /* 4.71 */
3943 /* case TB_MAPACCELERATORW: */ /* 4.71 */
3944 /* case TB_MARKBUTTON: */ /* 4.71 */
3945 /* case TB_MOVEBUTTON: */ /* 4.71 */
3947 case TB_PRESSBUTTON:
3948 return TOOLBAR_PressButton (hwnd, wParam, lParam);
3950 /* case TB_REPLACEBITMAP: */
3952 case TB_SAVERESTOREA:
3953 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
3955 case TB_SAVERESTOREW:
3956 return TOOLBAR_SaveRestoreW (hwnd, wParam, lParam);
3958 case TB_SETANCHORHIGHLIGHT:
3959 return TOOLBAR_SetAnchorHighlight (hwnd, wParam);
3961 case TB_SETBITMAPSIZE:
3962 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
3964 case TB_SETBUTTONINFOA:
3965 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
3967 case TB_SETBUTTONINFOW:
3968 return TOOLBAR_SetButtonInfoW (hwnd, wParam, lParam);
3970 case TB_SETBUTTONSIZE:
3971 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
3973 case TB_SETBUTTONWIDTH:
3974 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
3977 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
3979 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
3981 case TB_SETDISABLEDIMAGELIST:
3982 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
3984 case TB_SETDRAWTEXTFLAGS:
3985 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
3987 case TB_SETEXTENDEDSTYLE:
3988 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
3990 case TB_SETHOTIMAGELIST:
3991 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
3994 return TOOLBAR_SetHotItem (hwnd, wParam);
3996 case TB_SETIMAGELIST:
3997 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
4000 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
4002 /* case TB_SETINSERTMARK: */ /* 4.71 */
4004 case TB_SETINSERTMARKCOLOR:
4005 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
4007 case TB_SETMAXTEXTROWS:
4008 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
4010 /* case TB_SETPADDING: */ /* 4.71 */
4013 return TOOLBAR_SetParent (hwnd, wParam, lParam);
4016 return TOOLBAR_SetRows (hwnd, wParam, lParam);
4019 return TOOLBAR_SetState (hwnd, wParam, lParam);
4022 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
4024 case TB_SETTOOLTIPS:
4025 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
4027 case TB_SETUNICODEFORMAT:
4028 return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
4030 case CCM_SETVERSION:
4031 return TOOLBAR_SetVersion (hwnd, (INT)wParam);
4037 return TOOLBAR_Create (hwnd, wParam, lParam);
4040 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
4043 return TOOLBAR_GetFont (hwnd, wParam, lParam);
4045 /* case WM_KEYDOWN: */
4046 /* case WM_KILLFOCUS: */
4048 case WM_LBUTTONDBLCLK:
4049 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
4051 case WM_LBUTTONDOWN:
4052 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
4055 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
4058 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
4061 return TOOLBAR_MouseLeave (hwnd, wParam, lParam);
4064 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
4067 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
4070 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
4073 return TOOLBAR_Notify (hwnd, wParam, lParam);
4075 /* case WM_NOTIFYFORMAT: */
4078 return TOOLBAR_Paint (hwnd, wParam);
4081 return TOOLBAR_Size (hwnd, wParam, lParam);
4083 case WM_STYLECHANGED:
4084 return TOOLBAR_StyleChanged (hwnd, (INT)wParam, (LPSTYLESTRUCT)lParam);
4086 /* case WM_SYSCOLORCHANGE: */
4088 /* case WM_WININICHANGE: */
4093 case WM_MEASUREITEM:
4095 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
4098 if (uMsg >= WM_USER)
4099 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
4100 uMsg, wParam, lParam);
4101 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
4108 TOOLBAR_Register (void)
4112 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
4113 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
4114 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
4115 wndClass.cbClsExtra = 0;
4116 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
4117 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
4118 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
4119 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
4121 RegisterClassA (&wndClass);
4126 TOOLBAR_Unregister (void)
4128 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);