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.
18 * - iString of -1 is undocumented
21 * - Run tests using Waite Group Windows95 API Bible Volume 2.
22 * The second cdrom contains executables addstr.exe, btncount.exe,
23 * btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
24 * enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
25 * indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
26 * setparnt.exe, setrows.exe, toolwnd.exe.
27 * - Microsofts controlspy examples.
36 #include "wine/unicode.h"
37 #include "wine/winestring.h"
39 #include "imagelist.h"
42 #include "debugtools.h"
44 DEFAULT_DEBUG_CHANNEL(toolbar);
62 DWORD dwStructSize; /* size of TBBUTTON struct */
63 INT nHeight; /* height of the toolbar */
64 INT nWidth; /* width of the toolbar */
70 INT nRows; /* number of button rows */
71 INT nMaxTextRows; /* maximum number of text rows */
72 INT cxMin; /* minimum button width */
73 INT cxMax; /* maximum button width */
74 INT nNumButtons; /* number of buttons */
75 INT nNumBitmaps; /* number of bitmaps */
76 INT nNumStrings; /* number of strings */
77 BOOL bUnicode; /* ASCII (FALSE) or Unicode (TRUE)? */
78 BOOL bCaptured; /* mouse captured? */
81 INT nHotItem; /* index of the "hot" item */
82 HFONT hFont; /* text font */
83 HIMAGELIST himlInt; /* image list created internally */
84 HIMAGELIST himlDef; /* default image list */
85 HIMAGELIST himlHot; /* hot image list */
86 HIMAGELIST himlDis; /* disabled image list */
87 HWND hwndToolTip; /* handle to tool tip control */
88 HWND hwndNotify; /* handle to the window that gets notifications */
89 BOOL bTransparent; /* background transparency flag */
90 BOOL bAutoSize; /* auto size deadlock indicator */
91 BOOL bAnchor; /* anchor highlight enabled */
92 DWORD dwExStyle; /* extended toolbar style */
93 DWORD dwDTFlags; /* DrawText flags */
95 COLORREF clrInsertMark; /* insert mark color */
96 RECT rcBound; /* bounding rectangle */
99 TBUTTON_INFO *buttons; /* pointer to button array */
100 LPWSTR *strings; /* pointer to string array */
103 #define SEPARATOR_WIDTH 8
105 #define BOTTOM_BORDER 2
107 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
108 #define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE)
111 TOOLBAR_GetText(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr)
113 LPWSTR lpText = NULL;
115 /* FIXME: iString == -1 is undocumented */
116 if ((HIWORD(btnPtr->iString) != 0) && (btnPtr->iString != -1))
117 lpText = (LPWSTR)btnPtr->iString;
118 else if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
119 lpText = infoPtr->strings[btnPtr->iString];
125 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index)
127 if ((index>=0) && (index < infoPtr->nNumBitmaps))
135 TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
137 INT x = (lpRect->left + lpRect->right) / 2 - 1;
138 INT yBottom = lpRect->bottom - 3;
139 INT yTop = lpRect->top + 1;
141 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
142 MoveToEx (hdc, x, yBottom, NULL);
143 LineTo (hdc, x, yTop);
145 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
146 MoveToEx (hdc, x, yBottom, NULL);
147 LineTo (hdc, x, yTop);
151 * Draw the text string for this button.
152 * note: infoPtr->himlDis *SHOULD* be non-zero when infoPtr->himlDef
153 * is non-zero, so we can simply check himlDef to see if we have
157 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
158 HDC hdc, INT nState, DWORD dwStyle)
160 RECT rcText = btnPtr->rect;
164 LPWSTR lpText = NULL;
165 HIMAGELIST himl = infoPtr->himlDef;
167 TRACE ("iString: %x\n", btnPtr->iString);
169 /* get a pointer to the text */
170 lpText = TOOLBAR_GetText(infoPtr, btnPtr);
172 TRACE ("lpText: \"%s\"\n", debugstr_w(lpText));
177 InflateRect (&rcText, -3, -3);
179 if (himl && TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
180 if ((dwStyle & TBSTYLE_LIST) &&
181 ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
182 (btnPtr->iBitmap != I_IMAGENONE)) {
183 rcText.left += infoPtr->nBitmapWidth;
186 rcText.top += infoPtr->nBitmapHeight;
190 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
191 OffsetRect (&rcText, 1, 1);
193 hOldFont = SelectObject (hdc, infoPtr->hFont);
194 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
195 if (!(nState & TBSTATE_ENABLED)) {
196 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
197 OffsetRect (&rcText, 1, 1);
198 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
199 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
200 OffsetRect (&rcText, -1, -1);
201 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
203 else if (nState & TBSTATE_INDETERMINATE) {
204 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
205 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
208 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
209 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
212 SetTextColor (hdc, clrOld);
213 SelectObject (hdc, hOldFont);
214 if (nOldBkMode != TRANSPARENT)
215 SetBkMode (hdc, nOldBkMode);
221 TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
223 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
224 INT cx = lpRect->right - lpRect->left;
225 INT cy = lpRect->bottom - lpRect->top;
226 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
227 SelectObject (hdc, hbr);
232 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
233 HDC hdc, INT x, INT y)
235 /* FIXME: this function is a hack since it uses image list
236 internals directly */
238 HIMAGELIST himl = infoPtr->himlDef;
246 /* create new dc's */
247 hdcImageList = CreateCompatibleDC (0);
248 hdcMask = CreateCompatibleDC (0);
250 /* create new bitmap */
251 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
252 SelectObject (hdcMask, hbmMask);
254 /* copy the mask bitmap */
255 SelectObject (hdcImageList, himl->hbmMask);
256 SetBkColor (hdcImageList, RGB(255, 255, 255));
257 SetTextColor (hdcImageList, RGB(0, 0, 0));
258 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
259 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
262 /* add white mask from image */
263 SelectObject (hdcImageList, himl->hbmImage);
264 SetBkColor (hdcImageList, RGB(0, 0, 0));
265 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
266 hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
269 /* draw the new mask */
270 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
271 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
272 hdcMask, 0, 0, 0xB8074A);
274 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
275 BitBlt (hdc, x, y, himl->cx, himl->cy,
276 hdcMask, 0, 0, 0xB8074A);
278 DeleteObject (hbmMask);
280 DeleteDC (hdcImageList);
285 TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
287 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
288 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
290 INT xOffset = (infoPtr->nButtonWidth / 2) - (infoPtr->nBitmapWidth / 2);
292 if (btnPtr->fsState & TBSTATE_HIDDEN)
297 TRACE("iBitmap: %d\n", btnPtr->iBitmap);
300 if (btnPtr->fsStyle & TBSTYLE_SEP) {
301 /* with the FLAT style, iBitmap is the width and has already */
302 /* been taken into consideration in calculating the width */
303 /* so now we need to draw the vertical separator */
304 /* empirical tests show that iBitmap can/will be non-zero */
305 /* when drawing the vertical bar... */
306 if ((dwStyle & TBSTYLE_FLAT) /* && (btnPtr->iBitmap == 0) */)
307 TOOLBAR_DrawFlatSeparator (&rc, hdc);
312 if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
313 if (!(dwStyle & TBSTYLE_FLAT))
314 DrawEdge (hdc, &rc, EDGE_RAISED,
315 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
317 if (infoPtr->himlDis &&
318 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
319 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
320 rc.left + xOffset + 1, rc.top + 1, ILD_NORMAL);
322 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left + xOffset + 1, rc.top + 1);
324 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
328 /* pressed TBSTYLE_BUTTON */
329 if (btnPtr->fsState & TBSTATE_PRESSED) {
330 if (dwStyle & TBSTYLE_FLAT)
331 DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
333 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
334 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
335 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
336 rc.left + xOffset + 2, rc.top + 2, ILD_NORMAL);
338 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
342 /* checked TBSTYLE_CHECK */
343 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
344 (btnPtr->fsState & TBSTATE_CHECKED)) {
345 if (dwStyle & TBSTYLE_FLAT)
346 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
347 BF_RECT | BF_MIDDLE | BF_ADJUST);
349 DrawEdge (hdc, &rc, EDGE_SUNKEN,
350 BF_RECT | BF_MIDDLE | BF_ADJUST);
352 TOOLBAR_DrawPattern (hdc, &rc);
354 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
355 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
356 rc.left + xOffset, rc.top + 2, ILD_NORMAL);
358 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
363 if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
364 DrawEdge (hdc, &rc, EDGE_RAISED,
365 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
367 TOOLBAR_DrawPattern (hdc, &rc);
368 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left + xOffset + 1, rc.top + 1);
369 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
374 if (dwStyle & TBSTYLE_FLAT)
377 DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
379 FrameRect(hdc, &rc, GetSysColorBrush(COLOR_BTNFACE));
381 if (btnPtr->bHot && infoPtr->himlHot &&
382 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
383 ImageList_Draw (infoPtr->himlHot, btnPtr->iBitmap, hdc,
384 rc.left + xOffset + 2, rc.top + 2, ILD_NORMAL);
385 else if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
386 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
387 rc.left + xOffset + 2, rc.top + 2, ILD_NORMAL);
391 DrawEdge (hdc, &rc, EDGE_RAISED,
392 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
394 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
395 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
396 rc.left + xOffset + 1, rc.top + 1, ILD_NORMAL);
399 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
404 TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
406 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
407 TBUTTON_INFO *btnPtr;
411 /* redraw necessary buttons */
412 btnPtr = infoPtr->buttons;
413 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
415 if(IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect)))
416 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
421 TOOLBAR_MeasureString(HWND hwnd, INT index, LPSIZE lpSize)
423 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
424 TBUTTON_INFO *btnPtr;
431 hOldFont = SelectObject (hdc, infoPtr->hFont);
433 btnPtr = &infoPtr->buttons[index];
435 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
436 (btnPtr->iString > -1) &&
437 (btnPtr->iString < infoPtr->nNumStrings))
439 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
440 GetTextExtentPoint32W (hdc, lpText, lstrlenW (lpText), lpSize);
443 SelectObject (hdc, hOldFont);
446 TRACE("string size %ld x %ld!\n", lpSize->cx, lpSize->cy);
450 TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
452 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
453 TBUTTON_INFO *btnPtr;
461 btnPtr = infoPtr->buttons;
462 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
463 if(TOOLBAR_HasText(infoPtr, btnPtr))
465 TOOLBAR_MeasureString(hwnd,i,&sz);
466 if (sz.cx > lpSize->cx)
468 if (sz.cy > lpSize->cy)
473 TRACE("string size %ld x %ld!\n", lpSize->cx, lpSize->cy);
476 /***********************************************************************
477 * TOOLBAR_WrapToolbar
479 * This function walks through the buttons and seperators in the
480 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
481 * wrapping should occur based on the width of the toolbar window.
482 * It does *not* calculate button placement itself. That task
483 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
484 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
485 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
489 TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
491 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
492 TBUTTON_INFO *btnPtr;
495 BOOL bWrap, bButtonWrap;
497 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
498 /* no layout is necessary. Applications may use this style */
499 /* to perform their own layout on the toolbar. */
500 if( !(dwStyle & TBSTYLE_WRAPABLE) )
503 btnPtr = infoPtr->buttons;
504 x = infoPtr->nIndent;
506 /* this can get the parents width, to know how far we can extend
507 * this toolbar. We cannot use its height, as there may be multiple
508 * toolbars in a rebar control
510 GetClientRect( GetParent(hwnd), &rc );
511 infoPtr->nWidth = rc.right - rc.left;
514 for (i = 0; i < infoPtr->nNumButtons; i++ )
517 btnPtr[i].fsState &= ~TBSTATE_WRAP;
519 if (btnPtr[i].fsState & TBSTATE_HIDDEN)
522 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
523 /* it is the actual width of the separator. This is used for */
524 /* custom controls in toolbars. */
525 if (btnPtr[i].fsStyle & TBSTYLE_SEP)
526 cx = (btnPtr[i].iBitmap > 0) ?
527 btnPtr[i].iBitmap : SEPARATOR_WIDTH;
529 cx = infoPtr->nButtonWidth;
531 /* Two or more adjacent separators form a separator group. */
532 /* The first separator in a group should be wrapped to the */
533 /* next row if the previous wrapping is on a button. */
535 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
536 (i + 1 < infoPtr->nNumButtons ) &&
537 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
539 btnPtr[i].fsState |= TBSTATE_WRAP;
540 x = infoPtr->nIndent;
546 /* The layout makes sure the bitmap is visible, but not the button. */
547 if ( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
552 /* If the current button is a separator and not hidden, */
553 /* go to the next until it reaches a non separator. */
554 /* Wrap the last separator if it is before a button. */
555 while( ( (btnPtr[i].fsStyle & TBSTYLE_SEP) ||
556 (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
557 i < infoPtr->nNumButtons )
563 if( bFound && i < infoPtr->nNumButtons )
566 btnPtr[i].fsState |= TBSTATE_WRAP;
567 x = infoPtr->nIndent;
571 else if ( i >= infoPtr->nNumButtons)
574 /* If the current button is not a separator, find the last */
575 /* separator and wrap it. */
576 for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
578 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
579 !(btnPtr[j].fsState & TBSTATE_HIDDEN))
583 x = infoPtr->nIndent;
584 btnPtr[j].fsState |= TBSTATE_WRAP;
590 /* If no separator available for wrapping, wrap one of */
591 /* non-hidden previous button. */
595 j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
597 if (btnPtr[j].fsState & TBSTATE_HIDDEN)
602 x = infoPtr->nIndent;
603 btnPtr[j].fsState |= TBSTATE_WRAP;
609 /* If all above failed, wrap the current button. */
612 btnPtr[i].fsState |= TBSTATE_WRAP;
614 x = infoPtr->nIndent;
615 if (btnPtr[i].fsState & TBSTYLE_SEP )
627 /***********************************************************************
628 * TOOLBAR_CalcToolbar
630 * This function calculates button and separator placement. It first
631 * calculates the button sizes, gets the toolbar window width and then
632 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
633 * on. It assigns a new location to each item and sends this location to
634 * the tooltip window if appropriate. Finally, it updates the rcBound
635 * rect and calculates the new required toolbar window height.
639 TOOLBAR_CalcToolbar (HWND hwnd)
641 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
642 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
643 TBUTTON_INFO *btnPtr;
644 INT i, nRows, nSepRows;
648 BOOL usesBitmaps = FALSE;
650 TOOLBAR_CalcStrings (hwnd, &sizeString);
652 if (dwStyle & TBSTYLE_LIST)
654 infoPtr->nButtonHeight = max(infoPtr->nBitmapHeight, sizeString.cy) + 6;
655 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + sizeString.cx + 6;
658 for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
660 if (TOOLBAR_IsValidBitmapIndex(infoPtr,infoPtr->buttons[i].iBitmap))
664 if (sizeString.cy > 0)
667 infoPtr->nButtonHeight = sizeString.cy +
668 infoPtr->nBitmapHeight + 6;
670 infoPtr->nButtonHeight = sizeString.cy + 6;
672 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
673 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
675 if (sizeString.cx > infoPtr->nBitmapWidth)
676 infoPtr->nButtonWidth = sizeString.cx + 6;
677 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
678 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
681 if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin )
682 infoPtr->nButtonWidth = infoPtr->cxMin;
683 if ( infoPtr->cxMax >= 0 && infoPtr->nButtonWidth > infoPtr->cxMax )
684 infoPtr->nButtonWidth = infoPtr->cxMax;
686 TOOLBAR_WrapToolbar( hwnd, dwStyle );
688 x = infoPtr->nIndent;
689 y = (dwStyle & TBSTYLE_FLAT) ? 0 : TOP_BORDER;
692 * We will set the height below, and we set the width on entry
693 * so we do not reset them here..
696 GetClientRect( hwnd, &rc );
697 /* get initial values for toolbar */
698 infoPtr->nWidth = rc.right - rc.left;
699 infoPtr->nHeight = rc.bottom - rc.top;
702 /* from above, minimum is a button, and possible text */
703 cx = infoPtr->nButtonWidth;
705 /* cannot use just ButtonHeight, we may have no buttons! */
706 if (infoPtr->nNumButtons > 0)
707 infoPtr->nHeight = infoPtr->nButtonHeight;
709 cy = infoPtr->nHeight;
711 nRows = nSepRows = 0;
713 infoPtr->rcBound.top = y;
714 infoPtr->rcBound.left = x;
715 infoPtr->rcBound.bottom = y + cy;
716 infoPtr->rcBound.right = x;
718 btnPtr = infoPtr->buttons;
720 /* do not base height/width on parent, if the parent is a */
721 /* rebar control it could have multiple rows of toolbars */
722 /* GetClientRect( GetParent(hwnd), &rc ); */
723 /* cx = rc.right - rc.left; */
724 /* cy = rc.bottom - rc.top; */
726 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
729 if (btnPtr->fsState & TBSTATE_HIDDEN)
731 SetRectEmpty (&btnPtr->rect);
735 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
736 /* it is the actual width of the separator. This is used for */
737 /* custom controls in toolbars. */
738 if (btnPtr->fsStyle & TBSTYLE_SEP)
739 cx = (btnPtr->iBitmap > 0) ?
740 btnPtr->iBitmap : SEPARATOR_WIDTH;
743 if (btnPtr->fsStyle & TBSTYLE_AUTOSIZE)
746 TOOLBAR_MeasureString(hwnd,i,&sz);
750 cx = infoPtr->nButtonWidth;
752 cy = infoPtr->nHeight;
754 if (btnPtr->fsState & TBSTATE_WRAP )
757 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
759 if (infoPtr->rcBound.left > x)
760 infoPtr->rcBound.left = x;
761 if (infoPtr->rcBound.right < x + cx)
762 infoPtr->rcBound.right = x + cx;
763 if (infoPtr->rcBound.bottom < y + cy)
764 infoPtr->rcBound.bottom = y + cy;
766 /* Set the toolTip only for non-hidden, non-separator button */
767 if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP ))
771 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
772 ti.cbSize = sizeof(TTTOOLINFOA);
774 ti.uId = btnPtr->idCommand;
775 ti.rect = btnPtr->rect;
776 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
780 /* btnPtr->nRow is zero based. The space between the rows is */
781 /* also considered as a row. */
782 btnPtr->nRow = nRows + nSepRows;
785 if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
789 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
790 /* it is the actual width of the separator. This is used for */
791 /* custom controls in toolbars. */
792 y += cy + ( (btnPtr->iBitmap > 0 ) ?
793 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
795 /* nSepRows is used to calculate the extra height follwoing */
799 x = infoPtr->nIndent;
806 /* infoPtr->nRows is the number of rows on the toolbar */
807 infoPtr->nRows = nRows + nSepRows + 1;
809 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
811 infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
812 nSepRows * (SEPARATOR_WIDTH * 2 / 3) +
813 nSepRows * (infoPtr->nBitmapHeight + 1) +
815 TRACE("toolbar height %d, button width %d\n", infoPtr->nHeight, infoPtr->nButtonWidth);
820 TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
822 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
823 TBUTTON_INFO *btnPtr;
826 btnPtr = infoPtr->buttons;
827 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
828 if (btnPtr->fsState & TBSTATE_HIDDEN)
831 if (btnPtr->fsStyle & TBSTYLE_SEP) {
832 if (PtInRect (&btnPtr->rect, *lpPt)) {
833 TRACE(" ON SEPARATOR %d!\n", i);
838 if (PtInRect (&btnPtr->rect, *lpPt)) {
839 TRACE(" ON BUTTON %d!\n", i);
845 TRACE(" NOWHERE!\n");
851 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
853 TBUTTON_INFO *btnPtr;
856 btnPtr = infoPtr->buttons;
857 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
858 if (btnPtr->idCommand == idCommand) {
859 TRACE("command=%d index=%d\n", idCommand, i);
863 TRACE("no index found for command=%d\n", idCommand);
869 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
871 TBUTTON_INFO *btnPtr;
874 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
877 /* check index button */
878 btnPtr = &infoPtr->buttons[nIndex];
879 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
880 if (btnPtr->fsState & TBSTATE_CHECKED)
884 /* check previous buttons */
885 nRunIndex = nIndex - 1;
886 while (nRunIndex >= 0) {
887 btnPtr = &infoPtr->buttons[nRunIndex];
888 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
889 if (btnPtr->fsState & TBSTATE_CHECKED)
897 /* check next buttons */
898 nRunIndex = nIndex + 1;
899 while (nRunIndex < infoPtr->nNumButtons) {
900 btnPtr = &infoPtr->buttons[nRunIndex];
901 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
902 if (btnPtr->fsState & TBSTATE_CHECKED)
915 TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
916 WPARAM wParam, LPARAM lParam)
924 msg.time = GetMessageTime ();
925 msg.pt.x = LOWORD(GetMessagePos ());
926 msg.pt.y = HIWORD(GetMessagePos ());
928 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
932 /***********************************************************************
933 * TOOLBAR_CustomizeDialogProc
934 * This function implements the toolbar customization dialog.
937 TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
939 TOOLBAR_INFO *infoPtr = (TOOLBAR_INFO *)GetWindowLongA (hwnd, DWL_USER);
940 static HDSA hDsa = NULL;
945 infoPtr = (TOOLBAR_INFO *)lParam;
946 SetWindowLongA (hwnd, DWL_USER, (DWORD)infoPtr);
948 hDsa = DSA_Create (sizeof(TBUTTON_INFO), 5);
952 TBUTTON_INFO *btnPtr;
955 /* insert 'virtual' separator button into 'available buttons' list */
956 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
958 /* copy all buttons and append them to the right listbox */
959 btnPtr = infoPtr->buttons;
960 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
962 DSA_InsertItem (hDsa, i, btnPtr);
964 /* FIXME: hidden buttons appear in the 'toolbar buttons' list too */
965 if (btnPtr->fsState & TBSTATE_HIDDEN)
967 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
971 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
975 /* append 'virtual' separator button to the 'toolbar buttons' list */
981 EndDialog(hwnd, FALSE);
985 switch (LOWORD(wParam))
988 EndDialog(hwnd, FALSE);
999 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1001 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
1002 TBUTTON_INFO btnPtr;
1007 COLORREF oldText = 0;
1010 FIXME("action: %x itemState: %x\n",
1011 lpdis->itemAction, lpdis->itemState);
1013 DSA_GetItem (hDsa, 0 /*lpdis->itemID*/, &btnPtr);
1015 if (lpdis->itemState & ODS_FOCUS)
1017 oldBk = SetBkColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
1018 oldText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
1021 hOldPen = SelectObject (lpdis->hDC, GetSysColorPen ((lpdis->itemState & ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1022 hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1024 /* fill background rectangle */
1025 Rectangle (lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
1026 lpdis->rcItem.right, lpdis->rcItem.bottom);
1028 /* calculate button and text rectangles */
1029 CopyRect (&rcButton, &lpdis->rcItem);
1030 InflateRect (&rcButton, -1, -1);
1031 CopyRect (&rcText, &rcButton);
1032 rcButton.right = rcButton.left + infoPtr->nBitmapWidth + 6;
1033 rcText.left = rcButton.right + 2;
1035 /* draw focus rectangle */
1036 if (lpdis->itemState & ODS_FOCUS)
1037 DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
1040 DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
1042 /* draw image and text */
1043 if (wParam == IDC_AVAILBTN_LBOX && lpdis->itemID == 0)
1045 /* virtual separator in the 'available' list */
1046 DrawTextA (lpdis->hDC, "Separator", -1, &rcText,
1047 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1053 ImageList_Draw (infoPtr->himlDef, btnPtr.iBitmap, lpdis->hDC,
1054 rcButton.left+1, rcButton.top+1, ILD_NORMAL);
1056 DrawTextW (lpdis->hDC, infoPtr->strings[btnPtr.iString], -1, &rcText,
1057 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1061 if (lpdis->itemState & ODS_FOCUS)
1063 SetBkColor (lpdis->hDC, oldBk);
1064 SetTextColor (lpdis->hDC, oldText);
1067 SelectObject (lpdis->hDC, hOldBrush);
1068 SelectObject (lpdis->hDC, hOldPen);
1074 case WM_MEASUREITEM:
1075 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1077 MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*)lParam;
1080 lpmis->itemHeight = infoPtr->nBitmapHeight + 8;
1082 lpmis->itemHeight = 15 + 8; /* default height */
1094 /***********************************************************************
1095 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1099 TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1101 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1102 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
1103 INT nIndex = 0, nButtons, nCount;
1106 TRACE("hwnd=%x wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
1110 if (lpAddBmp->hInst == HINST_COMMCTRL)
1112 if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR)
1114 else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR)
1116 else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR)
1121 TRACE ("adding %d internal bitmaps!\n", nButtons);
1123 /* Windows resize all the buttons to the size of a newly added standard image */
1124 if (lpAddBmp->nID & 1)
1127 /* FIXME: on windows the size of the images is 25x24 but the size of the bitmap
1128 * in rsrc is only 24x24. Fix the bitmap (how?) and then fix this
1130 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1131 MAKELPARAM((WORD)24, (WORD)24));
1132 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1133 MAKELPARAM((WORD)31, (WORD)30));
1138 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1139 MAKELPARAM((WORD)16, (WORD)16));
1140 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1141 MAKELPARAM((WORD)22, (WORD)22));
1144 TOOLBAR_CalcToolbar (hwnd);
1148 nButtons = (INT)wParam;
1152 TRACE ("adding %d bitmaps!\n", nButtons);
1155 if (!(infoPtr->himlDef)) {
1156 /* create new default image list */
1157 TRACE ("creating default image list!\n");
1160 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
1161 ILC_COLOR | ILC_MASK, nButtons, 2);
1162 infoPtr->himlInt = infoPtr->himlDef;
1165 nCount = ImageList_GetImageCount(infoPtr->himlDef);
1167 /* Add bitmaps to the default image list */
1168 if (lpAddBmp->hInst == (HINSTANCE)0)
1171 ImageList_AddMasked (infoPtr->himlDef, (HBITMAP)lpAddBmp->nID,
1174 else if (lpAddBmp->hInst == HINST_COMMCTRL)
1176 /* Add system bitmaps */
1177 switch (lpAddBmp->nID)
1179 case IDB_STD_SMALL_COLOR:
1180 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1181 MAKEINTRESOURCEA(IDB_STD_SMALL));
1182 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1183 hbmLoad, CLR_DEFAULT);
1184 DeleteObject (hbmLoad);
1187 case IDB_STD_LARGE_COLOR:
1188 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1189 MAKEINTRESOURCEA(IDB_STD_LARGE));
1190 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1191 hbmLoad, CLR_DEFAULT);
1192 DeleteObject (hbmLoad);
1195 case IDB_VIEW_SMALL_COLOR:
1196 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1197 MAKEINTRESOURCEA(IDB_VIEW_SMALL));
1198 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1199 hbmLoad, CLR_DEFAULT);
1200 DeleteObject (hbmLoad);
1203 case IDB_VIEW_LARGE_COLOR:
1204 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1205 MAKEINTRESOURCEA(IDB_VIEW_LARGE));
1206 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1207 hbmLoad, CLR_DEFAULT);
1208 DeleteObject (hbmLoad);
1211 case IDB_HIST_SMALL_COLOR:
1212 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1213 MAKEINTRESOURCEA(IDB_HIST_SMALL));
1214 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1215 hbmLoad, CLR_DEFAULT);
1216 DeleteObject (hbmLoad);
1219 case IDB_HIST_LARGE_COLOR:
1220 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1221 MAKEINTRESOURCEA(IDB_HIST_LARGE));
1222 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1223 hbmLoad, CLR_DEFAULT);
1224 DeleteObject (hbmLoad);
1228 nIndex = ImageList_GetImageCount (infoPtr->himlDef);
1229 ERR ("invalid imagelist!\n");
1235 hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
1236 nIndex = ImageList_AddMasked (infoPtr->himlDef, hbmLoad, CLR_DEFAULT);
1237 DeleteObject (hbmLoad);
1242 INT imagecount = ImageList_GetImageCount(infoPtr->himlDef);
1244 if (infoPtr->nNumBitmaps + nButtons != imagecount)
1246 WARN("Desired images do not match received images : Previous image number %i Previous images in list %i added %i expecting total %i, Images in list %i\n",
1247 infoPtr->nNumBitmaps, nCount, imagecount - nCount,
1248 infoPtr->nNumBitmaps+nButtons,imagecount);
1250 infoPtr->nNumBitmaps = imagecount;
1253 infoPtr->nNumBitmaps += nButtons;
1261 TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1263 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1264 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1265 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1267 TRACE("adding %d buttons!\n", wParam);
1269 nAddButtons = (UINT)wParam;
1270 nOldButtons = infoPtr->nNumButtons;
1271 nNewButtons = nOldButtons + nAddButtons;
1273 if (infoPtr->nNumButtons == 0) {
1275 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1278 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1280 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1281 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1282 nOldButtons * sizeof(TBUTTON_INFO));
1283 COMCTL32_Free (oldButtons);
1286 infoPtr->nNumButtons = nNewButtons;
1288 /* insert new button data */
1289 for (nCount = 0; nCount < nAddButtons; nCount++) {
1290 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1291 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1292 btnPtr->idCommand = lpTbb[nCount].idCommand;
1293 btnPtr->fsState = lpTbb[nCount].fsState;
1294 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1295 btnPtr->dwData = lpTbb[nCount].dwData;
1296 btnPtr->iString = lpTbb[nCount].iString;
1297 btnPtr->bHot = FALSE;
1299 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1302 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1303 ti.cbSize = sizeof (TTTOOLINFOA);
1305 ti.uId = btnPtr->idCommand;
1307 ti.lpszText = LPSTR_TEXTCALLBACKA;
1309 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
1314 TOOLBAR_CalcToolbar (hwnd);
1316 InvalidateRect(hwnd, NULL, FALSE);
1323 TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1325 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1326 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1327 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1329 TRACE("adding %d buttons!\n", wParam);
1331 nAddButtons = (UINT)wParam;
1332 nOldButtons = infoPtr->nNumButtons;
1333 nNewButtons = nOldButtons + nAddButtons;
1335 if (infoPtr->nNumButtons == 0) {
1337 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1340 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1342 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1343 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1344 nOldButtons * sizeof(TBUTTON_INFO));
1345 COMCTL32_Free (oldButtons);
1348 infoPtr->nNumButtons = nNewButtons;
1350 /* insert new button data */
1351 for (nCount = 0; nCount < nAddButtons; nCount++) {
1352 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1353 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1354 btnPtr->idCommand = lpTbb[nCount].idCommand;
1355 btnPtr->fsState = lpTbb[nCount].fsState;
1356 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1357 btnPtr->dwData = lpTbb[nCount].dwData;
1358 btnPtr->iString = lpTbb[nCount].iString;
1359 btnPtr->bHot = FALSE;
1361 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1364 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
1365 ti.cbSize = sizeof (TTTOOLINFOW);
1367 ti.uId = btnPtr->idCommand;
1369 ti.lpszText = LPSTR_TEXTCALLBACKW;
1371 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
1376 TOOLBAR_CalcToolbar (hwnd);
1378 InvalidateRect(hwnd, NULL, FALSE);
1385 TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1387 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1390 if ((wParam) && (HIWORD(lParam) == 0)) {
1393 TRACE("adding string from resource!\n");
1395 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
1398 TRACE("len=%d \"%s\"\n", len, szString);
1399 nIndex = infoPtr->nNumStrings;
1400 if (infoPtr->nNumStrings == 0) {
1402 COMCTL32_Alloc (sizeof(LPWSTR));
1405 LPWSTR *oldStrings = infoPtr->strings;
1407 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1408 memcpy (&infoPtr->strings[0], &oldStrings[0],
1409 sizeof(LPWSTR) * infoPtr->nNumStrings);
1410 COMCTL32_Free (oldStrings);
1413 infoPtr->strings[infoPtr->nNumStrings] =
1414 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1415 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
1416 infoPtr->nNumStrings++;
1419 LPSTR p = (LPSTR)lParam;
1424 TRACE("adding string(s) from array!\n");
1426 nIndex = infoPtr->nNumStrings;
1429 TRACE("len=%d \"%s\"\n", len, p);
1431 if (infoPtr->nNumStrings == 0) {
1433 COMCTL32_Alloc (sizeof(LPWSTR));
1436 LPWSTR *oldStrings = infoPtr->strings;
1438 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1439 memcpy (&infoPtr->strings[0], &oldStrings[0],
1440 sizeof(LPWSTR) * infoPtr->nNumStrings);
1441 COMCTL32_Free (oldStrings);
1444 infoPtr->strings[infoPtr->nNumStrings] =
1445 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1446 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
1447 infoPtr->nNumStrings++;
1458 TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1460 #define MAX_RESOURCE_STRING_LENGTH 512
1461 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1464 if ((wParam) && (HIWORD(lParam) == 0)) {
1465 WCHAR szString[MAX_RESOURCE_STRING_LENGTH];
1467 TRACE("adding string from resource!\n");
1469 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
1470 szString, MAX_RESOURCE_STRING_LENGTH);
1472 TRACE("len=%d \"%s\"\n", len, debugstr_w(szString));
1473 TRACE("First char: 0x%x\n", *szString);
1474 if (szString[0] == L'|')
1476 PWSTR p = szString + 1;
1478 nIndex = infoPtr->nNumStrings;
1479 while (*p != L'|') {
1481 if (infoPtr->nNumStrings == 0) {
1483 COMCTL32_Alloc (sizeof(LPWSTR));
1486 LPWSTR *oldStrings = infoPtr->strings;
1488 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1489 memcpy (&infoPtr->strings[0], &oldStrings[0],
1490 sizeof(LPWSTR) * infoPtr->nNumStrings);
1491 COMCTL32_Free (oldStrings);
1494 len = COMCTL32_StrChrW (p, L'|') - p;
1495 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1496 infoPtr->strings[infoPtr->nNumStrings] =
1497 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1498 lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len);
1499 infoPtr->nNumStrings++;
1506 nIndex = infoPtr->nNumStrings;
1507 if (infoPtr->nNumStrings == 0) {
1509 COMCTL32_Alloc (sizeof(LPWSTR));
1512 LPWSTR *oldStrings = infoPtr->strings;
1514 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1515 memcpy (&infoPtr->strings[0], &oldStrings[0],
1516 sizeof(LPWSTR) * infoPtr->nNumStrings);
1517 COMCTL32_Free (oldStrings);
1520 infoPtr->strings[infoPtr->nNumStrings] =
1521 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1522 strcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
1523 infoPtr->nNumStrings++;
1527 LPWSTR p = (LPWSTR)lParam;
1532 TRACE("adding string(s) from array!\n");
1533 nIndex = infoPtr->nNumStrings;
1537 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1538 if (infoPtr->nNumStrings == 0) {
1540 COMCTL32_Alloc (sizeof(LPWSTR));
1543 LPWSTR *oldStrings = infoPtr->strings;
1545 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1546 memcpy (&infoPtr->strings[0], &oldStrings[0],
1547 sizeof(LPWSTR) * infoPtr->nNumStrings);
1548 COMCTL32_Free (oldStrings);
1551 infoPtr->strings[infoPtr->nNumStrings] =
1552 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1553 strcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1554 infoPtr->nNumStrings++;
1565 TOOLBAR_AutoSize (HWND hwnd)
1567 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1568 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1574 UINT uPosFlags = SWP_NOZORDER;
1576 TRACE("resize forced, style=%lx!\n", dwStyle);
1578 parent = GetParent (hwnd);
1579 GetClientRect(parent, &parent_rect);
1581 x = parent_rect.left;
1582 y = parent_rect.top;
1584 /* FIXME: we should be able to early out if nothing */
1585 /* has changed with nWidth != parent_rect width */
1587 if (dwStyle & CCS_NORESIZE) {
1588 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
1593 infoPtr->nWidth = parent_rect.right - parent_rect.left;
1594 TOOLBAR_CalcToolbar (hwnd);
1595 InvalidateRect( hwnd, NULL, TRUE );
1596 cy = infoPtr->nHeight;
1597 cx = infoPtr->nWidth;
1599 if (dwStyle & CCS_NOMOVEY) {
1600 GetWindowRect(hwnd, &window_rect);
1601 ScreenToClient(parent, (LPPOINT)&window_rect.left);
1602 y = window_rect.top;
1606 if (dwStyle & CCS_NOPARENTALIGN)
1607 uPosFlags |= SWP_NOMOVE;
1609 if (!(dwStyle & CCS_NODIVIDER))
1610 cy += GetSystemMetrics(SM_CYEDGE);
1612 if (dwStyle & WS_BORDER)
1615 cy += GetSystemMetrics(SM_CYEDGE);
1616 cx += GetSystemMetrics(SM_CYEDGE);
1619 infoPtr->bAutoSize = TRUE;
1620 SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
1622 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
1623 * the setwindowpos calls */
1624 infoPtr->bAutoSize = FALSE;
1631 TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
1633 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1635 return infoPtr->nNumButtons;
1640 TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1642 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1644 if (infoPtr == NULL) {
1645 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
1646 ERR("infoPtr == NULL!\n");
1650 infoPtr->dwStructSize = (DWORD)wParam;
1657 TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1659 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1660 TBUTTON_INFO *btnPtr;
1663 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1667 btnPtr = &infoPtr->buttons[nIndex];
1668 btnPtr->iBitmap = LOWORD(lParam);
1670 /* we HAVE to erase the background, the new bitmap could be */
1672 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
1679 TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1681 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1682 TBUTTON_INFO *btnPtr;
1685 BOOL bChecked = FALSE;
1687 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1691 btnPtr = &infoPtr->buttons[nIndex];
1693 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
1696 bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
1698 if (LOWORD(lParam) == FALSE)
1699 btnPtr->fsState &= ~TBSTATE_CHECKED;
1701 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
1703 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
1704 if (nOldIndex == nIndex)
1706 if (nOldIndex != -1)
1707 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
1709 btnPtr->fsState |= TBSTATE_CHECKED;
1712 if( bChecked != LOWORD(lParam) )
1714 if (nOldIndex != -1)
1716 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
1717 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
1719 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
1722 /* FIXME: Send a WM_NOTIFY?? */
1729 TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
1731 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1733 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1738 TOOLBAR_Customize (HWND hwnd)
1740 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1746 /* send TBN_BEGINADJUST notification */
1747 nmhdr.hwndFrom = hwnd;
1748 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1749 nmhdr.code = TBN_BEGINADJUST;
1751 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1752 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1754 if (!(hRes = FindResourceA (COMCTL32_hModule,
1755 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
1759 if(!(template = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
1762 ret = DialogBoxIndirectParamA (GetWindowLongA (hwnd, GWL_HINSTANCE),
1763 (LPDLGTEMPLATEA)template,
1765 (DLGPROC)TOOLBAR_CustomizeDialogProc,
1768 /* send TBN_ENDADJUST notification */
1769 nmhdr.code = TBN_ENDADJUST;
1771 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1772 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1779 TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1781 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1782 INT nIndex = (INT)wParam;
1784 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1787 if ((infoPtr->hwndToolTip) &&
1788 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
1791 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1792 ti.cbSize = sizeof (TTTOOLINFOA);
1794 ti.uId = infoPtr->buttons[nIndex].idCommand;
1796 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
1799 if (infoPtr->nNumButtons == 1) {
1800 TRACE(" simple delete!\n");
1801 COMCTL32_Free (infoPtr->buttons);
1802 infoPtr->buttons = NULL;
1803 infoPtr->nNumButtons = 0;
1806 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1807 TRACE("complex delete! [nIndex=%d]\n", nIndex);
1809 infoPtr->nNumButtons--;
1810 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
1812 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1813 nIndex * sizeof(TBUTTON_INFO));
1816 if (nIndex < infoPtr->nNumButtons) {
1817 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
1818 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
1821 COMCTL32_Free (oldButtons);
1824 TOOLBAR_CalcToolbar (hwnd);
1826 InvalidateRect (hwnd, NULL, TRUE);
1833 TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1835 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1836 TBUTTON_INFO *btnPtr;
1840 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1844 btnPtr = &infoPtr->buttons[nIndex];
1846 bState = btnPtr->fsState & TBSTATE_ENABLED;
1848 /* update the toolbar button state */
1849 if(LOWORD(lParam) == FALSE) {
1850 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
1852 btnPtr->fsState |= TBSTATE_ENABLED;
1855 /* redraw the button only if the state of the button changed */
1856 if(bState != (btnPtr->fsState & TBSTATE_ENABLED))
1858 InvalidateRect(hwnd, &btnPtr->rect,
1859 TOOLBAR_HasText(infoPtr, btnPtr));
1866 static inline LRESULT
1867 TOOLBAR_GetAnchorHighlight (HWND hwnd)
1869 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1871 return infoPtr->bAnchor;
1876 TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1878 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1881 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1885 return infoPtr->buttons[nIndex].iBitmap;
1889 static inline LRESULT
1890 TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
1892 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
1897 TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1899 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1900 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1901 INT nIndex = (INT)wParam;
1902 TBUTTON_INFO *btnPtr;
1904 if (infoPtr == NULL)
1910 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1913 btnPtr = &infoPtr->buttons[nIndex];
1914 lpTbb->iBitmap = btnPtr->iBitmap;
1915 lpTbb->idCommand = btnPtr->idCommand;
1916 lpTbb->fsState = btnPtr->fsState;
1917 lpTbb->fsStyle = btnPtr->fsStyle;
1918 lpTbb->dwData = btnPtr->dwData;
1919 lpTbb->iString = btnPtr->iString;
1926 TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1928 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1929 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
1930 TBUTTON_INFO *btnPtr;
1933 if (infoPtr == NULL)
1935 if (lpTbInfo == NULL)
1937 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOA))
1940 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1944 btnPtr = &infoPtr->buttons[nIndex];
1946 if (lpTbInfo->dwMask & TBIF_COMMAND)
1947 lpTbInfo->idCommand = btnPtr->idCommand;
1948 if (lpTbInfo->dwMask & TBIF_IMAGE)
1949 lpTbInfo->iImage = btnPtr->iBitmap;
1950 if (lpTbInfo->dwMask & TBIF_LPARAM)
1951 lpTbInfo->lParam = btnPtr->dwData;
1952 if (lpTbInfo->dwMask & TBIF_SIZE)
1953 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1954 if (lpTbInfo->dwMask & TBIF_STATE)
1955 lpTbInfo->fsState = btnPtr->fsState;
1956 if (lpTbInfo->dwMask & TBIF_STYLE)
1957 lpTbInfo->fsStyle = btnPtr->fsStyle;
1958 if (lpTbInfo->dwMask & TBIF_TEXT) {
1959 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
1961 lstrcpynWtoA (lpTbInfo->pszText,
1962 (LPWSTR)infoPtr->strings[btnPtr->iString],
1965 else lpTbInfo->pszText[0]=0;
1972 TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1974 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1975 LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
1976 TBUTTON_INFO *btnPtr;
1979 if (infoPtr == NULL)
1981 if (lpTbInfo == NULL)
1983 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
1986 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1990 btnPtr = &infoPtr->buttons[nIndex];
1992 if (lpTbInfo->dwMask & TBIF_COMMAND)
1993 lpTbInfo->idCommand = btnPtr->idCommand;
1994 if (lpTbInfo->dwMask & TBIF_IMAGE)
1995 lpTbInfo->iImage = btnPtr->iBitmap;
1996 if (lpTbInfo->dwMask & TBIF_LPARAM)
1997 lpTbInfo->lParam = btnPtr->dwData;
1998 if (lpTbInfo->dwMask & TBIF_SIZE)
1999 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
2000 if (lpTbInfo->dwMask & TBIF_STATE)
2001 lpTbInfo->fsState = btnPtr->fsState;
2002 if (lpTbInfo->dwMask & TBIF_STYLE)
2003 lpTbInfo->fsStyle = btnPtr->fsStyle;
2004 if (lpTbInfo->dwMask & TBIF_TEXT) {
2005 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
2006 lstrcpynW (lpTbInfo->pszText,
2007 (LPWSTR)infoPtr->strings[btnPtr->iString],
2016 TOOLBAR_GetButtonSize (HWND hwnd)
2018 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2020 return MAKELONG((WORD)infoPtr->nButtonWidth,
2021 (WORD)infoPtr->nButtonHeight);
2026 TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2028 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2029 INT nIndex, nStringIndex;
2031 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2035 nStringIndex = infoPtr->buttons[nIndex].iString;
2037 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
2039 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2045 lstrcpyWtoA ((LPSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
2047 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
2052 TOOLBAR_GetButtonTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2054 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2055 INT nIndex, nStringIndex;
2057 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2061 nStringIndex = infoPtr->buttons[nIndex].iString;
2063 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
2065 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2071 strcpyW ((LPWSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
2073 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
2077 /* << TOOLBAR_GetColorScheme >> */
2081 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2083 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2085 return (LRESULT)infoPtr->himlDis;
2089 inline static LRESULT
2090 TOOLBAR_GetExtendedStyle (HWND hwnd)
2092 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2094 return infoPtr->dwExStyle;
2099 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2101 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2103 return (LRESULT)infoPtr->himlHot;
2108 TOOLBAR_GetHotItem (HWND hwnd)
2110 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2112 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2115 if (infoPtr->nHotItem < 0)
2118 return (LRESULT)infoPtr->nHotItem;
2123 TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2125 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2127 return (LRESULT)infoPtr->himlDef;
2131 /* << TOOLBAR_GetInsertMark >> */
2132 /* << TOOLBAR_GetInsertMarkColor >> */
2136 TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2138 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2139 TBUTTON_INFO *btnPtr;
2143 if (infoPtr == NULL)
2145 nIndex = (INT)wParam;
2146 btnPtr = &infoPtr->buttons[nIndex];
2147 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2149 lpRect = (LPRECT)lParam;
2152 if (btnPtr->fsState & TBSTATE_HIDDEN)
2155 lpRect->left = btnPtr->rect.left;
2156 lpRect->right = btnPtr->rect.right;
2157 lpRect->bottom = btnPtr->rect.bottom;
2158 lpRect->top = btnPtr->rect.top;
2165 TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2167 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2168 LPSIZE lpSize = (LPSIZE)lParam;
2173 lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
2174 lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
2176 TRACE("maximum size %d x %d\n",
2177 infoPtr->rcBound.right - infoPtr->rcBound.left,
2178 infoPtr->rcBound.bottom - infoPtr->rcBound.top);
2184 /* << TOOLBAR_GetObject >> */
2185 /* << TOOLBAR_GetPadding >> */
2189 TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2191 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2192 TBUTTON_INFO *btnPtr;
2196 if (infoPtr == NULL)
2198 nIndex = (INT)wParam;
2199 btnPtr = &infoPtr->buttons[nIndex];
2200 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2202 lpRect = (LPRECT)lParam;
2206 lpRect->left = btnPtr->rect.left;
2207 lpRect->right = btnPtr->rect.right;
2208 lpRect->bottom = btnPtr->rect.bottom;
2209 lpRect->top = btnPtr->rect.top;
2216 TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2218 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2220 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
2221 return infoPtr->nRows;
2228 TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2230 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2233 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2237 return infoPtr->buttons[nIndex].fsState;
2242 TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2244 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2247 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2251 return infoPtr->buttons[nIndex].fsStyle;
2256 TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2258 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2260 if (infoPtr == NULL)
2263 return infoPtr->nMaxTextRows;
2268 TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
2270 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2272 if (infoPtr == NULL)
2274 return infoPtr->hwndToolTip;
2279 TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2281 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2283 TRACE("%s hwnd=0x%x stub!\n",
2284 infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
2286 return infoPtr->bUnicode;
2290 inline static LRESULT
2291 TOOLBAR_GetVersion (HWND hwnd)
2293 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2294 return infoPtr->iVersion;
2299 TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2301 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2302 TBUTTON_INFO *btnPtr;
2307 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2311 btnPtr = &infoPtr->buttons[nIndex];
2312 if (LOWORD(lParam) == FALSE)
2313 btnPtr->fsState &= ~TBSTATE_HIDDEN;
2315 btnPtr->fsState |= TBSTATE_HIDDEN;
2317 TOOLBAR_CalcToolbar (hwnd);
2319 InvalidateRect (hwnd, NULL, TRUE);
2325 inline static LRESULT
2326 TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2328 return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
2333 TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2335 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2336 TBUTTON_INFO *btnPtr;
2339 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2343 btnPtr = &infoPtr->buttons[nIndex];
2344 if (LOWORD(lParam) == FALSE)
2345 btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
2347 btnPtr->fsState |= TBSTATE_INDETERMINATE;
2349 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
2356 TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2358 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2359 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2360 INT nIndex = (INT)wParam;
2361 TBUTTON_INFO *oldButtons;
2367 /* EPP: this seems to be an undocumented call (from my IE4)
2368 * I assume in that case that:
2369 * - lpTbb->iString is a string pointer (not a string index in strings[] table
2370 * - index of insertion is at the end of existing buttons
2371 * I only see this happen with nIndex == -1, but it could have a special
2372 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
2377 if(lpTbb->iString) {
2378 len = lstrlenA((char*)lpTbb->iString) + 2;
2379 ptr = COMCTL32_Alloc(len);
2380 nIndex = infoPtr->nNumButtons;
2381 strcpy(ptr, (char*)lpTbb->iString);
2382 ptr[len - 1] = 0; /* ended by two '\0' */
2383 lpTbb->iString = TOOLBAR_AddStringA(hwnd, 0, (LPARAM)ptr);
2387 ERR("lpTbb->iString is NULL\n");
2391 } else if (nIndex < 0)
2394 TRACE("inserting button index=%d\n", nIndex);
2395 if (nIndex > infoPtr->nNumButtons) {
2396 nIndex = infoPtr->nNumButtons;
2397 TRACE("adjust index=%d\n", nIndex);
2400 oldButtons = infoPtr->buttons;
2401 infoPtr->nNumButtons++;
2402 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2403 /* pre insert copy */
2405 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2406 nIndex * sizeof(TBUTTON_INFO));
2409 /* insert new button */
2410 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2411 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2412 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2413 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2414 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2415 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2417 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2420 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2421 ti.cbSize = sizeof (TTTOOLINFOA);
2423 ti.uId = lpTbb->idCommand;
2425 ti.lpszText = LPSTR_TEXTCALLBACKA;
2427 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
2431 /* post insert copy */
2432 if (nIndex < infoPtr->nNumButtons - 1) {
2433 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2434 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2437 COMCTL32_Free (oldButtons);
2439 TOOLBAR_CalcToolbar (hwnd);
2441 InvalidateRect (hwnd, NULL, FALSE);
2448 TOOLBAR_InsertButtonW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2450 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2451 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2452 INT nIndex = (INT)wParam;
2453 TBUTTON_INFO *oldButtons;
2460 TRACE("inserting button index=%d\n", nIndex);
2461 if (nIndex > infoPtr->nNumButtons) {
2462 nIndex = infoPtr->nNumButtons;
2463 TRACE("adjust index=%d\n", nIndex);
2466 oldButtons = infoPtr->buttons;
2467 infoPtr->nNumButtons++;
2468 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2469 /* pre insert copy */
2471 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2472 nIndex * sizeof(TBUTTON_INFO));
2475 /* insert new button */
2476 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2477 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2478 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2479 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2480 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2481 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2483 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2486 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
2487 ti.cbSize = sizeof (TTTOOLINFOW);
2489 ti.uId = lpTbb->idCommand;
2491 ti.lpszText = LPSTR_TEXTCALLBACKW;
2493 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
2497 /* post insert copy */
2498 if (nIndex < infoPtr->nNumButtons - 1) {
2499 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2500 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2503 COMCTL32_Free (oldButtons);
2505 TOOLBAR_CalcToolbar (hwnd);
2507 InvalidateRect (hwnd, NULL, FALSE);
2513 /* << TOOLBAR_InsertMarkHitTest >> */
2517 TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
2519 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2522 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2526 return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
2531 TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
2533 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2536 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2540 return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
2545 TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
2547 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2550 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2554 return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
2559 TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
2561 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2564 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2568 return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
2573 TOOLBAR_IsButtonIndeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2575 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2578 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2582 return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
2587 TOOLBAR_IsButtonPressed (HWND hwnd, WPARAM wParam, LPARAM lParam)
2589 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2592 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2596 return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
2600 /* << TOOLBAR_LoadImages >> */
2601 /* << TOOLBAR_MapAccelerator >> */
2602 /* << TOOLBAR_MarkButton >> */
2603 /* << TOOLBAR_MoveButton >> */
2607 TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2609 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2610 TBUTTON_INFO *btnPtr;
2613 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2617 btnPtr = &infoPtr->buttons[nIndex];
2618 if (LOWORD(lParam) == FALSE)
2619 btnPtr->fsState &= ~TBSTATE_PRESSED;
2621 btnPtr->fsState |= TBSTATE_PRESSED;
2623 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
2629 /* << TOOLBAR_ReplaceBitmap >> */
2633 TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2636 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2637 LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
2639 if (lpSave == NULL) return 0;
2642 /* save toolbar information */
2643 FIXME("save to \"%s\" \"%s\"\n",
2644 lpSave->pszSubKey, lpSave->pszValueName);
2649 /* restore toolbar information */
2651 FIXME("restore from \"%s\" \"%s\"\n",
2652 lpSave->pszSubKey, lpSave->pszValueName);
2663 TOOLBAR_SaveRestoreW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2666 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2667 LPTBSAVEPARAMSW lpSave = (LPTBSAVEPARAMSW)lParam;
2673 /* save toolbar information */
2674 FIXME("save to \"%s\" \"%s\"\n",
2675 lpSave->pszSubKey, lpSave->pszValueName);
2680 /* restore toolbar information */
2682 FIXME("restore from \"%s\" \"%s\"\n",
2683 lpSave->pszSubKey, lpSave->pszValueName);
2694 TOOLBAR_SetAnchorHighlight (HWND hwnd, WPARAM wParam)
2696 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2697 BOOL bOldAnchor = infoPtr->bAnchor;
2699 infoPtr->bAnchor = (BOOL)wParam;
2701 return (LRESULT)bOldAnchor;
2706 TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2708 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2710 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
2713 if (infoPtr->nNumButtons > 0)
2714 WARN("%d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n",
2715 infoPtr->nNumButtons,
2716 infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
2717 LOWORD(lParam), HIWORD(lParam));
2719 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
2720 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
2722 /* uses image list internals directly */
2723 if (infoPtr->himlDef) {
2724 infoPtr->himlDef->cx = infoPtr->nBitmapWidth;
2725 infoPtr->himlDef->cy = infoPtr->nBitmapHeight;
2733 TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2735 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2736 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
2737 TBUTTON_INFO *btnPtr;
2742 if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
2745 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2749 btnPtr = &infoPtr->buttons[nIndex];
2750 if (lptbbi->dwMask & TBIF_COMMAND)
2751 btnPtr->idCommand = lptbbi->idCommand;
2752 if (lptbbi->dwMask & TBIF_IMAGE)
2753 btnPtr->iBitmap = lptbbi->iImage;
2754 if (lptbbi->dwMask & TBIF_LPARAM)
2755 btnPtr->dwData = lptbbi->lParam;
2756 /* if (lptbbi->dwMask & TBIF_SIZE) */
2757 /* btnPtr->cx = lptbbi->cx; */
2758 if (lptbbi->dwMask & TBIF_STATE)
2759 btnPtr->fsState = lptbbi->fsState;
2760 if (lptbbi->dwMask & TBIF_STYLE)
2761 btnPtr->fsStyle = lptbbi->fsStyle;
2763 if (lptbbi->dwMask & TBIF_TEXT) {
2764 if ((btnPtr->iString >= 0) ||
2765 (btnPtr->iString < infoPtr->nNumStrings)) {
2766 TRACE("Ooooooch\n");
2768 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2769 INT len = lstrlenA (lptbbi->pszText);
2770 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
2773 /* this is the ultimate sollution */
2774 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2783 TOOLBAR_SetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2785 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2786 LPTBBUTTONINFOW lptbbi = (LPTBBUTTONINFOW)lParam;
2787 TBUTTON_INFO *btnPtr;
2792 if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
2795 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2799 btnPtr = &infoPtr->buttons[nIndex];
2800 if (lptbbi->dwMask & TBIF_COMMAND)
2801 btnPtr->idCommand = lptbbi->idCommand;
2802 if (lptbbi->dwMask & TBIF_IMAGE)
2803 btnPtr->iBitmap = lptbbi->iImage;
2804 if (lptbbi->dwMask & TBIF_LPARAM)
2805 btnPtr->dwData = lptbbi->lParam;
2806 /* if (lptbbi->dwMask & TBIF_SIZE) */
2807 /* btnPtr->cx = lptbbi->cx; */
2808 if (lptbbi->dwMask & TBIF_STATE)
2809 btnPtr->fsState = lptbbi->fsState;
2810 if (lptbbi->dwMask & TBIF_STYLE)
2811 btnPtr->fsStyle = lptbbi->fsStyle;
2813 if (lptbbi->dwMask & TBIF_TEXT) {
2814 if ((btnPtr->iString >= 0) ||
2815 (btnPtr->iString < infoPtr->nNumStrings)) {
2817 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2818 INT len = lstrlenW (lptbbi->pszText);
2819 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
2822 /* this is the ultimate solution */
2823 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2832 TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2834 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2836 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
2838 ERR("invalid parameter\n");
2842 /* Button size can only be set before adding any button to the toolbar
2843 according to the documentation. */
2844 /* this appears to be wrong. WINZIP32.EXE (ver 8) calls this on
2845 one of its buttons after adding it to the toolbar, and it
2846 checks that the return value is nonzero - mjm */
2847 if( infoPtr->nNumButtons != 0 )
2849 WARN("Button size set after button in toolbar\n");
2853 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
2854 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
2860 TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
2862 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2864 if (infoPtr == NULL)
2867 infoPtr->cxMin = (INT)LOWORD(lParam);
2868 infoPtr->cxMax = (INT)HIWORD(lParam);
2875 TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
2877 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2878 INT nIndex = (INT)wParam;
2880 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2883 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
2885 if (infoPtr->hwndToolTip) {
2887 FIXME("change tool tip!\n");
2895 /* << TOOLBAR_SetColorScheme >> */
2899 TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2901 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2902 HIMAGELIST himlTemp;
2905 himlTemp = infoPtr->himlDis;
2906 infoPtr->himlDis = (HIMAGELIST)lParam;
2908 /* FIXME: redraw ? */
2910 return (LRESULT)himlTemp;
2915 TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
2917 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2920 dwTemp = infoPtr->dwDTFlags;
2921 infoPtr->dwDTFlags =
2922 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
2924 return (LRESULT)dwTemp;
2929 TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2931 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2934 dwTemp = infoPtr->dwExStyle;
2935 infoPtr->dwExStyle = (DWORD)lParam;
2937 return (LRESULT)dwTemp;
2942 TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2944 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2945 HIMAGELIST himlTemp;
2947 himlTemp = infoPtr->himlHot;
2948 infoPtr->himlHot = (HIMAGELIST)lParam;
2950 /* FIXME: redraw ? */
2952 return (LRESULT)himlTemp;
2957 TOOLBAR_SetHotItem (HWND hwnd, WPARAM wParam)
2959 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2960 INT nOldHotItem = infoPtr->nHotItem;
2962 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
2964 infoPtr->nHotItem = (INT)wParam;
2966 /* FIXME: What else must be done ??? */
2970 if (nOldHotItem < 0)
2973 return (LRESULT)nOldHotItem;
2978 TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2980 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2981 HIMAGELIST himlTemp;
2983 himlTemp = infoPtr->himlDef;
2984 infoPtr->himlDef = (HIMAGELIST)lParam;
2986 infoPtr->nNumBitmaps = ImageList_GetImageCount(infoPtr->himlDef);
2987 /* FIXME: redraw ? */
2989 return (LRESULT)himlTemp;
2994 TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2996 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3000 /* process only on indent changing */
3001 if(infoPtr->nIndent != (INT)wParam)
3003 infoPtr->nIndent = (INT)wParam;
3004 TOOLBAR_CalcToolbar (hwnd);
3005 InvalidateRect(hwnd, NULL, FALSE);
3012 /* << TOOLBAR_SetInsertMark >> */
3016 TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
3018 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3020 infoPtr->clrInsertMark = (COLORREF)lParam;
3022 /* FIXME : redraw ??*/
3029 TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3031 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3033 if (infoPtr == NULL)
3036 infoPtr->nMaxTextRows = (INT)wParam;
3042 /* << TOOLBAR_SetPadding >> */
3046 TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3048 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3053 if (infoPtr == NULL)
3055 hwndOldNotify = infoPtr->hwndNotify;
3056 infoPtr->hwndNotify = (HWND)wParam;
3058 return hwndOldNotify;
3063 TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3065 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3066 LPRECT lprc = (LPRECT)lParam;
3070 if (LOWORD(wParam) > 1) {
3071 FIXME("multiple rows not supported!\n");
3074 if(infoPtr->nRows != LOWORD(wParam))
3076 infoPtr->nRows = LOWORD(wParam);
3078 /* recalculate toolbar */
3079 TOOLBAR_CalcToolbar (hwnd);
3081 /* repaint toolbar */
3082 InvalidateRect(hwnd, NULL, FALSE);
3085 /* return bounding rectangle */
3087 lprc->left = infoPtr->rcBound.left;
3088 lprc->right = infoPtr->rcBound.right;
3089 lprc->top = infoPtr->rcBound.top;
3090 lprc->bottom = infoPtr->rcBound.bottom;
3098 TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
3100 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3101 TBUTTON_INFO *btnPtr;
3104 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3108 btnPtr = &infoPtr->buttons[nIndex];
3110 /* process state changing if current state doesn't match new state */
3111 if(btnPtr->fsState != LOWORD(lParam))
3113 btnPtr->fsState = LOWORD(lParam);
3114 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3123 TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3125 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3126 TBUTTON_INFO *btnPtr;
3129 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3133 btnPtr = &infoPtr->buttons[nIndex];
3135 /* process style change if current style doesn't match new style */
3136 if(btnPtr->fsStyle != LOWORD(lParam))
3138 btnPtr->fsStyle = LOWORD(lParam);
3139 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3142 if (infoPtr->hwndToolTip) {
3143 FIXME("change tool tip!\n");
3151 inline static LRESULT
3152 TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
3154 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3156 if (infoPtr == NULL)
3158 infoPtr->hwndToolTip = (HWND)wParam;
3164 TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
3166 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3169 TRACE("%s hwnd=0x%04x stub!\n",
3170 ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
3172 bTemp = infoPtr->bUnicode;
3173 infoPtr->bUnicode = (BOOL)wParam;
3180 TOOLBAR_SetVersion (HWND hwnd, INT iVersion)
3182 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3183 INT iOldVersion = infoPtr->iVersion;
3185 infoPtr->iVersion = iVersion;
3192 TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
3194 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3195 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3198 /* initialize info structure */
3199 infoPtr->nButtonHeight = 22;
3200 infoPtr->nButtonWidth = 24;
3201 infoPtr->nBitmapHeight = 15;
3202 infoPtr->nBitmapWidth = 16;
3204 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
3206 infoPtr->nMaxTextRows = 1;
3207 infoPtr->cxMin = -1;
3208 infoPtr->cxMax = -1;
3209 infoPtr->nNumBitmaps = 0;
3210 infoPtr->nNumStrings = 0;
3212 infoPtr->bCaptured = FALSE;
3213 infoPtr->bUnicode = IsWindowUnicode (hwnd);
3214 infoPtr->nButtonDown = -1;
3215 infoPtr->nOldHit = -1;
3216 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3217 infoPtr->hwndNotify = GetParent (hwnd);
3218 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
3219 infoPtr->dwDTFlags = (dwStyle & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE : DT_CENTER;
3220 infoPtr->bAnchor = FALSE; /* no anchor highlighting */
3221 infoPtr->iVersion = 0;
3223 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
3224 infoPtr->hFont = CreateFontIndirectA (&logFont);
3226 if (dwStyle & TBSTYLE_TOOLTIPS) {
3227 /* Create tooltip control */
3228 infoPtr->hwndToolTip =
3229 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
3230 CW_USEDEFAULT, CW_USEDEFAULT,
3231 CW_USEDEFAULT, CW_USEDEFAULT,
3234 /* Send NM_TOOLTIPSCREATED notification */
3235 if (infoPtr->hwndToolTip) {
3236 NMTOOLTIPSCREATED nmttc;
3238 nmttc.hdr.hwndFrom = hwnd;
3239 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3240 nmttc.hdr.code = NM_TOOLTIPSCREATED;
3241 nmttc.hwndToolTips = infoPtr->hwndToolTip;
3243 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3244 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
3248 TOOLBAR_CalcToolbar(hwnd);
3255 TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
3257 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3259 /* delete tooltip control */
3260 if (infoPtr->hwndToolTip)
3261 DestroyWindow (infoPtr->hwndToolTip);
3263 /* delete button data */
3264 if (infoPtr->buttons)
3265 COMCTL32_Free (infoPtr->buttons);
3267 /* delete strings */
3268 if (infoPtr->strings) {
3270 for (i = 0; i < infoPtr->nNumStrings; i++)
3271 if (infoPtr->strings[i])
3272 COMCTL32_Free (infoPtr->strings[i]);
3274 COMCTL32_Free (infoPtr->strings);
3277 /* destroy internal image list */
3278 if (infoPtr->himlInt)
3279 ImageList_Destroy (infoPtr->himlInt);
3281 /* delete default font */
3283 DeleteObject (infoPtr->hFont);
3285 /* free toolbar info data */
3286 COMCTL32_Free (infoPtr);
3287 SetWindowLongA (hwnd, 0, 0);
3294 TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
3296 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3298 if (infoPtr->bTransparent)
3299 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
3301 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
3306 TOOLBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
3308 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3310 return infoPtr->hFont;
3315 TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
3317 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3318 TBUTTON_INFO *btnPtr;
3322 pt.x = (INT)LOWORD(lParam);
3323 pt.y = (INT)HIWORD(lParam);
3324 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3327 btnPtr = &infoPtr->buttons[nHit];
3328 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3331 infoPtr->bCaptured = TRUE;
3332 infoPtr->nButtonDown = nHit;
3334 btnPtr->fsState |= TBSTATE_PRESSED;
3336 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3339 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
3340 TOOLBAR_Customize (hwnd);
3347 TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
3349 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3350 TBUTTON_INFO *btnPtr;
3354 if (infoPtr->hwndToolTip)
3355 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3356 WM_LBUTTONDOWN, wParam, lParam);
3358 pt.x = (INT)LOWORD(lParam);
3359 pt.y = (INT)HIWORD(lParam);
3360 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3363 btnPtr = &infoPtr->buttons[nHit];
3364 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3367 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN)
3371 nmtb.hdr.hwndFrom = hwnd;
3372 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3373 nmtb.hdr.code = TBN_DROPDOWN;
3374 nmtb.iItem = btnPtr->idCommand;
3376 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3377 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3381 infoPtr->bCaptured = TRUE;
3382 infoPtr->nButtonDown = nHit;
3383 infoPtr->nOldHit = nHit;
3385 btnPtr->fsState |= TBSTATE_PRESSED;
3386 btnPtr->bHot = FALSE;
3388 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3396 TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
3398 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3399 TBUTTON_INFO *btnPtr;
3403 BOOL bSendMessage = TRUE;
3405 if (infoPtr->hwndToolTip)
3406 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3407 WM_LBUTTONUP, wParam, lParam);
3409 pt.x = (INT)LOWORD(lParam);
3410 pt.y = (INT)HIWORD(lParam);
3411 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3413 /* restore hot effect to hot button disabled by TOOLBAR_LButtonDown() */
3414 /* if the cursor is still inside of the toolbar */
3415 if((infoPtr->nHotItem >= 0) && (nHit != -1))
3416 infoPtr->buttons[infoPtr->nHotItem].bHot = TRUE;
3418 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
3419 infoPtr->bCaptured = FALSE;
3421 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3422 btnPtr->fsState &= ~TBSTATE_PRESSED;
3424 if (nHit == infoPtr->nButtonDown) {
3425 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
3426 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
3427 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
3428 infoPtr->nButtonDown);
3429 if (nOldIndex == infoPtr->nButtonDown)
3430 bSendMessage = FALSE;
3431 if ((nOldIndex != infoPtr->nButtonDown) &&
3433 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
3434 btnPtr->fsState |= TBSTATE_CHECKED;
3437 if (btnPtr->fsState & TBSTATE_CHECKED)
3438 btnPtr->fsState &= ~TBSTATE_CHECKED;
3440 btnPtr->fsState |= TBSTATE_CHECKED;
3445 bSendMessage = FALSE;
3447 if (nOldIndex != -1)
3449 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
3450 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
3453 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3457 SendMessageA (GetParent(hwnd), WM_COMMAND,
3458 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
3460 // if ((GetWindowLongA(hwnd, GWL_STYLE) & TBSTYLE_DROPDOWN) ||
3461 // (btnPtr->fsStyle & 0x08/* BTNS_DROPDOWN */)) {
3463 * This appears to be an error. Instead of checking the style of the
3464 * button in question wine was checking the style of the toolbar
3465 * itself. This caused a number of strange behaviors. In my
3466 * invistigation i think the whole dropdown thing is still fairly
3467 * broken. but this helps fix some of the problems.
3470 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN) {
3473 nmtb.hdr.hwndFrom = hwnd;
3474 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3475 nmtb.hdr.code = TBN_DROPDOWN;
3477 /* nmtb.tbButton not used with TBN_DROPDOWN */
3478 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings)) {
3479 nmtb.pszText = infoPtr->strings[btnPtr->iString];
3480 nmtb.cchText = lstrlenW(nmtb.pszText);
3482 nmtb.pszText = NULL;
3485 nmtb.rcButton = btnPtr->rect;
3487 SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
3488 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3491 infoPtr->nButtonDown = -1;
3492 infoPtr->nOldHit = -1;
3499 TOOLBAR_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam)
3501 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3502 TBUTTON_INFO *hotBtnPtr, *btnPtr;
3504 if (infoPtr->nOldHit < 0)
3507 hotBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3509 /* Redraw the button if the last button we were over is the hot button and it
3511 if((infoPtr->nOldHit == infoPtr->nHotItem) && (hotBtnPtr->fsState & TBSTATE_ENABLED))
3513 hotBtnPtr->bHot = FALSE;
3515 InvalidateRect (hwnd, &hotBtnPtr->rect, TOOLBAR_HasText(infoPtr,
3519 /* If the last button we were over is depressed then make it not */
3520 /* depressed and redraw it */
3521 if(infoPtr->nOldHit == infoPtr->nButtonDown)
3523 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3525 btnPtr->fsState &= ~TBSTATE_PRESSED;
3527 InvalidateRect (hwnd, &(btnPtr->rect), TRUE);
3530 infoPtr->nOldHit = -1; /* reset the old hit index as we've left the toolbar */
3531 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3537 TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
3539 TBUTTON_INFO *btnPtr, *oldBtnPtr;
3540 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3543 TRACKMOUSEEVENT trackinfo;
3545 /* fill in the TRACKMOUSEEVENT struct */
3546 trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
3547 trackinfo.dwFlags = TME_QUERY;
3548 trackinfo.hwndTrack = hwnd;
3549 trackinfo.dwHoverTime = HOVER_DEFAULT;
3551 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
3552 _TrackMouseEvent(&trackinfo);
3554 /* Make sure tracking is enabled so we recieve a WM_MOUSELEAVE message */
3555 if(!(trackinfo.dwFlags & TME_LEAVE)) {
3556 trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
3558 /* call TRACKMOUSEEVENT so we recieve a WM_MOUSELEAVE message */
3559 /* and can properly deactivate the hot toolbar button */
3560 _TrackMouseEvent(&trackinfo);
3563 if (infoPtr->hwndToolTip)
3564 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3565 WM_MOUSEMOVE, wParam, lParam);
3567 pt.x = (INT)LOWORD(lParam);
3568 pt.y = (INT)HIWORD(lParam);
3570 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3572 if (infoPtr->nOldHit != nHit)
3574 /* Remove the effect of an old hot button if the button was enabled and was
3575 drawn with the hot button effect */
3576 if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem &&
3577 (infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED))
3579 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3580 oldBtnPtr->bHot = FALSE;
3582 InvalidateRect (hwnd, &oldBtnPtr->rect,
3583 TOOLBAR_HasText(infoPtr, oldBtnPtr));
3586 /* It's not a separator or in nowhere. It's a hot button. */
3589 btnPtr = &infoPtr->buttons[nHit];
3590 btnPtr->bHot = TRUE;
3592 infoPtr->nHotItem = nHit;
3594 /* only enabled buttons show hot effect */
3595 if(infoPtr->buttons[nHit].fsState & TBSTATE_ENABLED)
3597 InvalidateRect(hwnd, &btnPtr->rect,
3598 TOOLBAR_HasText(infoPtr, btnPtr));
3603 if (infoPtr->bCaptured) {
3604 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3605 if (infoPtr->nOldHit == infoPtr->nButtonDown) {
3606 btnPtr->fsState &= ~TBSTATE_PRESSED;
3607 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3609 else if (nHit == infoPtr->nButtonDown) {
3610 btnPtr->fsState |= TBSTATE_PRESSED;
3611 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3614 infoPtr->nOldHit = nHit;
3620 inline static LRESULT
3621 TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3623 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
3624 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
3626 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
3630 inline static LRESULT
3631 TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3633 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
3634 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
3636 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
3641 TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3643 TOOLBAR_INFO *infoPtr;
3645 /* allocate memory for info structure */
3646 infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
3647 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
3650 infoPtr->dwStructSize = sizeof(TBBUTTON);
3652 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
3653 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
3654 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
3655 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
3658 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
3663 TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3665 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3669 if (dwStyle & WS_MINIMIZE)
3670 return 0; /* Nothing to do */
3672 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
3674 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
3677 if (!(dwStyle & CCS_NODIVIDER))
3679 GetWindowRect (hwnd, &rcWindow);
3680 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3681 if( dwStyle & WS_BORDER )
3682 OffsetRect (&rcWindow, 1, 1);
3683 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
3686 ReleaseDC( hwnd, hdc );
3692 inline static LRESULT
3693 TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
3695 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3696 LPNMHDR lpnmh = (LPNMHDR)lParam;
3698 TRACE("passing WM_NOTIFY!\n");
3700 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
3701 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
3704 if (lpnmh->code == TTN_GETDISPINFOA) {
3705 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
3707 FIXME("retrieving ASCII string\n");
3710 else if (lpnmh->code == TTN_GETDISPINFOW) {
3711 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
3713 FIXME("retrieving UNICODE string\n");
3724 TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
3726 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3732 /* fill ps.rcPaint with a default rect */
3733 memcpy(&(ps.rcPaint), &(infoPtr->rcBound), sizeof(infoPtr->rcBound));
3735 TOOLBAR_CalcToolbar( hwnd );
3736 hdc = wParam==0 ? BeginPaint(hwnd, &ps) : (HDC)wParam;
3737 TOOLBAR_Refresh (hwnd, hdc, &ps);
3738 if (!wParam) EndPaint (hwnd, &ps);
3745 TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
3747 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3748 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3757 /* Resize deadlock check */
3758 if (infoPtr->bAutoSize) {
3759 infoPtr->bAutoSize = FALSE;
3763 /* FIXME: optimize to only update size if the new size doesn't */
3764 /* match the current size */
3766 flags = (INT) wParam;
3768 /* FIXME for flags =
3769 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
3772 TRACE("sizing toolbar!\n");
3774 if (flags == SIZE_RESTORED) {
3775 /* width and height don't apply */
3776 parent = GetParent (hwnd);
3777 GetClientRect(parent, &parent_rect);
3778 x = parent_rect.left;
3779 y = parent_rect.top;
3781 if (dwStyle & CCS_NORESIZE) {
3782 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
3785 * this sets the working width of the toolbar, and
3786 * Calc Toolbar will not adjust it, only the height
3788 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3789 cy = infoPtr->nHeight;
3790 cx = infoPtr->nWidth;
3791 TOOLBAR_CalcToolbar (hwnd);
3792 infoPtr->nWidth = cx;
3793 infoPtr->nHeight = cy;
3796 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3797 TOOLBAR_CalcToolbar (hwnd);
3798 cy = infoPtr->nHeight;
3799 cx = infoPtr->nWidth;
3801 if (dwStyle & CCS_NOMOVEY) {
3802 GetWindowRect(hwnd, &window_rect);
3803 ScreenToClient(parent, (LPPOINT)&window_rect.left);
3804 y = window_rect.top;
3808 if (dwStyle & CCS_NOPARENTALIGN) {
3809 uPosFlags |= SWP_NOMOVE;
3810 cy = infoPtr->nHeight;
3811 cx = infoPtr->nWidth;
3814 if (!(dwStyle & CCS_NODIVIDER))
3815 cy += GetSystemMetrics(SM_CYEDGE);
3817 if (dwStyle & WS_BORDER)
3820 cy += GetSystemMetrics(SM_CYEDGE);
3821 cx += GetSystemMetrics(SM_CYEDGE);
3824 SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
3825 cx, cy, uPosFlags | SWP_NOZORDER);
3832 TOOLBAR_StyleChanged (HWND hwnd, INT nType, LPSTYLESTRUCT lpStyle)
3834 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3836 if (nType == GWL_STYLE) {
3837 if (lpStyle->styleNew & TBSTYLE_LIST) {
3838 infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
3841 infoPtr->dwDTFlags = DT_CENTER;
3845 TOOLBAR_AutoSize (hwnd);
3847 InvalidateRect(hwnd, NULL, FALSE);
3854 static LRESULT WINAPI
3855 ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3861 return TOOLBAR_Destroy (hwnd, wParam, lParam);
3864 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
3867 if (!TOOLBAR_GetInfoPtr (hwnd))
3869 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3875 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
3877 case TB_ADDBUTTONSA:
3878 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
3880 case TB_ADDBUTTONSW:
3881 return TOOLBAR_AddButtonsW (hwnd, wParam, lParam);
3884 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
3887 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
3890 return TOOLBAR_AutoSize (hwnd);
3892 case TB_BUTTONCOUNT:
3893 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
3895 case TB_BUTTONSTRUCTSIZE:
3896 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
3898 case TB_CHANGEBITMAP:
3899 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
3901 case TB_CHECKBUTTON:
3902 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
3904 case TB_COMMANDTOINDEX:
3905 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
3908 return TOOLBAR_Customize (hwnd);
3910 case TB_DELETEBUTTON:
3911 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
3913 case TB_ENABLEBUTTON:
3914 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
3916 case TB_GETANCHORHIGHLIGHT:
3917 return TOOLBAR_GetAnchorHighlight (hwnd);
3920 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
3922 case TB_GETBITMAPFLAGS:
3923 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
3926 return TOOLBAR_GetButton (hwnd, wParam, lParam);
3928 case TB_GETBUTTONINFOA:
3929 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
3931 case TB_GETBUTTONINFOW:
3932 return TOOLBAR_GetButtonInfoW (hwnd, wParam, lParam);
3934 case TB_GETBUTTONSIZE:
3935 return TOOLBAR_GetButtonSize (hwnd);
3937 case TB_GETBUTTONTEXTA:
3938 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
3940 case TB_GETBUTTONTEXTW:
3941 return TOOLBAR_GetButtonTextW (hwnd, wParam, lParam);
3943 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
3945 case TB_GETDISABLEDIMAGELIST:
3946 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
3948 case TB_GETEXTENDEDSTYLE:
3949 return TOOLBAR_GetExtendedStyle (hwnd);
3951 case TB_GETHOTIMAGELIST:
3952 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
3955 return TOOLBAR_GetHotItem (hwnd);
3957 case TB_GETIMAGELIST:
3958 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
3960 /* case TB_GETINSERTMARK: */ /* 4.71 */
3961 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
3963 case TB_GETITEMRECT:
3964 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
3967 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
3969 /* case TB_GETOBJECT: */ /* 4.71 */
3970 /* case TB_GETPADDING: */ /* 4.71 */
3973 return TOOLBAR_GetRect (hwnd, wParam, lParam);
3976 return TOOLBAR_GetRows (hwnd, wParam, lParam);
3979 return TOOLBAR_GetState (hwnd, wParam, lParam);
3982 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
3984 case TB_GETTEXTROWS:
3985 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
3987 case TB_GETTOOLTIPS:
3988 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
3990 case TB_GETUNICODEFORMAT:
3991 return TOOLBAR_GetUnicodeFormat (hwnd, wParam, lParam);
3993 case CCM_GETVERSION:
3994 return TOOLBAR_GetVersion (hwnd);
3997 return TOOLBAR_HideButton (hwnd, wParam, lParam);
4000 return TOOLBAR_HitTest (hwnd, wParam, lParam);
4002 case TB_INDETERMINATE:
4003 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
4005 case TB_INSERTBUTTONA:
4006 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
4008 case TB_INSERTBUTTONW:
4009 return TOOLBAR_InsertButtonW (hwnd, wParam, lParam);
4011 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
4013 case TB_ISBUTTONCHECKED:
4014 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
4016 case TB_ISBUTTONENABLED:
4017 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
4019 case TB_ISBUTTONHIDDEN:
4020 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
4022 case TB_ISBUTTONHIGHLIGHTED:
4023 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
4025 case TB_ISBUTTONINDETERMINATE:
4026 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
4028 case TB_ISBUTTONPRESSED:
4029 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
4031 case TB_LOADIMAGES: /* 4.70 */
4032 FIXME("missing standard imagelists\n");
4035 /* case TB_MAPACCELERATORA: */ /* 4.71 */
4036 /* case TB_MAPACCELERATORW: */ /* 4.71 */
4037 /* case TB_MARKBUTTON: */ /* 4.71 */
4038 /* case TB_MOVEBUTTON: */ /* 4.71 */
4040 case TB_PRESSBUTTON:
4041 return TOOLBAR_PressButton (hwnd, wParam, lParam);
4043 /* case TB_REPLACEBITMAP: */
4045 case TB_SAVERESTOREA:
4046 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
4048 case TB_SAVERESTOREW:
4049 return TOOLBAR_SaveRestoreW (hwnd, wParam, lParam);
4051 case TB_SETANCHORHIGHLIGHT:
4052 return TOOLBAR_SetAnchorHighlight (hwnd, wParam);
4054 case TB_SETBITMAPSIZE:
4055 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
4057 case TB_SETBUTTONINFOA:
4058 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
4060 case TB_SETBUTTONINFOW:
4061 return TOOLBAR_SetButtonInfoW (hwnd, wParam, lParam);
4063 case TB_SETBUTTONSIZE:
4064 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
4066 case TB_SETBUTTONWIDTH:
4067 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
4070 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
4072 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
4074 case TB_SETDISABLEDIMAGELIST:
4075 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
4077 case TB_SETDRAWTEXTFLAGS:
4078 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
4080 case TB_SETEXTENDEDSTYLE:
4081 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
4083 case TB_SETHOTIMAGELIST:
4084 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
4087 return TOOLBAR_SetHotItem (hwnd, wParam);
4089 case TB_SETIMAGELIST:
4090 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
4093 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
4095 /* case TB_SETINSERTMARK: */ /* 4.71 */
4097 case TB_SETINSERTMARKCOLOR:
4098 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
4100 case TB_SETMAXTEXTROWS:
4101 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
4103 /* case TB_SETPADDING: */ /* 4.71 */
4106 return TOOLBAR_SetParent (hwnd, wParam, lParam);
4109 return TOOLBAR_SetRows (hwnd, wParam, lParam);
4112 return TOOLBAR_SetState (hwnd, wParam, lParam);
4115 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
4117 case TB_SETTOOLTIPS:
4118 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
4120 case TB_SETUNICODEFORMAT:
4121 return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
4123 case CCM_SETVERSION:
4124 return TOOLBAR_SetVersion (hwnd, (INT)wParam);
4130 return TOOLBAR_Create (hwnd, wParam, lParam);
4133 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
4136 return TOOLBAR_GetFont (hwnd, wParam, lParam);
4138 /* case WM_KEYDOWN: */
4139 /* case WM_KILLFOCUS: */
4141 case WM_LBUTTONDBLCLK:
4142 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
4144 case WM_LBUTTONDOWN:
4145 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
4148 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
4151 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
4154 return TOOLBAR_MouseLeave (hwnd, wParam, lParam);
4157 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
4160 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
4163 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
4166 return TOOLBAR_Notify (hwnd, wParam, lParam);
4168 /* case WM_NOTIFYFORMAT: */
4171 return TOOLBAR_Paint (hwnd, wParam);
4174 return TOOLBAR_Size (hwnd, wParam, lParam);
4176 case WM_STYLECHANGED:
4177 return TOOLBAR_StyleChanged (hwnd, (INT)wParam, (LPSTYLESTRUCT)lParam);
4179 /* case WM_SYSCOLORCHANGE: */
4181 /* case WM_WININICHANGE: */
4186 case WM_MEASUREITEM:
4188 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
4191 if (uMsg >= WM_USER)
4192 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
4193 uMsg, wParam, lParam);
4194 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
4201 TOOLBAR_Register (void)
4205 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
4206 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
4207 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
4208 wndClass.cbClsExtra = 0;
4209 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
4210 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
4211 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
4212 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
4214 RegisterClassA (&wndClass);
4219 TOOLBAR_Unregister (void)
4221 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);