4 * Copyright 1998,1999 Eric Kohl
7 * - A little bug in TOOLBAR_DrawMasked()
8 * - Button wrapping (under construction).
10 * - Notifications (under construction).
12 * - Tooltip support (almost complete).
13 * - Unicode suppport (under construction).
14 * - Fix TOOLBAR_SetButtonInfo32A/W.
15 * - Customize dialog (under construction).
16 * - TBSTYLE_AUTOSIZE for toolbar and buttons.
17 * - I_IMAGECALLBACK support.
20 * - Run tests using Waite Group Windows95 API Bible Volume 2.
21 * The second cdrom contains executables addstr.exe, btncount.exe,
22 * btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
23 * enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
24 * indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
25 * setparnt.exe, setrows.exe, toolwnd.exe.
26 * - Microsofts controlspy examples.
39 #include "debugtools.h"
41 DEFAULT_DEBUG_CHANNEL(toolbar)
43 #define SEPARATOR_WIDTH 8
45 #define BOTTOM_BORDER 2
47 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
50 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index)
52 if ((index>=0) && (index < infoPtr->nNumBitmaps))
60 TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
62 INT x = (lpRect->left + lpRect->right) / 2 - 1;
63 INT yBottom = lpRect->bottom - 3;
64 INT yTop = lpRect->top + 1;
66 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
67 MoveToEx (hdc, x, yBottom, NULL);
68 LineTo (hdc, x, yTop);
70 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
71 MoveToEx (hdc, x, yBottom, NULL);
72 LineTo (hdc, x, yTop);
76 * Draw the text string for this button.
77 * note: infoPtr->himlDis *SHOULD* be non-zero when infoPtr->himlDef
78 * is non-zero, so we can simply check himlDef to see if we have
82 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
83 HDC hdc, INT nState, DWORD dwStyle)
85 RECT rcText = btnPtr->rect;
90 HIMAGELIST himl = infoPtr->himlDef;
92 TRACE ("iString: %x\n", btnPtr->iString);
94 /* get a pointer to the text */
95 if (btnPtr->iString == -1)
96 FIXME("Undocumented Index -1\n");
97 else if (HIWORD(btnPtr->iString) != 0)
98 lpText = (LPWSTR)btnPtr->iString;
99 else if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
100 lpText = infoPtr->strings[btnPtr->iString];
102 TRACE ("lpText: \"%s\"\n", debugstr_w(lpText));
107 InflateRect (&rcText, -3, -3);
109 if (himl && TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
110 if ((dwStyle & TBSTYLE_LIST) &&
111 ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
112 (btnPtr->iBitmap != I_IMAGENONE)) {
113 rcText.left += infoPtr->nBitmapWidth;
116 rcText.top += infoPtr->nBitmapHeight;
120 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
121 OffsetRect (&rcText, 1, 1);
123 hOldFont = SelectObject (hdc, infoPtr->hFont);
124 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
125 if (!(nState & TBSTATE_ENABLED)) {
126 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
127 OffsetRect (&rcText, 1, 1);
128 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
129 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
130 OffsetRect (&rcText, -1, -1);
131 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
133 else if (nState & TBSTATE_INDETERMINATE) {
134 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
135 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
138 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
139 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
142 SetTextColor (hdc, clrOld);
143 SelectObject (hdc, hOldFont);
144 if (nOldBkMode != TRANSPARENT)
145 SetBkMode (hdc, nOldBkMode);
151 TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
153 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
154 INT cx = lpRect->right - lpRect->left;
155 INT cy = lpRect->bottom - lpRect->top;
156 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
157 SelectObject (hdc, hbr);
162 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
163 HDC hdc, INT x, INT y)
165 /* FIXME: this function is a hack since it uses image list
166 internals directly */
168 HIMAGELIST himl = infoPtr->himlDef;
176 /* create new dc's */
177 hdcImageList = CreateCompatibleDC (0);
178 hdcMask = CreateCompatibleDC (0);
180 /* create new bitmap */
181 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
182 SelectObject (hdcMask, hbmMask);
184 /* copy the mask bitmap */
185 SelectObject (hdcImageList, himl->hbmMask);
186 SetBkColor (hdcImageList, RGB(255, 255, 255));
187 SetTextColor (hdcImageList, RGB(0, 0, 0));
188 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
189 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
192 /* add white mask from image */
193 SelectObject (hdcImageList, himl->hbmImage);
194 SetBkColor (hdcImageList, RGB(0, 0, 0));
195 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
196 hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
199 /* draw the new mask */
200 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
201 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
202 hdcMask, 0, 0, 0xB8074A);
204 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
205 BitBlt (hdc, x, y, himl->cx, himl->cy,
206 hdcMask, 0, 0, 0xB8074A);
208 DeleteObject (hbmMask);
210 DeleteDC (hdcImageList);
215 TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
217 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
218 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
221 if (btnPtr->fsState & TBSTATE_HIDDEN)
226 TRACE("iBitmap: %d\n", btnPtr->iBitmap);
229 if (btnPtr->fsStyle & TBSTYLE_SEP) {
230 /* with the FLAT style, iBitmap is the width and has already */
231 /* been taken into consideration in calculating the width */
232 /* so now we need to draw the vertical separator */
233 /* empirical tests show that iBitmap can/will be non-zero */
234 /* when drawing the vertical bar... */
235 if ((dwStyle & TBSTYLE_FLAT) /* && (btnPtr->iBitmap == 0) */)
236 TOOLBAR_DrawFlatSeparator (&rc, hdc);
241 if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
242 if (!(dwStyle & TBSTYLE_FLAT))
243 DrawEdge (hdc, &rc, EDGE_RAISED,
244 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
246 if (infoPtr->himlDis &&
247 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
248 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
249 rc.left+1, rc.top+1, ILD_NORMAL);
251 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
253 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
257 /* pressed TBSTYLE_BUTTON */
258 if (btnPtr->fsState & TBSTATE_PRESSED) {
259 if (dwStyle & TBSTYLE_FLAT)
260 DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
262 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
263 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
264 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
265 rc.left+2, rc.top+2, ILD_NORMAL);
266 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
270 /* checked TBSTYLE_CHECK */
271 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
272 (btnPtr->fsState & TBSTATE_CHECKED)) {
273 if (dwStyle & TBSTYLE_FLAT)
274 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
275 BF_RECT | BF_MIDDLE | BF_ADJUST);
277 DrawEdge (hdc, &rc, EDGE_SUNKEN,
278 BF_RECT | BF_MIDDLE | BF_ADJUST);
280 TOOLBAR_DrawPattern (hdc, &rc);
282 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
283 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
284 rc.left+2, rc.top+2, ILD_NORMAL);
286 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
291 if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
292 DrawEdge (hdc, &rc, EDGE_RAISED,
293 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
295 TOOLBAR_DrawPattern (hdc, &rc);
296 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
297 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
302 if (dwStyle & TBSTYLE_FLAT)
305 DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
306 if (btnPtr->bHot && infoPtr->himlHot &&
307 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
308 ImageList_Draw (infoPtr->himlHot, btnPtr->iBitmap, hdc,
309 rc.left +2, rc.top +2, ILD_NORMAL);
310 else if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
311 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
312 rc.left +2, rc.top +2, ILD_NORMAL);
316 DrawEdge (hdc, &rc, EDGE_RAISED,
317 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
319 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
320 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
321 rc.left+1, rc.top+1, ILD_NORMAL);
324 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
329 TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
331 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
332 TBUTTON_INFO *btnPtr;
336 /* redraw necessary buttons */
337 btnPtr = infoPtr->buttons;
338 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
340 if(IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect)))
341 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
346 TOOLBAR_MeasureString(HWND hwnd, INT index, LPSIZE lpSize)
348 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
349 TBUTTON_INFO *btnPtr;
356 hOldFont = SelectObject (hdc, infoPtr->hFont);
358 btnPtr = &infoPtr->buttons[index];
360 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
361 (btnPtr->iString > -1) &&
362 (btnPtr->iString < infoPtr->nNumStrings))
364 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
365 GetTextExtentPoint32W (hdc, lpText, lstrlenW (lpText), lpSize);
368 SelectObject (hdc, hOldFont);
371 TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
375 TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
377 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
378 TBUTTON_INFO *btnPtr;
386 btnPtr = infoPtr->buttons;
387 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
388 TOOLBAR_MeasureString(hwnd,i,&sz);
389 if (sz.cx > lpSize->cx)
391 if (sz.cy > lpSize->cy)
395 TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
398 /***********************************************************************
399 * TOOLBAR_WrapToolbar
401 * This function walks through the buttons and seperators in the
402 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
403 * wrapping should occur based on the width of the toolbar window.
404 * It does *not* calculate button placement itself. That task
405 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
406 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
407 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
411 TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
413 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
414 TBUTTON_INFO *btnPtr;
417 BOOL bWrap, bButtonWrap;
419 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
420 /* no layout is necessary. Applications may use this style */
421 /* to perform their own layout on the toolbar. */
422 if( !(dwStyle & TBSTYLE_WRAPABLE) )
425 btnPtr = infoPtr->buttons;
426 x = infoPtr->nIndent;
428 /* this can get the parents width, to know how far we can extend
429 * this toolbar. We cannot use its height, as there may be multiple
430 * toolbars in a rebar control
432 GetClientRect( GetParent(hwnd), &rc );
433 infoPtr->nWidth = rc.right - rc.left;
436 for (i = 0; i < infoPtr->nNumButtons; i++ )
439 btnPtr[i].fsState &= ~TBSTATE_WRAP;
441 if (btnPtr[i].fsState & TBSTATE_HIDDEN)
444 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
445 /* it is the actual width of the separator. This is used for */
446 /* custom controls in toolbars. */
447 if (btnPtr[i].fsStyle & TBSTYLE_SEP)
448 cx = (btnPtr[i].iBitmap > 0) ?
449 btnPtr[i].iBitmap : SEPARATOR_WIDTH;
451 cx = infoPtr->nButtonWidth;
453 /* Two or more adjacent separators form a separator group. */
454 /* The first separator in a group should be wrapped to the */
455 /* next row if the previous wrapping is on a button. */
457 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
458 (i + 1 < infoPtr->nNumButtons ) &&
459 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
461 btnPtr[i].fsState |= TBSTATE_WRAP;
462 x = infoPtr->nIndent;
468 /* The layout makes sure the bitmap is visible, but not the button. */
469 if ( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
474 /* If the current button is a separator and not hidden, */
475 /* go to the next until it reaches a non separator. */
476 /* Wrap the last separator if it is before a button. */
477 while( ( (btnPtr[i].fsStyle & TBSTYLE_SEP) ||
478 (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
479 i < infoPtr->nNumButtons )
485 if( bFound && i < infoPtr->nNumButtons )
488 btnPtr[i].fsState |= TBSTATE_WRAP;
489 x = infoPtr->nIndent;
493 else if ( i >= infoPtr->nNumButtons)
496 /* If the current button is not a separator, find the last */
497 /* separator and wrap it. */
498 for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
500 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
501 !(btnPtr[j].fsState & TBSTATE_HIDDEN))
505 x = infoPtr->nIndent;
506 btnPtr[j].fsState |= TBSTATE_WRAP;
512 /* If no separator available for wrapping, wrap one of */
513 /* non-hidden previous button. */
517 j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
519 if (btnPtr[j].fsState & TBSTATE_HIDDEN)
524 x = infoPtr->nIndent;
525 btnPtr[j].fsState |= TBSTATE_WRAP;
531 /* If all above failed, wrap the current button. */
534 btnPtr[i].fsState |= TBSTATE_WRAP;
536 x = infoPtr->nIndent;
537 if (btnPtr[i].fsState & TBSTYLE_SEP )
548 /***********************************************************************
549 * TOOLBAR_CalcToolbar
551 * This function calculates button and separator placement. It first
552 * calculates the button sizes, gets the toolbar window width and then
553 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
554 * on. It assigns a new location to each item and sends this location to
555 * the tooltip window if appropriate. Finally, it updates the rcBound
556 * rect and calculates the new required toolbar window height.
560 TOOLBAR_CalcToolbar (HWND hwnd)
562 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
563 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
564 TBUTTON_INFO *btnPtr;
565 INT i, nRows, nSepRows;
570 TOOLBAR_CalcStrings (hwnd, &sizeString);
572 if (dwStyle & TBSTYLE_LIST) {
573 infoPtr->nButtonHeight = max(infoPtr->nBitmapHeight, sizeString.cy) + 6;
574 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + sizeString.cx + 6;
577 BOOL usesBitmaps = FALSE;
580 for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
581 if (TOOLBAR_IsValidBitmapIndex(infoPtr,infoPtr->buttons[i].iBitmap))
584 if (sizeString.cy > 0) {
586 infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
588 infoPtr->nButtonHeight = sizeString.cy + 6;
590 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
591 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
593 if (sizeString.cx > infoPtr->nBitmapWidth)
594 infoPtr->nButtonWidth = sizeString.cx + 6;
595 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
596 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
599 if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin )
600 infoPtr->nButtonWidth = infoPtr->cxMin;
601 if ( infoPtr->cxMax >= 0 && infoPtr->nButtonWidth > infoPtr->cxMax )
602 infoPtr->nButtonWidth = infoPtr->cxMax;
604 TOOLBAR_WrapToolbar( hwnd, dwStyle );
606 x = infoPtr->nIndent;
607 y = (dwStyle & TBSTYLE_FLAT) ? 0 : TOP_BORDER;
610 * We wills et the height below, and we set the width on entry
611 * so we do not reset them here..
614 GetClientRect( hwnd, &rc );
615 /* get initial values for toolbar */
616 infoPtr->nWidth = rc.right - rc.left;
617 infoPtr->nHeight = rc.bottom - rc.top;
620 /* from above, minimum is a button, and possible text */
621 cx = infoPtr->nButtonWidth;
622 /* cannot use just ButtonHeight, we may have no buttons! */
623 if (infoPtr->nNumButtons > 0)
624 infoPtr->nHeight = infoPtr->nButtonHeight;
625 cy = infoPtr->nHeight;
627 nRows = nSepRows = 0;
629 infoPtr->rcBound.top = y;
630 infoPtr->rcBound.left = x;
631 infoPtr->rcBound.bottom = y + cy;
632 infoPtr->rcBound.right = x;
634 btnPtr = infoPtr->buttons;
636 /* do not base height/width on parent, if the parent is a */
637 /* rebar control it could have multiple rows of toolbars */
638 /* GetClientRect( GetParent(hwnd), &rc ); */
639 /* cx = rc.right - rc.left; */
640 /* cy = rc.bottom - rc.top; */
642 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
645 if (btnPtr->fsState & TBSTATE_HIDDEN)
647 SetRectEmpty (&btnPtr->rect);
651 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
652 /* it is the actual width of the separator. This is used for */
653 /* custom controls in toolbars. */
654 if (btnPtr->fsStyle & TBSTYLE_SEP)
655 cx = (btnPtr->iBitmap > 0) ?
656 btnPtr->iBitmap : SEPARATOR_WIDTH;
658 if (btnPtr->fsStyle & TBSTYLE_AUTOSIZE)
661 TOOLBAR_MeasureString(hwnd,i,&sz);
665 cx = infoPtr->nButtonWidth;
667 cy = infoPtr->nHeight;
669 if (btnPtr->fsState & TBSTATE_WRAP )
672 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
674 if (infoPtr->rcBound.left > x)
675 infoPtr->rcBound.left = x;
676 if (infoPtr->rcBound.right < x + cx)
677 infoPtr->rcBound.right = x + cx;
678 if (infoPtr->rcBound.bottom < y + cy)
679 infoPtr->rcBound.bottom = y + cy;
681 /* Set the toolTip only for non-hidden, non-separator button */
682 if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP ))
686 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
687 ti.cbSize = sizeof(TTTOOLINFOA);
689 ti.uId = btnPtr->idCommand;
690 ti.rect = btnPtr->rect;
691 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
695 /* btnPtr->nRow is zero based. The space between the rows is */
696 /* also considered as a row. */
697 btnPtr->nRow = nRows + nSepRows;
700 if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
704 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
705 /* it is the actual width of the separator. This is used for */
706 /* custom controls in toolbars. */
707 y += cy + ( (btnPtr->iBitmap > 0 ) ?
708 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
710 /* nSepRows is used to calculate the extra height follwoing */
714 x = infoPtr->nIndent;
721 /* infoPtr->nRows is the number of rows on the toolbar */
722 infoPtr->nRows = nRows + nSepRows + 1;
724 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
726 infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
727 nSepRows * (SEPARATOR_WIDTH * 2 / 3) +
728 nSepRows * (infoPtr->nBitmapHeight + 1) +
730 TRACE("toolbar height %d\n", infoPtr->nHeight);
735 TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
737 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
738 TBUTTON_INFO *btnPtr;
741 btnPtr = infoPtr->buttons;
742 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
743 if (btnPtr->fsState & TBSTATE_HIDDEN)
746 if (btnPtr->fsStyle & TBSTYLE_SEP) {
747 if (PtInRect (&btnPtr->rect, *lpPt)) {
748 TRACE(" ON SEPARATOR %d!\n", i);
753 if (PtInRect (&btnPtr->rect, *lpPt)) {
754 TRACE(" ON BUTTON %d!\n", i);
760 TRACE(" NOWHERE!\n");
766 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
768 TBUTTON_INFO *btnPtr;
771 btnPtr = infoPtr->buttons;
772 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
773 if (btnPtr->idCommand == idCommand) {
774 TRACE("command=%d index=%d\n", idCommand, i);
778 TRACE("no index found for command=%d\n", idCommand);
784 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
786 TBUTTON_INFO *btnPtr;
789 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
792 /* check index button */
793 btnPtr = &infoPtr->buttons[nIndex];
794 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
795 if (btnPtr->fsState & TBSTATE_CHECKED)
799 /* check previous buttons */
800 nRunIndex = nIndex - 1;
801 while (nRunIndex >= 0) {
802 btnPtr = &infoPtr->buttons[nRunIndex];
803 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
804 if (btnPtr->fsState & TBSTATE_CHECKED)
812 /* check next buttons */
813 nRunIndex = nIndex + 1;
814 while (nRunIndex < infoPtr->nNumButtons) {
815 btnPtr = &infoPtr->buttons[nRunIndex];
816 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
817 if (btnPtr->fsState & TBSTATE_CHECKED)
830 TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
831 WPARAM wParam, LPARAM lParam)
839 msg.time = GetMessageTime ();
840 msg.pt.x = LOWORD(GetMessagePos ());
841 msg.pt.y = HIWORD(GetMessagePos ());
843 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
847 /***********************************************************************
848 * TOOLBAR_CustomizeDialogProc
849 * This function implements the toolbar customization dialog.
852 TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
854 TOOLBAR_INFO *infoPtr = (TOOLBAR_INFO *)GetWindowLongA (hwnd, DWL_USER);
855 static HDSA hDsa = NULL;
860 infoPtr = (TOOLBAR_INFO *)lParam;
861 SetWindowLongA (hwnd, DWL_USER, (DWORD)infoPtr);
863 hDsa = DSA_Create (sizeof(TBUTTON_INFO), 5);
867 TBUTTON_INFO *btnPtr;
870 /* insert 'virtual' separator button into 'available buttons' list */
871 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
873 /* copy all buttons and append them to the right listbox */
874 btnPtr = infoPtr->buttons;
875 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
877 DSA_InsertItem (hDsa, i, btnPtr);
879 /* FIXME: hidden buttons appear in the 'toolbar buttons' list too */
880 if (btnPtr->fsState & TBSTATE_HIDDEN)
882 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
886 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
890 /* append 'virtual' separator button to the 'toolbar buttons' list */
896 EndDialog(hwnd, FALSE);
900 switch (LOWORD(wParam))
903 EndDialog(hwnd, FALSE);
914 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
916 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
922 COLORREF oldText = 0;
925 FIXME("action: %x itemState: %x\n",
926 lpdis->itemAction, lpdis->itemState);
928 DSA_GetItem (hDsa, 0 /*lpdis->itemID*/, &btnPtr);
930 if (lpdis->itemState & ODS_FOCUS)
932 oldBk = SetBkColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
933 oldText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
936 hOldPen = SelectObject (lpdis->hDC, GetSysColorPen ((lpdis->itemState & ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
937 hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
939 /* fill background rectangle */
940 Rectangle (lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
941 lpdis->rcItem.right, lpdis->rcItem.bottom);
943 /* calculate button and text rectangles */
944 CopyRect (&rcButton, &lpdis->rcItem);
945 InflateRect (&rcButton, -1, -1);
946 CopyRect (&rcText, &rcButton);
947 rcButton.right = rcButton.left + infoPtr->nBitmapWidth + 6;
948 rcText.left = rcButton.right + 2;
950 /* draw focus rectangle */
951 if (lpdis->itemState & ODS_FOCUS)
952 DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
955 DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
957 /* draw image and text */
958 if (wParam == IDC_AVAILBTN_LBOX && lpdis->itemID == 0)
960 /* virtual separator in the 'available' list */
961 DrawTextA (lpdis->hDC, "Separator", -1, &rcText,
962 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
968 ImageList_Draw (infoPtr->himlDef, btnPtr.iBitmap, lpdis->hDC,
969 rcButton.left+1, rcButton.top+1, ILD_NORMAL);
971 DrawTextW (lpdis->hDC, infoPtr->strings[btnPtr.iString], -1, &rcText,
972 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
976 if (lpdis->itemState & ODS_FOCUS)
978 SetBkColor (lpdis->hDC, oldBk);
979 SetTextColor (lpdis->hDC, oldText);
982 SelectObject (lpdis->hDC, hOldBrush);
983 SelectObject (lpdis->hDC, hOldPen);
990 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
992 MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*)lParam;
995 lpmis->itemHeight = infoPtr->nBitmapHeight + 8;
997 lpmis->itemHeight = 15 + 8; /* default height */
1009 /***********************************************************************
1010 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1014 TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1016 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1017 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
1018 INT nIndex = 0, nButtons, nCount;
1021 TRACE("hwnd=%x wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
1025 if (lpAddBmp->hInst == HINST_COMMCTRL)
1027 if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR)
1029 else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR)
1031 else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR)
1036 TRACE ("adding %d internal bitmaps!\n", nButtons);
1038 /* Windows resize all the buttons to the size of a newly added standard image */
1039 if (lpAddBmp->nID & 1)
1042 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1043 MAKELPARAM((WORD)26, (WORD)26));
1044 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1045 MAKELPARAM((WORD)33, (WORD)33));
1050 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1051 MAKELPARAM((WORD)16, (WORD)16));
1052 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1053 MAKELPARAM((WORD)22, (WORD)22));
1056 TOOLBAR_CalcToolbar (hwnd);
1060 nButtons = (INT)wParam;
1064 TRACE ("adding %d bitmaps!\n", nButtons);
1067 if (!(infoPtr->himlDef)) {
1068 /* create new default image list */
1069 TRACE ("creating default image list!\n");
1072 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
1073 ILC_COLOR | ILC_MASK, nButtons, 2);
1074 infoPtr->himlInt = infoPtr->himlDef;
1077 nCount = ImageList_GetImageCount(infoPtr->himlDef);
1079 /* Add bitmaps to the default image list */
1080 if (lpAddBmp->hInst == (HINSTANCE)0)
1083 ImageList_AddMasked (infoPtr->himlDef, (HBITMAP)lpAddBmp->nID,
1086 else if (lpAddBmp->hInst == HINST_COMMCTRL)
1088 /* Add system bitmaps */
1089 switch (lpAddBmp->nID)
1091 case IDB_STD_SMALL_COLOR:
1092 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1093 MAKEINTRESOURCEA(IDB_STD_SMALL));
1094 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1095 hbmLoad, CLR_DEFAULT);
1096 DeleteObject (hbmLoad);
1099 case IDB_STD_LARGE_COLOR:
1100 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1101 MAKEINTRESOURCEA(IDB_STD_LARGE));
1102 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1103 hbmLoad, CLR_DEFAULT);
1104 DeleteObject (hbmLoad);
1107 case IDB_VIEW_SMALL_COLOR:
1108 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1109 MAKEINTRESOURCEA(IDB_VIEW_SMALL));
1110 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1111 hbmLoad, CLR_DEFAULT);
1112 DeleteObject (hbmLoad);
1115 case IDB_VIEW_LARGE_COLOR:
1116 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1117 MAKEINTRESOURCEA(IDB_VIEW_LARGE));
1118 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1119 hbmLoad, CLR_DEFAULT);
1120 DeleteObject (hbmLoad);
1123 case IDB_HIST_SMALL_COLOR:
1124 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1125 MAKEINTRESOURCEA(IDB_HIST_SMALL));
1126 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1127 hbmLoad, CLR_DEFAULT);
1128 DeleteObject (hbmLoad);
1131 case IDB_HIST_LARGE_COLOR:
1132 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1133 MAKEINTRESOURCEA(IDB_HIST_LARGE));
1134 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1135 hbmLoad, CLR_DEFAULT);
1136 DeleteObject (hbmLoad);
1140 nIndex = ImageList_GetImageCount (infoPtr->himlDef);
1141 ERR ("invalid imagelist!\n");
1147 hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
1148 nIndex = ImageList_AddMasked (infoPtr->himlDef, hbmLoad, CLR_DEFAULT);
1149 DeleteObject (hbmLoad);
1154 INT imagecount = ImageList_GetImageCount(infoPtr->himlDef);
1156 if (infoPtr->nNumBitmaps + nButtons != imagecount)
1158 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",
1159 infoPtr->nNumBitmaps, nCount, imagecount - nCount,
1160 infoPtr->nNumBitmaps+nButtons,imagecount);
1162 infoPtr->nNumBitmaps = imagecount;
1165 infoPtr->nNumBitmaps += nButtons;
1173 TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1175 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1176 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1177 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1179 TRACE("adding %d buttons!\n", wParam);
1181 nAddButtons = (UINT)wParam;
1182 nOldButtons = infoPtr->nNumButtons;
1183 nNewButtons = nOldButtons + nAddButtons;
1185 if (infoPtr->nNumButtons == 0) {
1187 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1190 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1192 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1193 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1194 nOldButtons * sizeof(TBUTTON_INFO));
1195 COMCTL32_Free (oldButtons);
1198 infoPtr->nNumButtons = nNewButtons;
1200 /* insert new button data */
1201 for (nCount = 0; nCount < nAddButtons; nCount++) {
1202 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1203 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1204 btnPtr->idCommand = lpTbb[nCount].idCommand;
1205 btnPtr->fsState = lpTbb[nCount].fsState;
1206 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1207 btnPtr->dwData = lpTbb[nCount].dwData;
1208 btnPtr->iString = lpTbb[nCount].iString;
1209 btnPtr->bHot = FALSE;
1211 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1214 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1215 ti.cbSize = sizeof (TTTOOLINFOA);
1217 ti.uId = btnPtr->idCommand;
1219 ti.lpszText = LPSTR_TEXTCALLBACKA;
1221 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
1226 TOOLBAR_CalcToolbar (hwnd);
1228 InvalidateRect(hwnd, NULL, FALSE);
1235 TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1237 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1238 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1239 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1241 TRACE("adding %d buttons!\n", wParam);
1243 nAddButtons = (UINT)wParam;
1244 nOldButtons = infoPtr->nNumButtons;
1245 nNewButtons = nOldButtons + nAddButtons;
1247 if (infoPtr->nNumButtons == 0) {
1249 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1252 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1254 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1255 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1256 nOldButtons * sizeof(TBUTTON_INFO));
1257 COMCTL32_Free (oldButtons);
1260 infoPtr->nNumButtons = nNewButtons;
1262 /* insert new button data */
1263 for (nCount = 0; nCount < nAddButtons; nCount++) {
1264 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1265 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1266 btnPtr->idCommand = lpTbb[nCount].idCommand;
1267 btnPtr->fsState = lpTbb[nCount].fsState;
1268 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1269 btnPtr->dwData = lpTbb[nCount].dwData;
1270 btnPtr->iString = lpTbb[nCount].iString;
1271 btnPtr->bHot = FALSE;
1273 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1276 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
1277 ti.cbSize = sizeof (TTTOOLINFOW);
1279 ti.uId = btnPtr->idCommand;
1281 ti.lpszText = LPSTR_TEXTCALLBACKW;
1283 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
1288 TOOLBAR_CalcToolbar (hwnd);
1290 InvalidateRect(hwnd, NULL, FALSE);
1297 TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1299 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1302 if ((wParam) && (HIWORD(lParam) == 0)) {
1305 TRACE("adding string from resource!\n");
1307 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
1310 TRACE("len=%d \"%s\"\n", len, szString);
1311 nIndex = infoPtr->nNumStrings;
1312 if (infoPtr->nNumStrings == 0) {
1314 COMCTL32_Alloc (sizeof(LPWSTR));
1317 LPWSTR *oldStrings = infoPtr->strings;
1319 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1320 memcpy (&infoPtr->strings[0], &oldStrings[0],
1321 sizeof(LPWSTR) * infoPtr->nNumStrings);
1322 COMCTL32_Free (oldStrings);
1325 infoPtr->strings[infoPtr->nNumStrings] =
1326 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1327 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
1328 infoPtr->nNumStrings++;
1331 LPSTR p = (LPSTR)lParam;
1336 TRACE("adding string(s) from array!\n");
1338 nIndex = infoPtr->nNumStrings;
1341 TRACE("len=%d \"%s\"\n", len, p);
1343 if (infoPtr->nNumStrings == 0) {
1345 COMCTL32_Alloc (sizeof(LPWSTR));
1348 LPWSTR *oldStrings = infoPtr->strings;
1350 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1351 memcpy (&infoPtr->strings[0], &oldStrings[0],
1352 sizeof(LPWSTR) * infoPtr->nNumStrings);
1353 COMCTL32_Free (oldStrings);
1356 infoPtr->strings[infoPtr->nNumStrings] =
1357 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1358 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
1359 infoPtr->nNumStrings++;
1370 TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1372 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1375 if ((wParam) && (HIWORD(lParam) == 0)) {
1376 WCHAR szString[256];
1378 TRACE("adding string from resource!\n");
1380 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
1383 TRACE("len=%d \"%s\"\n", len, debugstr_w(szString));
1384 TRACE("First char: 0x%x\n", *szString);
1385 if (szString[0] == L'|')
1387 PWSTR p = szString + 1;
1389 nIndex = infoPtr->nNumStrings;
1390 while (*p != L'|') {
1392 if (infoPtr->nNumStrings == 0) {
1394 COMCTL32_Alloc (sizeof(LPWSTR));
1397 LPWSTR *oldStrings = infoPtr->strings;
1399 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1400 memcpy (&infoPtr->strings[0], &oldStrings[0],
1401 sizeof(LPWSTR) * infoPtr->nNumStrings);
1402 COMCTL32_Free (oldStrings);
1405 len = COMCTL32_StrChrW (p, L'|') - p;
1406 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1407 infoPtr->strings[infoPtr->nNumStrings] =
1408 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1409 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1410 infoPtr->nNumStrings++;
1417 nIndex = infoPtr->nNumStrings;
1418 if (infoPtr->nNumStrings == 0) {
1420 COMCTL32_Alloc (sizeof(LPWSTR));
1423 LPWSTR *oldStrings = infoPtr->strings;
1425 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1426 memcpy (&infoPtr->strings[0], &oldStrings[0],
1427 sizeof(LPWSTR) * infoPtr->nNumStrings);
1428 COMCTL32_Free (oldStrings);
1431 infoPtr->strings[infoPtr->nNumStrings] =
1432 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1433 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
1434 infoPtr->nNumStrings++;
1438 LPWSTR p = (LPWSTR)lParam;
1443 TRACE("adding string(s) from array!\n");
1444 nIndex = infoPtr->nNumStrings;
1448 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1449 if (infoPtr->nNumStrings == 0) {
1451 COMCTL32_Alloc (sizeof(LPWSTR));
1454 LPWSTR *oldStrings = infoPtr->strings;
1456 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1457 memcpy (&infoPtr->strings[0], &oldStrings[0],
1458 sizeof(LPWSTR) * infoPtr->nNumStrings);
1459 COMCTL32_Free (oldStrings);
1462 infoPtr->strings[infoPtr->nNumStrings] =
1463 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1464 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1465 infoPtr->nNumStrings++;
1476 TOOLBAR_AutoSize (HWND hwnd)
1478 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1479 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1485 UINT uPosFlags = SWP_NOZORDER;
1487 TRACE("resize forced, style=%lx!\n", dwStyle);
1489 parent = GetParent (hwnd);
1490 GetClientRect(parent, &parent_rect);
1492 x = parent_rect.left;
1493 y = parent_rect.top;
1495 if (dwStyle & CCS_NORESIZE) {
1496 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
1501 infoPtr->nWidth = parent_rect.right - parent_rect.left;
1502 TOOLBAR_CalcToolbar (hwnd);
1503 InvalidateRect( hwnd, NULL, TRUE );
1504 cy = infoPtr->nHeight;
1505 cx = infoPtr->nWidth;
1507 if (dwStyle & CCS_NOMOVEY) {
1508 GetWindowRect(hwnd, &window_rect);
1509 ScreenToClient(parent, (LPPOINT)&window_rect.left);
1510 y = window_rect.top;
1514 if (dwStyle & CCS_NOPARENTALIGN)
1515 uPosFlags |= SWP_NOMOVE;
1517 if (!(dwStyle & CCS_NODIVIDER))
1518 cy += GetSystemMetrics(SM_CYEDGE);
1520 if (dwStyle & WS_BORDER)
1523 cy += GetSystemMetrics(SM_CYEDGE);
1524 cx += GetSystemMetrics(SM_CYEDGE);
1527 infoPtr->bAutoSize = TRUE;
1528 SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
1530 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
1531 * the setwindowpos calls */
1532 infoPtr->bAutoSize = FALSE;
1539 TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
1541 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1543 return infoPtr->nNumButtons;
1548 TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1550 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1552 if (infoPtr == NULL) {
1553 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
1554 ERR("infoPtr == NULL!\n");
1558 infoPtr->dwStructSize = (DWORD)wParam;
1565 TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1567 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1568 TBUTTON_INFO *btnPtr;
1571 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1575 btnPtr = &infoPtr->buttons[nIndex];
1576 btnPtr->iBitmap = LOWORD(lParam);
1578 RedrawWindow(hwnd,&btnPtr->rect,0,RDW_ERASE|RDW_INVALIDATE);
1585 TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1587 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1588 TBUTTON_INFO *btnPtr;
1591 BOOL bChecked = FALSE;
1593 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1597 btnPtr = &infoPtr->buttons[nIndex];
1599 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
1602 bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
1604 if (LOWORD(lParam) == FALSE)
1605 btnPtr->fsState &= ~TBSTATE_CHECKED;
1607 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
1609 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
1610 if (nOldIndex == nIndex)
1612 if (nOldIndex != -1)
1613 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
1615 btnPtr->fsState |= TBSTATE_CHECKED;
1618 if( bChecked != LOWORD(lParam) )
1620 if (nOldIndex != -1)
1621 RedrawWindow(hwnd,&infoPtr->buttons[nOldIndex].rect,(HRGN)NULL,
1622 RDW_ERASE|RDW_INVALIDATE);
1623 RedrawWindow(hwnd,&btnPtr->rect,0,RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
1626 /* FIXME: Send a WM_NOTIFY?? */
1633 TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
1635 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1637 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1642 TOOLBAR_Customize (HWND hwnd)
1644 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1650 /* send TBN_BEGINADJUST notification */
1651 nmhdr.hwndFrom = hwnd;
1652 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1653 nmhdr.code = TBN_BEGINADJUST;
1655 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1656 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1658 if (!(hRes = FindResourceA (COMCTL32_hModule,
1659 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
1663 if(!(template = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
1666 ret = DialogBoxIndirectParamA (GetWindowLongA (hwnd, GWL_HINSTANCE),
1667 (LPDLGTEMPLATEA)template,
1669 (DLGPROC)TOOLBAR_CustomizeDialogProc,
1672 /* send TBN_ENDADJUST notification */
1673 nmhdr.code = TBN_ENDADJUST;
1675 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1676 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1683 TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1685 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1686 INT nIndex = (INT)wParam;
1688 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1691 if ((infoPtr->hwndToolTip) &&
1692 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
1695 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1696 ti.cbSize = sizeof (TTTOOLINFOA);
1698 ti.uId = infoPtr->buttons[nIndex].idCommand;
1700 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
1703 if (infoPtr->nNumButtons == 1) {
1704 TRACE(" simple delete!\n");
1705 COMCTL32_Free (infoPtr->buttons);
1706 infoPtr->buttons = NULL;
1707 infoPtr->nNumButtons = 0;
1710 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1711 TRACE("complex delete! [nIndex=%d]\n", nIndex);
1713 infoPtr->nNumButtons--;
1714 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
1716 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1717 nIndex * sizeof(TBUTTON_INFO));
1720 if (nIndex < infoPtr->nNumButtons) {
1721 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
1722 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
1725 COMCTL32_Free (oldButtons);
1728 TOOLBAR_CalcToolbar (hwnd);
1730 InvalidateRect (hwnd, NULL, TRUE);
1737 TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1739 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1740 TBUTTON_INFO *btnPtr;
1744 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1748 btnPtr = &infoPtr->buttons[nIndex];
1750 bState = btnPtr->fsState & TBSTATE_ENABLED;
1752 /* update the toolbar button state */
1753 if(LOWORD(lParam) == FALSE) {
1754 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
1756 btnPtr->fsState |= TBSTATE_ENABLED;
1759 /* redraw the button only if the state of the button changed */
1760 if(bState != (btnPtr->fsState & TBSTATE_ENABLED)) {
1761 RedrawWindow(hwnd,&btnPtr->rect,0,RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
1768 static inline LRESULT
1769 TOOLBAR_GetAnchorHighlight (HWND hwnd)
1771 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1773 return infoPtr->bAnchor;
1778 TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1780 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1783 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1787 return infoPtr->buttons[nIndex].iBitmap;
1791 static inline LRESULT
1792 TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
1794 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
1799 TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1801 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1802 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1803 INT nIndex = (INT)wParam;
1804 TBUTTON_INFO *btnPtr;
1806 if (infoPtr == NULL)
1812 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1815 btnPtr = &infoPtr->buttons[nIndex];
1816 lpTbb->iBitmap = btnPtr->iBitmap;
1817 lpTbb->idCommand = btnPtr->idCommand;
1818 lpTbb->fsState = btnPtr->fsState;
1819 lpTbb->fsStyle = btnPtr->fsStyle;
1820 lpTbb->dwData = btnPtr->dwData;
1821 lpTbb->iString = btnPtr->iString;
1828 TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1830 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1831 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
1832 TBUTTON_INFO *btnPtr;
1835 if (infoPtr == NULL)
1837 if (lpTbInfo == NULL)
1839 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOA))
1842 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1846 btnPtr = &infoPtr->buttons[nIndex];
1848 if (lpTbInfo->dwMask & TBIF_COMMAND)
1849 lpTbInfo->idCommand = btnPtr->idCommand;
1850 if (lpTbInfo->dwMask & TBIF_IMAGE)
1851 lpTbInfo->iImage = btnPtr->iBitmap;
1852 if (lpTbInfo->dwMask & TBIF_LPARAM)
1853 lpTbInfo->lParam = btnPtr->dwData;
1854 if (lpTbInfo->dwMask & TBIF_SIZE)
1855 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1856 if (lpTbInfo->dwMask & TBIF_STATE)
1857 lpTbInfo->fsState = btnPtr->fsState;
1858 if (lpTbInfo->dwMask & TBIF_STYLE)
1859 lpTbInfo->fsStyle = btnPtr->fsStyle;
1860 if (lpTbInfo->dwMask & TBIF_TEXT) {
1861 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
1863 lstrcpynWtoA (lpTbInfo->pszText,
1864 (LPWSTR)infoPtr->strings[btnPtr->iString],
1867 else lpTbInfo->pszText[0]=0;
1874 TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1876 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1877 LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
1878 TBUTTON_INFO *btnPtr;
1881 if (infoPtr == NULL)
1883 if (lpTbInfo == NULL)
1885 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
1888 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1892 btnPtr = &infoPtr->buttons[nIndex];
1894 if (lpTbInfo->dwMask & TBIF_COMMAND)
1895 lpTbInfo->idCommand = btnPtr->idCommand;
1896 if (lpTbInfo->dwMask & TBIF_IMAGE)
1897 lpTbInfo->iImage = btnPtr->iBitmap;
1898 if (lpTbInfo->dwMask & TBIF_LPARAM)
1899 lpTbInfo->lParam = btnPtr->dwData;
1900 if (lpTbInfo->dwMask & TBIF_SIZE)
1901 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1902 if (lpTbInfo->dwMask & TBIF_STATE)
1903 lpTbInfo->fsState = btnPtr->fsState;
1904 if (lpTbInfo->dwMask & TBIF_STYLE)
1905 lpTbInfo->fsStyle = btnPtr->fsStyle;
1906 if (lpTbInfo->dwMask & TBIF_TEXT) {
1907 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
1908 lstrcpynW (lpTbInfo->pszText,
1909 (LPWSTR)infoPtr->strings[btnPtr->iString],
1918 TOOLBAR_GetButtonSize (HWND hwnd)
1920 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1922 return MAKELONG((WORD)infoPtr->nButtonWidth,
1923 (WORD)infoPtr->nButtonHeight);
1928 TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1930 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1931 INT nIndex, nStringIndex;
1933 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1937 nStringIndex = infoPtr->buttons[nIndex].iString;
1939 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
1941 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
1947 lstrcpyWtoA ((LPSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
1949 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
1954 TOOLBAR_GetButtonTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1956 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1957 INT nIndex, nStringIndex;
1959 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1963 nStringIndex = infoPtr->buttons[nIndex].iString;
1965 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
1967 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
1973 lstrcpyW ((LPWSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
1975 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
1979 /* << TOOLBAR_GetColorScheme >> */
1983 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1985 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1987 return (LRESULT)infoPtr->himlDis;
1991 inline static LRESULT
1992 TOOLBAR_GetExtendedStyle (HWND hwnd)
1994 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1996 return infoPtr->dwExStyle;
2001 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2003 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2005 return (LRESULT)infoPtr->himlHot;
2010 TOOLBAR_GetHotItem (HWND hwnd)
2012 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2014 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2017 if (infoPtr->nHotItem < 0)
2020 return (LRESULT)infoPtr->nHotItem;
2025 TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2027 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2029 return (LRESULT)infoPtr->himlDef;
2033 /* << TOOLBAR_GetInsertMark >> */
2034 /* << TOOLBAR_GetInsertMarkColor >> */
2038 TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2040 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2041 TBUTTON_INFO *btnPtr;
2045 if (infoPtr == NULL)
2047 nIndex = (INT)wParam;
2048 btnPtr = &infoPtr->buttons[nIndex];
2049 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2051 lpRect = (LPRECT)lParam;
2054 if (btnPtr->fsState & TBSTATE_HIDDEN)
2057 TOOLBAR_CalcToolbar( hwnd );
2059 lpRect->left = btnPtr->rect.left;
2060 lpRect->right = btnPtr->rect.right;
2061 lpRect->bottom = btnPtr->rect.bottom;
2062 lpRect->top = btnPtr->rect.top;
2069 TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2071 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2072 LPSIZE lpSize = (LPSIZE)lParam;
2077 lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
2078 lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
2080 TRACE("maximum size %d x %d\n",
2081 infoPtr->rcBound.right - infoPtr->rcBound.left,
2082 infoPtr->rcBound.bottom - infoPtr->rcBound.top);
2088 /* << TOOLBAR_GetObject >> */
2089 /* << TOOLBAR_GetPadding >> */
2093 TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2095 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2096 TBUTTON_INFO *btnPtr;
2100 if (infoPtr == NULL)
2102 nIndex = (INT)wParam;
2103 btnPtr = &infoPtr->buttons[nIndex];
2104 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2106 lpRect = (LPRECT)lParam;
2110 lpRect->left = btnPtr->rect.left;
2111 lpRect->right = btnPtr->rect.right;
2112 lpRect->bottom = btnPtr->rect.bottom;
2113 lpRect->top = btnPtr->rect.top;
2120 TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2122 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2124 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
2125 return infoPtr->nRows;
2132 TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2134 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2137 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2141 return infoPtr->buttons[nIndex].fsState;
2146 TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2148 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2151 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2155 return infoPtr->buttons[nIndex].fsStyle;
2160 TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2162 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2164 if (infoPtr == NULL)
2167 return infoPtr->nMaxTextRows;
2172 TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
2174 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2176 if (infoPtr == NULL)
2178 return infoPtr->hwndToolTip;
2183 TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2185 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2187 TRACE("%s hwnd=0x%x stub!\n",
2188 infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
2190 return infoPtr->bUnicode;
2194 inline static LRESULT
2195 TOOLBAR_GetVersion (HWND hwnd)
2197 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2198 return infoPtr->iVersion;
2203 TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2205 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2206 TBUTTON_INFO *btnPtr;
2209 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2213 btnPtr = &infoPtr->buttons[nIndex];
2214 if (LOWORD(lParam) == FALSE)
2215 btnPtr->fsState &= ~TBSTATE_HIDDEN;
2217 btnPtr->fsState |= TBSTATE_HIDDEN;
2219 TOOLBAR_CalcToolbar (hwnd);
2221 InvalidateRect (hwnd, NULL, TRUE);
2227 inline static LRESULT
2228 TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2230 return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
2235 TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2237 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2238 TBUTTON_INFO *btnPtr;
2241 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2245 btnPtr = &infoPtr->buttons[nIndex];
2246 if (LOWORD(lParam) == FALSE)
2247 btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
2249 btnPtr->fsState |= TBSTATE_INDETERMINATE;
2251 RedrawWindow(hwnd,&btnPtr->rect,0,
2252 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
2259 TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2261 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2262 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2263 INT nIndex = (INT)wParam;
2264 TBUTTON_INFO *oldButtons;
2270 /* EPP: this seems to be an undocumented call (from my IE4)
2271 * I assume in that case that:
2272 * - lpTbb->iString is a string pointer (not a string index in strings[] table
2273 * - index of insertion is at the end of existing buttons
2274 * I only see this happen with nIndex == -1, but it could have a special
2275 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
2280 if(lpTbb->iString) {
2281 len = lstrlenA((char*)lpTbb->iString) + 2;
2282 ptr = COMCTL32_Alloc(len);
2283 nIndex = infoPtr->nNumButtons;
2284 strcpy(ptr, (char*)lpTbb->iString);
2285 ptr[len - 1] = 0; /* ended by two '\0' */
2286 lpTbb->iString = TOOLBAR_AddStringA(hwnd, 0, (LPARAM)ptr);
2290 ERR("lpTbb->iString is NULL\n");
2294 } else if (nIndex < 0)
2297 TRACE("inserting button index=%d\n", nIndex);
2298 if (nIndex > infoPtr->nNumButtons) {
2299 nIndex = infoPtr->nNumButtons;
2300 TRACE("adjust index=%d\n", nIndex);
2303 oldButtons = infoPtr->buttons;
2304 infoPtr->nNumButtons++;
2305 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2306 /* pre insert copy */
2308 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2309 nIndex * sizeof(TBUTTON_INFO));
2312 /* insert new button */
2313 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2314 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2315 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2316 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2317 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2318 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2320 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2323 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2324 ti.cbSize = sizeof (TTTOOLINFOA);
2326 ti.uId = lpTbb->idCommand;
2328 ti.lpszText = LPSTR_TEXTCALLBACKA;
2330 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
2334 /* post insert copy */
2335 if (nIndex < infoPtr->nNumButtons - 1) {
2336 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2337 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2340 COMCTL32_Free (oldButtons);
2342 TOOLBAR_CalcToolbar (hwnd);
2344 InvalidateRect (hwnd, NULL, FALSE);
2351 TOOLBAR_InsertButtonW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2353 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2354 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2355 INT nIndex = (INT)wParam;
2356 TBUTTON_INFO *oldButtons;
2363 TRACE("inserting button index=%d\n", nIndex);
2364 if (nIndex > infoPtr->nNumButtons) {
2365 nIndex = infoPtr->nNumButtons;
2366 TRACE("adjust index=%d\n", nIndex);
2369 oldButtons = infoPtr->buttons;
2370 infoPtr->nNumButtons++;
2371 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2372 /* pre insert copy */
2374 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2375 nIndex * sizeof(TBUTTON_INFO));
2378 /* insert new button */
2379 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2380 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2381 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2382 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2383 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2384 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2386 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2389 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
2390 ti.cbSize = sizeof (TTTOOLINFOW);
2392 ti.uId = lpTbb->idCommand;
2394 ti.lpszText = LPSTR_TEXTCALLBACKW;
2396 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
2400 /* post insert copy */
2401 if (nIndex < infoPtr->nNumButtons - 1) {
2402 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2403 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2406 COMCTL32_Free (oldButtons);
2408 TOOLBAR_CalcToolbar (hwnd);
2410 InvalidateRect (hwnd, NULL, FALSE);
2416 /* << TOOLBAR_InsertMarkHitTest >> */
2420 TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
2422 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2425 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2429 return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
2434 TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
2436 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2439 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2443 return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
2448 TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
2450 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2453 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2457 return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
2462 TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
2464 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2467 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2471 return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
2476 TOOLBAR_IsButtonIndeterminate (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_INDETERMINATE);
2490 TOOLBAR_IsButtonPressed (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_PRESSED);
2503 /* << TOOLBAR_LoadImages >> */
2504 /* << TOOLBAR_MapAccelerator >> */
2505 /* << TOOLBAR_MarkButton >> */
2506 /* << TOOLBAR_MoveButton >> */
2510 TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2512 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2513 TBUTTON_INFO *btnPtr;
2516 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2520 btnPtr = &infoPtr->buttons[nIndex];
2521 if (LOWORD(lParam) == FALSE)
2522 btnPtr->fsState &= ~TBSTATE_PRESSED;
2524 btnPtr->fsState |= TBSTATE_PRESSED;
2526 RedrawWindow(hwnd,&btnPtr->rect,0,
2527 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
2533 /* << TOOLBAR_ReplaceBitmap >> */
2537 TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2540 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2541 LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
2543 if (lpSave == NULL) return 0;
2546 /* save toolbar information */
2547 FIXME("save to \"%s\" \"%s\"\n",
2548 lpSave->pszSubKey, lpSave->pszValueName);
2553 /* restore toolbar information */
2555 FIXME("restore from \"%s\" \"%s\"\n",
2556 lpSave->pszSubKey, lpSave->pszValueName);
2567 TOOLBAR_SaveRestoreW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2570 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2571 LPTBSAVEPARAMSW lpSave = (LPTBSAVEPARAMSW)lParam;
2577 /* save toolbar information */
2578 FIXME("save to \"%s\" \"%s\"\n",
2579 lpSave->pszSubKey, lpSave->pszValueName);
2584 /* restore toolbar information */
2586 FIXME("restore from \"%s\" \"%s\"\n",
2587 lpSave->pszSubKey, lpSave->pszValueName);
2598 TOOLBAR_SetAnchorHighlight (HWND hwnd, WPARAM wParam)
2600 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2601 BOOL bOldAnchor = infoPtr->bAnchor;
2603 infoPtr->bAnchor = (BOOL)wParam;
2605 return (LRESULT)bOldAnchor;
2610 TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2612 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2614 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
2617 if (infoPtr->nNumButtons > 0)
2618 WARN("%d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n",
2619 infoPtr->nNumButtons,
2620 infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
2621 LOWORD(lParam), HIWORD(lParam));
2623 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
2624 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
2626 /* uses image list internals directly */
2627 if (infoPtr->himlDef) {
2628 infoPtr->himlDef->cx = infoPtr->nBitmapWidth;
2629 infoPtr->himlDef->cy = infoPtr->nBitmapHeight;
2637 TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2639 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2640 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
2641 TBUTTON_INFO *btnPtr;
2646 if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
2649 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2653 btnPtr = &infoPtr->buttons[nIndex];
2654 if (lptbbi->dwMask & TBIF_COMMAND)
2655 btnPtr->idCommand = lptbbi->idCommand;
2656 if (lptbbi->dwMask & TBIF_IMAGE)
2657 btnPtr->iBitmap = lptbbi->iImage;
2658 if (lptbbi->dwMask & TBIF_LPARAM)
2659 btnPtr->dwData = lptbbi->lParam;
2660 /* if (lptbbi->dwMask & TBIF_SIZE) */
2661 /* btnPtr->cx = lptbbi->cx; */
2662 if (lptbbi->dwMask & TBIF_STATE)
2663 btnPtr->fsState = lptbbi->fsState;
2664 if (lptbbi->dwMask & TBIF_STYLE)
2665 btnPtr->fsStyle = lptbbi->fsStyle;
2667 if (lptbbi->dwMask & TBIF_TEXT) {
2668 if ((btnPtr->iString >= 0) ||
2669 (btnPtr->iString < infoPtr->nNumStrings)) {
2670 TRACE("Ooooooch\n");
2672 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2673 INT len = lstrlenA (lptbbi->pszText);
2674 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
2677 /* this is the ultimate sollution */
2678 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2687 TOOLBAR_SetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2689 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2690 LPTBBUTTONINFOW lptbbi = (LPTBBUTTONINFOW)lParam;
2691 TBUTTON_INFO *btnPtr;
2696 if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
2699 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2703 btnPtr = &infoPtr->buttons[nIndex];
2704 if (lptbbi->dwMask & TBIF_COMMAND)
2705 btnPtr->idCommand = lptbbi->idCommand;
2706 if (lptbbi->dwMask & TBIF_IMAGE)
2707 btnPtr->iBitmap = lptbbi->iImage;
2708 if (lptbbi->dwMask & TBIF_LPARAM)
2709 btnPtr->dwData = lptbbi->lParam;
2710 /* if (lptbbi->dwMask & TBIF_SIZE) */
2711 /* btnPtr->cx = lptbbi->cx; */
2712 if (lptbbi->dwMask & TBIF_STATE)
2713 btnPtr->fsState = lptbbi->fsState;
2714 if (lptbbi->dwMask & TBIF_STYLE)
2715 btnPtr->fsStyle = lptbbi->fsStyle;
2717 if (lptbbi->dwMask & TBIF_TEXT) {
2718 if ((btnPtr->iString >= 0) ||
2719 (btnPtr->iString < infoPtr->nNumStrings)) {
2721 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2722 INT len = lstrlenW (lptbbi->pszText);
2723 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
2726 /* this is the ultimate sollution */
2727 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2736 TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2738 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2740 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
2742 ERR("invalid parameter\n");
2746 /* Button size can only be set before adding any button to the toolbar
2747 according to the documentation. */
2748 /* this appears to be wrong. WINZIP32.EXE (ver 8) calls this on
2749 one of its buttons after adding it to the toolbar, and it
2750 checks that the return value is nonzero - mjm */
2751 if( infoPtr->nNumButtons != 0 )
2753 FIXME("Button size set after button in toolbar\n");
2757 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
2758 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
2764 TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
2766 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2768 if (infoPtr == NULL)
2771 infoPtr->cxMin = (INT)LOWORD(lParam);
2772 infoPtr->cxMax = (INT)HIWORD(lParam);
2779 TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
2781 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2782 INT nIndex = (INT)wParam;
2784 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2787 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
2789 if (infoPtr->hwndToolTip) {
2791 FIXME("change tool tip!\n");
2799 /* << TOOLBAR_SetColorScheme >> */
2803 TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2805 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2806 HIMAGELIST himlTemp;
2809 himlTemp = infoPtr->himlDis;
2810 infoPtr->himlDis = (HIMAGELIST)lParam;
2812 /* FIXME: redraw ? */
2814 return (LRESULT)himlTemp;
2819 TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
2821 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2824 dwTemp = infoPtr->dwDTFlags;
2825 infoPtr->dwDTFlags =
2826 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
2828 return (LRESULT)dwTemp;
2833 TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2835 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2838 dwTemp = infoPtr->dwExStyle;
2839 infoPtr->dwExStyle = (DWORD)lParam;
2841 return (LRESULT)dwTemp;
2846 TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2848 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2849 HIMAGELIST himlTemp;
2851 himlTemp = infoPtr->himlHot;
2852 infoPtr->himlHot = (HIMAGELIST)lParam;
2854 /* FIXME: redraw ? */
2856 return (LRESULT)himlTemp;
2861 TOOLBAR_SetHotItem (HWND hwnd, WPARAM wParam)
2863 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2864 INT nOldHotItem = infoPtr->nHotItem;
2866 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
2868 infoPtr->nHotItem = (INT)wParam;
2870 /* FIXME: What else must be done ??? */
2874 if (nOldHotItem < 0)
2877 return (LRESULT)nOldHotItem;
2882 TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2884 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2885 HIMAGELIST himlTemp;
2887 himlTemp = infoPtr->himlDef;
2888 infoPtr->himlDef = (HIMAGELIST)lParam;
2890 infoPtr->nNumBitmaps = ImageList_GetImageCount(infoPtr->himlDef);
2891 /* FIXME: redraw ? */
2893 return (LRESULT)himlTemp;
2898 TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2900 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2902 infoPtr->nIndent = (INT)wParam;
2904 TOOLBAR_CalcToolbar (hwnd);
2906 InvalidateRect(hwnd, NULL, FALSE);
2912 /* << TOOLBAR_SetInsertMark >> */
2916 TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2918 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2920 infoPtr->clrInsertMark = (COLORREF)lParam;
2922 /* FIXME : redraw ??*/
2929 TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2931 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2933 if (infoPtr == NULL)
2936 infoPtr->nMaxTextRows = (INT)wParam;
2942 /* << TOOLBAR_SetPadding >> */
2946 TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2948 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2951 if (infoPtr == NULL)
2953 hwndOldNotify = infoPtr->hwndNotify;
2954 infoPtr->hwndNotify = (HWND)wParam;
2956 return hwndOldNotify;
2961 TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2963 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2964 LPRECT lprc = (LPRECT)lParam;
2966 if (LOWORD(wParam) > 1) {
2968 FIXME("multiple rows not supported!\n");
2972 /* recalculate toolbar */
2973 TOOLBAR_CalcToolbar (hwnd);
2975 /* return bounding rectangle */
2977 lprc->left = infoPtr->rcBound.left;
2978 lprc->right = infoPtr->rcBound.right;
2979 lprc->top = infoPtr->rcBound.top;
2980 lprc->bottom = infoPtr->rcBound.bottom;
2983 /* repaint toolbar */
2984 InvalidateRect(hwnd, NULL, FALSE);
2991 TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2993 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2994 TBUTTON_INFO *btnPtr;
2997 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3001 btnPtr = &infoPtr->buttons[nIndex];
3002 btnPtr->fsState = LOWORD(lParam);
3004 RedrawWindow(hwnd,&btnPtr->rect,0,
3005 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3012 TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3014 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3015 TBUTTON_INFO *btnPtr;
3018 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3022 btnPtr = &infoPtr->buttons[nIndex];
3023 btnPtr->fsStyle = LOWORD(lParam);
3025 RedrawWindow(hwnd,&btnPtr->rect,0,
3026 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3028 if (infoPtr->hwndToolTip) {
3030 FIXME("change tool tip!\n");
3038 inline static LRESULT
3039 TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
3041 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3043 if (infoPtr == NULL)
3045 infoPtr->hwndToolTip = (HWND)wParam;
3051 TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
3053 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3056 TRACE("%s hwnd=0x%04x stub!\n",
3057 ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
3059 bTemp = infoPtr->bUnicode;
3060 infoPtr->bUnicode = (BOOL)wParam;
3067 TOOLBAR_SetVersion (HWND hwnd, INT iVersion)
3069 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3070 INT iOldVersion = infoPtr->iVersion;
3072 infoPtr->iVersion = iVersion;
3079 TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
3081 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3082 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3085 /* initialize info structure */
3086 infoPtr->nButtonHeight = 22;
3087 infoPtr->nButtonWidth = 24;
3088 infoPtr->nBitmapHeight = 15;
3089 infoPtr->nBitmapWidth = 16;
3091 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
3093 infoPtr->nMaxTextRows = 1;
3094 infoPtr->cxMin = -1;
3095 infoPtr->cxMax = -1;
3096 infoPtr->nNumBitmaps = 0;
3097 infoPtr->nNumStrings = 0;
3099 infoPtr->bCaptured = FALSE;
3100 infoPtr->bUnicode = IsWindowUnicode (hwnd);
3101 infoPtr->nButtonDown = -1;
3102 infoPtr->nOldHit = -1;
3103 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3104 infoPtr->hwndNotify = GetParent (hwnd);
3105 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
3106 infoPtr->dwDTFlags = (dwStyle & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE : DT_CENTER;
3107 infoPtr->bAnchor = FALSE; /* no anchor highlighting */
3108 infoPtr->iVersion = 0;
3110 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
3111 infoPtr->hFont = CreateFontIndirectA (&logFont);
3113 if (dwStyle & TBSTYLE_TOOLTIPS) {
3114 /* Create tooltip control */
3115 infoPtr->hwndToolTip =
3116 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
3117 CW_USEDEFAULT, CW_USEDEFAULT,
3118 CW_USEDEFAULT, CW_USEDEFAULT,
3121 /* Send NM_TOOLTIPSCREATED notification */
3122 if (infoPtr->hwndToolTip) {
3123 NMTOOLTIPSCREATED nmttc;
3125 nmttc.hdr.hwndFrom = hwnd;
3126 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3127 nmttc.hdr.code = NM_TOOLTIPSCREATED;
3128 nmttc.hwndToolTips = infoPtr->hwndToolTip;
3130 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3131 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
3140 TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
3142 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3144 /* delete tooltip control */
3145 if (infoPtr->hwndToolTip)
3146 DestroyWindow (infoPtr->hwndToolTip);
3148 /* delete button data */
3149 if (infoPtr->buttons)
3150 COMCTL32_Free (infoPtr->buttons);
3152 /* delete strings */
3153 if (infoPtr->strings) {
3155 for (i = 0; i < infoPtr->nNumStrings; i++)
3156 if (infoPtr->strings[i])
3157 COMCTL32_Free (infoPtr->strings[i]);
3159 COMCTL32_Free (infoPtr->strings);
3162 /* destroy internal image list */
3163 if (infoPtr->himlInt)
3164 ImageList_Destroy (infoPtr->himlInt);
3166 /* delete default font */
3168 DeleteObject (infoPtr->hFont);
3170 /* free toolbar info data */
3171 COMCTL32_Free (infoPtr);
3172 SetWindowLongA (hwnd, 0, 0);
3179 TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
3181 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3183 if (infoPtr->bTransparent)
3184 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
3186 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
3191 TOOLBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
3193 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3195 return infoPtr->hFont;
3200 TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
3202 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3203 TBUTTON_INFO *btnPtr;
3207 pt.x = (INT)LOWORD(lParam);
3208 pt.y = (INT)HIWORD(lParam);
3209 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3212 btnPtr = &infoPtr->buttons[nHit];
3213 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3216 infoPtr->bCaptured = TRUE;
3217 infoPtr->nButtonDown = nHit;
3219 btnPtr->fsState |= TBSTATE_PRESSED;
3221 RedrawWindow(hwnd,&btnPtr->rect,0,
3222 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3224 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
3225 TOOLBAR_Customize (hwnd);
3232 TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
3234 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3235 TBUTTON_INFO *btnPtr;
3239 if (infoPtr->hwndToolTip)
3240 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3241 WM_LBUTTONDOWN, wParam, lParam);
3243 pt.x = (INT)LOWORD(lParam);
3244 pt.y = (INT)HIWORD(lParam);
3245 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3248 btnPtr = &infoPtr->buttons[nHit];
3249 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3252 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN)
3256 nmtb.hdr.hwndFrom = hwnd;
3257 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3258 nmtb.hdr.code = TBN_DROPDOWN;
3259 nmtb.iItem = btnPtr->idCommand;
3261 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3262 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3266 infoPtr->bCaptured = TRUE;
3267 infoPtr->nButtonDown = nHit;
3268 infoPtr->nOldHit = nHit;
3270 btnPtr->fsState |= TBSTATE_PRESSED;
3271 btnPtr->bHot = FALSE;
3273 RedrawWindow(hwnd,&btnPtr->rect,0,
3274 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3281 TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
3283 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3284 TBUTTON_INFO *btnPtr;
3288 BOOL bSendMessage = TRUE;
3290 if (infoPtr->hwndToolTip)
3291 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3292 WM_LBUTTONUP, wParam, lParam);
3294 pt.x = (INT)LOWORD(lParam);
3295 pt.y = (INT)HIWORD(lParam);
3296 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3298 /* restore hot effect to hot button disabled by TOOLBAR_LButtonDown() */
3299 if(infoPtr->nHotItem >= 0)
3300 infoPtr->buttons[infoPtr->nHotItem].bHot = TRUE;
3302 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
3303 infoPtr->bCaptured = FALSE;
3305 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3306 btnPtr->fsState &= ~TBSTATE_PRESSED;
3308 if (nHit == infoPtr->nButtonDown) {
3309 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
3310 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
3311 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
3312 infoPtr->nButtonDown);
3313 if (nOldIndex == infoPtr->nButtonDown)
3314 bSendMessage = FALSE;
3315 if ((nOldIndex != infoPtr->nButtonDown) &&
3317 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
3318 btnPtr->fsState |= TBSTATE_CHECKED;
3321 if (btnPtr->fsState & TBSTATE_CHECKED)
3322 btnPtr->fsState &= ~TBSTATE_CHECKED;
3324 btnPtr->fsState |= TBSTATE_CHECKED;
3329 bSendMessage = FALSE;
3331 if (nOldIndex != -1)
3332 RedrawWindow(hwnd,&infoPtr->buttons[nOldIndex].rect,0,
3333 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3334 RedrawWindow(hwnd,&btnPtr->rect,0,
3335 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3338 SendMessageA (GetParent(hwnd), WM_COMMAND,
3339 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
3341 // if ((GetWindowLongA(hwnd, GWL_STYLE) & TBSTYLE_DROPDOWN) ||
3342 // (btnPtr->fsStyle & 0x08/* BTNS_DROPDOWN */)) {
3344 * This appears to be an error. Instead of checking the style of the
3345 * button in question wine was checking the style of the toolbar
3346 * itself. This caused a number of strange behaviors. In my
3347 * invistigation i think the whole dropdown thing is still fairly
3348 * broken. but this helps fix some of the problems.
3351 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN) {
3354 nmtb.hdr.hwndFrom = hwnd;
3355 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3356 nmtb.hdr.code = TBN_DROPDOWN;
3358 /* nmtb.tbButton not used with TBN_DROPDOWN */
3359 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings)) {
3360 nmtb.pszText = infoPtr->strings[btnPtr->iString];
3361 nmtb.cchText = lstrlenW(nmtb.pszText);
3363 nmtb.pszText = NULL;
3366 nmtb.rcButton = btnPtr->rect;
3368 SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
3369 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3372 infoPtr->nButtonDown = -1;
3373 infoPtr->nOldHit = -1;
3380 TOOLBAR_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam)
3382 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3383 TBUTTON_INFO *hotBtnPtr;
3385 if (infoPtr->nOldHit < 0)
3388 hotBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3390 /* Redraw the button if the last button we were over is the hot button and it
3392 if((infoPtr->nOldHit == infoPtr->nHotItem) && (hotBtnPtr->fsState & TBSTATE_ENABLED))
3394 hotBtnPtr->bHot = FALSE;
3396 InvalidateRect (hwnd, &hotBtnPtr->rect, TRUE);
3399 infoPtr->nOldHit = -1; /* reset the old hit index as we've left the toolbar */
3400 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3406 TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
3408 TBUTTON_INFO *btnPtr, *oldBtnPtr;
3409 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3412 TRACKMOUSEEVENT trackinfo;
3414 /* fill in the TRACKMOUSEEVENT struct */
3415 trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
3416 trackinfo.dwFlags = TME_QUERY;
3417 trackinfo.hwndTrack = hwnd;
3418 trackinfo.dwHoverTime = HOVER_DEFAULT;
3420 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
3421 _TrackMouseEvent(&trackinfo);
3423 /* Make sure tracking is enabled so we recieve a WM_MOUSELEAVE message */
3424 if(!(trackinfo.dwFlags & TME_LEAVE)) {
3425 trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
3427 /* call TRACKMOUSEEVENT so we recieve a WM_MOUSELEAVE message */
3428 /* and can properly deactivate the hot toolbar button */
3429 _TrackMouseEvent(&trackinfo);
3432 if (infoPtr->hwndToolTip)
3433 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3434 WM_MOUSEMOVE, wParam, lParam);
3436 pt.x = (INT)LOWORD(lParam);
3437 pt.y = (INT)HIWORD(lParam);
3439 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3441 if (infoPtr->nOldHit != nHit)
3443 /* Remove the effect of an old hot button if the button was enabled and was
3444 drawn with the hot button effect */
3445 if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem &&
3446 (infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED))
3448 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3449 oldBtnPtr->bHot = FALSE;
3451 InvalidateRect (hwnd, &oldBtnPtr->rect, TRUE);
3454 /* It's not a separator or in nowhere. It's a hot button. */
3457 btnPtr = &infoPtr->buttons[nHit];
3458 btnPtr->bHot = TRUE;
3460 infoPtr->nHotItem = nHit;
3462 /* only enabled buttons show hot effect */
3463 if(infoPtr->buttons[nHit].fsState & TBSTATE_ENABLED)
3465 RedrawWindow(hwnd,&btnPtr->rect,0,
3466 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3470 if (infoPtr->bCaptured) {
3471 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3472 if (infoPtr->nOldHit == infoPtr->nButtonDown) {
3473 btnPtr->fsState &= ~TBSTATE_PRESSED;
3474 RedrawWindow(hwnd,&btnPtr->rect,0,
3475 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3477 else if (nHit == infoPtr->nButtonDown) {
3478 btnPtr->fsState |= TBSTATE_PRESSED;
3479 RedrawWindow(hwnd,&btnPtr->rect,0,
3480 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
3483 infoPtr->nOldHit = nHit;
3489 inline static LRESULT
3490 TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3492 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
3493 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
3495 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
3499 inline static LRESULT
3500 TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3502 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
3503 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
3505 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
3510 TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3512 TOOLBAR_INFO *infoPtr;
3514 /* allocate memory for info structure */
3515 infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
3516 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
3519 infoPtr->dwStructSize = sizeof(TBBUTTON);
3521 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
3522 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
3523 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
3524 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
3527 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
3532 TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3534 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3538 if (dwStyle & WS_MINIMIZE)
3539 return 0; /* Nothing to do */
3541 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
3543 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
3546 if (!(dwStyle & CCS_NODIVIDER))
3548 GetWindowRect (hwnd, &rcWindow);
3549 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3550 if( dwStyle & WS_BORDER )
3551 OffsetRect (&rcWindow, 1, 1);
3552 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
3555 ReleaseDC( hwnd, hdc );
3561 inline static LRESULT
3562 TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
3564 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3565 LPNMHDR lpnmh = (LPNMHDR)lParam;
3567 TRACE("passing WM_NOTIFY!\n");
3569 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
3570 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
3573 if (lpnmh->code == TTN_GETDISPINFOA) {
3574 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
3576 FIXME("retrieving ASCII string\n");
3579 else if (lpnmh->code == TTN_GETDISPINFOW) {
3580 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
3582 FIXME("retrieving UNICODE string\n");
3593 TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
3595 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3599 /* fill ps.rcPaint with a default rect */
3600 memcpy(&(ps.rcPaint), &(infoPtr->rcBound), sizeof(infoPtr->rcBound));
3602 TOOLBAR_CalcToolbar( hwnd );
3603 hdc = wParam==0 ? BeginPaint(hwnd, &ps) : (HDC)wParam;
3604 TOOLBAR_Refresh (hwnd, hdc, &ps);
3605 if (!wParam) EndPaint (hwnd, &ps);
3612 TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
3614 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3615 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3624 /* Resize deadlock check */
3625 if (infoPtr->bAutoSize) {
3626 infoPtr->bAutoSize = FALSE;
3630 flags = (INT) wParam;
3632 /* FIXME for flags =
3633 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
3636 TRACE("sizing toolbar!\n");
3638 if (flags == SIZE_RESTORED) {
3639 /* width and height don't apply */
3640 parent = GetParent (hwnd);
3641 GetClientRect(parent, &parent_rect);
3642 x = parent_rect.left;
3643 y = parent_rect.top;
3645 if (dwStyle & CCS_NORESIZE) {
3646 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
3649 * this sets the working width of the toolbar, and
3650 * Calc Toolbar will not adjust it, only the height
3652 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3653 cy = infoPtr->nHeight;
3654 cx = infoPtr->nWidth;
3655 TOOLBAR_CalcToolbar (hwnd);
3656 infoPtr->nWidth = cx;
3657 infoPtr->nHeight = cy;
3660 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3661 TOOLBAR_CalcToolbar (hwnd);
3662 cy = infoPtr->nHeight;
3663 cx = infoPtr->nWidth;
3665 if (dwStyle & CCS_NOMOVEY) {
3666 GetWindowRect(hwnd, &window_rect);
3667 ScreenToClient(parent, (LPPOINT)&window_rect.left);
3668 y = window_rect.top;
3672 if (dwStyle & CCS_NOPARENTALIGN) {
3673 uPosFlags |= SWP_NOMOVE;
3674 cy = infoPtr->nHeight;
3675 cx = infoPtr->nWidth;
3678 if (!(dwStyle & CCS_NODIVIDER))
3679 cy += GetSystemMetrics(SM_CYEDGE);
3681 if (dwStyle & WS_BORDER)
3684 cy += GetSystemMetrics(SM_CYEDGE);
3685 cx += GetSystemMetrics(SM_CYEDGE);
3688 SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
3689 cx, cy, uPosFlags | SWP_NOZORDER);
3696 TOOLBAR_StyleChanged (HWND hwnd, INT nType, LPSTYLESTRUCT lpStyle)
3698 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3700 if (nType == GWL_STYLE) {
3701 if (lpStyle->styleNew & TBSTYLE_LIST) {
3702 infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
3705 infoPtr->dwDTFlags = DT_CENTER;
3709 TOOLBAR_AutoSize (hwnd);
3711 InvalidateRect(hwnd, NULL, FALSE);
3718 static LRESULT WINAPI
3719 ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3725 return TOOLBAR_Destroy (hwnd, wParam, lParam);
3728 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
3731 if (!TOOLBAR_GetInfoPtr (hwnd))
3733 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3739 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
3741 case TB_ADDBUTTONSA:
3742 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
3744 case TB_ADDBUTTONSW:
3745 return TOOLBAR_AddButtonsW (hwnd, wParam, lParam);
3748 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
3751 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
3754 return TOOLBAR_AutoSize (hwnd);
3756 case TB_BUTTONCOUNT:
3757 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
3759 case TB_BUTTONSTRUCTSIZE:
3760 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
3762 case TB_CHANGEBITMAP:
3763 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
3765 case TB_CHECKBUTTON:
3766 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
3768 case TB_COMMANDTOINDEX:
3769 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
3772 return TOOLBAR_Customize (hwnd);
3774 case TB_DELETEBUTTON:
3775 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
3777 case TB_ENABLEBUTTON:
3778 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
3780 case TB_GETANCHORHIGHLIGHT:
3781 return TOOLBAR_GetAnchorHighlight (hwnd);
3784 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
3786 case TB_GETBITMAPFLAGS:
3787 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
3790 return TOOLBAR_GetButton (hwnd, wParam, lParam);
3792 case TB_GETBUTTONINFOA:
3793 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
3795 case TB_GETBUTTONINFOW:
3796 return TOOLBAR_GetButtonInfoW (hwnd, wParam, lParam);
3798 case TB_GETBUTTONSIZE:
3799 return TOOLBAR_GetButtonSize (hwnd);
3801 case TB_GETBUTTONTEXTA:
3802 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
3804 case TB_GETBUTTONTEXTW:
3805 return TOOLBAR_GetButtonTextW (hwnd, wParam, lParam);
3807 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
3809 case TB_GETDISABLEDIMAGELIST:
3810 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
3812 case TB_GETEXTENDEDSTYLE:
3813 return TOOLBAR_GetExtendedStyle (hwnd);
3815 case TB_GETHOTIMAGELIST:
3816 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
3819 return TOOLBAR_GetHotItem (hwnd);
3821 case TB_GETIMAGELIST:
3822 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
3824 /* case TB_GETINSERTMARK: */ /* 4.71 */
3825 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
3827 case TB_GETITEMRECT:
3828 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
3831 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
3833 /* case TB_GETOBJECT: */ /* 4.71 */
3834 /* case TB_GETPADDING: */ /* 4.71 */
3837 return TOOLBAR_GetRect (hwnd, wParam, lParam);
3840 return TOOLBAR_GetRows (hwnd, wParam, lParam);
3843 return TOOLBAR_GetState (hwnd, wParam, lParam);
3846 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
3848 case TB_GETTEXTROWS:
3849 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
3851 case TB_GETTOOLTIPS:
3852 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
3854 case TB_GETUNICODEFORMAT:
3855 return TOOLBAR_GetUnicodeFormat (hwnd, wParam, lParam);
3857 case CCM_GETVERSION:
3858 return TOOLBAR_GetVersion (hwnd);
3861 return TOOLBAR_HideButton (hwnd, wParam, lParam);
3864 return TOOLBAR_HitTest (hwnd, wParam, lParam);
3866 case TB_INDETERMINATE:
3867 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
3869 case TB_INSERTBUTTONA:
3870 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
3872 case TB_INSERTBUTTONW:
3873 return TOOLBAR_InsertButtonW (hwnd, wParam, lParam);
3875 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
3877 case TB_ISBUTTONCHECKED:
3878 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
3880 case TB_ISBUTTONENABLED:
3881 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
3883 case TB_ISBUTTONHIDDEN:
3884 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
3886 case TB_ISBUTTONHIGHLIGHTED:
3887 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
3889 case TB_ISBUTTONINDETERMINATE:
3890 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
3892 case TB_ISBUTTONPRESSED:
3893 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
3895 case TB_LOADIMAGES: /* 4.70 */
3896 FIXME("missing standard imagelists\n");
3899 /* case TB_MAPACCELERATORA: */ /* 4.71 */
3900 /* case TB_MAPACCELERATORW: */ /* 4.71 */
3901 /* case TB_MARKBUTTON: */ /* 4.71 */
3902 /* case TB_MOVEBUTTON: */ /* 4.71 */
3904 case TB_PRESSBUTTON:
3905 return TOOLBAR_PressButton (hwnd, wParam, lParam);
3907 /* case TB_REPLACEBITMAP: */
3909 case TB_SAVERESTOREA:
3910 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
3912 case TB_SAVERESTOREW:
3913 return TOOLBAR_SaveRestoreW (hwnd, wParam, lParam);
3915 case TB_SETANCHORHIGHLIGHT:
3916 return TOOLBAR_SetAnchorHighlight (hwnd, wParam);
3918 case TB_SETBITMAPSIZE:
3919 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
3921 case TB_SETBUTTONINFOA:
3922 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
3924 case TB_SETBUTTONINFOW:
3925 return TOOLBAR_SetButtonInfoW (hwnd, wParam, lParam);
3927 case TB_SETBUTTONSIZE:
3928 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
3930 case TB_SETBUTTONWIDTH:
3931 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
3934 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
3936 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
3938 case TB_SETDISABLEDIMAGELIST:
3939 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
3941 case TB_SETDRAWTEXTFLAGS:
3942 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
3944 case TB_SETEXTENDEDSTYLE:
3945 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
3947 case TB_SETHOTIMAGELIST:
3948 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
3951 return TOOLBAR_SetHotItem (hwnd, wParam);
3953 case TB_SETIMAGELIST:
3954 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
3957 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
3959 /* case TB_SETINSERTMARK: */ /* 4.71 */
3961 case TB_SETINSERTMARKCOLOR:
3962 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
3964 case TB_SETMAXTEXTROWS:
3965 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
3967 /* case TB_SETPADDING: */ /* 4.71 */
3970 return TOOLBAR_SetParent (hwnd, wParam, lParam);
3973 return TOOLBAR_SetRows (hwnd, wParam, lParam);
3976 return TOOLBAR_SetState (hwnd, wParam, lParam);
3979 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
3981 case TB_SETTOOLTIPS:
3982 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
3984 case TB_SETUNICODEFORMAT:
3985 return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
3987 case CCM_SETVERSION:
3988 return TOOLBAR_SetVersion (hwnd, (INT)wParam);
3994 return TOOLBAR_Create (hwnd, wParam, lParam);
3997 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
4000 return TOOLBAR_GetFont (hwnd, wParam, lParam);
4002 /* case WM_KEYDOWN: */
4003 /* case WM_KILLFOCUS: */
4005 case WM_LBUTTONDBLCLK:
4006 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
4008 case WM_LBUTTONDOWN:
4009 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
4012 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
4015 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
4018 return TOOLBAR_MouseLeave (hwnd, wParam, lParam);
4021 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
4024 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
4027 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
4030 return TOOLBAR_Notify (hwnd, wParam, lParam);
4032 /* case WM_NOTIFYFORMAT: */
4035 return TOOLBAR_Paint (hwnd, wParam);
4038 return TOOLBAR_Size (hwnd, wParam, lParam);
4040 case WM_STYLECHANGED:
4041 return TOOLBAR_StyleChanged (hwnd, (INT)wParam, (LPSTYLESTRUCT)lParam);
4043 /* case WM_SYSCOLORCHANGE: */
4045 /* case WM_WININICHANGE: */
4050 case WM_MEASUREITEM:
4052 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
4055 if (uMsg >= WM_USER)
4056 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
4057 uMsg, wParam, lParam);
4058 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
4065 TOOLBAR_Register (void)
4069 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
4070 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
4071 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
4072 wndClass.cbClsExtra = 0;
4073 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
4074 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
4075 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
4076 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
4078 RegisterClassA (&wndClass);
4083 TOOLBAR_Unregister (void)
4085 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);