4 * Copyright 1998,1999 Eric Kohl
5 * Copyright 2000 Eric Kohl for CodeWeavers
8 * - A little bug in TOOLBAR_DrawMasked()
9 * - Button wrapping (under construction).
11 * - Notifications (under construction).
13 * - Tooltip support (almost complete).
14 * - Unicode suppport (under construction).
15 * - Fix TOOLBAR_SetButtonInfo32A/W.
16 * - TBSTYLE_AUTOSIZE for toolbar and buttons.
17 * - I_IMAGECALLBACK support.
18 * - iString of -1 is undocumented
19 * - Customization dialog:
21 * - Minor buglet in 'available buttons' list:
22 * Buttons are not listed in M$-like order. M$ seems to use a single
23 * internal list to store the button information of both listboxes.
24 * - Drag list support.
25 * - Help and Reset button support.
28 * - Run tests using Waite Group Windows95 API Bible Volume 2.
29 * The second cdrom contains executables addstr.exe, btncount.exe,
30 * btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
31 * enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
32 * indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
33 * setparnt.exe, setrows.exe, toolwnd.exe.
34 * - Microsofts controlspy examples.
35 * - Charles Petzold's 'Programming Windows': gadgets.exe
44 #include "wine/unicode.h"
46 #include "imagelist.h"
48 #include "debugtools.h"
50 DEFAULT_DEBUG_CHANNEL(toolbar);
68 DWORD dwStructSize; /* size of TBBUTTON struct */
69 INT nHeight; /* height of the toolbar */
70 INT nWidth; /* width of the toolbar */
76 INT nRows; /* number of button rows */
77 INT nMaxTextRows; /* maximum number of text rows */
78 INT cxMin; /* minimum button width */
79 INT cxMax; /* maximum button width */
80 INT nNumButtons; /* number of buttons */
81 INT nNumBitmaps; /* number of bitmaps */
82 INT nNumStrings; /* number of strings */
83 BOOL bUnicode; /* ASCII (FALSE) or Unicode (TRUE)? */
84 BOOL bCaptured; /* mouse captured? */
87 INT nHotItem; /* index of the "hot" item */
88 HFONT hFont; /* text font */
89 HIMAGELIST himlInt; /* image list created internally */
90 HIMAGELIST himlDef; /* default image list */
91 HIMAGELIST himlHot; /* hot image list */
92 HIMAGELIST himlDis; /* disabled image list */
93 HWND hwndToolTip; /* handle to tool tip control */
94 HWND hwndNotify; /* handle to the window that gets notifications */
95 HWND hwndSelf; /* my own handle */
96 BOOL bTransparent; /* background transparency flag */
97 BOOL bAutoSize; /* auto size deadlock indicator */
98 BOOL bAnchor; /* anchor highlight enabled */
99 BOOL bNtfUnicode; /* TRUE if NOTIFYs use {W} */
100 DWORD dwExStyle; /* extended toolbar style */
101 DWORD dwDTFlags; /* DrawText flags */
103 COLORREF clrInsertMark; /* insert mark color */
104 RECT rcBound; /* bounding rectangle */
107 TBUTTON_INFO *buttons; /* pointer to button array */
108 LPWSTR *strings; /* pointer to string array */
109 } TOOLBAR_INFO, *PTOOLBAR_INFO;
112 /* used by customization dialog */
115 PTOOLBAR_INFO tbInfo;
117 } CUSTDLG_INFO, *PCUSTDLG_INFO;
125 } CUSTOMBUTTON, *PCUSTOMBUTTON;
128 #define SEPARATOR_WIDTH 8
130 #define BOTTOM_BORDER 2
131 #define DDARROW_WIDTH 11
133 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
134 #define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE)
135 #define TOOLBAR_HasDropDownArrows(exStyle) ((exStyle & TBSTYLE_EX_DRAWDDARROWS) ? TRUE : FALSE)
139 TOOLBAR_DumpButton(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *bP, INT btn_num, BOOL internal)
141 if (TRACE_ON(toolbar)){
142 TRACE("button %d id %d, bitmap=%d, state=%02x, style=%02x, data=%08lx, string=%d\n",
143 btn_num, bP->idCommand,
144 bP->iBitmap, bP->fsState, bP->fsStyle, bP->dwData, bP->iString);
146 TRACE("button %d id %d, hot=%s, row=%d, rect=(%d,%d)-(%d,%d)\n",
147 btn_num, bP->idCommand,
148 (bP->bHot) ? "TRUE":"FALSE", bP->nRow,
149 bP->rect.left, bP->rect.top,
150 bP->rect.right, bP->rect.bottom);
156 TOOLBAR_DumpToolbar(TOOLBAR_INFO *iP, INT line)
158 if (TRACE_ON(toolbar)) {
162 dwStyle = GetWindowLongA (iP->hwndSelf, GWL_STYLE);
163 TRACE("toolbar %08x at line %d, exStyle=%08lx, buttons=%d, bitmaps=%d, strings=%d, style=%08lx\n",
165 iP->dwExStyle, iP->nNumButtons, iP->nNumBitmaps,
166 iP->nNumStrings, dwStyle);
167 TRACE("toolbar %08x at line %d, himlInt=%p, himlDef=%p, himlHot=%p, himlDis=%p\n",
169 iP->himlInt, iP->himlDef, iP->himlHot, iP->himlDis);
170 for(i=0; i<iP->nNumButtons; i++) {
171 TOOLBAR_DumpButton(iP, &iP->buttons[i], i, TRUE);
178 TOOLBAR_SendNotify (NMHDR *nmhdr, TOOLBAR_INFO *infoPtr, UINT code)
180 nmhdr->idFrom = GetDlgCtrlID (infoPtr->hwndSelf);
181 nmhdr->hwndFrom = infoPtr->hwndSelf;
184 TRACE("to window %04x, code=%08x, %s\n", infoPtr->hwndNotify, code,
185 (infoPtr->bNtfUnicode) ? "via Unicode" : "via ANSI");
187 if (infoPtr->bNtfUnicode)
188 return SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
189 (WPARAM) nmhdr->idFrom, (LPARAM)nmhdr);
191 return SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
192 (WPARAM) nmhdr->idFrom, (LPARAM)nmhdr);
196 TOOLBAR_GetText(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr)
198 LPWSTR lpText = NULL;
200 /* FIXME: iString == -1 is undocumented */
201 if ((HIWORD(btnPtr->iString) != 0) && (btnPtr->iString != -1))
202 lpText = (LPWSTR)btnPtr->iString;
203 else if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
204 lpText = infoPtr->strings[btnPtr->iString];
209 /***********************************************************************
210 * TOOLBAR_GetBitmapIndex
212 * This function returns the bitmap index associated with a button.
213 * If the button specifies I_IMAGECALLBACK, then the TBN_GETDISPINFO
214 * is issued to retrieve the index.
217 TOOLBAR_GetBitmapIndex(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr)
219 INT ret = btnPtr->iBitmap;
221 if (ret == I_IMAGECALLBACK) {
222 /* issue TBN_GETDISPINFO */
225 nmgd.idCommand = btnPtr->idCommand;
226 nmgd.lParam = btnPtr->dwData;
227 nmgd.dwMask = TBNF_IMAGE;
228 TOOLBAR_SendNotify ((NMHDR *) &nmgd, infoPtr,
229 (infoPtr->bNtfUnicode) ? TBN_GETDISPINFOW :
231 if (nmgd.dwMask & TBNF_DI_SETITEM) {
232 btnPtr->iBitmap = nmgd.iImage;
235 TRACE("TBN_GETDISPINFOA returned bitmap id %d, mask=%08lx, nNumBitmaps=%d\n",
236 ret, nmgd.dwMask, infoPtr->nNumBitmaps);
243 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index)
245 if (((index>=0) && (index <= infoPtr->nNumBitmaps)) ||
246 (index == I_IMAGECALLBACK))
253 /***********************************************************************
254 * TOOLBAR_DrawImageList
256 * This function validates the bitmap index (including I_IMAGECALLBACK
257 * functionality). It then draws the image via the ImageList_Draw
258 * function. It returns TRUE if the image was drawn, FALSE otherwise.
261 TOOLBAR_DrawImageList (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST himl,
262 HDC hdc, UINT left, UINT top, UINT draw_flags)
266 if (!himl) return FALSE;
268 if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
269 ERR("index %d is not valid, max %d\n",
270 btnPtr->iBitmap, infoPtr->nNumBitmaps);
274 if ((index = TOOLBAR_GetBitmapIndex(infoPtr, btnPtr)) < 0) {
275 if (index == -1) return FALSE;
276 ERR("TBN_GETDISPINFO returned invalid index %d\n",
280 TRACE("drawing index=%d, himl=%p, left=%d, top=%d, flags=%08x\n",
281 index, himl, left, top, draw_flags);
283 ImageList_Draw (himl, index, hdc, left, top, draw_flags);
288 /***********************************************************************
289 * TOOLBAR_TestImageExist
291 * This function is similar to TOOLBAR_DrawImageList, except it does not
292 * draw the image. The I_IMAGECALLBACK functionality is implemented.
295 TOOLBAR_TestImageExist (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST himl)
299 if (!himl) return FALSE;
301 if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
302 ERR("index %d is not valid, max %d\n",
303 btnPtr->iBitmap, infoPtr->nNumBitmaps);
307 if ((index = TOOLBAR_GetBitmapIndex(infoPtr, btnPtr)) < 0) {
308 if (index == -1) return FALSE;
309 ERR("TBN_GETDISPINFO returned invalid index %d\n",
318 TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
320 INT x = (lpRect->left + lpRect->right) / 2 - 1;
321 INT yBottom = lpRect->bottom - 3;
322 INT yTop = lpRect->top + 1;
324 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
325 MoveToEx (hdc, x, yBottom, NULL);
326 LineTo (hdc, x, yTop);
328 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
329 MoveToEx (hdc, x, yBottom, NULL);
330 LineTo (hdc, x, yTop);
334 /***********************************************************************
335 * TOOLBAR_DrawDDFlatSeparator
337 * This function draws the separator that was flaged as TBSTYLE_DROPDOWN.
338 * In this case, the separator is a pixel high line of COLOR_BTNSHADOW,
339 * followed by a pixel high line of COLOR_BTNHIGHLIGHT. These separators
340 * are horizontal as opposed to the vertical separators for not dropdown
343 * FIXME: It is possible that the height of each line is really SM_CYBORDER.
346 TOOLBAR_DrawDDFlatSeparator (LPRECT lpRect, HDC hdc, TBUTTON_INFO *btnPtr)
349 COLORREF oldcolor, newcolor;
351 myrect.left = lpRect->left;
352 myrect.right = lpRect->right;
353 myrect.top = lpRect->top + (lpRect->bottom - lpRect->top - 2)/2;
354 myrect.bottom = myrect.top + 1;
356 InflateRect (&myrect, -2, 0);
358 TRACE("rect=(%d,%d)-(%d,%d)\n",
359 myrect.left, myrect.top, myrect.right, myrect.bottom);
361 newcolor = GetSysColor (COLOR_BTNSHADOW);
362 oldcolor = SetBkColor (hdc, newcolor);
363 ExtTextOutA (hdc, 0, 0, ETO_OPAQUE, &myrect, 0, 0, 0);
365 myrect.top = myrect.bottom;
366 myrect.bottom = myrect.top + 1;
368 newcolor = GetSysColor (COLOR_BTNHIGHLIGHT);
369 SetBkColor (hdc, newcolor);
370 ExtTextOutA (hdc, 0, 0, ETO_OPAQUE, &myrect, 0, 0, 0);
372 SetBkColor (hdc, oldcolor);
377 TOOLBAR_DrawArrow (HDC hdc, INT left, INT top, INT colorRef)
380 SelectObject ( hdc, GetSysColorPen (colorRef));
383 MoveToEx (hdc, x, y, NULL);
384 LineTo (hdc, x+5, y++); x++;
385 MoveToEx (hdc, x, y, NULL);
386 LineTo (hdc, x+3, y++); x++;
387 MoveToEx (hdc, x, y, NULL);
388 LineTo (hdc, x+1, y++);
392 * Draw the text string for this button.
393 * note: infoPtr->himlDis *SHOULD* be non-zero when infoPtr->himlDef
394 * is non-zero, so we can simply check himlDef to see if we have
398 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
399 HDC hdc, INT nState, DWORD dwStyle)
401 RECT rcText = btnPtr->rect;
405 LPWSTR lpText = NULL;
406 HIMAGELIST himl = infoPtr->himlDef;
408 TRACE ("iString: %x\n", btnPtr->iString);
410 /* get a pointer to the text */
411 lpText = TOOLBAR_GetText(infoPtr, btnPtr);
413 TRACE ("lpText: %s\n", debugstr_w(lpText));
418 InflateRect (&rcText, -3, -3);
420 if (himl && TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
421 /* The following test looked like this before
422 * I changed it. IE4 "Links" toolbar would not
423 * draw correctly with the original code. - GA 8/01
424 * ((dwStyle & TBSTYLE_LIST) &&
425 * ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
426 * (btnPtr->iBitmap != I_IMAGENONE))
428 if (dwStyle & TBSTYLE_LIST) {
429 /* LIST style w/ ICON offset is by matching native. */
430 /* Matches IE4 "Links" bar. - GA 8/01 */
431 rcText.left += (infoPtr->nBitmapWidth + 2);
434 rcText.top += infoPtr->nBitmapHeight;
438 if (dwStyle & TBSTYLE_LIST) {
439 /* LIST style w/o ICON offset is by matching native. */
440 /* Matches IE4 "menu" bar. - GA 8/01 */
445 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
446 OffsetRect (&rcText, 1, 1);
448 TRACE("string rect=(%d,%d)-(%d,%d)\n",
449 rcText.left, rcText.top, rcText.right, rcText.bottom);
451 hOldFont = SelectObject (hdc, infoPtr->hFont);
452 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
453 if (!(nState & TBSTATE_ENABLED)) {
454 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
455 OffsetRect (&rcText, 1, 1);
456 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
457 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
458 OffsetRect (&rcText, -1, -1);
459 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
461 else if (nState & TBSTATE_INDETERMINATE) {
462 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
463 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
466 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
467 DrawTextW (hdc, lpText, -1, &rcText, infoPtr->dwDTFlags);
470 SetTextColor (hdc, clrOld);
471 SelectObject (hdc, hOldFont);
472 if (nOldBkMode != TRANSPARENT)
473 SetBkMode (hdc, nOldBkMode);
479 TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
481 HBRUSH hbr = SelectObject (hdc, COMCTL32_hPattern55AABrush);
482 INT cx = lpRect->right - lpRect->left;
483 INT cy = lpRect->bottom - lpRect->top;
484 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
485 SelectObject (hdc, hbr);
490 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
491 HDC hdc, INT x, INT y)
493 /* FIXME: this function is a hack since it uses image list
494 internals directly */
496 HIMAGELIST himl = infoPtr->himlDef;
504 /* create new dc's */
505 hdcImageList = CreateCompatibleDC (0);
506 hdcMask = CreateCompatibleDC (0);
508 /* create new bitmap */
509 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
510 SelectObject (hdcMask, hbmMask);
512 /* copy the mask bitmap */
513 SelectObject (hdcImageList, himl->hbmMask);
514 SetBkColor (hdcImageList, RGB(255, 255, 255));
515 SetTextColor (hdcImageList, RGB(0, 0, 0));
516 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
517 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
519 /* draw the new mask */
520 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
521 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
522 hdcMask, 0, 0, 0xB8074A);
524 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
525 BitBlt (hdc, x, y, himl->cx, himl->cy,
526 hdcMask, 0, 0, 0xB8074A);
528 DeleteObject (hbmMask);
530 DeleteDC (hdcImageList);
535 TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
537 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
538 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
539 BOOL hasDropDownArrow = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) &&
540 (btnPtr->fsStyle & TBSTYLE_DROPDOWN);
541 RECT rc, rcArrow, rcBitmap;
543 if (btnPtr->fsState & TBSTATE_HIDDEN)
547 CopyRect (&rcArrow, &rc);
548 CopyRect(&rcBitmap, &rc);
550 FillRect( hdc, &rc, GetSysColorBrush(COLOR_BTNFACE));
552 if (hasDropDownArrow)
554 if (dwStyle & TBSTYLE_FLAT)
555 rc.right = max(rc.left, rc.right - DDARROW_WIDTH);
557 rc.right = max(rc.left, rc.right - DDARROW_WIDTH - 2);
558 rcArrow.left = rc.right;
561 /* Center the bitmap horizontally and vertically */
562 if (dwStyle & TBSTYLE_LIST)
565 rcBitmap.left+=(infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2;
567 if(TOOLBAR_HasText(infoPtr, btnPtr))
568 rcBitmap.top+=2; /* this looks to be the correct value from vmware comparison - cmm */
570 rcBitmap.top+=(infoPtr->nButtonHeight - infoPtr->nBitmapHeight) / 2;
572 TRACE("iBitmap: %d, start=(%d,%d) w=%d, h=%d\n",
573 btnPtr->iBitmap, rcBitmap.left, rcBitmap.top,
574 infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
577 if (btnPtr->fsStyle & TBSTYLE_SEP) {
578 /* with the FLAT style, iBitmap is the width and has already */
579 /* been taken into consideration in calculating the width */
580 /* so now we need to draw the vertical separator */
581 /* empirical tests show that iBitmap can/will be non-zero */
582 /* when drawing the vertical bar... */
583 if ((dwStyle & TBSTYLE_FLAT) /* && (btnPtr->iBitmap == 0) */) {
584 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN)
585 TOOLBAR_DrawDDFlatSeparator (&rc, hdc, btnPtr);
587 TOOLBAR_DrawFlatSeparator (&rc, hdc);
593 if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
594 if (!(dwStyle & TBSTYLE_FLAT))
596 DrawEdge (hdc, &rc, EDGE_RAISED,
597 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
598 if (hasDropDownArrow)
599 DrawEdge (hdc, &rcArrow, EDGE_RAISED,
600 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
603 if (hasDropDownArrow)
605 TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top+1, COLOR_3DHIGHLIGHT);
606 TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_3DSHADOW);
609 if (!TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDis,
610 hdc, rcBitmap.left, rcBitmap.top,
612 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
614 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
618 /* pressed TBSTYLE_BUTTON */
619 if (btnPtr->fsState & TBSTATE_PRESSED) {
620 if (dwStyle & TBSTYLE_FLAT)
622 DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
623 if (hasDropDownArrow)
624 DrawEdge (hdc, &rcArrow, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
628 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
629 if (hasDropDownArrow)
630 DrawEdge (hdc, &rcArrow, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
633 if (hasDropDownArrow)
634 TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
636 TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDef,
637 hdc, rcBitmap.left+1, rcBitmap.top+1,
640 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
644 /* checked TBSTYLE_CHECK */
645 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
646 (btnPtr->fsState & TBSTATE_CHECKED)) {
647 if (dwStyle & TBSTYLE_FLAT)
648 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
649 BF_RECT | BF_MIDDLE | BF_ADJUST);
651 DrawEdge (hdc, &rc, EDGE_SUNKEN,
652 BF_RECT | BF_MIDDLE | BF_ADJUST);
654 TOOLBAR_DrawPattern (hdc, &rc);
656 TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDef,
657 hdc, rcBitmap.left+1, rcBitmap.top+1,
660 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
665 if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
666 DrawEdge (hdc, &rc, EDGE_RAISED,
667 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
669 TOOLBAR_DrawPattern (hdc, &rc);
670 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
671 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
676 if (dwStyle & TBSTYLE_FLAT)
680 DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
681 if (hasDropDownArrow)
682 DrawEdge (hdc, &rcArrow, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
686 FrameRect(hdc, &rc, GetSysColorBrush(COLOR_BTNFACE));
687 if (hasDropDownArrow)
688 FrameRect(hdc, &rcArrow, GetSysColorBrush(COLOR_BTNFACE));
691 if (hasDropDownArrow)
692 TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top, COLOR_WINDOWFRAME);
695 /* if hot, attempt to draw with himlHot, if fails, use himlDef */
696 if (!TOOLBAR_DrawImageList (infoPtr, btnPtr,
699 rcBitmap.top, ILD_NORMAL))
700 TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDef,
701 hdc, rcBitmap.left, rcBitmap.top,
705 TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDef,
706 hdc, rcBitmap.left, rcBitmap.top,
711 DrawEdge (hdc, &rc, EDGE_RAISED,
712 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
714 if (hasDropDownArrow)
716 DrawEdge (hdc, &rcArrow, EDGE_RAISED,
717 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
718 TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top, COLOR_WINDOWFRAME);
721 TOOLBAR_DrawImageList (infoPtr, btnPtr, infoPtr->himlDef,
722 hdc, rcBitmap.left, rcBitmap.top,
726 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
731 TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
733 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
734 TBUTTON_INFO *btnPtr;
738 /* if imagelist belongs to the app, it can be changed
739 by the app after setting it */
740 if (infoPtr->himlDef != infoPtr->himlInt)
741 infoPtr->nNumBitmaps = ImageList_GetImageCount(infoPtr->himlDef);
743 TOOLBAR_DumpToolbar (infoPtr, __LINE__);
745 /* redraw necessary buttons */
746 btnPtr = infoPtr->buttons;
747 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
749 if(IntersectRect(&rcTemp, &(ps->rcPaint), &(btnPtr->rect)))
750 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
754 /***********************************************************************
755 * TOOLBAR_MeasureString
757 * This function gets the width and height of a string in pixels. This
758 * is done first by using GetTextExtentPoint to get the basic width
759 * and height. The DrawText is called with DT_CALCRECT to get the exact
760 * width. The reason is because the text may have more than one "&" (or
761 * prefix characters as M$ likes to call them). The prefix character
762 * indicates where the underline goes, except for the string "&&" which
763 * is reduced to a single "&". GetTextExtentPoint does not process these
764 * only DrawText does. Note that the TBSTYLE_NOPREFIX is handled here.
767 TOOLBAR_MeasureString(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
768 HDC hdc, LPSIZE lpSize)
775 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
776 (btnPtr->iString > -1) &&
777 (btnPtr->iString < infoPtr->nNumStrings))
779 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
781 /* first get size of all the text */
782 GetTextExtentPoint32W (hdc, lpText, strlenW (lpText), lpSize);
784 /* feed above size into the rectangle for DrawText */
785 myrect.left = myrect.top = 0;
786 myrect.right = lpSize->cx;
787 myrect.bottom = lpSize->cy;
789 /* Use DrawText to get true size as drawn (less pesky "&") */
790 DrawTextW (hdc, lpText, -1, &myrect, DT_VCENTER | DT_SINGLELINE |
791 DT_CALCRECT | ((btnPtr->fsStyle & TBSTYLE_NOPREFIX) ?
794 /* feed back to caller */
795 lpSize->cx = myrect.right;
796 lpSize->cy = myrect.bottom;
799 TRACE("string size %ld x %ld!\n", lpSize->cx, lpSize->cy);
802 /***********************************************************************
803 * TOOLBAR_CalcStrings
805 * This function walks through each string and measures it and returns
806 * the largest height and width to caller.
809 TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
811 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
812 TBUTTON_INFO *btnPtr;
822 hOldFont = SelectObject (hdc, infoPtr->hFont);
824 btnPtr = infoPtr->buttons;
825 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
826 if(TOOLBAR_HasText(infoPtr, btnPtr))
828 TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);
829 if (sz.cx > lpSize->cx)
831 if (sz.cy > lpSize->cy)
836 SelectObject (hdc, hOldFont);
837 ReleaseDC (hwnd, hdc);
839 TRACE("max string size %ld x %ld!\n", lpSize->cx, lpSize->cy);
842 /***********************************************************************
843 * TOOLBAR_WrapToolbar
845 * This function walks through the buttons and seperators in the
846 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
847 * wrapping should occur based on the width of the toolbar window.
848 * It does *not* calculate button placement itself. That task
849 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
850 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
851 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
855 TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
857 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
858 TBUTTON_INFO *btnPtr;
861 BOOL bWrap, bButtonWrap;
863 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
864 /* no layout is necessary. Applications may use this style */
865 /* to perform their own layout on the toolbar. */
866 if( !(dwStyle & TBSTYLE_WRAPABLE) )
869 btnPtr = infoPtr->buttons;
870 x = infoPtr->nIndent;
872 /* this can get the parents width, to know how far we can extend
873 * this toolbar. We cannot use its height, as there may be multiple
874 * toolbars in a rebar control
876 GetClientRect( GetParent(hwnd), &rc );
877 infoPtr->nWidth = rc.right - rc.left;
880 TRACE("start ButtonWidth=%d, BitmapWidth=%d, nWidth=%d, nIndent=%d\n",
881 infoPtr->nButtonWidth, infoPtr->nBitmapWidth, infoPtr->nWidth,
884 for (i = 0; i < infoPtr->nNumButtons; i++ )
887 btnPtr[i].fsState &= ~TBSTATE_WRAP;
889 if (btnPtr[i].fsState & TBSTATE_HIDDEN)
892 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
893 /* it is the actual width of the separator. This is used for */
894 /* custom controls in toolbars. */
896 /* TBSTYLE_DROPDOWN separators are treated as buttons for */
897 /* width. - GA 8/01 */
898 if ((btnPtr[i].fsStyle & TBSTYLE_SEP) &&
899 !(btnPtr[i].fsStyle & TBSTYLE_DROPDOWN))
900 cx = (btnPtr[i].iBitmap > 0) ?
901 btnPtr[i].iBitmap : SEPARATOR_WIDTH;
903 cx = infoPtr->nButtonWidth;
905 /* Two or more adjacent separators form a separator group. */
906 /* The first separator in a group should be wrapped to the */
907 /* next row if the previous wrapping is on a button. */
909 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
910 (i + 1 < infoPtr->nNumButtons ) &&
911 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
913 TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle);
914 btnPtr[i].fsState |= TBSTATE_WRAP;
915 x = infoPtr->nIndent;
921 /* The layout makes sure the bitmap is visible, but not the button. */
922 /* Test added to also wrap after a button that starts a row but */
923 /* is bigger than the area. - GA 8/01 */
924 if (( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
925 > infoPtr->nWidth ) ||
926 ((x == infoPtr->nIndent) && (cx > infoPtr->nWidth)))
930 /* If the current button is a separator and not hidden, */
931 /* go to the next until it reaches a non separator. */
932 /* Wrap the last separator if it is before a button. */
933 while( ( (btnPtr[i].fsStyle & TBSTYLE_SEP) ||
934 (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
935 i < infoPtr->nNumButtons )
941 if( bFound && i < infoPtr->nNumButtons )
944 TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n",
945 i, btnPtr[i].fsStyle, x, cx);
946 btnPtr[i].fsState |= TBSTATE_WRAP;
947 x = infoPtr->nIndent;
951 else if ( i >= infoPtr->nNumButtons)
954 /* If the current button is not a separator, find the last */
955 /* separator and wrap it. */
956 for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
958 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
959 !(btnPtr[j].fsState & TBSTATE_HIDDEN))
963 TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n",
964 i, btnPtr[i].fsStyle, x, cx);
965 x = infoPtr->nIndent;
966 btnPtr[j].fsState |= TBSTATE_WRAP;
972 /* If no separator available for wrapping, wrap one of */
973 /* non-hidden previous button. */
977 j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
979 if (btnPtr[j].fsState & TBSTATE_HIDDEN)
984 TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n",
985 i, btnPtr[i].fsStyle, x, cx);
986 x = infoPtr->nIndent;
987 btnPtr[j].fsState |= TBSTATE_WRAP;
993 /* If all above failed, wrap the current button. */
996 TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n",
997 i, btnPtr[i].fsStyle, x, cx);
998 btnPtr[i].fsState |= TBSTATE_WRAP;
1000 x = infoPtr->nIndent;
1001 if (btnPtr[i].fsStyle & TBSTYLE_SEP )
1002 bButtonWrap = FALSE;
1008 TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n",
1009 i, btnPtr[i].fsStyle, x, cx);
1016 /***********************************************************************
1017 * TOOLBAR_CalcToolbar
1019 * This function calculates button and separator placement. It first
1020 * calculates the button sizes, gets the toolbar window width and then
1021 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
1022 * on. It assigns a new location to each item and sends this location to
1023 * the tooltip window if appropriate. Finally, it updates the rcBound
1024 * rect and calculates the new required toolbar window height.
1028 TOOLBAR_CalcToolbar (HWND hwnd)
1030 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
1031 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1032 TBUTTON_INFO *btnPtr;
1033 INT i, nRows, nSepRows;
1037 BOOL usesBitmaps = FALSE;
1038 BOOL hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle);
1040 TOOLBAR_CalcStrings (hwnd, &sizeString);
1042 if (dwStyle & TBSTYLE_LIST)
1044 infoPtr->nButtonHeight = max(infoPtr->nBitmapHeight, sizeString.cy) + 6;
1045 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + sizeString.cx + 6;
1048 for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
1050 if (TOOLBAR_IsValidBitmapIndex(infoPtr,infoPtr->buttons[i].iBitmap))
1054 if (sizeString.cy > 0)
1057 infoPtr->nButtonHeight = sizeString.cy +
1058 infoPtr->nBitmapHeight + 6;
1060 infoPtr->nButtonHeight = sizeString.cy + 6;
1062 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
1063 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
1065 if (sizeString.cx > infoPtr->nBitmapWidth)
1066 infoPtr->nButtonWidth = sizeString.cx + 6;
1067 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
1068 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
1071 if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin )
1072 infoPtr->nButtonWidth = infoPtr->cxMin;
1073 if ( infoPtr->cxMax >= 0 && infoPtr->nButtonWidth > infoPtr->cxMax )
1074 infoPtr->nButtonWidth = infoPtr->cxMax;
1076 TOOLBAR_WrapToolbar( hwnd, dwStyle );
1078 x = infoPtr->nIndent;
1079 y = (dwStyle & TBSTYLE_FLAT) ? 0 : TOP_BORDER;
1082 * We will set the height below, and we set the width on entry
1083 * so we do not reset them here..
1086 GetClientRect( hwnd, &rc );
1087 /* get initial values for toolbar */
1088 infoPtr->nWidth = rc.right - rc.left;
1089 infoPtr->nHeight = rc.bottom - rc.top;
1092 /* from above, minimum is a button, and possible text */
1093 cx = infoPtr->nButtonWidth;
1095 /* cannot use just ButtonHeight, we may have no buttons! */
1096 if (infoPtr->nNumButtons > 0)
1097 infoPtr->nHeight = infoPtr->nButtonHeight;
1099 cy = infoPtr->nHeight;
1101 nRows = nSepRows = 0;
1103 infoPtr->rcBound.top = y;
1104 infoPtr->rcBound.left = x;
1105 infoPtr->rcBound.bottom = y + cy;
1106 infoPtr->rcBound.right = x;
1108 btnPtr = infoPtr->buttons;
1110 /* do not base height/width on parent, if the parent is a */
1111 /* rebar control it could have multiple rows of toolbars */
1112 /* GetClientRect( GetParent(hwnd), &rc ); */
1113 /* cx = rc.right - rc.left; */
1114 /* cy = rc.bottom - rc.top; */
1116 TRACE("cy=%d\n", cy);
1118 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
1121 if (btnPtr->fsState & TBSTATE_HIDDEN)
1123 SetRectEmpty (&btnPtr->rect);
1127 cy = infoPtr->nHeight;
1129 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
1130 /* it is the actual width of the separator. This is used for */
1131 /* custom controls in toolbars. */
1132 if (btnPtr->fsStyle & TBSTYLE_SEP) {
1133 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN) {
1134 cy = (btnPtr->iBitmap > 0) ?
1135 btnPtr->iBitmap : SEPARATOR_WIDTH;
1136 cx = infoPtr->nButtonWidth;
1139 cx = (btnPtr->iBitmap > 0) ?
1140 btnPtr->iBitmap : SEPARATOR_WIDTH;
1144 if (btnPtr->fsStyle & TBSTYLE_AUTOSIZE)
1151 hOldFont = SelectObject (hdc, infoPtr->hFont);
1153 TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz);
1155 SelectObject (hdc, hOldFont);
1156 ReleaseDC (hwnd, hdc);
1158 /* Fudge amount measured against IE4 "menu" and "Links" */
1159 /* toolbars with native control (v4.71). - GA 8/01 */
1160 cx = sz.cx + 6 + 5 + 5;
1161 if ((dwStyle & TBSTYLE_LIST) &&
1162 (TOOLBAR_TestImageExist (infoPtr, btnPtr, infoPtr->himlDef)))
1163 cx += infoPtr->nBitmapWidth;
1166 cx = infoPtr->nButtonWidth;
1168 if (hasDropDownArrows && (btnPtr->fsStyle & TBSTYLE_DROPDOWN))
1169 cx += DDARROW_WIDTH;
1171 if (btnPtr->fsState & TBSTATE_WRAP )
1174 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
1176 if (infoPtr->rcBound.left > x)
1177 infoPtr->rcBound.left = x;
1178 if (infoPtr->rcBound.right < x + cx)
1179 infoPtr->rcBound.right = x + cx;
1180 if (infoPtr->rcBound.bottom < y + cy)
1181 infoPtr->rcBound.bottom = y + cy;
1183 /* Set the toolTip only for non-hidden, non-separator button */
1184 if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP ))
1188 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1189 ti.cbSize = sizeof(TTTOOLINFOA);
1191 ti.uId = btnPtr->idCommand;
1192 ti.rect = btnPtr->rect;
1193 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
1197 /* btnPtr->nRow is zero based. The space between the rows is */
1198 /* also considered as a row. */
1199 btnPtr->nRow = nRows + nSepRows;
1201 TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d\n",
1202 i, btnPtr->fsStyle, bWrap, nRows, nSepRows, btnPtr->nRow);
1206 if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
1210 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
1211 /* it is the actual width of the separator. This is used for */
1212 /* custom controls in toolbars. */
1213 if ( !(btnPtr->fsStyle & TBSTYLE_DROPDOWN))
1214 y += cy + ( (btnPtr->iBitmap > 0 ) ?
1215 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
1219 /* nSepRows is used to calculate the extra height follwoing */
1223 x = infoPtr->nIndent;
1230 /* infoPtr->nRows is the number of rows on the toolbar */
1231 infoPtr->nRows = nRows + nSepRows + 1;
1233 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
1235 infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
1236 nSepRows * (SEPARATOR_WIDTH * 2 / 3) +
1237 nSepRows * (infoPtr->nBitmapHeight + 1) +
1239 TRACE("toolbar height %d, button width %d\n", infoPtr->nHeight, infoPtr->nButtonWidth);
1244 TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
1246 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1247 TBUTTON_INFO *btnPtr;
1250 btnPtr = infoPtr->buttons;
1251 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
1252 if (btnPtr->fsState & TBSTATE_HIDDEN)
1255 if (btnPtr->fsStyle & TBSTYLE_SEP) {
1256 if (PtInRect (&btnPtr->rect, *lpPt)) {
1257 TRACE(" ON SEPARATOR %d!\n", i);
1262 if (PtInRect (&btnPtr->rect, *lpPt)) {
1263 TRACE(" ON BUTTON %d!\n", i);
1269 TRACE(" NOWHERE!\n");
1275 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
1277 TBUTTON_INFO *btnPtr;
1280 btnPtr = infoPtr->buttons;
1281 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
1282 if (btnPtr->idCommand == idCommand) {
1283 TRACE("command=%d index=%d\n", idCommand, i);
1287 TRACE("no index found for command=%d\n", idCommand);
1293 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
1295 TBUTTON_INFO *btnPtr;
1298 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
1301 /* check index button */
1302 btnPtr = &infoPtr->buttons[nIndex];
1303 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
1304 if (btnPtr->fsState & TBSTATE_CHECKED)
1308 /* check previous buttons */
1309 nRunIndex = nIndex - 1;
1310 while (nRunIndex >= 0) {
1311 btnPtr = &infoPtr->buttons[nRunIndex];
1312 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
1313 if (btnPtr->fsState & TBSTATE_CHECKED)
1321 /* check next buttons */
1322 nRunIndex = nIndex + 1;
1323 while (nRunIndex < infoPtr->nNumButtons) {
1324 btnPtr = &infoPtr->buttons[nRunIndex];
1325 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
1326 if (btnPtr->fsState & TBSTATE_CHECKED)
1339 TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
1340 WPARAM wParam, LPARAM lParam)
1346 msg.wParam = wParam;
1347 msg.lParam = lParam;
1348 msg.time = GetMessageTime ();
1349 msg.pt.x = LOWORD(GetMessagePos ());
1350 msg.pt.y = HIWORD(GetMessagePos ());
1352 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
1356 /***********************************************************************
1357 * TOOLBAR_CustomizeDialogProc
1358 * This function implements the toolbar customization dialog.
1361 TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1363 PCUSTDLG_INFO custInfo = (PCUSTDLG_INFO)GetWindowLongA (hwnd, DWL_USER);
1364 PCUSTOMBUTTON btnInfo;
1366 TOOLBAR_INFO *infoPtr = custInfo->tbInfo;
1371 custInfo = (PCUSTDLG_INFO)lParam;
1372 SetWindowLongA (hwnd, DWL_USER, (DWORD)custInfo);
1380 /* send TBN_QUERYINSERT notification */
1381 nmtb.iItem = custInfo->tbInfo->nNumButtons;
1383 if (!TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_QUERYINSERT))
1386 /* add items to 'toolbar buttons' list and check if removable */
1387 for (i = 0; i < custInfo->tbInfo->nNumButtons; i++)
1389 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1390 memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
1391 btnInfo->btn.fsStyle = TBSTYLE_SEP;
1392 btnInfo->bVirtual = FALSE;
1393 LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
1395 /* send TBN_QUERYDELETE notification */
1397 btnInfo->bRemovable = TOOLBAR_SendNotify ((NMHDR *) &nmtb,
1401 index = (int)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, 0);
1402 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1405 /* insert separator button into 'available buttons' list */
1406 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1407 memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
1408 btnInfo->btn.fsStyle = TBSTYLE_SEP;
1409 btnInfo->bVirtual = FALSE;
1410 btnInfo->bRemovable = TRUE;
1411 LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
1412 index = (int)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
1413 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1415 /* insert all buttons into dsa */
1418 /* send TBN_GETBUTTONINFO notification */
1420 nmtb.pszText = Buffer;
1423 if (!TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_GETBUTTONINFOA))
1426 TRACE("style: %x\n", nmtb.tbButton.fsStyle);
1428 /* insert button into the apropriate list */
1429 index = TOOLBAR_GetButtonIndex (custInfo->tbInfo, nmtb.tbButton.idCommand);
1432 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1433 memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
1434 btnInfo->bVirtual = FALSE;
1435 btnInfo->bRemovable = TRUE;
1436 if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
1437 strcpy (btnInfo->text, nmtb.pszText);
1439 index = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, 0);
1440 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1444 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1445 memcpy (&btnInfo->btn, &nmtb.tbButton, sizeof(TBBUTTON));
1446 if (!(nmtb.tbButton.fsStyle & TBSTYLE_SEP))
1447 strcpy (btnInfo->text, nmtb.pszText);
1449 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1453 /* select first item in the 'available' list */
1454 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, 0, 0);
1456 /* append 'virtual' separator button to the 'toolbar buttons' list */
1457 btnInfo = (PCUSTOMBUTTON)COMCTL32_Alloc(sizeof(CUSTOMBUTTON));
1458 memset (&btnInfo->btn, 0, sizeof(TBBUTTON));
1459 btnInfo->btn.fsStyle = TBSTYLE_SEP;
1460 btnInfo->bVirtual = TRUE;
1461 btnInfo->bRemovable = FALSE;
1462 LoadStringA (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
1463 index = (int)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
1464 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1466 /* select last item in the 'toolbar' list */
1467 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index, 0);
1468 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETTOPINDEX, index, 0);
1470 /* set focus and disable buttons */
1471 PostMessageA (hwnd, WM_USER, 0, 0);
1476 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1477 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1478 EnableWindow (GetDlgItem (hwnd,IDC_REMOVE_BTN), FALSE);
1479 SetFocus (GetDlgItem (hwnd, IDC_TOOLBARBTN_LBOX));
1483 EndDialog(hwnd, FALSE);
1487 switch (LOWORD(wParam))
1489 case IDC_TOOLBARBTN_LBOX:
1490 if (HIWORD(wParam) == LBN_SELCHANGE)
1492 PCUSTOMBUTTON btnInfo;
1497 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1498 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1500 /* send TBN_QUERYINSERT notification */
1502 TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
1505 /* get list box item */
1506 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1508 if (index == (count - 1))
1510 /* last item (virtual separator) */
1511 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1512 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1514 else if (index == (count - 2))
1516 /* second last item (last non-virtual item) */
1517 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
1518 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1520 else if (index == 0)
1523 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1524 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
1528 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
1529 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
1532 EnableWindow (GetDlgItem (hwnd,IDC_REMOVE_BTN), btnInfo->bRemovable);
1536 case IDC_MOVEUP_BTN:
1538 PCUSTOMBUTTON btnInfo;
1542 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1543 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1544 TRACE("Move up: index %d\n", index);
1546 /* send TBN_QUERYINSERT notification */
1549 if (TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
1552 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1554 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_DELETESTRING, index, 0);
1555 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_INSERTSTRING, index-1, 0);
1556 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index-1, (LPARAM)btnInfo);
1557 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index-1 , 0);
1560 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), FALSE);
1561 else if (index >= (count - 3))
1562 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), TRUE);
1564 SendMessageA (custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
1565 SendMessageA (custInfo->tbHwnd, TB_INSERTBUTTONA, index-1, (LPARAM)&(btnInfo->btn));
1570 case IDC_MOVEDN_BTN: /* move down */
1572 PCUSTOMBUTTON btnInfo;
1576 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1577 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1578 TRACE("Move up: index %d\n", index);
1580 /* send TBN_QUERYINSERT notification */
1582 if (TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
1585 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1587 /* move button down */
1588 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_DELETESTRING, index, 0);
1589 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_INSERTSTRING, index+1, 0);
1590 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index+1, (LPARAM)btnInfo);
1591 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index+1 , 0);
1594 EnableWindow (GetDlgItem (hwnd,IDC_MOVEUP_BTN), TRUE);
1595 else if (index >= (count - 3))
1596 EnableWindow (GetDlgItem (hwnd,IDC_MOVEDN_BTN), FALSE);
1598 SendMessageA (custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
1599 SendMessageA (custInfo->tbHwnd, TB_INSERTBUTTONA, index+1, (LPARAM)&(btnInfo->btn));
1604 case IDC_REMOVE_BTN: /* remove button */
1606 PCUSTOMBUTTON btnInfo;
1609 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1610 TRACE("Remove: index %d\n", index);
1612 /* send TBN_QUERYDELETE notification */
1614 if (TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
1617 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
1618 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_DELETESTRING, index, 0);
1619 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index , 0);
1621 SendMessageA (custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
1623 /* insert into 'available button' list */
1624 if (!(btnInfo->btn.fsStyle & TBSTYLE_SEP))
1626 index = (int)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, 0);
1627 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1630 COMCTL32_Free (btnInfo);
1635 case IDOK: /* Add button */
1640 count = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETCOUNT, 0, 0);
1641 index = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETCURSEL, 0, 0);
1642 TRACE("Add: index %d\n", index);
1644 /* send TBN_QUERYINSERT notification */
1646 if (TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
1649 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, index, 0);
1653 /* remove from 'available buttons' list */
1654 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_DELETESTRING, index, 0);
1655 if (index == count-1)
1656 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, index-1 , 0);
1658 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, index , 0);
1662 PCUSTOMBUTTON btnNew;
1664 /* duplicate 'separator' button */
1665 btnNew = (PCUSTOMBUTTON)COMCTL32_Alloc (sizeof(CUSTOMBUTTON));
1666 memcpy (btnNew, btnInfo, sizeof(CUSTOMBUTTON));
1670 /* insert into 'toolbar button' list */
1671 index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
1672 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_INSERTSTRING, index, 0);
1673 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
1675 SendMessageA (custInfo->tbHwnd, TB_INSERTBUTTONA, index, (LPARAM)&(btnInfo->btn));
1681 EndDialog(hwnd, FALSE);
1691 /* delete items from 'toolbar buttons' listbox*/
1692 count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
1693 for (i = 0; i < count; i++)
1695 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, i, 0);
1696 COMCTL32_Free(btnInfo);
1697 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, 0, 0);
1699 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_RESETCONTENT, 0, 0);
1702 /* delete items from 'available buttons' listbox*/
1703 count = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETCOUNT, 0, 0);
1704 for (i = 0; i < count; i++)
1706 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, i, 0);
1707 COMCTL32_Free(btnInfo);
1708 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, i, 0);
1710 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_RESETCONTENT, 0, 0);
1715 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1717 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
1722 COLORREF oldText = 0;
1726 btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, wParam, LB_GETITEMDATA, (WPARAM)lpdis->itemID, 0);
1727 if (btnInfo == NULL)
1729 FIXME("btnInfo invalid!\n");
1733 /* set colors and select objects */
1734 oldBk = SetBkColor (lpdis->hDC, GetSysColor((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1735 if (btnInfo->bVirtual)
1736 oldText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_GRAYTEXT));
1738 oldText = SetTextColor (lpdis->hDC, GetSysColor((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHTTEXT:COLOR_WINDOWTEXT));
1739 hOldPen = SelectObject (lpdis->hDC, GetSysColorPen ((lpdis->itemState & ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1740 hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1742 /* fill background rectangle */
1743 Rectangle (lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
1744 lpdis->rcItem.right, lpdis->rcItem.bottom);
1746 /* calculate button and text rectangles */
1747 CopyRect (&rcButton, &lpdis->rcItem);
1748 InflateRect (&rcButton, -1, -1);
1749 CopyRect (&rcText, &rcButton);
1750 rcButton.right = rcButton.left + custInfo->tbInfo->nBitmapWidth + 6;
1751 rcText.left = rcButton.right + 2;
1753 /* draw focus rectangle */
1754 if (lpdis->itemState & ODS_FOCUS)
1755 DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
1758 DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
1760 /* draw image and text */
1761 if ((btnInfo->btn.fsStyle & TBSTYLE_SEP) == 0)
1762 ImageList_Draw (custInfo->tbInfo->himlDef, btnInfo->btn.iBitmap, lpdis->hDC,
1763 rcButton.left+3, rcButton.top+3, ILD_NORMAL);
1764 DrawTextA (lpdis->hDC, btnInfo->text, -1, &rcText,
1765 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1767 /* delete objects and reset colors */
1768 SelectObject (lpdis->hDC, hOldBrush);
1769 SelectObject (lpdis->hDC, hOldPen);
1770 SetBkColor (lpdis->hDC, oldBk);
1771 SetTextColor (lpdis->hDC, oldText);
1777 case WM_MEASUREITEM:
1778 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1780 MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*)lParam;
1782 if (custInfo && custInfo->tbInfo)
1783 lpmis->itemHeight = custInfo->tbInfo->nBitmapHeight + 8;
1785 lpmis->itemHeight = 15 + 8; /* default height */
1797 /***********************************************************************
1798 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1802 TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1804 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1805 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
1806 INT nIndex = 0, nButtons, nCount;
1809 TRACE("hwnd=%x wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
1813 if (lpAddBmp->hInst == HINST_COMMCTRL)
1815 if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR)
1817 else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR)
1819 else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR)
1824 TRACE ("adding %d internal bitmaps!\n", nButtons);
1826 /* Windows resize all the buttons to the size of a newly added standard image */
1827 if (lpAddBmp->nID & 1)
1830 /* FIXME: on windows the size of the images is 25x24 but the size of the bitmap
1831 * in rsrc is only 24x24. Fix the bitmap (how?) and then fix this
1833 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1834 MAKELPARAM((WORD)24, (WORD)24));
1835 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1836 MAKELPARAM((WORD)31, (WORD)30));
1841 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1842 MAKELPARAM((WORD)16, (WORD)16));
1843 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1844 MAKELPARAM((WORD)22, (WORD)22));
1847 TOOLBAR_CalcToolbar (hwnd);
1851 nButtons = (INT)wParam;
1855 TRACE ("adding %d bitmaps!\n", nButtons);
1858 if (!(infoPtr->himlDef)) {
1859 /* create new default image list */
1860 TRACE ("creating default image list!\n");
1863 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
1864 ILC_COLOR | ILC_MASK, nButtons, 2);
1865 infoPtr->himlInt = infoPtr->himlDef;
1868 nCount = ImageList_GetImageCount(infoPtr->himlDef);
1870 /* Add bitmaps to the default image list */
1871 if (lpAddBmp->hInst == (HINSTANCE)0)
1874 ImageList_AddMasked (infoPtr->himlDef, (HBITMAP)lpAddBmp->nID,
1877 else if (lpAddBmp->hInst == HINST_COMMCTRL)
1879 /* Add system bitmaps */
1880 switch (lpAddBmp->nID)
1882 case IDB_STD_SMALL_COLOR:
1883 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1884 MAKEINTRESOURCEA(IDB_STD_SMALL));
1885 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1886 hbmLoad, CLR_DEFAULT);
1887 DeleteObject (hbmLoad);
1890 case IDB_STD_LARGE_COLOR:
1891 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1892 MAKEINTRESOURCEA(IDB_STD_LARGE));
1893 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1894 hbmLoad, CLR_DEFAULT);
1895 DeleteObject (hbmLoad);
1898 case IDB_VIEW_SMALL_COLOR:
1899 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1900 MAKEINTRESOURCEA(IDB_VIEW_SMALL));
1901 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1902 hbmLoad, CLR_DEFAULT);
1903 DeleteObject (hbmLoad);
1906 case IDB_VIEW_LARGE_COLOR:
1907 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1908 MAKEINTRESOURCEA(IDB_VIEW_LARGE));
1909 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1910 hbmLoad, CLR_DEFAULT);
1911 DeleteObject (hbmLoad);
1914 case IDB_HIST_SMALL_COLOR:
1915 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1916 MAKEINTRESOURCEA(IDB_HIST_SMALL));
1917 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1918 hbmLoad, CLR_DEFAULT);
1919 DeleteObject (hbmLoad);
1922 case IDB_HIST_LARGE_COLOR:
1923 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1924 MAKEINTRESOURCEA(IDB_HIST_LARGE));
1925 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1926 hbmLoad, CLR_DEFAULT);
1927 DeleteObject (hbmLoad);
1931 nIndex = ImageList_GetImageCount (infoPtr->himlDef);
1932 ERR ("invalid imagelist!\n");
1938 hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
1939 nIndex = ImageList_AddMasked (infoPtr->himlDef, hbmLoad, CLR_DEFAULT);
1940 DeleteObject (hbmLoad);
1945 INT imagecount = ImageList_GetImageCount(infoPtr->himlDef);
1947 if (infoPtr->nNumBitmaps + nButtons != imagecount)
1949 WARN("Desired images do not match received images : Previous image number %i Previous images in list %i added %i expecting total %i, Images in list %i\n",
1950 infoPtr->nNumBitmaps, nCount, imagecount - nCount,
1951 infoPtr->nNumBitmaps+nButtons,imagecount);
1953 infoPtr->nNumBitmaps = imagecount;
1956 infoPtr->nNumBitmaps += nButtons;
1959 InvalidateRect(hwnd, NULL, FALSE);
1966 TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1968 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1969 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1970 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1972 TRACE("adding %d buttons!\n", wParam);
1974 nAddButtons = (UINT)wParam;
1975 nOldButtons = infoPtr->nNumButtons;
1976 nNewButtons = nOldButtons + nAddButtons;
1978 if (infoPtr->nNumButtons == 0) {
1980 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1983 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1985 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1986 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1987 nOldButtons * sizeof(TBUTTON_INFO));
1988 COMCTL32_Free (oldButtons);
1991 infoPtr->nNumButtons = nNewButtons;
1993 /* insert new button data */
1994 for (nCount = 0; nCount < nAddButtons; nCount++) {
1995 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1996 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1997 btnPtr->idCommand = lpTbb[nCount].idCommand;
1998 btnPtr->fsState = lpTbb[nCount].fsState;
1999 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
2000 btnPtr->dwData = lpTbb[nCount].dwData;
2001 btnPtr->iString = lpTbb[nCount].iString;
2002 btnPtr->bHot = FALSE;
2004 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
2007 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2008 ti.cbSize = sizeof (TTTOOLINFOA);
2010 ti.uId = btnPtr->idCommand;
2012 ti.lpszText = LPSTR_TEXTCALLBACKA;
2014 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
2019 TOOLBAR_CalcToolbar (hwnd);
2021 InvalidateRect(hwnd, NULL, FALSE);
2028 TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2030 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2031 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2032 INT nOldButtons, nNewButtons, nAddButtons, nCount;
2034 TRACE("adding %d buttons!\n", wParam);
2036 nAddButtons = (UINT)wParam;
2037 nOldButtons = infoPtr->nNumButtons;
2038 nNewButtons = nOldButtons + nAddButtons;
2040 if (infoPtr->nNumButtons == 0) {
2042 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
2045 TBUTTON_INFO *oldButtons = infoPtr->buttons;
2047 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
2048 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2049 nOldButtons * sizeof(TBUTTON_INFO));
2050 COMCTL32_Free (oldButtons);
2053 infoPtr->nNumButtons = nNewButtons;
2055 /* insert new button data */
2056 for (nCount = 0; nCount < nAddButtons; nCount++) {
2057 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
2058 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
2059 btnPtr->idCommand = lpTbb[nCount].idCommand;
2060 btnPtr->fsState = lpTbb[nCount].fsState;
2061 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
2062 btnPtr->dwData = lpTbb[nCount].dwData;
2063 btnPtr->iString = lpTbb[nCount].iString;
2064 btnPtr->bHot = FALSE;
2066 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
2069 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
2070 ti.cbSize = sizeof (TTTOOLINFOW);
2072 ti.uId = btnPtr->idCommand;
2074 ti.lpszText = LPSTR_TEXTCALLBACKW;
2076 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
2081 TOOLBAR_CalcToolbar (hwnd);
2083 InvalidateRect(hwnd, NULL, FALSE);
2090 TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2092 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2095 if ((wParam) && (HIWORD(lParam) == 0)) {
2098 TRACE("adding string from resource!\n");
2100 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
2103 TRACE("len=%d \"%s\"\n", len, szString);
2104 nIndex = infoPtr->nNumStrings;
2105 if (infoPtr->nNumStrings == 0) {
2107 COMCTL32_Alloc (sizeof(LPWSTR));
2110 LPWSTR *oldStrings = infoPtr->strings;
2112 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
2113 memcpy (&infoPtr->strings[0], &oldStrings[0],
2114 sizeof(LPWSTR) * infoPtr->nNumStrings);
2115 COMCTL32_Free (oldStrings);
2118 lenW = MultiByteToWideChar( CP_ACP, 0, szString, -1, NULL, 0 );
2119 infoPtr->strings[infoPtr->nNumStrings] = COMCTL32_Alloc (sizeof(WCHAR)*lenW);
2120 MultiByteToWideChar( CP_ACP, 0, szString, -1,
2121 infoPtr->strings[infoPtr->nNumStrings], lenW );
2122 infoPtr->nNumStrings++;
2125 LPSTR p = (LPSTR)lParam;
2130 TRACE("adding string(s) from array!\n");
2132 nIndex = infoPtr->nNumStrings;
2135 TRACE("len=%d \"%s\"\n", len, p);
2137 if (infoPtr->nNumStrings == 0) {
2139 COMCTL32_Alloc (sizeof(LPWSTR));
2142 LPWSTR *oldStrings = infoPtr->strings;
2144 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
2145 memcpy (&infoPtr->strings[0], &oldStrings[0],
2146 sizeof(LPWSTR) * infoPtr->nNumStrings);
2147 COMCTL32_Free (oldStrings);
2150 lenW = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
2151 infoPtr->strings[infoPtr->nNumStrings] = COMCTL32_Alloc (sizeof(WCHAR)*lenW);
2152 MultiByteToWideChar( CP_ACP, 0, p, -1,
2153 infoPtr->strings[infoPtr->nNumStrings], lenW );
2154 infoPtr->nNumStrings++;
2165 TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2167 #define MAX_RESOURCE_STRING_LENGTH 512
2168 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2171 if ((wParam) && (HIWORD(lParam) == 0)) {
2172 WCHAR szString[MAX_RESOURCE_STRING_LENGTH];
2174 TRACE("adding string from resource!\n");
2176 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
2177 szString, MAX_RESOURCE_STRING_LENGTH);
2179 TRACE("len=%d %s\n", len, debugstr_w(szString));
2180 TRACE("First char: 0x%x\n", *szString);
2181 if (szString[0] == L'|')
2183 PWSTR p = szString + 1;
2185 nIndex = infoPtr->nNumStrings;
2186 while (*p != L'|') {
2188 if (infoPtr->nNumStrings == 0) {
2190 COMCTL32_Alloc (sizeof(LPWSTR));
2193 LPWSTR *oldStrings = infoPtr->strings;
2195 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
2196 memcpy (&infoPtr->strings[0], &oldStrings[0],
2197 sizeof(LPWSTR) * infoPtr->nNumStrings);
2198 COMCTL32_Free (oldStrings);
2201 len = COMCTL32_StrChrW (p, L'|') - p;
2202 TRACE("len=%d %s\n", len, debugstr_w(p));
2203 infoPtr->strings[infoPtr->nNumStrings] =
2204 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
2205 lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len);
2206 infoPtr->nNumStrings++;
2213 nIndex = infoPtr->nNumStrings;
2214 if (infoPtr->nNumStrings == 0) {
2216 COMCTL32_Alloc (sizeof(LPWSTR));
2219 LPWSTR *oldStrings = infoPtr->strings;
2221 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
2222 memcpy (&infoPtr->strings[0], &oldStrings[0],
2223 sizeof(LPWSTR) * infoPtr->nNumStrings);
2224 COMCTL32_Free (oldStrings);
2227 infoPtr->strings[infoPtr->nNumStrings] =
2228 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
2229 strcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
2230 infoPtr->nNumStrings++;
2234 LPWSTR p = (LPWSTR)lParam;
2239 TRACE("adding string(s) from array!\n");
2240 nIndex = infoPtr->nNumStrings;
2244 TRACE("len=%d %s\n", len, debugstr_w(p));
2245 if (infoPtr->nNumStrings == 0) {
2247 COMCTL32_Alloc (sizeof(LPWSTR));
2250 LPWSTR *oldStrings = infoPtr->strings;
2252 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
2253 memcpy (&infoPtr->strings[0], &oldStrings[0],
2254 sizeof(LPWSTR) * infoPtr->nNumStrings);
2255 COMCTL32_Free (oldStrings);
2258 infoPtr->strings[infoPtr->nNumStrings] =
2259 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
2260 strcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
2261 infoPtr->nNumStrings++;
2272 TOOLBAR_AutoSize (HWND hwnd)
2274 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2275 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2281 UINT uPosFlags = SWP_NOZORDER;
2283 TRACE("resize forced, style=%lx!\n", dwStyle);
2285 parent = GetParent (hwnd);
2286 GetClientRect(parent, &parent_rect);
2288 x = parent_rect.left;
2289 y = parent_rect.top;
2291 /* FIXME: we should be able to early out if nothing */
2292 /* has changed with nWidth != parent_rect width */
2294 if (dwStyle & CCS_NORESIZE) {
2295 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
2300 infoPtr->nWidth = parent_rect.right - parent_rect.left;
2301 TOOLBAR_CalcToolbar (hwnd);
2302 InvalidateRect( hwnd, NULL, TRUE );
2303 cy = infoPtr->nHeight;
2304 cx = infoPtr->nWidth;
2306 if (dwStyle & CCS_NOMOVEY) {
2307 GetWindowRect(hwnd, &window_rect);
2308 ScreenToClient(parent, (LPPOINT)&window_rect.left);
2309 y = window_rect.top;
2313 if (dwStyle & CCS_NOPARENTALIGN)
2314 uPosFlags |= SWP_NOMOVE;
2316 if (!(dwStyle & CCS_NODIVIDER))
2317 cy += GetSystemMetrics(SM_CYEDGE);
2319 if (dwStyle & WS_BORDER)
2322 cy += GetSystemMetrics(SM_CYEDGE);
2323 cx += GetSystemMetrics(SM_CYEDGE);
2326 infoPtr->bAutoSize = TRUE;
2327 SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
2329 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
2330 * the setwindowpos calls */
2331 infoPtr->bAutoSize = FALSE;
2338 TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
2340 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2342 return infoPtr->nNumButtons;
2347 TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2349 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2351 if (infoPtr == NULL) {
2352 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
2353 ERR("infoPtr == NULL!\n");
2357 infoPtr->dwStructSize = (DWORD)wParam;
2364 TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
2366 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2367 TBUTTON_INFO *btnPtr;
2370 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2374 btnPtr = &infoPtr->buttons[nIndex];
2375 btnPtr->iBitmap = LOWORD(lParam);
2377 /* we HAVE to erase the background, the new bitmap could be */
2379 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
2386 TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2388 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2389 TBUTTON_INFO *btnPtr;
2392 BOOL bChecked = FALSE;
2394 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2398 btnPtr = &infoPtr->buttons[nIndex];
2400 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
2403 bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
2405 if (LOWORD(lParam) == FALSE)
2406 btnPtr->fsState &= ~TBSTATE_CHECKED;
2408 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
2410 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
2411 if (nOldIndex == nIndex)
2413 if (nOldIndex != -1)
2414 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
2416 btnPtr->fsState |= TBSTATE_CHECKED;
2419 if( bChecked != LOWORD(lParam) )
2421 if (nOldIndex != -1)
2423 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
2424 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
2426 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
2429 /* FIXME: Send a WM_NOTIFY?? */
2436 TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
2438 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2440 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2445 TOOLBAR_Customize (HWND hwnd)
2447 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2448 CUSTDLG_INFO custInfo;
2454 custInfo.tbInfo = infoPtr;
2455 custInfo.tbHwnd = hwnd;
2457 /* send TBN_BEGINADJUST notification */
2458 TOOLBAR_SendNotify ((NMHDR *) &nmhdr, infoPtr,
2461 if (!(hRes = FindResourceA (COMCTL32_hModule,
2462 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
2466 if(!(template = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
2469 ret = DialogBoxIndirectParamA (GetWindowLongA (hwnd, GWL_HINSTANCE),
2470 (LPDLGTEMPLATEA)template,
2472 (DLGPROC)TOOLBAR_CustomizeDialogProc,
2475 /* send TBN_ENDADJUST notification */
2476 TOOLBAR_SendNotify ((NMHDR *) &nmhdr, infoPtr,
2484 TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2486 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2487 INT nIndex = (INT)wParam;
2489 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2492 if ((infoPtr->hwndToolTip) &&
2493 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
2496 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2497 ti.cbSize = sizeof (TTTOOLINFOA);
2499 ti.uId = infoPtr->buttons[nIndex].idCommand;
2501 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
2504 if (infoPtr->nNumButtons == 1) {
2505 TRACE(" simple delete!\n");
2506 COMCTL32_Free (infoPtr->buttons);
2507 infoPtr->buttons = NULL;
2508 infoPtr->nNumButtons = 0;
2511 TBUTTON_INFO *oldButtons = infoPtr->buttons;
2512 TRACE("complex delete! [nIndex=%d]\n", nIndex);
2514 infoPtr->nNumButtons--;
2515 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2517 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2518 nIndex * sizeof(TBUTTON_INFO));
2521 if (nIndex < infoPtr->nNumButtons) {
2522 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
2523 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
2526 COMCTL32_Free (oldButtons);
2529 TOOLBAR_CalcToolbar (hwnd);
2531 InvalidateRect (hwnd, NULL, TRUE);
2538 TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2540 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2541 TBUTTON_INFO *btnPtr;
2545 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2549 btnPtr = &infoPtr->buttons[nIndex];
2551 bState = btnPtr->fsState & TBSTATE_ENABLED;
2553 /* update the toolbar button state */
2554 if(LOWORD(lParam) == FALSE) {
2555 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
2557 btnPtr->fsState |= TBSTATE_ENABLED;
2560 /* redraw the button only if the state of the button changed */
2561 if(bState != (btnPtr->fsState & TBSTATE_ENABLED))
2563 InvalidateRect(hwnd, &btnPtr->rect,
2564 TOOLBAR_HasText(infoPtr, btnPtr));
2571 static inline LRESULT
2572 TOOLBAR_GetAnchorHighlight (HWND hwnd)
2574 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2576 return infoPtr->bAnchor;
2581 TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
2583 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2586 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2590 return infoPtr->buttons[nIndex].iBitmap;
2594 static inline LRESULT
2595 TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
2597 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
2602 TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2604 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2605 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2606 INT nIndex = (INT)wParam;
2607 TBUTTON_INFO *btnPtr;
2609 if (infoPtr == NULL)
2615 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2618 btnPtr = &infoPtr->buttons[nIndex];
2619 lpTbb->iBitmap = btnPtr->iBitmap;
2620 lpTbb->idCommand = btnPtr->idCommand;
2621 lpTbb->fsState = btnPtr->fsState;
2622 lpTbb->fsStyle = btnPtr->fsStyle;
2623 lpTbb->dwData = btnPtr->dwData;
2624 lpTbb->iString = btnPtr->iString;
2631 TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2633 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2634 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
2635 TBUTTON_INFO *btnPtr;
2638 if (infoPtr == NULL)
2640 if (lpTbInfo == NULL)
2642 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOA))
2645 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2649 btnPtr = &infoPtr->buttons[nIndex];
2651 if (lpTbInfo->dwMask & TBIF_COMMAND)
2652 lpTbInfo->idCommand = btnPtr->idCommand;
2653 if (lpTbInfo->dwMask & TBIF_IMAGE)
2654 lpTbInfo->iImage = btnPtr->iBitmap;
2655 if (lpTbInfo->dwMask & TBIF_LPARAM)
2656 lpTbInfo->lParam = btnPtr->dwData;
2657 if (lpTbInfo->dwMask & TBIF_SIZE)
2658 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
2659 if (lpTbInfo->dwMask & TBIF_STATE)
2660 lpTbInfo->fsState = btnPtr->fsState;
2661 if (lpTbInfo->dwMask & TBIF_STYLE)
2662 lpTbInfo->fsStyle = btnPtr->fsStyle;
2663 if (lpTbInfo->dwMask & TBIF_TEXT) {
2664 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings))
2666 if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)infoPtr->strings[btnPtr->iString], -1,
2667 lpTbInfo->pszText, lpTbInfo->cchText, NULL, NULL ))
2668 lpTbInfo->pszText[lpTbInfo->cchText-1] = 0;
2670 else lpTbInfo->pszText[0]=0;
2677 TOOLBAR_GetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2679 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2680 LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
2681 TBUTTON_INFO *btnPtr;
2684 if (infoPtr == NULL)
2686 if (lpTbInfo == NULL)
2688 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
2691 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2695 btnPtr = &infoPtr->buttons[nIndex];
2697 if (lpTbInfo->dwMask & TBIF_COMMAND)
2698 lpTbInfo->idCommand = btnPtr->idCommand;
2699 if (lpTbInfo->dwMask & TBIF_IMAGE)
2700 lpTbInfo->iImage = btnPtr->iBitmap;
2701 if (lpTbInfo->dwMask & TBIF_LPARAM)
2702 lpTbInfo->lParam = btnPtr->dwData;
2703 if (lpTbInfo->dwMask & TBIF_SIZE)
2704 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
2705 if (lpTbInfo->dwMask & TBIF_STATE)
2706 lpTbInfo->fsState = btnPtr->fsState;
2707 if (lpTbInfo->dwMask & TBIF_STYLE)
2708 lpTbInfo->fsStyle = btnPtr->fsStyle;
2709 if (lpTbInfo->dwMask & TBIF_TEXT) {
2710 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
2711 lstrcpynW (lpTbInfo->pszText,
2712 (LPWSTR)infoPtr->strings[btnPtr->iString],
2721 TOOLBAR_GetButtonSize (HWND hwnd)
2723 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2725 return MAKELONG((WORD)infoPtr->nButtonWidth,
2726 (WORD)infoPtr->nButtonHeight);
2731 TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2733 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2734 INT nIndex, nStringIndex;
2736 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2740 nStringIndex = infoPtr->buttons[nIndex].iString;
2742 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
2744 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2750 return WideCharToMultiByte( CP_ACP, 0, (LPWSTR)infoPtr->strings[nStringIndex], -1,
2751 (LPSTR)lParam, 0x7fffffff, NULL, NULL ) - 1;
2756 TOOLBAR_GetButtonTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2758 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2759 INT nIndex, nStringIndex;
2761 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2765 nStringIndex = infoPtr->buttons[nIndex].iString;
2767 TRACE("index=%d stringIndex=%d\n", nIndex, nStringIndex);
2769 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2775 strcpyW ((LPWSTR)lParam, (LPWSTR)infoPtr->strings[nStringIndex]);
2777 return strlenW ((LPWSTR)infoPtr->strings[nStringIndex]);
2781 /* << TOOLBAR_GetColorScheme >> */
2785 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2787 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2789 return (LRESULT)infoPtr->himlDis;
2793 inline static LRESULT
2794 TOOLBAR_GetExtendedStyle (HWND hwnd)
2796 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2798 return infoPtr->dwExStyle;
2803 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2805 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2807 return (LRESULT)infoPtr->himlHot;
2812 TOOLBAR_GetHotItem (HWND hwnd)
2814 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2816 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2819 if (infoPtr->nHotItem < 0)
2822 return (LRESULT)infoPtr->nHotItem;
2827 TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2829 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2831 return (LRESULT)infoPtr->himlDef;
2835 /* << TOOLBAR_GetInsertMark >> */
2836 /* << TOOLBAR_GetInsertMarkColor >> */
2840 TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2842 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2843 TBUTTON_INFO *btnPtr;
2847 if (infoPtr == NULL)
2849 nIndex = (INT)wParam;
2850 btnPtr = &infoPtr->buttons[nIndex];
2851 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2853 lpRect = (LPRECT)lParam;
2856 if (btnPtr->fsState & TBSTATE_HIDDEN)
2859 lpRect->left = btnPtr->rect.left;
2860 lpRect->right = btnPtr->rect.right;
2861 lpRect->bottom = btnPtr->rect.bottom;
2862 lpRect->top = btnPtr->rect.top;
2869 TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2871 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2872 LPSIZE lpSize = (LPSIZE)lParam;
2877 lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
2878 lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
2880 TRACE("maximum size %d x %d\n",
2881 infoPtr->rcBound.right - infoPtr->rcBound.left,
2882 infoPtr->rcBound.bottom - infoPtr->rcBound.top);
2888 /* << TOOLBAR_GetObject >> */
2889 /* << TOOLBAR_GetPadding >> */
2893 TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2895 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2896 TBUTTON_INFO *btnPtr;
2900 if (infoPtr == NULL)
2902 nIndex = (INT)wParam;
2903 btnPtr = &infoPtr->buttons[nIndex];
2904 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2906 lpRect = (LPRECT)lParam;
2910 lpRect->left = btnPtr->rect.left;
2911 lpRect->right = btnPtr->rect.right;
2912 lpRect->bottom = btnPtr->rect.bottom;
2913 lpRect->top = btnPtr->rect.top;
2920 TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2922 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2924 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
2925 return infoPtr->nRows;
2932 TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2934 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2937 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2941 return infoPtr->buttons[nIndex].fsState;
2946 TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2948 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2951 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2955 return infoPtr->buttons[nIndex].fsStyle;
2960 TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2962 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2964 if (infoPtr == NULL)
2967 return infoPtr->nMaxTextRows;
2972 TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
2974 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2976 if (infoPtr == NULL)
2978 return infoPtr->hwndToolTip;
2983 TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2985 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2987 TRACE("%s hwnd=0x%x stub!\n",
2988 infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
2990 return infoPtr->bUnicode;
2994 inline static LRESULT
2995 TOOLBAR_GetVersion (HWND hwnd)
2997 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2998 return infoPtr->iVersion;
3003 TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
3005 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3006 TBUTTON_INFO *btnPtr;
3011 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3015 btnPtr = &infoPtr->buttons[nIndex];
3016 if (LOWORD(lParam) == FALSE)
3017 btnPtr->fsState &= ~TBSTATE_HIDDEN;
3019 btnPtr->fsState |= TBSTATE_HIDDEN;
3021 TOOLBAR_CalcToolbar (hwnd);
3023 InvalidateRect (hwnd, NULL, TRUE);
3029 inline static LRESULT
3030 TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
3032 return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
3037 TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3039 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3040 TBUTTON_INFO *btnPtr;
3043 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3047 btnPtr = &infoPtr->buttons[nIndex];
3048 if (LOWORD(lParam) == FALSE)
3049 btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
3051 btnPtr->fsState |= TBSTATE_INDETERMINATE;
3053 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
3060 TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
3062 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3063 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
3064 INT nIndex = (INT)wParam;
3065 TBUTTON_INFO *oldButtons;
3070 TOOLBAR_DumpButton(infoPtr, (TBUTTON_INFO *)lpTbb, nIndex, FALSE);
3073 /* EPP: this seems to be an undocumented call (from my IE4)
3074 * I assume in that case that:
3075 * - lpTbb->iString is a string pointer (not a string index in strings[] table
3076 * - index of insertion is at the end of existing buttons
3077 * I only see this happen with nIndex == -1, but it could have a special
3078 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
3083 /* FIXME: iString == -1 is undocumented */
3084 if(lpTbb->iString && lpTbb->iString!=-1) {
3085 len = strlen((char*)lpTbb->iString) + 2;
3086 ptr = COMCTL32_Alloc(len);
3087 nIndex = infoPtr->nNumButtons;
3088 strcpy(ptr, (char*)lpTbb->iString);
3089 ptr[len - 1] = 0; /* ended by two '\0' */
3090 lpTbb->iString = TOOLBAR_AddStringA(hwnd, 0, (LPARAM)ptr);
3094 ERR("lpTbb->iString is NULL\n");
3098 } else if (nIndex < 0)
3101 TRACE("inserting button index=%d\n", nIndex);
3102 if (nIndex > infoPtr->nNumButtons) {
3103 nIndex = infoPtr->nNumButtons;
3104 TRACE("adjust index=%d\n", nIndex);
3107 oldButtons = infoPtr->buttons;
3108 infoPtr->nNumButtons++;
3109 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
3110 /* pre insert copy */
3112 memcpy (&infoPtr->buttons[0], &oldButtons[0],
3113 nIndex * sizeof(TBUTTON_INFO));
3116 /* insert new button */
3117 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
3118 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
3119 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
3120 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
3121 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
3122 infoPtr->buttons[nIndex].iString = lpTbb->iString;
3124 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
3127 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
3128 ti.cbSize = sizeof (TTTOOLINFOA);
3130 ti.uId = lpTbb->idCommand;
3132 ti.lpszText = LPSTR_TEXTCALLBACKA;
3134 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
3138 /* post insert copy */
3139 if (nIndex < infoPtr->nNumButtons - 1) {
3140 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
3141 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
3144 COMCTL32_Free (oldButtons);
3146 TOOLBAR_CalcToolbar (hwnd);
3148 InvalidateRect (hwnd, NULL, FALSE);
3155 TOOLBAR_InsertButtonW (HWND hwnd, WPARAM wParam, LPARAM lParam)
3157 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3158 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
3159 INT nIndex = (INT)wParam;
3160 TBUTTON_INFO *oldButtons;
3167 TRACE("inserting button index=%d\n", nIndex);
3168 if (nIndex > infoPtr->nNumButtons) {
3169 nIndex = infoPtr->nNumButtons;
3170 TRACE("adjust index=%d\n", nIndex);
3173 oldButtons = infoPtr->buttons;
3174 infoPtr->nNumButtons++;
3175 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
3176 /* pre insert copy */
3178 memcpy (&infoPtr->buttons[0], &oldButtons[0],
3179 nIndex * sizeof(TBUTTON_INFO));
3182 /* insert new button */
3183 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
3184 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
3185 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
3186 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
3187 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
3188 infoPtr->buttons[nIndex].iString = lpTbb->iString;
3190 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
3193 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
3194 ti.cbSize = sizeof (TTTOOLINFOW);
3196 ti.uId = lpTbb->idCommand;
3198 ti.lpszText = LPSTR_TEXTCALLBACKW;
3200 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
3204 /* post insert copy */
3205 if (nIndex < infoPtr->nNumButtons - 1) {
3206 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
3207 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
3210 COMCTL32_Free (oldButtons);
3212 InvalidateRect (hwnd, NULL, FALSE);
3218 /* << TOOLBAR_InsertMarkHitTest >> */
3222 TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
3224 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3227 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3231 return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
3236 TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
3238 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3241 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3245 return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
3250 TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
3252 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3255 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3259 return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
3264 TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
3266 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3269 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3273 return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
3278 TOOLBAR_IsButtonIndeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3280 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3283 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3287 return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
3292 TOOLBAR_IsButtonPressed (HWND hwnd, WPARAM wParam, LPARAM lParam)
3294 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3297 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3301 return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
3305 /* << TOOLBAR_LoadImages >> */
3306 /* << TOOLBAR_MapAccelerator >> */
3307 /* << TOOLBAR_MarkButton >> */
3308 /* << TOOLBAR_MoveButton >> */
3312 TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
3314 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3315 TBUTTON_INFO *btnPtr;
3318 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3322 btnPtr = &infoPtr->buttons[nIndex];
3323 if (LOWORD(lParam) == FALSE)
3324 btnPtr->fsState &= ~TBSTATE_PRESSED;
3326 btnPtr->fsState |= TBSTATE_PRESSED;
3328 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));
3334 /* << TOOLBAR_ReplaceBitmap >> */
3338 TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
3341 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3342 LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
3344 if (lpSave == NULL) return 0;
3347 /* save toolbar information */
3348 FIXME("save to \"%s\" \"%s\"\n",
3349 lpSave->pszSubKey, lpSave->pszValueName);
3354 /* restore toolbar information */
3356 FIXME("restore from \"%s\" \"%s\"\n",
3357 lpSave->pszSubKey, lpSave->pszValueName);
3368 TOOLBAR_SaveRestoreW (HWND hwnd, WPARAM wParam, LPARAM lParam)
3371 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3372 LPTBSAVEPARAMSW lpSave = (LPTBSAVEPARAMSW)lParam;
3378 /* save toolbar information */
3379 FIXME("save to \"%s\" \"%s\"\n",
3380 lpSave->pszSubKey, lpSave->pszValueName);
3385 /* restore toolbar information */
3387 FIXME("restore from \"%s\" \"%s\"\n",
3388 lpSave->pszSubKey, lpSave->pszValueName);
3399 TOOLBAR_SetAnchorHighlight (HWND hwnd, WPARAM wParam)
3401 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3402 BOOL bOldAnchor = infoPtr->bAnchor;
3404 infoPtr->bAnchor = (BOOL)wParam;
3406 return (LRESULT)bOldAnchor;
3411 TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3413 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3415 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
3418 if (infoPtr->nNumButtons > 0)
3419 WARN("%d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n",
3420 infoPtr->nNumButtons,
3421 infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
3422 LOWORD(lParam), HIWORD(lParam));
3424 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
3425 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
3427 /* uses image list internals directly */
3428 if (infoPtr->himlDef) {
3429 infoPtr->himlDef->cx = infoPtr->nBitmapWidth;
3430 infoPtr->himlDef->cy = infoPtr->nBitmapHeight;
3438 TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
3440 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3441 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
3442 TBUTTON_INFO *btnPtr;
3447 if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
3450 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3454 btnPtr = &infoPtr->buttons[nIndex];
3455 if (lptbbi->dwMask & TBIF_COMMAND)
3456 btnPtr->idCommand = lptbbi->idCommand;
3457 if (lptbbi->dwMask & TBIF_IMAGE)
3458 btnPtr->iBitmap = lptbbi->iImage;
3459 if (lptbbi->dwMask & TBIF_LPARAM)
3460 btnPtr->dwData = lptbbi->lParam;
3461 /* if (lptbbi->dwMask & TBIF_SIZE) */
3462 /* btnPtr->cx = lptbbi->cx; */
3463 if (lptbbi->dwMask & TBIF_STATE)
3464 btnPtr->fsState = lptbbi->fsState;
3465 if (lptbbi->dwMask & TBIF_STYLE)
3466 btnPtr->fsStyle = lptbbi->fsStyle;
3468 if (lptbbi->dwMask & TBIF_TEXT) {
3469 if ((btnPtr->iString >= 0) ||
3470 (btnPtr->iString < infoPtr->nNumStrings)) {
3471 TRACE("Ooooooch\n");
3473 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
3474 INT len = lstrlenA (lptbbi->pszText);
3475 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
3478 /* this is the ultimate sollution */
3479 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3488 TOOLBAR_SetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
3490 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3491 LPTBBUTTONINFOW lptbbi = (LPTBBUTTONINFOW)lParam;
3492 TBUTTON_INFO *btnPtr;
3497 if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
3500 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3504 btnPtr = &infoPtr->buttons[nIndex];
3505 if (lptbbi->dwMask & TBIF_COMMAND)
3506 btnPtr->idCommand = lptbbi->idCommand;
3507 if (lptbbi->dwMask & TBIF_IMAGE)
3508 btnPtr->iBitmap = lptbbi->iImage;
3509 if (lptbbi->dwMask & TBIF_LPARAM)
3510 btnPtr->dwData = lptbbi->lParam;
3511 /* if (lptbbi->dwMask & TBIF_SIZE) */
3512 /* btnPtr->cx = lptbbi->cx; */
3513 if (lptbbi->dwMask & TBIF_STATE)
3514 btnPtr->fsState = lptbbi->fsState;
3515 if (lptbbi->dwMask & TBIF_STYLE)
3516 btnPtr->fsStyle = lptbbi->fsStyle;
3518 if (lptbbi->dwMask & TBIF_TEXT) {
3519 if ((btnPtr->iString >= 0) ||
3520 (btnPtr->iString < infoPtr->nNumStrings)) {
3522 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
3523 INT len = lstrlenW (lptbbi->pszText);
3524 *lpString = COMCTL32_ReAlloc (lpString, sizeof(WCHAR)*(len+1));
3527 /* this is the ultimate solution */
3528 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3537 TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3539 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3541 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
3543 ERR("invalid parameter\n");
3547 /* The documentation claims you can only change the button size before
3548 * any button has been added. But this is wrong.
3549 * WINZIP32.EXE (ver 8) calls this on one of its buttons after adding
3550 * it to the toolbar, and it checks that the return value is nonzero - mjm
3551 * Further testing shows that we must actually perform the change too.
3553 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
3554 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
3560 TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
3562 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3564 if (infoPtr == NULL) {
3565 TRACE("Toolbar not initialized yet?????\n");
3569 /* if setting to current values, ignore */
3570 if ((infoPtr->cxMin == (INT)LOWORD(lParam)) &&
3571 (infoPtr->cxMax == (INT)HIWORD(lParam))) {
3572 TRACE("matches current width, min=%d, max=%d, no recalc\n",
3573 infoPtr->cxMin, infoPtr->cxMax);
3577 /* save new values */
3578 infoPtr->cxMin = (INT)LOWORD(lParam);
3579 infoPtr->cxMax = (INT)HIWORD(lParam);
3581 /* if both values are 0 then we are done */
3583 TRACE("setting both min and max to 0, norecalc\n");
3587 /* otherwise we need to recalc the toolbar and in some cases
3588 recalc the bounding rectangle (does DrawText w/ DT_CALCRECT
3589 which doesn't actually draw - GA). */
3590 TRACE("number of buttons %d, cx=%d, cy=%d, recalcing\n",
3591 infoPtr->nNumButtons, infoPtr->cxMin, infoPtr->cxMax);
3593 TOOLBAR_CalcToolbar (hwnd);
3595 InvalidateRect (hwnd, NULL, TRUE);
3602 TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
3604 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3605 INT nIndex = (INT)wParam;
3607 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
3610 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
3612 if (infoPtr->hwndToolTip) {
3614 FIXME("change tool tip!\n");
3622 /* << TOOLBAR_SetColorScheme >> */
3626 TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3628 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3629 HIMAGELIST himlTemp;
3632 himlTemp = infoPtr->himlDis;
3633 infoPtr->himlDis = (HIMAGELIST)lParam;
3635 /* FIXME: redraw ? */
3637 return (LRESULT)himlTemp;
3642 TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
3644 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3647 dwTemp = infoPtr->dwDTFlags;
3648 infoPtr->dwDTFlags =
3649 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
3651 return (LRESULT)dwTemp;
3656 TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3658 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3661 dwTemp = infoPtr->dwExStyle;
3662 infoPtr->dwExStyle = (DWORD)lParam;
3664 return (LRESULT)dwTemp;
3669 TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3671 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3672 HIMAGELIST himlTemp;
3674 himlTemp = infoPtr->himlHot;
3675 infoPtr->himlHot = (HIMAGELIST)lParam;
3677 /* FIXME: redraw ? */
3679 return (LRESULT)himlTemp;
3684 TOOLBAR_SetHotItem (HWND hwnd, WPARAM wParam)
3686 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3687 INT nOldHotItem = infoPtr->nHotItem;
3688 TBUTTON_INFO *btnPtr;
3690 if ((INT) wParam < 0 || (INT)wParam > infoPtr->nNumButtons)
3693 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
3696 infoPtr->nHotItem = (INT)wParam;
3697 if ((INT)wParam >=0)
3699 btnPtr = &infoPtr->buttons[(INT)wParam];
3700 btnPtr->bHot = TRUE;
3701 InvalidateRect (hwnd, &btnPtr->rect,
3702 TOOLBAR_HasText(infoPtr, btnPtr));
3706 btnPtr = &infoPtr->buttons[nOldHotItem];
3707 btnPtr->bHot = FALSE;
3708 InvalidateRect (hwnd, &btnPtr->rect,
3709 TOOLBAR_HasText(infoPtr, btnPtr));
3713 if (nOldHotItem < 0)
3716 return (LRESULT)nOldHotItem;
3721 TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3723 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3724 HIMAGELIST himlTemp;
3726 himlTemp = infoPtr->himlDef;
3727 infoPtr->himlDef = (HIMAGELIST)lParam;
3729 infoPtr->nNumBitmaps = ImageList_GetImageCount(infoPtr->himlDef);
3731 ImageList_GetIconSize(infoPtr->himlDef, &infoPtr->nBitmapWidth,
3732 &infoPtr->nBitmapHeight);
3733 TRACE("hwnd %08x, new himl=%08x, count=%d, bitmap w=%d, h=%d\n",
3734 hwnd, (INT)infoPtr->himlDef, infoPtr->nNumBitmaps,
3735 infoPtr->nBitmapWidth, infoPtr->nBitmapHeight);
3737 /* FIXME: redraw ? */
3739 return (LRESULT)himlTemp;
3744 TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3746 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3748 infoPtr->nIndent = (INT)wParam;
3752 /* process only on indent changing */
3753 if(infoPtr->nIndent != (INT)wParam)
3755 infoPtr->nIndent = (INT)wParam;
3756 TOOLBAR_CalcToolbar (hwnd);
3757 InvalidateRect(hwnd, NULL, FALSE);
3764 /* << TOOLBAR_SetInsertMark >> */
3768 TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
3770 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3772 infoPtr->clrInsertMark = (COLORREF)lParam;
3774 /* FIXME : redraw ??*/
3781 TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3783 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3785 if (infoPtr == NULL)
3788 infoPtr->nMaxTextRows = (INT)wParam;
3794 /* << TOOLBAR_SetPadding >> */
3798 TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3800 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3805 if (infoPtr == NULL)
3807 hwndOldNotify = infoPtr->hwndNotify;
3808 infoPtr->hwndNotify = (HWND)wParam;
3810 return hwndOldNotify;
3815 TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3817 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3818 LPRECT lprc = (LPRECT)lParam;
3822 if (LOWORD(wParam) > 1) {
3823 FIXME("multiple rows not supported!\n");
3826 if(infoPtr->nRows != LOWORD(wParam))
3828 infoPtr->nRows = LOWORD(wParam);
3830 /* recalculate toolbar */
3831 TOOLBAR_CalcToolbar (hwnd);
3833 /* repaint toolbar */
3834 InvalidateRect(hwnd, NULL, FALSE);
3837 /* return bounding rectangle */
3839 lprc->left = infoPtr->rcBound.left;
3840 lprc->right = infoPtr->rcBound.right;
3841 lprc->top = infoPtr->rcBound.top;
3842 lprc->bottom = infoPtr->rcBound.bottom;
3850 TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
3852 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3853 TBUTTON_INFO *btnPtr;
3856 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3860 btnPtr = &infoPtr->buttons[nIndex];
3862 /* process state changing if current state doesn't match new state */
3863 if(btnPtr->fsState != LOWORD(lParam))
3865 btnPtr->fsState = LOWORD(lParam);
3866 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3875 TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3877 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3878 TBUTTON_INFO *btnPtr;
3881 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3885 btnPtr = &infoPtr->buttons[nIndex];
3887 /* process style change if current style doesn't match new style */
3888 if(btnPtr->fsStyle != LOWORD(lParam))
3890 btnPtr->fsStyle = LOWORD(lParam);
3891 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
3894 if (infoPtr->hwndToolTip) {
3895 FIXME("change tool tip!\n");
3903 inline static LRESULT
3904 TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
3906 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3908 if (infoPtr == NULL)
3910 infoPtr->hwndToolTip = (HWND)wParam;
3916 TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
3918 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3921 TRACE("%s hwnd=0x%04x stub!\n",
3922 ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
3924 bTemp = infoPtr->bUnicode;
3925 infoPtr->bUnicode = (BOOL)wParam;
3932 TOOLBAR_SetVersion (HWND hwnd, INT iVersion)
3934 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3935 INT iOldVersion = infoPtr->iVersion;
3937 infoPtr->iVersion = iVersion;
3944 TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
3946 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3947 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3950 /* initialize info structure */
3951 infoPtr->nButtonHeight = 22;
3952 infoPtr->nButtonWidth = 24;
3953 infoPtr->nBitmapHeight = 15;
3954 infoPtr->nBitmapWidth = 16;
3956 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
3958 infoPtr->nMaxTextRows = 1;
3959 infoPtr->cxMin = -1;
3960 infoPtr->cxMax = -1;
3961 infoPtr->nNumBitmaps = 0;
3962 infoPtr->nNumStrings = 0;
3964 infoPtr->bCaptured = FALSE;
3965 infoPtr->bUnicode = IsWindowUnicode (hwnd);
3966 infoPtr->nButtonDown = -1;
3967 infoPtr->nOldHit = -1;
3968 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3969 infoPtr->hwndNotify = GetParent (hwnd);
3970 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
3971 infoPtr->dwDTFlags = (dwStyle & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE : DT_CENTER;
3972 infoPtr->bAnchor = FALSE; /* no anchor highlighting */
3973 infoPtr->iVersion = 0;
3974 infoPtr->bNtfUnicode = FALSE;
3975 infoPtr->hwndSelf = hwnd;
3977 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
3978 infoPtr->hFont = CreateFontIndirectA (&logFont);
3980 if (dwStyle & TBSTYLE_TOOLTIPS) {
3981 /* Create tooltip control */
3982 infoPtr->hwndToolTip =
3983 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
3984 CW_USEDEFAULT, CW_USEDEFAULT,
3985 CW_USEDEFAULT, CW_USEDEFAULT,
3988 /* Send NM_TOOLTIPSCREATED notification */
3989 if (infoPtr->hwndToolTip) {
3990 NMTOOLTIPSCREATED nmttc;
3992 nmttc.hwndToolTips = infoPtr->hwndToolTip;
3994 TOOLBAR_SendNotify ((NMHDR *) &nmttc, infoPtr,
3995 NM_TOOLTIPSCREATED);
3999 TOOLBAR_CalcToolbar(hwnd);
4006 TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
4008 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4010 /* delete tooltip control */
4011 if (infoPtr->hwndToolTip)
4012 DestroyWindow (infoPtr->hwndToolTip);
4014 /* delete button data */
4015 if (infoPtr->buttons)
4016 COMCTL32_Free (infoPtr->buttons);
4018 /* delete strings */
4019 if (infoPtr->strings) {
4021 for (i = 0; i < infoPtr->nNumStrings; i++)
4022 if (infoPtr->strings[i])
4023 COMCTL32_Free (infoPtr->strings[i]);
4025 COMCTL32_Free (infoPtr->strings);
4028 /* destroy internal image list */
4029 if (infoPtr->himlInt)
4030 ImageList_Destroy (infoPtr->himlInt);
4032 /* delete default font */
4034 DeleteObject (infoPtr->hFont);
4036 /* free toolbar info data */
4037 COMCTL32_Free (infoPtr);
4038 SetWindowLongA (hwnd, 0, 0);
4045 TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
4047 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4049 if (infoPtr->bTransparent)
4050 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
4052 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
4057 TOOLBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
4059 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4061 return infoPtr->hFont;
4066 TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
4068 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4069 TBUTTON_INFO *btnPtr;
4073 pt.x = (INT)LOWORD(lParam);
4074 pt.y = (INT)HIWORD(lParam);
4075 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
4078 btnPtr = &infoPtr->buttons[nHit];
4079 if (!(btnPtr->fsState & TBSTATE_ENABLED))
4082 infoPtr->bCaptured = TRUE;
4083 infoPtr->nButtonDown = nHit;
4085 btnPtr->fsState |= TBSTATE_PRESSED;
4087 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
4090 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
4091 TOOLBAR_Customize (hwnd);
4098 TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
4100 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4101 TBUTTON_INFO *btnPtr;
4106 if (infoPtr->hwndToolTip)
4107 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
4108 WM_LBUTTONDOWN, wParam, lParam);
4110 pt.x = (INT)LOWORD(lParam);
4111 pt.y = (INT)HIWORD(lParam);
4112 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
4116 btnPtr = &infoPtr->buttons[nHit];
4117 if (!(btnPtr->fsState & TBSTATE_ENABLED))
4120 infoPtr->nOldHit = nHit;
4122 CopyRect(&arrowRect, &btnPtr->rect);
4123 arrowRect.left = max(btnPtr->rect.left, btnPtr->rect.right - DDARROW_WIDTH);
4125 /* for EX_DRAWDDARROWS style, click must be in the drop-down arrow rect */
4126 if ((btnPtr->fsStyle & TBSTYLE_DROPDOWN) &&
4127 ((TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) && PtInRect(&arrowRect, pt)) ||
4128 (!TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle))))
4132 * this time we must force a Redraw, so the btn is
4133 * painted down before CaptureChanged repaints it up
4135 RedrawWindow(hwnd,&btnPtr->rect,0,
4136 RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);
4138 nmtb.iItem = btnPtr->idCommand;
4139 memset(&nmtb.tbButton, 0, sizeof(TBBUTTON));
4142 memset(&nmtb.rcButton, 0, sizeof(RECT));
4143 res = TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
4145 if (res != TBDDRET_TREATPRESSED)
4146 /* ??? guess (GA) */
4148 /* otherwise drop through and process as pushed */
4150 /* SetCapture (hwnd); */
4151 infoPtr->bCaptured = TRUE;
4152 infoPtr->nButtonDown = nHit;
4154 btnPtr->fsState |= TBSTATE_PRESSED;
4155 btnPtr->bHot = FALSE;
4157 InvalidateRect(hwnd, &btnPtr->rect,
4158 TOOLBAR_HasText(infoPtr, btnPtr));
4162 /* native issues the TBN_BEGINDRAG here */
4163 nmtb.iItem = btnPtr->idCommand;
4164 nmtb.tbButton.iBitmap = btnPtr->iBitmap;
4165 nmtb.tbButton.idCommand = btnPtr->idCommand;
4166 nmtb.tbButton.fsState = btnPtr->fsState;
4167 nmtb.tbButton.fsStyle = btnPtr->fsStyle;
4168 nmtb.tbButton.dwData = btnPtr->dwData;
4169 nmtb.tbButton.iString = btnPtr->iString;
4170 nmtb.cchText = 0; /* !!! not correct */
4171 nmtb.pszText = 0; /* !!! not correct */
4172 TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
4180 TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
4182 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4183 TBUTTON_INFO *btnPtr;
4187 BOOL bSendMessage = TRUE;
4192 if (infoPtr->hwndToolTip)
4193 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
4194 WM_LBUTTONUP, wParam, lParam);
4196 pt.x = (INT)LOWORD(lParam);
4197 pt.y = (INT)HIWORD(lParam);
4198 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
4200 /* restore hot effect to hot button disabled by TOOLBAR_LButtonDown() */
4201 /* if the cursor is still inside of the toolbar */
4202 if((infoPtr->nHotItem >= 0) && (nHit != -1))
4203 infoPtr->buttons[infoPtr->nHotItem].bHot = TRUE;
4205 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
4206 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
4207 btnPtr->fsState &= ~TBSTATE_PRESSED;
4209 if (nHit == infoPtr->nButtonDown) {
4210 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
4211 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
4212 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
4213 infoPtr->nButtonDown);
4214 if (nOldIndex == infoPtr->nButtonDown)
4215 bSendMessage = FALSE;
4216 if ((nOldIndex != infoPtr->nButtonDown) &&
4218 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
4219 btnPtr->fsState |= TBSTATE_CHECKED;
4222 if (btnPtr->fsState & TBSTATE_CHECKED)
4223 btnPtr->fsState &= ~TBSTATE_CHECKED;
4225 btnPtr->fsState |= TBSTATE_CHECKED;
4230 bSendMessage = FALSE;
4232 if (nOldIndex != -1)
4234 InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect,
4235 TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
4239 * now we can ReleaseCapture, which triggers CAPTURECHANGED msg,
4240 * that resets bCaptured and btn TBSTATE_PRESSED flags,
4241 * and obliterates nButtonDown and nOldHit (see TOOLBAR_CaptureChanged)
4245 /* Issue NM_RELEASEDCAPTURE to parent to let him know it is released */
4246 TOOLBAR_SendNotify ((NMHDR *) &hdr, infoPtr,
4247 NM_RELEASEDCAPTURE);
4249 /* native issues TBN_ENDDRAG here, if _LBUTTONDOWN issued the
4252 nmtb.iItem = btnPtr->idCommand;
4253 nmtb.tbButton.iBitmap = btnPtr->iBitmap;
4254 nmtb.tbButton.idCommand = btnPtr->idCommand;
4255 nmtb.tbButton.fsState = btnPtr->fsState;
4256 nmtb.tbButton.fsStyle = btnPtr->fsStyle;
4257 nmtb.tbButton.dwData = btnPtr->dwData;
4258 nmtb.tbButton.iString = btnPtr->iString;
4259 nmtb.cchText = 0; /* !!! not correct */
4260 nmtb.pszText = 0; /* !!! not correct */
4261 TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr,
4265 SendMessageA (GetParent(hwnd), WM_COMMAND,
4266 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
4268 /* !!! Undocumented - toolbar at 4.71 level and above sends
4269 * either NMRCLICK or NM_CLICK with the NMMOUSE structure.
4270 * Only NM_RCLICK is documented.
4272 nmmouse.dwItemSpec = btnPtr->idCommand;
4273 nmmouse.dwItemData = btnPtr->dwData;
4274 TOOLBAR_SendNotify ((NMHDR *) &nmmouse, infoPtr,
4282 TOOLBAR_CaptureChanged(HWND hwnd)
4284 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4285 TBUTTON_INFO *btnPtr;
4287 infoPtr->bCaptured = FALSE;
4289 if (infoPtr->nButtonDown >= 0)
4291 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
4292 btnPtr->fsState &= ~TBSTATE_PRESSED;
4294 infoPtr->nButtonDown = -1;
4295 infoPtr->nOldHit = -1;
4297 InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
4304 TOOLBAR_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam)
4306 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4307 TBUTTON_INFO *hotBtnPtr, *btnPtr;
4309 if (infoPtr->nOldHit < 0)
4312 hotBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
4314 /* Redraw the button if the last button we were over is the hot button and it
4316 if((infoPtr->nOldHit == infoPtr->nHotItem) && (hotBtnPtr->fsState & TBSTATE_ENABLED))
4318 hotBtnPtr->bHot = FALSE;
4320 InvalidateRect (hwnd, &hotBtnPtr->rect, TOOLBAR_HasText(infoPtr,
4324 /* If the last button we were over is depressed then make it not */
4325 /* depressed and redraw it */
4326 if(infoPtr->nOldHit == infoPtr->nButtonDown)
4328 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
4330 btnPtr->fsState &= ~TBSTATE_PRESSED;
4332 InvalidateRect (hwnd, &(btnPtr->rect), TRUE);
4335 infoPtr->nOldHit = -1; /* reset the old hit index as we've left the toolbar */
4336 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
4342 TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
4344 TBUTTON_INFO *btnPtr, *oldBtnPtr;
4345 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4348 TRACKMOUSEEVENT trackinfo;
4350 /* fill in the TRACKMOUSEEVENT struct */
4351 trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
4352 trackinfo.dwFlags = TME_QUERY;
4353 trackinfo.hwndTrack = hwnd;
4354 trackinfo.dwHoverTime = HOVER_DEFAULT;
4356 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
4357 _TrackMouseEvent(&trackinfo);
4359 /* Make sure tracking is enabled so we receive a WM_MOUSELEAVE message */
4360 if(!(trackinfo.dwFlags & TME_LEAVE)) {
4361 trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
4363 /* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
4364 /* and can properly deactivate the hot toolbar button */
4365 _TrackMouseEvent(&trackinfo);
4368 if (infoPtr->hwndToolTip)
4369 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
4370 WM_MOUSEMOVE, wParam, lParam);
4372 pt.x = (INT)LOWORD(lParam);
4373 pt.y = (INT)HIWORD(lParam);
4375 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
4377 if (infoPtr->nOldHit != nHit)
4379 /* Remove the effect of an old hot button if the button was enabled and was
4380 drawn with the hot button effect */
4381 if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem &&
4382 (infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED))
4384 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
4385 oldBtnPtr->bHot = FALSE;
4387 InvalidateRect (hwnd, &oldBtnPtr->rect,
4388 TOOLBAR_HasText(infoPtr, oldBtnPtr));
4391 /* It's not a separator or in nowhere. It's a hot button. */
4394 btnPtr = &infoPtr->buttons[nHit];
4396 infoPtr->nHotItem = nHit;
4398 /* only enabled buttons show hot effect */
4399 if(infoPtr->buttons[nHit].fsState & TBSTATE_ENABLED)
4401 btnPtr->bHot = TRUE;
4402 InvalidateRect(hwnd, &btnPtr->rect,
4403 TOOLBAR_HasText(infoPtr, btnPtr));
4408 if (infoPtr->bCaptured) {
4409 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
4410 if (infoPtr->nOldHit == infoPtr->nButtonDown) {
4411 btnPtr->fsState &= ~TBSTATE_PRESSED;
4412 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
4414 else if (nHit == infoPtr->nButtonDown) {
4415 btnPtr->fsState |= TBSTATE_PRESSED;
4416 InvalidateRect(hwnd, &btnPtr->rect, TRUE);
4419 infoPtr->nOldHit = nHit;
4425 inline static LRESULT
4426 TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
4428 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
4429 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
4431 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
4435 inline static LRESULT
4436 TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
4438 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
4439 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
4441 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
4446 TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
4448 TOOLBAR_INFO *infoPtr;
4450 /* allocate memory for info structure */
4451 infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
4452 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
4455 infoPtr->dwStructSize = sizeof(TBBUTTON);
4457 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
4458 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
4459 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
4460 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
4463 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
4468 TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
4470 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
4474 if (dwStyle & WS_MINIMIZE)
4475 return 0; /* Nothing to do */
4477 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
4479 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
4482 if (!(dwStyle & CCS_NODIVIDER))
4484 GetWindowRect (hwnd, &rcWindow);
4485 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
4486 if( dwStyle & WS_BORDER )
4487 OffsetRect (&rcWindow, 1, 1);
4488 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
4491 ReleaseDC( hwnd, hdc );
4497 inline static LRESULT
4498 TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
4500 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4501 LPNMHDR lpnmh = (LPNMHDR)lParam;
4503 TRACE("passing WM_NOTIFY!\n");
4505 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
4506 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
4509 if (lpnmh->code == TTN_GETDISPINFOA) {
4510 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
4512 FIXME("retrieving ASCII string\n");
4515 else if (lpnmh->code == TTN_GETDISPINFOW) {
4516 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
4518 FIXME("retrieving UNICODE string\n");
4529 TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
4531 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
4535 /* fill ps.rcPaint with a default rect */
4536 memcpy(&(ps.rcPaint), &(infoPtr->rcBound), sizeof(infoPtr->rcBound));
4538 hdc = wParam==0 ? BeginPaint(hwnd, &ps) : (HDC)wParam;
4540 TRACE("psrect=(%d,%d)-(%d,%d)\n",
4541 ps.rcPaint.left, ps.rcPaint.top,
4542 ps.rcPaint.right, ps.rcPaint.bottom);
4544 TOOLBAR_Refresh (hwnd, hdc, &ps);
4545 if (!wParam) EndPaint (hwnd, &ps);
4552 TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
4554 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4555 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
4564 /* Resize deadlock check */
4565 if (infoPtr->bAutoSize) {
4566 infoPtr->bAutoSize = FALSE;
4570 /* FIXME: optimize to only update size if the new size doesn't */
4571 /* match the current size */
4573 flags = (INT) wParam;
4575 /* FIXME for flags =
4576 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
4579 TRACE("sizing toolbar!\n");
4581 if (flags == SIZE_RESTORED) {
4582 /* width and height don't apply */
4583 parent = GetParent (hwnd);
4584 GetClientRect(parent, &parent_rect);
4585 x = parent_rect.left;
4586 y = parent_rect.top;
4588 if (dwStyle & CCS_NORESIZE) {
4589 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
4592 * this sets the working width of the toolbar, and
4593 * Calc Toolbar will not adjust it, only the height
4595 infoPtr->nWidth = parent_rect.right - parent_rect.left;
4596 cy = infoPtr->nHeight;
4597 cx = infoPtr->nWidth;
4598 TOOLBAR_CalcToolbar (hwnd);
4599 infoPtr->nWidth = cx;
4600 infoPtr->nHeight = cy;
4603 infoPtr->nWidth = parent_rect.right - parent_rect.left;
4604 TOOLBAR_CalcToolbar (hwnd);
4605 cy = infoPtr->nHeight;
4606 cx = infoPtr->nWidth;
4608 if (dwStyle & CCS_NOMOVEY) {
4609 GetWindowRect(hwnd, &window_rect);
4610 ScreenToClient(parent, (LPPOINT)&window_rect.left);
4611 y = window_rect.top;
4615 if (dwStyle & CCS_NOPARENTALIGN) {
4616 uPosFlags |= SWP_NOMOVE;
4617 cy = infoPtr->nHeight;
4618 cx = infoPtr->nWidth;
4621 if (!(dwStyle & CCS_NODIVIDER))
4622 cy += GetSystemMetrics(SM_CYEDGE);
4624 if (dwStyle & WS_BORDER)
4627 cy += GetSystemMetrics(SM_CYEDGE);
4628 cx += GetSystemMetrics(SM_CYEDGE);
4631 SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
4632 cx, cy, uPosFlags | SWP_NOZORDER);
4639 TOOLBAR_StyleChanged (HWND hwnd, INT nType, LPSTYLESTRUCT lpStyle)
4641 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4643 if (nType == GWL_STYLE) {
4644 if (lpStyle->styleNew & TBSTYLE_LIST) {
4645 infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
4648 infoPtr->dwDTFlags = DT_CENTER;
4652 TOOLBAR_AutoSize (hwnd);
4654 InvalidateRect(hwnd, NULL, FALSE);
4661 static LRESULT WINAPI
4662 ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
4664 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n",
4665 hwnd, uMsg, /* SPY_GetMsgName(uMsg), */ wParam, lParam);
4667 if (!TOOLBAR_GetInfoPtr(hwnd) && (uMsg != WM_NCCREATE))
4668 return DefWindowProcA( hwnd, uMsg, wParam, lParam );
4673 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
4675 case TB_ADDBUTTONSA:
4676 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
4678 case TB_ADDBUTTONSW:
4679 return TOOLBAR_AddButtonsW (hwnd, wParam, lParam);
4682 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
4685 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
4688 return TOOLBAR_AutoSize (hwnd);
4690 case TB_BUTTONCOUNT:
4691 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
4693 case TB_BUTTONSTRUCTSIZE:
4694 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
4696 case TB_CHANGEBITMAP:
4697 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
4699 case TB_CHECKBUTTON:
4700 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
4702 case TB_COMMANDTOINDEX:
4703 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
4706 return TOOLBAR_Customize (hwnd);
4708 case TB_DELETEBUTTON:
4709 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
4711 case TB_ENABLEBUTTON:
4712 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
4714 case TB_GETANCHORHIGHLIGHT:
4715 return TOOLBAR_GetAnchorHighlight (hwnd);
4718 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
4720 case TB_GETBITMAPFLAGS:
4721 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
4724 return TOOLBAR_GetButton (hwnd, wParam, lParam);
4726 case TB_GETBUTTONINFOA:
4727 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
4729 case TB_GETBUTTONINFOW:
4730 return TOOLBAR_GetButtonInfoW (hwnd, wParam, lParam);
4732 case TB_GETBUTTONSIZE:
4733 return TOOLBAR_GetButtonSize (hwnd);
4735 case TB_GETBUTTONTEXTA:
4736 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
4738 case TB_GETBUTTONTEXTW:
4739 return TOOLBAR_GetButtonTextW (hwnd, wParam, lParam);
4741 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
4743 case TB_GETDISABLEDIMAGELIST:
4744 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
4746 case TB_GETEXTENDEDSTYLE:
4747 return TOOLBAR_GetExtendedStyle (hwnd);
4749 case TB_GETHOTIMAGELIST:
4750 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
4753 return TOOLBAR_GetHotItem (hwnd);
4755 case TB_GETIMAGELIST:
4756 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
4758 /* case TB_GETINSERTMARK: */ /* 4.71 */
4759 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
4761 case TB_GETITEMRECT:
4762 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
4765 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
4767 /* case TB_GETOBJECT: */ /* 4.71 */
4768 /* case TB_GETPADDING: */ /* 4.71 */
4771 return TOOLBAR_GetRect (hwnd, wParam, lParam);
4774 return TOOLBAR_GetRows (hwnd, wParam, lParam);
4777 return TOOLBAR_GetState (hwnd, wParam, lParam);
4780 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
4782 case TB_GETTEXTROWS:
4783 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
4785 case TB_GETTOOLTIPS:
4786 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
4788 case TB_GETUNICODEFORMAT:
4789 return TOOLBAR_GetUnicodeFormat (hwnd, wParam, lParam);
4791 case CCM_GETVERSION:
4792 return TOOLBAR_GetVersion (hwnd);
4795 return TOOLBAR_HideButton (hwnd, wParam, lParam);
4798 return TOOLBAR_HitTest (hwnd, wParam, lParam);
4800 case TB_INDETERMINATE:
4801 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
4803 case TB_INSERTBUTTONA:
4804 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
4806 case TB_INSERTBUTTONW:
4807 return TOOLBAR_InsertButtonW (hwnd, wParam, lParam);
4809 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
4811 case TB_ISBUTTONCHECKED:
4812 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
4814 case TB_ISBUTTONENABLED:
4815 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
4817 case TB_ISBUTTONHIDDEN:
4818 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
4820 case TB_ISBUTTONHIGHLIGHTED:
4821 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
4823 case TB_ISBUTTONINDETERMINATE:
4824 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
4826 case TB_ISBUTTONPRESSED:
4827 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
4829 case TB_LOADIMAGES: /* 4.70 */
4830 FIXME("missing standard imagelists\n");
4833 /* case TB_MAPACCELERATORA: */ /* 4.71 */
4834 /* case TB_MAPACCELERATORW: */ /* 4.71 */
4835 /* case TB_MARKBUTTON: */ /* 4.71 */
4836 /* case TB_MOVEBUTTON: */ /* 4.71 */
4838 case TB_PRESSBUTTON:
4839 return TOOLBAR_PressButton (hwnd, wParam, lParam);
4841 /* case TB_REPLACEBITMAP: */
4843 case TB_SAVERESTOREA:
4844 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
4846 case TB_SAVERESTOREW:
4847 return TOOLBAR_SaveRestoreW (hwnd, wParam, lParam);
4849 case TB_SETANCHORHIGHLIGHT:
4850 return TOOLBAR_SetAnchorHighlight (hwnd, wParam);
4852 case TB_SETBITMAPSIZE:
4853 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
4855 case TB_SETBUTTONINFOA:
4856 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
4858 case TB_SETBUTTONINFOW:
4859 return TOOLBAR_SetButtonInfoW (hwnd, wParam, lParam);
4861 case TB_SETBUTTONSIZE:
4862 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
4864 case TB_SETBUTTONWIDTH:
4865 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
4868 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
4870 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
4872 case TB_SETDISABLEDIMAGELIST:
4873 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
4875 case TB_SETDRAWTEXTFLAGS:
4876 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
4878 case TB_SETEXTENDEDSTYLE:
4879 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
4881 case TB_SETHOTIMAGELIST:
4882 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
4885 return TOOLBAR_SetHotItem (hwnd, wParam);
4887 case TB_SETIMAGELIST:
4888 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
4891 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
4893 /* case TB_SETINSERTMARK: */ /* 4.71 */
4895 case TB_SETINSERTMARKCOLOR:
4896 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
4898 case TB_SETMAXTEXTROWS:
4899 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
4901 /* case TB_SETPADDING: */ /* 4.71 */
4904 return TOOLBAR_SetParent (hwnd, wParam, lParam);
4907 return TOOLBAR_SetRows (hwnd, wParam, lParam);
4910 return TOOLBAR_SetState (hwnd, wParam, lParam);
4913 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
4915 case TB_SETTOOLTIPS:
4916 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
4918 case TB_SETUNICODEFORMAT:
4919 return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
4921 case CCM_SETVERSION:
4922 return TOOLBAR_SetVersion (hwnd, (INT)wParam);
4928 return TOOLBAR_Create (hwnd, wParam, lParam);
4931 return TOOLBAR_Destroy (hwnd, wParam, lParam);
4934 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
4937 return TOOLBAR_GetFont (hwnd, wParam, lParam);
4939 /* case WM_KEYDOWN: */
4940 /* case WM_KILLFOCUS: */
4942 case WM_LBUTTONDBLCLK:
4943 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
4945 case WM_LBUTTONDOWN:
4946 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
4949 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
4952 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
4955 return TOOLBAR_MouseLeave (hwnd, wParam, lParam);
4957 case WM_CAPTURECHANGED:
4958 return TOOLBAR_CaptureChanged(hwnd);
4961 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
4964 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
4967 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
4970 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
4973 return TOOLBAR_Notify (hwnd, wParam, lParam);
4975 /* case WM_NOTIFYFORMAT: */
4978 return TOOLBAR_Paint (hwnd, wParam);
4981 return TOOLBAR_Size (hwnd, wParam, lParam);
4983 case WM_STYLECHANGED:
4984 return TOOLBAR_StyleChanged (hwnd, (INT)wParam, (LPSTYLESTRUCT)lParam);
4986 /* case WM_SYSCOLORCHANGE: */
4988 /* case WM_WININICHANGE: */
4993 case WM_MEASUREITEM:
4995 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
4998 if (uMsg >= WM_USER)
4999 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
5000 uMsg, wParam, lParam);
5001 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
5008 TOOLBAR_Register (void)
5012 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
5013 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
5014 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
5015 wndClass.cbClsExtra = 0;
5016 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
5017 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
5018 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
5019 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
5021 RegisterClassA (&wndClass);
5026 TOOLBAR_Unregister (void)
5028 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);