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"
38 #include "imagelist.h"
41 #include "debugtools.h"
43 DEFAULT_DEBUG_CHANNEL(toolbar);
61 DWORD dwStructSize; /* size of TBBUTTON struct */
62 INT nHeight; /* height of the toolbar */
63 INT nWidth; /* width of the toolbar */
69 INT nRows; /* number of button rows */
70 INT nMaxTextRows; /* maximum number of text rows */
71 INT cxMin; /* minimum button width */
72 INT cxMax; /* maximum button width */
73 INT nNumButtons; /* number of buttons */
74 INT nNumBitmaps; /* number of bitmaps */
75 INT nNumStrings; /* number of strings */
76 BOOL bUnicode; /* ASCII (FALSE) or Unicode (TRUE)? */
77 BOOL bCaptured; /* mouse captured? */
80 INT nHotItem; /* index of the "hot" item */
81 HFONT hFont; /* text font */
82 HIMAGELIST himlInt; /* image list created internally */
83 HIMAGELIST himlDef; /* default image list */
84 HIMAGELIST himlHot; /* hot image list */
85 HIMAGELIST himlDis; /* disabled image list */
86 HWND hwndToolTip; /* handle to tool tip control */
87 HWND hwndNotify; /* handle to the window that gets notifications */
88 BOOL bTransparent; /* background transparency flag */
89 BOOL bAutoSize; /* auto size deadlock indicator */
90 BOOL bAnchor; /* anchor highlight enabled */
91 DWORD dwExStyle; /* extended toolbar style */
92 DWORD dwDTFlags; /* DrawText flags */
94 COLORREF clrInsertMark; /* insert mark color */
95 RECT rcBound; /* bounding rectangle */
98 TBUTTON_INFO *buttons; /* pointer to button array */
99 LPWSTR *strings; /* pointer to string array */
102 #define SEPARATOR_WIDTH 8
104 #define BOTTOM_BORDER 2
106 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
107 #define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE)
110 TOOLBAR_GetText(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr)
112 LPWSTR lpText = NULL;
114 /* FIXME: iString == -1 is undocumented */
115 if ((HIWORD(btnPtr->iString) != 0) && (btnPtr->iString != -1))
116 lpText = (LPWSTR)btnPtr->iString;
117 else if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
118 lpText = infoPtr->strings[btnPtr->iString];
124 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index)
126 if ((index>=0) && (index < infoPtr->nNumBitmaps))
134 TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
136 INT x = (lpRect->left + lpRect->right) / 2 - 1;
137 INT yBottom = lpRect->bottom - 3;
138 INT yTop = lpRect->top + 1;
140 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
141 MoveToEx (hdc, x, yBottom, NULL);
142 LineTo (hdc, x, yTop);
144 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
145 MoveToEx (hdc, x, yBottom, NULL);
146 LineTo (hdc, x, yTop);
150 * Draw the text string for this button.
151 * note: infoPtr->himlDis *SHOULD* be non-zero when infoPtr->himlDef
152 * is non-zero, so we can simply check himlDef to see if we have
156 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
157 HDC hdc, INT nState, DWORD dwStyle)
159 RECT rcText = btnPtr->rect;
163 LPWSTR lpText = NULL;
164 HIMAGELIST himl = infoPtr->himlDef;
166 TRACE ("iString: %x\n", btnPtr->iString);
168 /* get a pointer to the text */
169 lpText = TOOLBAR_GetText(infoPtr, btnPtr);
171 TRACE ("lpText: \"%s\"\n", debugstr_w(lpText));
176 InflateRect (&rcText, -3, -3);
178 if (himl && TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
179 if ((dwStyle & TBSTYLE_LIST) &&
180 ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
181 (btnPtr->iBitmap != I_IMAGENONE)) {
182 rcText.left += infoPtr->nBitmapWidth;
185 rcText.top += infoPtr->nBitmapHeight;
189 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
190 OffsetRect (&rcText, 1, 1);
192 hOldFont = SelectObject (hdc, infoPtr->hFont);
193 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
194 if (!(nState & TBSTATE_ENABLED)) {
195 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
196 OffsetRect (&rcText, 1, 1);
197 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
198 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
199 OffsetRect (&rcText, -1, -1);
200 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
202 else if (nState & TBSTATE_INDETERMINATE) {
203 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
204 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
207 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
208 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
211 SetTextColor (hdc, clrOld);
212 SelectObject (hdc, hOldFont);
213 if (nOldBkMode != TRANSPARENT)
214 SetBkMode (hdc, nOldBkMode);
220 TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
222 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
223 INT cx = lpRect->right - lpRect->left;
224 INT cy = lpRect->bottom - lpRect->top;
225 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
226 SelectObject (hdc, hbr);
231 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
232 HDC hdc, INT x, INT y)
234 /* FIXME: this function is a hack since it uses image list
235 internals directly */
237 HIMAGELIST himl = infoPtr->himlDef;
245 /* create new dc's */
246 hdcImageList = CreateCompatibleDC (0);
247 hdcMask = CreateCompatibleDC (0);
249 /* create new bitmap */
250 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
251 SelectObject (hdcMask, hbmMask);
253 /* copy the mask bitmap */
254 SelectObject (hdcImageList, himl->hbmMask);
255 SetBkColor (hdcImageList, RGB(255, 255, 255));
256 SetTextColor (hdcImageList, RGB(0, 0, 0));
257 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
258 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
261 /* add white mask from image */
262 SelectObject (hdcImageList, himl->hbmImage);
263 SetBkColor (hdcImageList, RGB(0, 0, 0));
264 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
265 hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
268 /* draw the new mask */
269 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
270 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
271 hdcMask, 0, 0, 0xB8074A);
273 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
274 BitBlt (hdc, x, y, himl->cx, himl->cy,
275 hdcMask, 0, 0, 0xB8074A);
277 DeleteObject (hbmMask);
279 DeleteDC (hdcImageList);
284 TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
286 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
287 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
290 if (btnPtr->fsState & TBSTATE_HIDDEN)
295 TRACE("iBitmap: %d\n", btnPtr->iBitmap);
298 if (btnPtr->fsStyle & TBSTYLE_SEP) {
299 /* with the FLAT style, iBitmap is the width and has already */
300 /* been taken into consideration in calculating the width */
301 /* so now we need to draw the vertical separator */
302 /* empirical tests show that iBitmap can/will be non-zero */
303 /* when drawing the vertical bar... */
304 if ((dwStyle & TBSTYLE_FLAT) /* && (btnPtr->iBitmap == 0) */)
305 TOOLBAR_DrawFlatSeparator (&rc, hdc);
310 if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
311 if (!(dwStyle & TBSTYLE_FLAT))
312 DrawEdge (hdc, &rc, EDGE_RAISED,
313 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
315 if (infoPtr->himlDis &&
316 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
317 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
318 rc.left+1, rc.top+1, ILD_NORMAL);
320 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
322 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
326 /* pressed TBSTYLE_BUTTON */
327 if (btnPtr->fsState & TBSTATE_PRESSED) {
328 if (dwStyle & TBSTYLE_FLAT)
329 DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
331 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
332 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
333 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
334 rc.left+2, rc.top+2, ILD_NORMAL);
335 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
339 /* checked TBSTYLE_CHECK */
340 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
341 (btnPtr->fsState & TBSTATE_CHECKED)) {
342 if (dwStyle & TBSTYLE_FLAT)
343 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
344 BF_RECT | BF_MIDDLE | BF_ADJUST);
346 DrawEdge (hdc, &rc, EDGE_SUNKEN,
347 BF_RECT | BF_MIDDLE | BF_ADJUST);
349 TOOLBAR_DrawPattern (hdc, &rc);
351 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
352 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
353 rc.left+2, rc.top+2, ILD_NORMAL);
355 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
360 if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
361 DrawEdge (hdc, &rc, EDGE_RAISED,
362 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
364 TOOLBAR_DrawPattern (hdc, &rc);
365 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
366 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
371 if (dwStyle & TBSTYLE_FLAT)
374 DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
376 FrameRect(hdc, &rc, GetSysColorBrush(COLOR_BTNFACE));
378 if (btnPtr->bHot && infoPtr->himlHot &&
379 TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
380 ImageList_Draw (infoPtr->himlHot, btnPtr->iBitmap, hdc,
381 rc.left +2, rc.top +2, ILD_NORMAL);
382 else if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
383 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
384 rc.left +2, rc.top +2, ILD_NORMAL);
388 DrawEdge (hdc, &rc, EDGE_RAISED,
389 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
391 if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap))
392 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
393 rc.left+1, rc.top+1, ILD_NORMAL);
396 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
401 TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
403 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
404 TBUTTON_INFO *btnPtr;
408 /* redraw necessary buttons */
409 btnPtr = infoPtr->buttons;
410 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
412 if(IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect)))
413 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
418 TOOLBAR_MeasureString(HWND hwnd, INT index, LPSIZE lpSize)
420 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
421 TBUTTON_INFO *btnPtr;
428 hOldFont = SelectObject (hdc, infoPtr->hFont);
430 btnPtr = &infoPtr->buttons[index];
432 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
433 (btnPtr->iString > -1) &&
434 (btnPtr->iString < infoPtr->nNumStrings))
436 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
437 GetTextExtentPoint32W (hdc, lpText, lstrlenW (lpText), lpSize);
440 SelectObject (hdc, hOldFont);
443 TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
447 TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
449 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
450 TBUTTON_INFO *btnPtr;
458 btnPtr = infoPtr->buttons;
459 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
460 if(TOOLBAR_HasText(infoPtr, btnPtr))
462 TOOLBAR_MeasureString(hwnd,i,&sz);
463 if (sz.cx > lpSize->cx)
465 if (sz.cy > lpSize->cy)
470 TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
473 /***********************************************************************
474 * TOOLBAR_WrapToolbar
476 * This function walks through the buttons and seperators in the
477 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
478 * wrapping should occur based on the width of the toolbar window.
479 * It does *not* calculate button placement itself. That task
480 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
481 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
482 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
486 TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
488 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
489 TBUTTON_INFO *btnPtr;
492 BOOL bWrap, bButtonWrap;
494 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
495 /* no layout is necessary. Applications may use this style */
496 /* to perform their own layout on the toolbar. */
497 if( !(dwStyle & TBSTYLE_WRAPABLE) )
500 btnPtr = infoPtr->buttons;
501 x = infoPtr->nIndent;
503 /* this can get the parents width, to know how far we can extend
504 * this toolbar. We cannot use its height, as there may be multiple
505 * toolbars in a rebar control
507 GetClientRect( GetParent(hwnd), &rc );
508 infoPtr->nWidth = rc.right - rc.left;
511 for (i = 0; i < infoPtr->nNumButtons; i++ )
514 btnPtr[i].fsState &= ~TBSTATE_WRAP;
516 if (btnPtr[i].fsState & TBSTATE_HIDDEN)
519 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
520 /* it is the actual width of the separator. This is used for */
521 /* custom controls in toolbars. */
522 if (btnPtr[i].fsStyle & TBSTYLE_SEP)
523 cx = (btnPtr[i].iBitmap > 0) ?
524 btnPtr[i].iBitmap : SEPARATOR_WIDTH;
526 cx = infoPtr->nButtonWidth;
528 /* Two or more adjacent separators form a separator group. */
529 /* The first separator in a group should be wrapped to the */
530 /* next row if the previous wrapping is on a button. */
532 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
533 (i + 1 < infoPtr->nNumButtons ) &&
534 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
536 btnPtr[i].fsState |= TBSTATE_WRAP;
537 x = infoPtr->nIndent;
543 /* The layout makes sure the bitmap is visible, but not the button. */
544 if ( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
549 /* If the current button is a separator and not hidden, */
550 /* go to the next until it reaches a non separator. */
551 /* Wrap the last separator if it is before a button. */
552 while( ( (btnPtr[i].fsStyle & TBSTYLE_SEP) ||
553 (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
554 i < infoPtr->nNumButtons )
560 if( bFound && i < infoPtr->nNumButtons )
563 btnPtr[i].fsState |= TBSTATE_WRAP;
564 x = infoPtr->nIndent;
568 else if ( i >= infoPtr->nNumButtons)
571 /* If the current button is not a separator, find the last */
572 /* separator and wrap it. */
573 for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
575 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
576 !(btnPtr[j].fsState & TBSTATE_HIDDEN))
580 x = infoPtr->nIndent;
581 btnPtr[j].fsState |= TBSTATE_WRAP;
587 /* If no separator available for wrapping, wrap one of */
588 /* non-hidden previous button. */
592 j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
594 if (btnPtr[j].fsState & TBSTATE_HIDDEN)
599 x = infoPtr->nIndent;
600 btnPtr[j].fsState |= TBSTATE_WRAP;
606 /* If all above failed, wrap the current button. */
609 btnPtr[i].fsState |= TBSTATE_WRAP;
611 x = infoPtr->nIndent;
612 if (btnPtr[i].fsState & TBSTYLE_SEP )
624 /***********************************************************************
625 * TOOLBAR_CalcToolbar
627 * This function calculates button and separator placement. It first
628 * calculates the button sizes, gets the toolbar window width and then
629 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
630 * on. It assigns a new location to each item and sends this location to
631 * the tooltip window if appropriate. Finally, it updates the rcBound
632 * rect and calculates the new required toolbar window height.
636 TOOLBAR_CalcToolbar (HWND hwnd)
638 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
639 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
640 TBUTTON_INFO *btnPtr;
641 INT i, nRows, nSepRows;
645 BOOL usesBitmaps = FALSE;
647 TOOLBAR_CalcStrings (hwnd, &sizeString);
649 if (dwStyle & TBSTYLE_LIST)
651 infoPtr->nButtonHeight = max(infoPtr->nBitmapHeight, sizeString.cy) + 6;
652 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + sizeString.cx + 6;
655 for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
657 if (TOOLBAR_IsValidBitmapIndex(infoPtr,infoPtr->buttons[i].iBitmap))
661 if (sizeString.cy > 0)
664 infoPtr->nButtonHeight = sizeString.cy +
665 infoPtr->nBitmapHeight + 6;
667 infoPtr->nButtonHeight = sizeString.cy + 6;
669 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
670 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
672 if (sizeString.cx > infoPtr->nBitmapWidth)
673 infoPtr->nButtonWidth = sizeString.cx + 6;
674 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
675 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
678 if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin )
679 infoPtr->nButtonWidth = infoPtr->cxMin;
680 if ( infoPtr->cxMax >= 0 && infoPtr->nButtonWidth > infoPtr->cxMax )
681 infoPtr->nButtonWidth = infoPtr->cxMax;
683 TOOLBAR_WrapToolbar( hwnd, dwStyle );
685 x = infoPtr->nIndent;
686 y = (dwStyle & TBSTYLE_FLAT) ? 0 : TOP_BORDER;
689 * We will set the height below, and we set the width on entry
690 * so we do not reset them here..
693 GetClientRect( hwnd, &rc );
694 /* get initial values for toolbar */
695 infoPtr->nWidth = rc.right - rc.left;
696 infoPtr->nHeight = rc.bottom - rc.top;
699 /* from above, minimum is a button, and possible text */
700 cx = infoPtr->nButtonWidth;
702 /* cannot use just ButtonHeight, we may have no buttons! */
703 if (infoPtr->nNumButtons > 0)
704 infoPtr->nHeight = infoPtr->nButtonHeight;
706 cy = infoPtr->nHeight;
708 nRows = nSepRows = 0;
710 infoPtr->rcBound.top = y;
711 infoPtr->rcBound.left = x;
712 infoPtr->rcBound.bottom = y + cy;
713 infoPtr->rcBound.right = x;
715 btnPtr = infoPtr->buttons;
717 /* do not base height/width on parent, if the parent is a */
718 /* rebar control it could have multiple rows of toolbars */
719 /* GetClientRect( GetParent(hwnd), &rc ); */
720 /* cx = rc.right - rc.left; */
721 /* cy = rc.bottom - rc.top; */
723 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
726 if (btnPtr->fsState & TBSTATE_HIDDEN)
728 SetRectEmpty (&btnPtr->rect);
732 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
733 /* it is the actual width of the separator. This is used for */
734 /* custom controls in toolbars. */
735 if (btnPtr->fsStyle & TBSTYLE_SEP)
736 cx = (btnPtr->iBitmap > 0) ?
737 btnPtr->iBitmap : SEPARATOR_WIDTH;
740 if (btnPtr->fsStyle & TBSTYLE_AUTOSIZE)
743 TOOLBAR_MeasureString(hwnd,i,&sz);
747 cx = infoPtr->nButtonWidth;
749 cy = infoPtr->nHeight;
751 if (btnPtr->fsState & TBSTATE_WRAP )
754 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
756 if (infoPtr->rcBound.left > x)
757 infoPtr->rcBound.left = x;
758 if (infoPtr->rcBound.right < x + cx)
759 infoPtr->rcBound.right = x + cx;
760 if (infoPtr->rcBound.bottom < y + cy)
761 infoPtr->rcBound.bottom = y + cy;
763 /* Set the toolTip only for non-hidden, non-separator button */
764 if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP ))
768 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
769 ti.cbSize = sizeof(TTTOOLINFOA);
771 ti.uId = btnPtr->idCommand;
772 ti.rect = btnPtr->rect;
773 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
777 /* btnPtr->nRow is zero based. The space between the rows is */
778 /* also considered as a row. */
779 btnPtr->nRow = nRows + nSepRows;
782 if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
786 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
787 /* it is the actual width of the separator. This is used for */
788 /* custom controls in toolbars. */
789 y += cy + ( (btnPtr->iBitmap > 0 ) ?
790 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
792 /* nSepRows is used to calculate the extra height follwoing */
796 x = infoPtr->nIndent;
803 /* infoPtr->nRows is the number of rows on the toolbar */
804 infoPtr->nRows = nRows + nSepRows + 1;
806 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
808 infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
809 nSepRows * (SEPARATOR_WIDTH * 2 / 3) +
810 nSepRows * (infoPtr->nBitmapHeight + 1) +
812 TRACE("toolbar height %d\n", infoPtr->nHeight);
817 TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
819 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
820 TBUTTON_INFO *btnPtr;
823 btnPtr = infoPtr->buttons;
824 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
825 if (btnPtr->fsState & TBSTATE_HIDDEN)
828 if (btnPtr->fsStyle & TBSTYLE_SEP) {
829 if (PtInRect (&btnPtr->rect, *lpPt)) {
830 TRACE(" ON SEPARATOR %d!\n", i);
835 if (PtInRect (&btnPtr->rect, *lpPt)) {
836 TRACE(" ON BUTTON %d!\n", i);
842 TRACE(" NOWHERE!\n");
848 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
850 TBUTTON_INFO *btnPtr;
853 btnPtr = infoPtr->buttons;
854 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
855 if (btnPtr->idCommand == idCommand) {
856 TRACE("command=%d index=%d\n", idCommand, i);
860 TRACE("no index found for command=%d\n", idCommand);
866 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
868 TBUTTON_INFO *btnPtr;
871 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
874 /* check index button */
875 btnPtr = &infoPtr->buttons[nIndex];
876 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
877 if (btnPtr->fsState & TBSTATE_CHECKED)
881 /* check previous buttons */
882 nRunIndex = nIndex - 1;
883 while (nRunIndex >= 0) {
884 btnPtr = &infoPtr->buttons[nRunIndex];
885 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
886 if (btnPtr->fsState & TBSTATE_CHECKED)
894 /* check next buttons */
895 nRunIndex = nIndex + 1;
896 while (nRunIndex < infoPtr->nNumButtons) {
897 btnPtr = &infoPtr->buttons[nRunIndex];
898 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
899 if (btnPtr->fsState & TBSTATE_CHECKED)
912 TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
913 WPARAM wParam, LPARAM lParam)
921 msg.time = GetMessageTime ();
922 msg.pt.x = LOWORD(GetMessagePos ());
923 msg.pt.y = HIWORD(GetMessagePos ());
925 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
929 /***********************************************************************
930 * TOOLBAR_CustomizeDialogProc
931 * This function implements the toolbar customization dialog.
934 TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
936 TOOLBAR_INFO *infoPtr = (TOOLBAR_INFO *)GetWindowLongA (hwnd, DWL_USER);
937 static HDSA hDsa = NULL;
942 infoPtr = (TOOLBAR_INFO *)lParam;
943 SetWindowLongA (hwnd, DWL_USER, (DWORD)infoPtr);
945 hDsa = DSA_Create (sizeof(TBUTTON_INFO), 5);
949 TBUTTON_INFO *btnPtr;
952 /* insert 'virtual' separator button into 'available buttons' list */
953 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
955 /* copy all buttons and append them to the right listbox */
956 btnPtr = infoPtr->buttons;
957 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
959 DSA_InsertItem (hDsa, i, btnPtr);
961 /* FIXME: hidden buttons appear in the 'toolbar buttons' list too */
962 if (btnPtr->fsState & TBSTATE_HIDDEN)
964 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
968 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
972 /* append 'virtual' separator button to the 'toolbar buttons' list */
978 EndDialog(hwnd, FALSE);
982 switch (LOWORD(wParam))
985 EndDialog(hwnd, FALSE);
996 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
998 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
1004 COLORREF oldText = 0;
1007 FIXME("action: %x itemState: %x\n",
1008 lpdis->itemAction, lpdis->itemState);
1010 DSA_GetItem (hDsa, 0 /*lpdis->itemID*/, &btnPtr);
1012 if (lpdis->itemState & ODS_FOCUS)
1014 oldBk = SetBkColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
1015 oldText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
1018 hOldPen = SelectObject (lpdis->hDC, GetSysColorPen ((lpdis->itemState & ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1019 hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1021 /* fill background rectangle */
1022 Rectangle (lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
1023 lpdis->rcItem.right, lpdis->rcItem.bottom);
1025 /* calculate button and text rectangles */
1026 CopyRect (&rcButton, &lpdis->rcItem);
1027 InflateRect (&rcButton, -1, -1);
1028 CopyRect (&rcText, &rcButton);
1029 rcButton.right = rcButton.left + infoPtr->nBitmapWidth + 6;
1030 rcText.left = rcButton.right + 2;
1032 /* draw focus rectangle */
1033 if (lpdis->itemState & ODS_FOCUS)
1034 DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
1037 DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
1039 /* draw image and text */
1040 if (wParam == IDC_AVAILBTN_LBOX && lpdis->itemID == 0)
1042 /* virtual separator in the 'available' list */
1043 DrawTextA (lpdis->hDC, "Separator", -1, &rcText,
1044 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1050 ImageList_Draw (infoPtr->himlDef, btnPtr.iBitmap, lpdis->hDC,
1051 rcButton.left+1, rcButton.top+1, ILD_NORMAL);
1053 DrawTextW (lpdis->hDC, infoPtr->strings[btnPtr.iString], -1, &rcText,
1054 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1058 if (lpdis->itemState & ODS_FOCUS)
1060 SetBkColor (lpdis->hDC, oldBk);
1061 SetTextColor (lpdis->hDC, oldText);
1064 SelectObject (lpdis->hDC, hOldBrush);
1065 SelectObject (lpdis->hDC, hOldPen);
1071 case WM_MEASUREITEM:
1072 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1074 MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*)lParam;
1077 lpmis->itemHeight = infoPtr->nBitmapHeight + 8;
1079 lpmis->itemHeight = 15 + 8; /* default height */
1091 /***********************************************************************
1092 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1096 TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1098 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1099 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
1100 INT nIndex = 0, nButtons, nCount;
1103 TRACE("hwnd=%x wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
1107 if (lpAddBmp->hInst == HINST_COMMCTRL)
1109 if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR)
1111 else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR)
1113 else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR)
1118 TRACE ("adding %d internal bitmaps!\n", nButtons);
1120 /* Windows resize all the buttons to the size of a newly added standard image */
1121 if (lpAddBmp->nID & 1)
1124 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1125 MAKELPARAM((WORD)26, (WORD)26));
1126 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1127 MAKELPARAM((WORD)33, (WORD)33));
1132 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1133 MAKELPARAM((WORD)16, (WORD)16));
1134 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1135 MAKELPARAM((WORD)22, (WORD)22));
1138 TOOLBAR_CalcToolbar (hwnd);
1142 nButtons = (INT)wParam;
1146 TRACE ("adding %d bitmaps!\n", nButtons);
1149 if (!(infoPtr->himlDef)) {
1150 /* create new default image list */
1151 TRACE ("creating default image list!\n");
1154 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
1155 ILC_COLOR | ILC_MASK, nButtons, 2);
1156 infoPtr->himlInt = infoPtr->himlDef;
1159 nCount = ImageList_GetImageCount(infoPtr->himlDef);
1161 /* Add bitmaps to the default image list */
1162 if (lpAddBmp->hInst == (HINSTANCE)0)
1165 ImageList_AddMasked (infoPtr->himlDef, (HBITMAP)lpAddBmp->nID,
1168 else if (lpAddBmp->hInst == HINST_COMMCTRL)
1170 /* Add system bitmaps */
1171 switch (lpAddBmp->nID)
1173 case IDB_STD_SMALL_COLOR:
1174 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1175 MAKEINTRESOURCEA(IDB_STD_SMALL));
1176 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1177 hbmLoad, CLR_DEFAULT);
1178 DeleteObject (hbmLoad);
1181 case IDB_STD_LARGE_COLOR:
1182 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1183 MAKEINTRESOURCEA(IDB_STD_LARGE));
1184 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1185 hbmLoad, CLR_DEFAULT);
1186 DeleteObject (hbmLoad);
1189 case IDB_VIEW_SMALL_COLOR:
1190 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1191 MAKEINTRESOURCEA(IDB_VIEW_SMALL));
1192 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1193 hbmLoad, CLR_DEFAULT);
1194 DeleteObject (hbmLoad);
1197 case IDB_VIEW_LARGE_COLOR:
1198 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1199 MAKEINTRESOURCEA(IDB_VIEW_LARGE));
1200 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1201 hbmLoad, CLR_DEFAULT);
1202 DeleteObject (hbmLoad);
1205 case IDB_HIST_SMALL_COLOR:
1206 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1207 MAKEINTRESOURCEA(IDB_HIST_SMALL));
1208 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1209 hbmLoad, CLR_DEFAULT);
1210 DeleteObject (hbmLoad);
1213 case IDB_HIST_LARGE_COLOR:
1214 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1215 MAKEINTRESOURCEA(IDB_HIST_LARGE));
1216 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1217 hbmLoad, CLR_DEFAULT);
1218 DeleteObject (hbmLoad);
1222 nIndex = ImageList_GetImageCount (infoPtr->himlDef);
1223 ERR ("invalid imagelist!\n");
1229 hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
1230 nIndex = ImageList_AddMasked (infoPtr->himlDef, hbmLoad, CLR_DEFAULT);
1231 DeleteObject (hbmLoad);
1236 INT imagecount = ImageList_GetImageCount(infoPtr->himlDef);
1238 if (infoPtr->nNumBitmaps + nButtons != imagecount)
1240 WARN("Desired images do not match recieved images : Previous image number %i Previous images in list %i added %i expecting total %i, Images in list %i\n",
1241 infoPtr->nNumBitmaps, nCount, imagecount - nCount,
1242 infoPtr->nNumBitmaps+nButtons,imagecount);
1244 infoPtr->nNumBitmaps = imagecount;
1247 infoPtr->nNumBitmaps += nButtons;
1255 TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1257 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1258 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1259 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1261 TRACE("adding %d buttons!\n", wParam);
1263 nAddButtons = (UINT)wParam;
1264 nOldButtons = infoPtr->nNumButtons;
1265 nNewButtons = nOldButtons + nAddButtons;
1267 if (infoPtr->nNumButtons == 0) {
1269 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1272 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1274 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1275 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1276 nOldButtons * sizeof(TBUTTON_INFO));
1277 COMCTL32_Free (oldButtons);
1280 infoPtr->nNumButtons = nNewButtons;
1282 /* insert new button data */
1283 for (nCount = 0; nCount < nAddButtons; nCount++) {
1284 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1285 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1286 btnPtr->idCommand = lpTbb[nCount].idCommand;
1287 btnPtr->fsState = lpTbb[nCount].fsState;
1288 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1289 btnPtr->dwData = lpTbb[nCount].dwData;
1290 btnPtr->iString = lpTbb[nCount].iString;
1291 btnPtr->bHot = FALSE;
1293 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1296 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1297 ti.cbSize = sizeof (TTTOOLINFOA);
1299 ti.uId = btnPtr->idCommand;
1301 ti.lpszText = LPSTR_TEXTCALLBACKA;
1303 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
1308 TOOLBAR_CalcToolbar (hwnd);
1310 InvalidateRect(hwnd, NULL, FALSE);
1317 TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1319 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1320 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1321 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1323 TRACE("adding %d buttons!\n", wParam);
1325 nAddButtons = (UINT)wParam;
1326 nOldButtons = infoPtr->nNumButtons;
1327 nNewButtons = nOldButtons + nAddButtons;
1329 if (infoPtr->nNumButtons == 0) {
1331 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1334 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1336 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1337 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1338 nOldButtons * sizeof(TBUTTON_INFO));
1339 COMCTL32_Free (oldButtons);
1342 infoPtr->nNumButtons = nNewButtons;
1344 /* insert new button data */
1345 for (nCount = 0; nCount < nAddButtons; nCount++) {
1346 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1347 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1348 btnPtr->idCommand = lpTbb[nCount].idCommand;
1349 btnPtr->fsState = lpTbb[nCount].fsState;
1350 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1351 btnPtr->dwData = lpTbb[nCount].dwData;
1352 btnPtr->iString = lpTbb[nCount].iString;
1353 btnPtr->bHot = FALSE;
1355 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1358 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
1359 ti.cbSize = sizeof (TTTOOLINFOW);
1361 ti.uId = btnPtr->idCommand;
1363 ti.lpszText = LPSTR_TEXTCALLBACKW;
1365 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
1370 TOOLBAR_CalcToolbar (hwnd);
1372 InvalidateRect(hwnd, NULL, FALSE);
1379 TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1381 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1384 if ((wParam) && (HIWORD(lParam) == 0)) {
1387 TRACE("adding string from resource!\n");
1389 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
1392 TRACE("len=%d \"%s\"\n", len, szString);
1393 nIndex = infoPtr->nNumStrings;
1394 if (infoPtr->nNumStrings == 0) {
1396 COMCTL32_Alloc (sizeof(LPWSTR));
1399 LPWSTR *oldStrings = infoPtr->strings;
1401 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1402 memcpy (&infoPtr->strings[0], &oldStrings[0],
1403 sizeof(LPWSTR) * infoPtr->nNumStrings);
1404 COMCTL32_Free (oldStrings);
1407 infoPtr->strings[infoPtr->nNumStrings] =
1408 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1409 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
1410 infoPtr->nNumStrings++;
1413 LPSTR p = (LPSTR)lParam;
1418 TRACE("adding string(s) from array!\n");
1420 nIndex = infoPtr->nNumStrings;
1423 TRACE("len=%d \"%s\"\n", len, p);
1425 if (infoPtr->nNumStrings == 0) {
1427 COMCTL32_Alloc (sizeof(LPWSTR));
1430 LPWSTR *oldStrings = infoPtr->strings;
1432 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1433 memcpy (&infoPtr->strings[0], &oldStrings[0],
1434 sizeof(LPWSTR) * infoPtr->nNumStrings);
1435 COMCTL32_Free (oldStrings);
1438 infoPtr->strings[infoPtr->nNumStrings] =
1439 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1440 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
1441 infoPtr->nNumStrings++;
1452 TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1454 #define MAX_RESOURCE_STRING_LENGTH 512
1455 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1458 if ((wParam) && (HIWORD(lParam) == 0)) {
1459 WCHAR szString[MAX_RESOURCE_STRING_LENGTH];
1461 TRACE("adding string from resource!\n");
1463 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
1464 szString, MAX_RESOURCE_STRING_LENGTH);
1466 TRACE("len=%d \"%s\"\n", len, debugstr_w(szString));
1467 TRACE("First char: 0x%x\n", *szString);
1468 if (szString[0] == L'|')
1470 PWSTR p = szString + 1;
1472 nIndex = infoPtr->nNumStrings;
1473 while (*p != L'|') {
1475 if (infoPtr->nNumStrings == 0) {
1477 COMCTL32_Alloc (sizeof(LPWSTR));
1480 LPWSTR *oldStrings = infoPtr->strings;
1482 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1483 memcpy (&infoPtr->strings[0], &oldStrings[0],
1484 sizeof(LPWSTR) * infoPtr->nNumStrings);
1485 COMCTL32_Free (oldStrings);
1488 len = COMCTL32_StrChrW (p, L'|') - p;
1489 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1490 infoPtr->strings[infoPtr->nNumStrings] =
1491 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1492 lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len);
1493 infoPtr->nNumStrings++;
1500 nIndex = infoPtr->nNumStrings;
1501 if (infoPtr->nNumStrings == 0) {
1503 COMCTL32_Alloc (sizeof(LPWSTR));
1506 LPWSTR *oldStrings = infoPtr->strings;
1508 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1509 memcpy (&infoPtr->strings[0], &oldStrings[0],
1510 sizeof(LPWSTR) * infoPtr->nNumStrings);
1511 COMCTL32_Free (oldStrings);
1514 infoPtr->strings[infoPtr->nNumStrings] =
1515 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1516 strcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
1517 infoPtr->nNumStrings++;
1521 LPWSTR p = (LPWSTR)lParam;
1526 TRACE("adding string(s) from array!\n");
1527 nIndex = infoPtr->nNumStrings;
1531 TRACE("len=%d \"%s\"\n", len, debugstr_w(p));
1532 if (infoPtr->nNumStrings == 0) {
1534 COMCTL32_Alloc (sizeof(LPWSTR));
1537 LPWSTR *oldStrings = infoPtr->strings;
1539 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1540 memcpy (&infoPtr->strings[0], &oldStrings[0],
1541 sizeof(LPWSTR) * infoPtr->nNumStrings);
1542 COMCTL32_Free (oldStrings);
1545 infoPtr->strings[infoPtr->nNumStrings] =
1546 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1547 strcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1548 infoPtr->nNumStrings++;
1559 TOOLBAR_AutoSize (HWND hwnd)
1561 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1562 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1568 UINT uPosFlags = SWP_NOZORDER;
1570 TRACE("resize forced, style=%lx!\n", dwStyle);
1572 parent = GetParent (hwnd);
1573 GetClientRect(parent, &parent_rect);
1575 x = parent_rect.left;
1576 y = parent_rect.top;
1578 /* FIXME: we should be able to early out if nothing */
1579 /* has changed with nWidth != parent_rect width */
1581 if (dwStyle & CCS_NORESIZE) {
1582 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
1587 infoPtr->nWidth = parent_rect.right - parent_rect.left;
1588 TOOLBAR_CalcToolbar (hwnd);
1589 InvalidateRect( hwnd, NULL, TRUE );
1590 cy = infoPtr->nHeight;
1591 cx = infoPtr->nWidth;
1593 if (dwStyle & CCS_NOMOVEY) {
1594 GetWindowRect(hwnd, &window_rect);
1595 ScreenToClient(parent, (LPPOINT)&window_rect.left);
1596 y = window_rect.top;
1600 if (dwStyle & CCS_NOPARENTALIGN)
1601 uPosFlags |= SWP_NOMOVE;
1603 if (!(dwStyle & CCS_NODIVIDER))
1604 cy += GetSystemMetrics(SM_CYEDGE);
1606 if (dwStyle & WS_BORDER)
1609 cy += GetSystemMetrics(SM_CYEDGE);
1610 cx += GetSystemMetrics(SM_CYEDGE);
1613 infoPtr->bAutoSize = TRUE;
1614 SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
1616 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
1617 * the setwindowpos calls */
1618 infoPtr->bAutoSize = FALSE;
1625 TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
1627 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1629 return infoPtr->nNumButtons;
1634 TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1636 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1638 if (infoPtr == NULL) {
1639 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
1640 ERR("infoPtr == NULL!\n");
1644 infoPtr->dwStructSize = (DWORD)wParam;
1651 TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1653 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1654 TBUTTON_INFO *btnPtr;
1657 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1661 btnPtr = &infoPtr->buttons[nIndex];
1662 btnPtr->iBitmap = LOWORD(lParam);
1664 /* we HAVE to erase the background, the new bitmap could be */
1666 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
1673 TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1675 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1676 TBUTTON_INFO *btnPtr;
1679 BOOL bChecked = FALSE;
1681 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1685 btnPtr = &infoPtr->buttons[nIndex];
1687 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
1690 bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
1692 if (LOWORD(lParam) == FALSE)
1693 btnPtr->fsState &= ~TBSTATE_CHECKED;
1695 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
1697 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
1698 if (nOldIndex == nIndex)
1700 if (nOldIndex != -1)
1701 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
1703 btnPtr->fsState |= TBSTATE_CHECKED;
1706 if( bChecked != LOWORD(lParam) )
1708 if (nOldIndex != -1)
1710 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
1711 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
1713 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
1716 /* FIXME: Send a WM_NOTIFY?? */
1723 TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
1725 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1727 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1732 TOOLBAR_Customize (HWND hwnd)
1734 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1740 /* send TBN_BEGINADJUST notification */
1741 nmhdr.hwndFrom = hwnd;
1742 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1743 nmhdr.code = TBN_BEGINADJUST;
1745 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1746 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1748 if (!(hRes = FindResourceA (COMCTL32_hModule,
1749 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
1753 if(!(template = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
1756 ret = DialogBoxIndirectParamA (GetWindowLongA (hwnd, GWL_HINSTANCE),
1757 (LPDLGTEMPLATEA)template,
1759 (DLGPROC)TOOLBAR_CustomizeDialogProc,
1762 /* send TBN_ENDADJUST notification */
1763 nmhdr.code = TBN_ENDADJUST;
1765 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1766 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1773 TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1775 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1776 INT nIndex = (INT)wParam;
1778 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1781 if ((infoPtr->hwndToolTip) &&
1782 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
1785 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1786 ti.cbSize = sizeof (TTTOOLINFOA);
1788 ti.uId = infoPtr->buttons[nIndex].idCommand;
1790 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
1793 if (infoPtr->nNumButtons == 1) {
1794 TRACE(" simple delete!\n");
1795 COMCTL32_Free (infoPtr->buttons);
1796 infoPtr->buttons = NULL;
1797 infoPtr->nNumButtons = 0;
1800 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1801 TRACE("complex delete! [nIndex=%d]\n", nIndex);
1803 infoPtr->nNumButtons--;
1804 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
1806 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1807 nIndex * sizeof(TBUTTON_INFO));
1810 if (nIndex < infoPtr->nNumButtons) {
1811 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
1812 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
1815 COMCTL32_Free (oldButtons);
1818 TOOLBAR_CalcToolbar (hwnd);
1820 InvalidateRect (hwnd, NULL, TRUE);
1827 TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1829 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1830 TBUTTON_INFO *btnPtr;
1834 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1838 btnPtr = &infoPtr->buttons[nIndex];
1840 bState = btnPtr->fsState & TBSTATE_ENABLED;
1842 /* update the toolbar button state */
1843 if(LOWORD(lParam) == FALSE) {
1844 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
1846 btnPtr->fsState |= TBSTATE_ENABLED;
1849 /* redraw the button only if the state of the button changed */
1850 if(bState != (btnPtr->fsState & TBSTATE_ENABLED))
1852 InvalidateRect(hwnd, &btnPtr->rect,
1853 TOOLBAR_HasText(infoPtr, btnPtr));
1860 static inline LRESULT
1861 TOOLBAR_GetAnchorHighlight (HWND hwnd)
1863 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1865 return infoPtr->bAnchor;
1870 TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1872 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1875 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1879 return infoPtr->buttons[nIndex].iBitmap;
1883 static inline LRESULT
1884 TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
1886 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
1891 TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1893 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1894 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1895 INT nIndex = (INT)wParam;
1896 TBUTTON_INFO *btnPtr;
1898 if (infoPtr == NULL)
1904 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1907 btnPtr = &infoPtr->buttons[nIndex];
1908 lpTbb->iBitmap = btnPtr->iBitmap;
1909 lpTbb->idCommand = btnPtr->idCommand;
1910 lpTbb->fsState = btnPtr->fsState;
1911 lpTbb->fsStyle = btnPtr->fsStyle;
1912 lpTbb->dwData = btnPtr->dwData;
1913 lpTbb->iString = btnPtr->iString;
1920 TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1922 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1923 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
1924 TBUTTON_INFO *btnPtr;
1927 if (infoPtr == NULL)
1929 if (lpTbInfo == NULL)
1931 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOA))
1934 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1938 btnPtr = &infoPtr->buttons[nIndex];
1940 if (lpTbInfo->dwMask & TBIF_COMMAND)
1941 lpTbInfo->idCommand = btnPtr->idCommand;
1942 if (lpTbInfo->dwMask & TBIF_IMAGE)
1943 lpTbInfo->iImage = btnPtr->iBitmap;
1944 if (lpTbInfo->dwMask & TBIF_LPARAM)
1945 lpTbInfo->lParam = btnPtr->dwData;
1946 if (lpTbInfo->dwMask & TBIF_SIZE)
1947 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1948 if (lpTbInfo->dwMask & TBIF_STATE)
1949 lpTbInfo->fsState = btnPtr->fsState;
1950 if (lpTbInfo->dwMask & TBIF_STYLE)
1951 lpTbInfo->fsStyle = btnPtr->fsStyle;
1952 if (lpTbInfo->dwMask & TBIF_TEXT) {
1953 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
1955 lstrcpynWtoA (lpTbInfo->pszText,
1956 (LPWSTR)infoPtr->strings[btnPtr->iString],
1959 else lpTbInfo->pszText[0]=0;
1966 TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1968 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1969 LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
1970 TBUTTON_INFO *btnPtr;
1973 if (infoPtr == NULL)
1975 if (lpTbInfo == NULL)
1977 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
1980 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1984 btnPtr = &infoPtr->buttons[nIndex];
1986 if (lpTbInfo->dwMask & TBIF_COMMAND)
1987 lpTbInfo->idCommand = btnPtr->idCommand;
1988 if (lpTbInfo->dwMask & TBIF_IMAGE)
1989 lpTbInfo->iImage = btnPtr->iBitmap;
1990 if (lpTbInfo->dwMask & TBIF_LPARAM)
1991 lpTbInfo->lParam = btnPtr->dwData;
1992 if (lpTbInfo->dwMask & TBIF_SIZE)
1993 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1994 if (lpTbInfo->dwMask & TBIF_STATE)
1995 lpTbInfo->fsState = btnPtr->fsState;
1996 if (lpTbInfo->dwMask & TBIF_STYLE)
1997 lpTbInfo->fsStyle = btnPtr->fsStyle;
1998 if (lpTbInfo->dwMask & TBIF_TEXT) {
1999 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
2000 lstrcpynW (lpTbInfo->pszText,
2001 (LPWSTR)infoPtr->strings[btnPtr->iString],
2010 TOOLBAR_GetButtonSize (HWND hwnd)
2012 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2014 return MAKELONG((WORD)infoPtr->nButtonWidth,
2015 (WORD)infoPtr->nButtonHeight);
2020 TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2022 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2023 INT nIndex, nStringIndex;
2025 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2029 nStringIndex = infoPtr->buttons[nIndex].iString;
2031 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
2033 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2039 lstrcpyWtoA ((LPSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
2041 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
2046 TOOLBAR_GetButtonTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2048 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2049 INT nIndex, nStringIndex;
2051 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2055 nStringIndex = infoPtr->buttons[nIndex].iString;
2057 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
2059 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2065 strcpyW ((LPWSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
2067 return lstrlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
2071 /* << TOOLBAR_GetColorScheme >> */
2075 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2077 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2079 return (LRESULT)infoPtr->himlDis;
2083 inline static LRESULT
2084 TOOLBAR_GetExtendedStyle (HWND hwnd)
2086 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2088 return infoPtr->dwExStyle;
2093 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2095 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2097 return (LRESULT)infoPtr->himlHot;
2102 TOOLBAR_GetHotItem (HWND hwnd)
2104 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2106 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2109 if (infoPtr->nHotItem < 0)
2112 return (LRESULT)infoPtr->nHotItem;
2117 TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2119 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2121 return (LRESULT)infoPtr->himlDef;
2125 /* << TOOLBAR_GetInsertMark >> */
2126 /* << TOOLBAR_GetInsertMarkColor >> */
2130 TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2132 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2133 TBUTTON_INFO *btnPtr;
2139 if (infoPtr == NULL)
2141 nIndex = (INT)wParam;
2142 btnPtr = &infoPtr->buttons[nIndex];
2143 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2145 lpRect = (LPRECT)lParam;
2148 if (btnPtr->fsState & TBSTATE_HIDDEN)
2151 lpRect->left = btnPtr->rect.left;
2152 lpRect->right = btnPtr->rect.right;
2153 lpRect->bottom = btnPtr->rect.bottom;
2154 lpRect->top = btnPtr->rect.top;
2161 TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2163 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2164 LPSIZE lpSize = (LPSIZE)lParam;
2169 lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
2170 lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
2172 TRACE("maximum size %d x %d\n",
2173 infoPtr->rcBound.right - infoPtr->rcBound.left,
2174 infoPtr->rcBound.bottom - infoPtr->rcBound.top);
2180 /* << TOOLBAR_GetObject >> */
2181 /* << TOOLBAR_GetPadding >> */
2185 TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2187 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2188 TBUTTON_INFO *btnPtr;
2192 if (infoPtr == NULL)
2194 nIndex = (INT)wParam;
2195 btnPtr = &infoPtr->buttons[nIndex];
2196 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2198 lpRect = (LPRECT)lParam;
2202 lpRect->left = btnPtr->rect.left;
2203 lpRect->right = btnPtr->rect.right;
2204 lpRect->bottom = btnPtr->rect.bottom;
2205 lpRect->top = btnPtr->rect.top;
2212 TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2214 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2216 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
2217 return infoPtr->nRows;
2224 TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2226 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2229 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2233 return infoPtr->buttons[nIndex].fsState;
2238 TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2240 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2243 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2247 return infoPtr->buttons[nIndex].fsStyle;
2252 TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2254 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2256 if (infoPtr == NULL)
2259 return infoPtr->nMaxTextRows;
2264 TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
2266 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2268 if (infoPtr == NULL)
2270 return infoPtr->hwndToolTip;
2275 TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2277 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2279 TRACE("%s hwnd=0x%x stub!\n",
2280 infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
2282 return infoPtr->bUnicode;
2286 inline static LRESULT
2287 TOOLBAR_GetVersion (HWND hwnd)
2289 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2290 return infoPtr->iVersion;
2295 TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2297 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2298 TBUTTON_INFO *btnPtr;
2303 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2307 btnPtr = &infoPtr->buttons[nIndex];
2308 if (LOWORD(lParam) == FALSE)
2309 btnPtr->fsState &= ~TBSTATE_HIDDEN;
2311 btnPtr->fsState |= TBSTATE_HIDDEN;
2313 TOOLBAR_CalcToolbar (hwnd);
2315 InvalidateRect (hwnd, NULL, TRUE);
2321 inline static LRESULT
2322 TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2324 return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
2329 TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2331 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2332 TBUTTON_INFO *btnPtr;
2335 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2339 btnPtr = &infoPtr->buttons[nIndex];
2340 if (LOWORD(lParam) == FALSE)
2341 btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
2343 btnPtr->fsState |= TBSTATE_INDETERMINATE;
2345 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
2352 TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2354 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2355 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2356 INT nIndex = (INT)wParam;
2357 TBUTTON_INFO *oldButtons;
2363 /* EPP: this seems to be an undocumented call (from my IE4)
2364 * I assume in that case that:
2365 * - lpTbb->iString is a string pointer (not a string index in strings[] table
2366 * - index of insertion is at the end of existing buttons
2367 * I only see this happen with nIndex == -1, but it could have a special
2368 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
2373 if(lpTbb->iString) {
2374 len = lstrlenA((char*)lpTbb->iString) + 2;
2375 ptr = COMCTL32_Alloc(len);
2376 nIndex = infoPtr->nNumButtons;
2377 strcpy(ptr, (char*)lpTbb->iString);
2378 ptr[len - 1] = 0; /* ended by two '\0' */
2379 lpTbb->iString = TOOLBAR_AddStringA(hwnd, 0, (LPARAM)ptr);
2383 ERR("lpTbb->iString is NULL\n");
2387 } else if (nIndex < 0)
2390 TRACE("inserting button index=%d\n", nIndex);
2391 if (nIndex > infoPtr->nNumButtons) {
2392 nIndex = infoPtr->nNumButtons;
2393 TRACE("adjust index=%d\n", nIndex);
2396 oldButtons = infoPtr->buttons;
2397 infoPtr->nNumButtons++;
2398 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2399 /* pre insert copy */
2401 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2402 nIndex * sizeof(TBUTTON_INFO));
2405 /* insert new button */
2406 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2407 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2408 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2409 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2410 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2411 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2413 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2416 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2417 ti.cbSize = sizeof (TTTOOLINFOA);
2419 ti.uId = lpTbb->idCommand;
2421 ti.lpszText = LPSTR_TEXTCALLBACKA;
2423 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
2427 /* post insert copy */
2428 if (nIndex < infoPtr->nNumButtons - 1) {
2429 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2430 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2433 COMCTL32_Free (oldButtons);
2435 TOOLBAR_CalcToolbar (hwnd);
2437 InvalidateRect (hwnd, NULL, FALSE);
2444 TOOLBAR_InsertButtonW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2446 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2447 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2448 INT nIndex = (INT)wParam;
2449 TBUTTON_INFO *oldButtons;
2456 TRACE("inserting button index=%d\n", nIndex);
2457 if (nIndex > infoPtr->nNumButtons) {
2458 nIndex = infoPtr->nNumButtons;
2459 TRACE("adjust index=%d\n", nIndex);
2462 oldButtons = infoPtr->buttons;
2463 infoPtr->nNumButtons++;
2464 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2465 /* pre insert copy */
2467 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2468 nIndex * sizeof(TBUTTON_INFO));
2471 /* insert new button */
2472 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2473 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2474 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2475 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2476 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2477 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2479 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2482 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
2483 ti.cbSize = sizeof (TTTOOLINFOW);
2485 ti.uId = lpTbb->idCommand;
2487 ti.lpszText = LPSTR_TEXTCALLBACKW;
2489 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
2493 /* post insert copy */
2494 if (nIndex < infoPtr->nNumButtons - 1) {
2495 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2496 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2499 COMCTL32_Free (oldButtons);
2501 TOOLBAR_CalcToolbar (hwnd);
2503 InvalidateRect (hwnd, NULL, FALSE);
2509 /* << TOOLBAR_InsertMarkHitTest >> */
2513 TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
2515 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2518 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2522 return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
2527 TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
2529 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2532 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2536 return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
2541 TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
2543 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2546 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2550 return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
2555 TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
2557 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2560 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2564 return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
2569 TOOLBAR_IsButtonIndeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2571 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2574 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2578 return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
2583 TOOLBAR_IsButtonPressed (HWND hwnd, WPARAM wParam, LPARAM lParam)
2585 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2588 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2592 return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
2596 /* << TOOLBAR_LoadImages >> */
2597 /* << TOOLBAR_MapAccelerator >> */
2598 /* << TOOLBAR_MarkButton >> */
2599 /* << TOOLBAR_MoveButton >> */
2603 TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2605 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2606 TBUTTON_INFO *btnPtr;
2609 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2613 btnPtr = &infoPtr->buttons[nIndex];
2614 if (LOWORD(lParam) == FALSE)
2615 btnPtr->fsState &= ~TBSTATE_PRESSED;
2617 btnPtr->fsState |= TBSTATE_PRESSED;
2619 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
2625 /* << TOOLBAR_ReplaceBitmap >> */
2629 TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2632 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2633 LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
2635 if (lpSave == NULL) return 0;
2638 /* save toolbar information */
2639 FIXME("save to \"%s\" \"%s\"\n",
2640 lpSave->pszSubKey, lpSave->pszValueName);
2645 /* restore toolbar information */
2647 FIXME("restore from \"%s\" \"%s\"\n",
2648 lpSave->pszSubKey, lpSave->pszValueName);
2659 TOOLBAR_SaveRestoreW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2662 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2663 LPTBSAVEPARAMSW lpSave = (LPTBSAVEPARAMSW)lParam;
2669 /* save toolbar information */
2670 FIXME("save to \"%s\" \"%s\"\n",
2671 lpSave->pszSubKey, lpSave->pszValueName);
2676 /* restore toolbar information */
2678 FIXME("restore from \"%s\" \"%s\"\n",
2679 lpSave->pszSubKey, lpSave->pszValueName);
2690 TOOLBAR_SetAnchorHighlight (HWND hwnd, WPARAM wParam)
2692 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2693 BOOL bOldAnchor = infoPtr->bAnchor;
2695 infoPtr->bAnchor = (BOOL)wParam;
2697 return (LRESULT)bOldAnchor;
2702 TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2704 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2706 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
2709 if (infoPtr->nNumButtons > 0)
2710 WARN("%d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n",
2711 infoPtr->nNumButtons,
2712 infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
2713 LOWORD(lParam), HIWORD(lParam));
2715 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
2716 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
2718 /* uses image list internals directly */
2719 if (infoPtr->himlDef) {
2720 infoPtr->himlDef->cx = infoPtr->nBitmapWidth;
2721 infoPtr->himlDef->cy = infoPtr->nBitmapHeight;
2729 TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2731 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2732 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
2733 TBUTTON_INFO *btnPtr;
2738 if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
2741 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2745 btnPtr = &infoPtr->buttons[nIndex];
2746 if (lptbbi->dwMask & TBIF_COMMAND)
2747 btnPtr->idCommand = lptbbi->idCommand;
2748 if (lptbbi->dwMask & TBIF_IMAGE)
2749 btnPtr->iBitmap = lptbbi->iImage;
2750 if (lptbbi->dwMask & TBIF_LPARAM)
2751 btnPtr->dwData = lptbbi->lParam;
2752 /* if (lptbbi->dwMask & TBIF_SIZE) */
2753 /* btnPtr->cx = lptbbi->cx; */
2754 if (lptbbi->dwMask & TBIF_STATE)
2755 btnPtr->fsState = lptbbi->fsState;
2756 if (lptbbi->dwMask & TBIF_STYLE)
2757 btnPtr->fsStyle = lptbbi->fsStyle;
2759 if (lptbbi->dwMask & TBIF_TEXT) {
2760 if ((btnPtr->iString >= 0) ||
2761 (btnPtr->iString < infoPtr->nNumStrings)) {
2762 TRACE("Ooooooch\n");
2764 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2765 INT len = lstrlenA (lptbbi->pszText);
2766 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
2769 /* this is the ultimate sollution */
2770 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2779 TOOLBAR_SetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2781 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2782 LPTBBUTTONINFOW lptbbi = (LPTBBUTTONINFOW)lParam;
2783 TBUTTON_INFO *btnPtr;
2788 if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
2791 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2795 btnPtr = &infoPtr->buttons[nIndex];
2796 if (lptbbi->dwMask & TBIF_COMMAND)
2797 btnPtr->idCommand = lptbbi->idCommand;
2798 if (lptbbi->dwMask & TBIF_IMAGE)
2799 btnPtr->iBitmap = lptbbi->iImage;
2800 if (lptbbi->dwMask & TBIF_LPARAM)
2801 btnPtr->dwData = lptbbi->lParam;
2802 /* if (lptbbi->dwMask & TBIF_SIZE) */
2803 /* btnPtr->cx = lptbbi->cx; */
2804 if (lptbbi->dwMask & TBIF_STATE)
2805 btnPtr->fsState = lptbbi->fsState;
2806 if (lptbbi->dwMask & TBIF_STYLE)
2807 btnPtr->fsStyle = lptbbi->fsStyle;
2809 if (lptbbi->dwMask & TBIF_TEXT) {
2810 if ((btnPtr->iString >= 0) ||
2811 (btnPtr->iString < infoPtr->nNumStrings)) {
2813 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2814 INT len = lstrlenW (lptbbi->pszText);
2815 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
2818 /* this is the ultimate sollution */
2819 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2828 TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2830 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2832 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
2834 ERR("invalid parameter\n");
2838 /* Button size can only be set before adding any button to the toolbar
2839 according to the documentation. */
2840 /* this appears to be wrong. WINZIP32.EXE (ver 8) calls this on
2841 one of its buttons after adding it to the toolbar, and it
2842 checks that the return value is nonzero - mjm */
2843 if( infoPtr->nNumButtons != 0 )
2845 WARN("Button size set after button in toolbar\n");
2849 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
2850 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
2856 TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
2858 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2860 if (infoPtr == NULL)
2863 infoPtr->cxMin = (INT)LOWORD(lParam);
2864 infoPtr->cxMax = (INT)HIWORD(lParam);
2871 TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
2873 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2874 INT nIndex = (INT)wParam;
2876 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2879 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
2881 if (infoPtr->hwndToolTip) {
2883 FIXME("change tool tip!\n");
2891 /* << TOOLBAR_SetColorScheme >> */
2895 TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2897 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2898 HIMAGELIST himlTemp;
2901 himlTemp = infoPtr->himlDis;
2902 infoPtr->himlDis = (HIMAGELIST)lParam;
2904 /* FIXME: redraw ? */
2906 return (LRESULT)himlTemp;
2911 TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
2913 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2916 dwTemp = infoPtr->dwDTFlags;
2917 infoPtr->dwDTFlags =
2918 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
2920 return (LRESULT)dwTemp;
2925 TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2927 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2930 dwTemp = infoPtr->dwExStyle;
2931 infoPtr->dwExStyle = (DWORD)lParam;
2933 return (LRESULT)dwTemp;
2938 TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2940 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2941 HIMAGELIST himlTemp;
2943 himlTemp = infoPtr->himlHot;
2944 infoPtr->himlHot = (HIMAGELIST)lParam;
2946 /* FIXME: redraw ? */
2948 return (LRESULT)himlTemp;
2953 TOOLBAR_SetHotItem (HWND hwnd, WPARAM wParam)
2955 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2956 INT nOldHotItem = infoPtr->nHotItem;
2958 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
2960 infoPtr->nHotItem = (INT)wParam;
2962 /* FIXME: What else must be done ??? */
2966 if (nOldHotItem < 0)
2969 return (LRESULT)nOldHotItem;
2974 TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2976 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2977 HIMAGELIST himlTemp;
2979 himlTemp = infoPtr->himlDef;
2980 infoPtr->himlDef = (HIMAGELIST)lParam;
2982 infoPtr->nNumBitmaps = ImageList_GetImageCount(infoPtr->himlDef);
2983 /* FIXME: redraw ? */
2985 return (LRESULT)himlTemp;
2990 TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2992 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2996 /* process only on indent changing */
2997 if(infoPtr->nIndent != (INT)wParam)
2999 infoPtr->nIndent = (INT)wParam;
3000 TOOLBAR_CalcToolbar (hwnd);
3001 InvalidateRect(hwnd, NULL, FALSE);
3008 /* << TOOLBAR_SetInsertMark >> */
3012 TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
3014 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3016 infoPtr->clrInsertMark = (COLORREF)lParam;
3018 /* FIXME : redraw ??*/
3025 TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3027 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3029 if (infoPtr == NULL)
3032 infoPtr->nMaxTextRows = (INT)wParam;
3038 /* << TOOLBAR_SetPadding >> */
3042 TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3044 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3049 if (infoPtr == NULL)
3051 hwndOldNotify = infoPtr->hwndNotify;
3052 infoPtr->hwndNotify = (HWND)wParam;
3054 return hwndOldNotify;
3059 TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3061 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3062 LPRECT lprc = (LPRECT)lParam;
3066 if (LOWORD(wParam) > 1) {
3067 FIXME("multiple rows not supported!\n");
3070 if(infoPtr->nRows != LOWORD(wParam))
3072 infoPtr->nRows = LOWORD(wParam);
3074 /* recalculate toolbar */
3075 TOOLBAR_CalcToolbar (hwnd);
3077 /* repaint toolbar */
3078 InvalidateRect(hwnd, NULL, FALSE);
3081 /* return bounding rectangle */
3083 lprc->left = infoPtr->rcBound.left;
3084 lprc->right = infoPtr->rcBound.right;
3085 lprc->top = infoPtr->rcBound.top;
3086 lprc->bottom = infoPtr->rcBound.bottom;
3094 TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
3096 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3097 TBUTTON_INFO *btnPtr;
3100 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3104 btnPtr = &infoPtr->buttons[nIndex];
3106 /* process state changing if current state doesn't match new state */
3107 if(btnPtr->fsState != LOWORD(lParam))
3109 btnPtr->fsState = LOWORD(lParam);
3110 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3119 TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3121 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3122 TBUTTON_INFO *btnPtr;
3125 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3129 btnPtr = &infoPtr->buttons[nIndex];
3131 /* process style change if current style doesn't match new style */
3132 if(btnPtr->fsStyle != LOWORD(lParam))
3134 btnPtr->fsStyle = LOWORD(lParam);
3135 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3138 if (infoPtr->hwndToolTip) {
3139 FIXME("change tool tip!\n");
3147 inline static LRESULT
3148 TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
3150 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3152 if (infoPtr == NULL)
3154 infoPtr->hwndToolTip = (HWND)wParam;
3160 TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
3162 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3165 TRACE("%s hwnd=0x%04x stub!\n",
3166 ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
3168 bTemp = infoPtr->bUnicode;
3169 infoPtr->bUnicode = (BOOL)wParam;
3176 TOOLBAR_SetVersion (HWND hwnd, INT iVersion)
3178 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3179 INT iOldVersion = infoPtr->iVersion;
3181 infoPtr->iVersion = iVersion;
3188 TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
3190 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3191 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3194 /* initialize info structure */
3195 infoPtr->nButtonHeight = 22;
3196 infoPtr->nButtonWidth = 24;
3197 infoPtr->nBitmapHeight = 15;
3198 infoPtr->nBitmapWidth = 16;
3200 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
3202 infoPtr->nMaxTextRows = 1;
3203 infoPtr->cxMin = -1;
3204 infoPtr->cxMax = -1;
3205 infoPtr->nNumBitmaps = 0;
3206 infoPtr->nNumStrings = 0;
3208 infoPtr->bCaptured = FALSE;
3209 infoPtr->bUnicode = IsWindowUnicode (hwnd);
3210 infoPtr->nButtonDown = -1;
3211 infoPtr->nOldHit = -1;
3212 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3213 infoPtr->hwndNotify = GetParent (hwnd);
3214 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
3215 infoPtr->dwDTFlags = (dwStyle & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE : DT_CENTER;
3216 infoPtr->bAnchor = FALSE; /* no anchor highlighting */
3217 infoPtr->iVersion = 0;
3219 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
3220 infoPtr->hFont = CreateFontIndirectA (&logFont);
3222 if (dwStyle & TBSTYLE_TOOLTIPS) {
3223 /* Create tooltip control */
3224 infoPtr->hwndToolTip =
3225 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
3226 CW_USEDEFAULT, CW_USEDEFAULT,
3227 CW_USEDEFAULT, CW_USEDEFAULT,
3230 /* Send NM_TOOLTIPSCREATED notification */
3231 if (infoPtr->hwndToolTip) {
3232 NMTOOLTIPSCREATED nmttc;
3234 nmttc.hdr.hwndFrom = hwnd;
3235 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3236 nmttc.hdr.code = NM_TOOLTIPSCREATED;
3237 nmttc.hwndToolTips = infoPtr->hwndToolTip;
3239 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3240 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
3244 TOOLBAR_CalcToolbar(hwnd);
3251 TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
3253 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3255 /* delete tooltip control */
3256 if (infoPtr->hwndToolTip)
3257 DestroyWindow (infoPtr->hwndToolTip);
3259 /* delete button data */
3260 if (infoPtr->buttons)
3261 COMCTL32_Free (infoPtr->buttons);
3263 /* delete strings */
3264 if (infoPtr->strings) {
3266 for (i = 0; i < infoPtr->nNumStrings; i++)
3267 if (infoPtr->strings[i])
3268 COMCTL32_Free (infoPtr->strings[i]);
3270 COMCTL32_Free (infoPtr->strings);
3273 /* destroy internal image list */
3274 if (infoPtr->himlInt)
3275 ImageList_Destroy (infoPtr->himlInt);
3277 /* delete default font */
3279 DeleteObject (infoPtr->hFont);
3281 /* free toolbar info data */
3282 COMCTL32_Free (infoPtr);
3283 SetWindowLongA (hwnd, 0, 0);
3290 TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
3292 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3294 if (infoPtr->bTransparent)
3295 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
3297 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
3302 TOOLBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
3304 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3306 return infoPtr->hFont;
3311 TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
3313 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3314 TBUTTON_INFO *btnPtr;
3318 pt.x = (INT)LOWORD(lParam);
3319 pt.y = (INT)HIWORD(lParam);
3320 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3323 btnPtr = &infoPtr->buttons[nHit];
3324 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3327 infoPtr->bCaptured = TRUE;
3328 infoPtr->nButtonDown = nHit;
3330 btnPtr->fsState |= TBSTATE_PRESSED;
3332 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3335 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
3336 TOOLBAR_Customize (hwnd);
3343 TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
3345 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3346 TBUTTON_INFO *btnPtr;
3350 if (infoPtr->hwndToolTip)
3351 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3352 WM_LBUTTONDOWN, wParam, lParam);
3354 pt.x = (INT)LOWORD(lParam);
3355 pt.y = (INT)HIWORD(lParam);
3356 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3359 btnPtr = &infoPtr->buttons[nHit];
3360 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3363 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN)
3367 nmtb.hdr.hwndFrom = hwnd;
3368 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3369 nmtb.hdr.code = TBN_DROPDOWN;
3370 nmtb.iItem = btnPtr->idCommand;
3372 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
3373 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3377 infoPtr->bCaptured = TRUE;
3378 infoPtr->nButtonDown = nHit;
3379 infoPtr->nOldHit = nHit;
3381 btnPtr->fsState |= TBSTATE_PRESSED;
3382 btnPtr->bHot = FALSE;
3384 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3392 TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
3394 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3395 TBUTTON_INFO *btnPtr;
3399 BOOL bSendMessage = TRUE;
3401 if (infoPtr->hwndToolTip)
3402 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3403 WM_LBUTTONUP, wParam, lParam);
3405 pt.x = (INT)LOWORD(lParam);
3406 pt.y = (INT)HIWORD(lParam);
3407 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3409 /* restore hot effect to hot button disabled by TOOLBAR_LButtonDown() */
3410 /* if the cursor is still inside of the toolbar */
3411 if((infoPtr->nHotItem >= 0) && (nHit != -1))
3412 infoPtr->buttons[infoPtr->nHotItem].bHot = TRUE;
3414 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
3415 infoPtr->bCaptured = FALSE;
3417 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3418 btnPtr->fsState &= ~TBSTATE_PRESSED;
3420 if (nHit == infoPtr->nButtonDown) {
3421 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
3422 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
3423 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
3424 infoPtr->nButtonDown);
3425 if (nOldIndex == infoPtr->nButtonDown)
3426 bSendMessage = FALSE;
3427 if ((nOldIndex != infoPtr->nButtonDown) &&
3429 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
3430 btnPtr->fsState |= TBSTATE_CHECKED;
3433 if (btnPtr->fsState & TBSTATE_CHECKED)
3434 btnPtr->fsState &= ~TBSTATE_CHECKED;
3436 btnPtr->fsState |= TBSTATE_CHECKED;
3441 bSendMessage = FALSE;
3443 if (nOldIndex != -1)
3445 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
3446 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
3449 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3453 SendMessageA (GetParent(hwnd), WM_COMMAND,
3454 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
3456 // if ((GetWindowLongA(hwnd, GWL_STYLE) & TBSTYLE_DROPDOWN) ||
3457 // (btnPtr->fsStyle & 0x08/* BTNS_DROPDOWN */)) {
3459 * This appears to be an error. Instead of checking the style of the
3460 * button in question wine was checking the style of the toolbar
3461 * itself. This caused a number of strange behaviors. In my
3462 * invistigation i think the whole dropdown thing is still fairly
3463 * broken. but this helps fix some of the problems.
3466 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN) {
3469 nmtb.hdr.hwndFrom = hwnd;
3470 nmtb.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
3471 nmtb.hdr.code = TBN_DROPDOWN;
3473 /* nmtb.tbButton not used with TBN_DROPDOWN */
3474 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings)) {
3475 nmtb.pszText = infoPtr->strings[btnPtr->iString];
3476 nmtb.cchText = lstrlenW(nmtb.pszText);
3478 nmtb.pszText = NULL;
3481 nmtb.rcButton = btnPtr->rect;
3483 SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
3484 (WPARAM)nmtb.hdr.idFrom, (LPARAM)&nmtb);
3487 infoPtr->nButtonDown = -1;
3488 infoPtr->nOldHit = -1;
3495 TOOLBAR_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam)
3497 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3498 TBUTTON_INFO *hotBtnPtr, *btnPtr;
3500 if (infoPtr->nOldHit < 0)
3503 hotBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3505 /* Redraw the button if the last button we were over is the hot button and it
3507 if((infoPtr->nOldHit == infoPtr->nHotItem) && (hotBtnPtr->fsState & TBSTATE_ENABLED))
3509 hotBtnPtr->bHot = FALSE;
3511 InvalidateRect (hwnd, &hotBtnPtr->rect, TOOLBAR_HasText(infoPtr,
3515 /* If the last button we were over is depressed then make it not */
3516 /* depressed and redraw it */
3517 if(infoPtr->nOldHit == infoPtr->nButtonDown)
3519 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3521 btnPtr->fsState &= ~TBSTATE_PRESSED;
3523 InvalidateRect (hwnd, &(btnPtr->rect), TRUE);
3526 infoPtr->nOldHit = -1; /* reset the old hit index as we've left the toolbar */
3527 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3533 TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
3535 TBUTTON_INFO *btnPtr, *oldBtnPtr;
3536 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3539 TRACKMOUSEEVENT trackinfo;
3541 /* fill in the TRACKMOUSEEVENT struct */
3542 trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
3543 trackinfo.dwFlags = TME_QUERY;
3544 trackinfo.hwndTrack = hwnd;
3545 trackinfo.dwHoverTime = HOVER_DEFAULT;
3547 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
3548 _TrackMouseEvent(&trackinfo);
3550 /* Make sure tracking is enabled so we recieve a WM_MOUSELEAVE message */
3551 if(!(trackinfo.dwFlags & TME_LEAVE)) {
3552 trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
3554 /* call TRACKMOUSEEVENT so we recieve a WM_MOUSELEAVE message */
3555 /* and can properly deactivate the hot toolbar button */
3556 _TrackMouseEvent(&trackinfo);
3559 if (infoPtr->hwndToolTip)
3560 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3561 WM_MOUSEMOVE, wParam, lParam);
3563 pt.x = (INT)LOWORD(lParam);
3564 pt.y = (INT)HIWORD(lParam);
3566 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3568 if (infoPtr->nOldHit != nHit)
3570 /* Remove the effect of an old hot button if the button was enabled and was
3571 drawn with the hot button effect */
3572 if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem &&
3573 (infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED))
3575 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3576 oldBtnPtr->bHot = FALSE;
3578 InvalidateRect (hwnd, &oldBtnPtr->rect,
3579 TOOLBAR_HasText(infoPtr, oldBtnPtr));
3582 /* It's not a separator or in nowhere. It's a hot button. */
3585 btnPtr = &infoPtr->buttons[nHit];
3586 btnPtr->bHot = TRUE;
3588 infoPtr->nHotItem = nHit;
3590 /* only enabled buttons show hot effect */
3591 if(infoPtr->buttons[nHit].fsState & TBSTATE_ENABLED)
3593 InvalidateRect(hwnd, &btnPtr->rect,
3594 TOOLBAR_HasText(infoPtr, btnPtr));
3599 if (infoPtr->bCaptured) {
3600 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3601 if (infoPtr->nOldHit == infoPtr->nButtonDown) {
3602 btnPtr->fsState &= ~TBSTATE_PRESSED;
3603 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3605 else if (nHit == infoPtr->nButtonDown) {
3606 btnPtr->fsState |= TBSTATE_PRESSED;
3607 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
3610 infoPtr->nOldHit = nHit;
3616 inline static LRESULT
3617 TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3619 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
3620 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
3622 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
3626 inline static LRESULT
3627 TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3629 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
3630 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
3632 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
3637 TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3639 TOOLBAR_INFO *infoPtr;
3641 /* allocate memory for info structure */
3642 infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
3643 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
3646 infoPtr->dwStructSize = sizeof(TBBUTTON);
3648 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
3649 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
3650 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
3651 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
3654 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
3659 TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3661 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3665 if (dwStyle & WS_MINIMIZE)
3666 return 0; /* Nothing to do */
3668 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
3670 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
3673 if (!(dwStyle & CCS_NODIVIDER))
3675 GetWindowRect (hwnd, &rcWindow);
3676 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3677 if( dwStyle & WS_BORDER )
3678 OffsetRect (&rcWindow, 1, 1);
3679 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
3682 ReleaseDC( hwnd, hdc );
3688 inline static LRESULT
3689 TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
3691 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3692 LPNMHDR lpnmh = (LPNMHDR)lParam;
3694 TRACE("passing WM_NOTIFY!\n");
3696 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
3697 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
3700 if (lpnmh->code == TTN_GETDISPINFOA) {
3701 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
3703 FIXME("retrieving ASCII string\n");
3706 else if (lpnmh->code == TTN_GETDISPINFOW) {
3707 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
3709 FIXME("retrieving UNICODE string\n");
3720 TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
3722 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3728 /* fill ps.rcPaint with a default rect */
3729 memcpy(&(ps.rcPaint), &(infoPtr->rcBound), sizeof(infoPtr->rcBound));
3731 TOOLBAR_CalcToolbar( hwnd );
3732 hdc = wParam==0 ? BeginPaint(hwnd, &ps) : (HDC)wParam;
3733 TOOLBAR_Refresh (hwnd, hdc, &ps);
3734 if (!wParam) EndPaint (hwnd, &ps);
3741 TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
3743 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3744 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3753 /* Resize deadlock check */
3754 if (infoPtr->bAutoSize) {
3755 infoPtr->bAutoSize = FALSE;
3759 /* FIXME: optimize to only update size if the new size doesn't */
3760 /* match the current size */
3762 flags = (INT) wParam;
3764 /* FIXME for flags =
3765 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
3768 TRACE("sizing toolbar!\n");
3770 if (flags == SIZE_RESTORED) {
3771 /* width and height don't apply */
3772 parent = GetParent (hwnd);
3773 GetClientRect(parent, &parent_rect);
3774 x = parent_rect.left;
3775 y = parent_rect.top;
3777 if (dwStyle & CCS_NORESIZE) {
3778 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
3781 * this sets the working width of the toolbar, and
3782 * Calc Toolbar will not adjust it, only the height
3784 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3785 cy = infoPtr->nHeight;
3786 cx = infoPtr->nWidth;
3787 TOOLBAR_CalcToolbar (hwnd);
3788 infoPtr->nWidth = cx;
3789 infoPtr->nHeight = cy;
3792 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3793 TOOLBAR_CalcToolbar (hwnd);
3794 cy = infoPtr->nHeight;
3795 cx = infoPtr->nWidth;
3797 if (dwStyle & CCS_NOMOVEY) {
3798 GetWindowRect(hwnd, &window_rect);
3799 ScreenToClient(parent, (LPPOINT)&window_rect.left);
3800 y = window_rect.top;
3804 if (dwStyle & CCS_NOPARENTALIGN) {
3805 uPosFlags |= SWP_NOMOVE;
3806 cy = infoPtr->nHeight;
3807 cx = infoPtr->nWidth;
3810 if (!(dwStyle & CCS_NODIVIDER))
3811 cy += GetSystemMetrics(SM_CYEDGE);
3813 if (dwStyle & WS_BORDER)
3816 cy += GetSystemMetrics(SM_CYEDGE);
3817 cx += GetSystemMetrics(SM_CYEDGE);
3820 SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
3821 cx, cy, uPosFlags | SWP_NOZORDER);
3828 TOOLBAR_StyleChanged (HWND hwnd, INT nType, LPSTYLESTRUCT lpStyle)
3830 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3832 if (nType == GWL_STYLE) {
3833 if (lpStyle->styleNew & TBSTYLE_LIST) {
3834 infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
3837 infoPtr->dwDTFlags = DT_CENTER;
3841 TOOLBAR_AutoSize (hwnd);
3843 InvalidateRect(hwnd, NULL, FALSE);
3850 static LRESULT WINAPI
3851 ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3857 return TOOLBAR_Destroy (hwnd, wParam, lParam);
3860 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
3863 if (!TOOLBAR_GetInfoPtr (hwnd))
3865 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3871 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
3873 case TB_ADDBUTTONSA:
3874 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
3876 case TB_ADDBUTTONSW:
3877 return TOOLBAR_AddButtonsW (hwnd, wParam, lParam);
3880 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
3883 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
3886 return TOOLBAR_AutoSize (hwnd);
3888 case TB_BUTTONCOUNT:
3889 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
3891 case TB_BUTTONSTRUCTSIZE:
3892 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
3894 case TB_CHANGEBITMAP:
3895 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
3897 case TB_CHECKBUTTON:
3898 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
3900 case TB_COMMANDTOINDEX:
3901 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
3904 return TOOLBAR_Customize (hwnd);
3906 case TB_DELETEBUTTON:
3907 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
3909 case TB_ENABLEBUTTON:
3910 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
3912 case TB_GETANCHORHIGHLIGHT:
3913 return TOOLBAR_GetAnchorHighlight (hwnd);
3916 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
3918 case TB_GETBITMAPFLAGS:
3919 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
3922 return TOOLBAR_GetButton (hwnd, wParam, lParam);
3924 case TB_GETBUTTONINFOA:
3925 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
3927 case TB_GETBUTTONINFOW:
3928 return TOOLBAR_GetButtonInfoW (hwnd, wParam, lParam);
3930 case TB_GETBUTTONSIZE:
3931 return TOOLBAR_GetButtonSize (hwnd);
3933 case TB_GETBUTTONTEXTA:
3934 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
3936 case TB_GETBUTTONTEXTW:
3937 return TOOLBAR_GetButtonTextW (hwnd, wParam, lParam);
3939 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
3941 case TB_GETDISABLEDIMAGELIST:
3942 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
3944 case TB_GETEXTENDEDSTYLE:
3945 return TOOLBAR_GetExtendedStyle (hwnd);
3947 case TB_GETHOTIMAGELIST:
3948 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
3951 return TOOLBAR_GetHotItem (hwnd);
3953 case TB_GETIMAGELIST:
3954 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
3956 /* case TB_GETINSERTMARK: */ /* 4.71 */
3957 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
3959 case TB_GETITEMRECT:
3960 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
3963 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
3965 /* case TB_GETOBJECT: */ /* 4.71 */
3966 /* case TB_GETPADDING: */ /* 4.71 */
3969 return TOOLBAR_GetRect (hwnd, wParam, lParam);
3972 return TOOLBAR_GetRows (hwnd, wParam, lParam);
3975 return TOOLBAR_GetState (hwnd, wParam, lParam);
3978 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
3980 case TB_GETTEXTROWS:
3981 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
3983 case TB_GETTOOLTIPS:
3984 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
3986 case TB_GETUNICODEFORMAT:
3987 return TOOLBAR_GetUnicodeFormat (hwnd, wParam, lParam);
3989 case CCM_GETVERSION:
3990 return TOOLBAR_GetVersion (hwnd);
3993 return TOOLBAR_HideButton (hwnd, wParam, lParam);
3996 return TOOLBAR_HitTest (hwnd, wParam, lParam);
3998 case TB_INDETERMINATE:
3999 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
4001 case TB_INSERTBUTTONA:
4002 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
4004 case TB_INSERTBUTTONW:
4005 return TOOLBAR_InsertButtonW (hwnd, wParam, lParam);
4007 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
4009 case TB_ISBUTTONCHECKED:
4010 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
4012 case TB_ISBUTTONENABLED:
4013 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
4015 case TB_ISBUTTONHIDDEN:
4016 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
4018 case TB_ISBUTTONHIGHLIGHTED:
4019 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
4021 case TB_ISBUTTONINDETERMINATE:
4022 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
4024 case TB_ISBUTTONPRESSED:
4025 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
4027 case TB_LOADIMAGES: /* 4.70 */
4028 FIXME("missing standard imagelists\n");
4031 /* case TB_MAPACCELERATORA: */ /* 4.71 */
4032 /* case TB_MAPACCELERATORW: */ /* 4.71 */
4033 /* case TB_MARKBUTTON: */ /* 4.71 */
4034 /* case TB_MOVEBUTTON: */ /* 4.71 */
4036 case TB_PRESSBUTTON:
4037 return TOOLBAR_PressButton (hwnd, wParam, lParam);
4039 /* case TB_REPLACEBITMAP: */
4041 case TB_SAVERESTOREA:
4042 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
4044 case TB_SAVERESTOREW:
4045 return TOOLBAR_SaveRestoreW (hwnd, wParam, lParam);
4047 case TB_SETANCHORHIGHLIGHT:
4048 return TOOLBAR_SetAnchorHighlight (hwnd, wParam);
4050 case TB_SETBITMAPSIZE:
4051 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
4053 case TB_SETBUTTONINFOA:
4054 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
4056 case TB_SETBUTTONINFOW:
4057 return TOOLBAR_SetButtonInfoW (hwnd, wParam, lParam);
4059 case TB_SETBUTTONSIZE:
4060 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
4062 case TB_SETBUTTONWIDTH:
4063 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
4066 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
4068 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
4070 case TB_SETDISABLEDIMAGELIST:
4071 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
4073 case TB_SETDRAWTEXTFLAGS:
4074 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
4076 case TB_SETEXTENDEDSTYLE:
4077 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
4079 case TB_SETHOTIMAGELIST:
4080 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
4083 return TOOLBAR_SetHotItem (hwnd, wParam);
4085 case TB_SETIMAGELIST:
4086 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
4089 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
4091 /* case TB_SETINSERTMARK: */ /* 4.71 */
4093 case TB_SETINSERTMARKCOLOR:
4094 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
4096 case TB_SETMAXTEXTROWS:
4097 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
4099 /* case TB_SETPADDING: */ /* 4.71 */
4102 return TOOLBAR_SetParent (hwnd, wParam, lParam);
4105 return TOOLBAR_SetRows (hwnd, wParam, lParam);
4108 return TOOLBAR_SetState (hwnd, wParam, lParam);
4111 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
4113 case TB_SETTOOLTIPS:
4114 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
4116 case TB_SETUNICODEFORMAT:
4117 return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
4119 case CCM_SETVERSION:
4120 return TOOLBAR_SetVersion (hwnd, (INT)wParam);
4126 return TOOLBAR_Create (hwnd, wParam, lParam);
4129 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
4132 return TOOLBAR_GetFont (hwnd, wParam, lParam);
4134 /* case WM_KEYDOWN: */
4135 /* case WM_KILLFOCUS: */
4137 case WM_LBUTTONDBLCLK:
4138 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
4140 case WM_LBUTTONDOWN:
4141 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
4144 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
4147 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
4150 return TOOLBAR_MouseLeave (hwnd, wParam, lParam);
4153 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
4156 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
4159 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
4162 return TOOLBAR_Notify (hwnd, wParam, lParam);
4164 /* case WM_NOTIFYFORMAT: */
4167 return TOOLBAR_Paint (hwnd, wParam);
4170 return TOOLBAR_Size (hwnd, wParam, lParam);
4172 case WM_STYLECHANGED:
4173 return TOOLBAR_StyleChanged (hwnd, (INT)wParam, (LPSTYLESTRUCT)lParam);
4175 /* case WM_SYSCOLORCHANGE: */
4177 /* case WM_WININICHANGE: */
4182 case WM_MEASUREITEM:
4184 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
4187 if (uMsg >= WM_USER)
4188 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
4189 uMsg, wParam, lParam);
4190 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
4197 TOOLBAR_Register (void)
4201 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
4202 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
4203 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
4204 wndClass.cbClsExtra = 0;
4205 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
4206 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
4207 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
4208 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
4210 RegisterClassA (&wndClass);
4215 TOOLBAR_Unregister (void)
4217 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);