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 BOOL bTransparent
; /* background transparency flag */
96 BOOL bAutoSize
; /* auto size deadlock indicator */
97 BOOL bAnchor
; /* anchor highlight enabled */
98 DWORD dwExStyle
; /* extended toolbar style */
99 DWORD dwDTFlags
; /* DrawText flags */
101 COLORREF clrInsertMark
; /* insert mark color */
102 RECT rcBound
; /* bounding rectangle */
105 TBUTTON_INFO
*buttons
; /* pointer to button array */
106 LPWSTR
*strings
; /* pointer to string array */
107 } TOOLBAR_INFO
, *PTOOLBAR_INFO
;
110 /* used by customization dialog */
113 PTOOLBAR_INFO tbInfo
;
115 } CUSTDLG_INFO
, *PCUSTDLG_INFO
;
123 } CUSTOMBUTTON
, *PCUSTOMBUTTON
;
126 #define SEPARATOR_WIDTH 8
128 #define BOTTOM_BORDER 2
129 #define DDARROW_WIDTH 11
131 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
132 #define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE)
133 #define TOOLBAR_HasDropDownArrows(exStyle) ((exStyle & TBSTYLE_EX_DRAWDDARROWS) ? TRUE : FALSE)
136 TOOLBAR_GetText(TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
)
138 LPWSTR lpText
= NULL
;
140 /* FIXME: iString == -1 is undocumented */
141 if ((HIWORD(btnPtr
->iString
) != 0) && (btnPtr
->iString
!= -1))
142 lpText
= (LPWSTR
)btnPtr
->iString
;
143 else if ((btnPtr
->iString
>= 0) && (btnPtr
->iString
< infoPtr
->nNumStrings
))
144 lpText
= infoPtr
->strings
[btnPtr
->iString
];
150 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO
*infoPtr
, INT index
)
152 if ((index
>=0) && (index
< infoPtr
->nNumBitmaps
))
160 TOOLBAR_DrawFlatSeparator (LPRECT lpRect
, HDC hdc
)
162 INT x
= (lpRect
->left
+ lpRect
->right
) / 2 - 1;
163 INT yBottom
= lpRect
->bottom
- 3;
164 INT yTop
= lpRect
->top
+ 1;
166 SelectObject ( hdc
, GetSysColorPen (COLOR_3DSHADOW
));
167 MoveToEx (hdc
, x
, yBottom
, NULL
);
168 LineTo (hdc
, x
, yTop
);
170 SelectObject ( hdc
, GetSysColorPen (COLOR_3DHILIGHT
));
171 MoveToEx (hdc
, x
, yBottom
, NULL
);
172 LineTo (hdc
, x
, yTop
);
176 TOOLBAR_DrawArrow (HDC hdc
, INT left
, INT top
, INT colorRef
)
179 SelectObject ( hdc
, GetSysColorPen (colorRef
));
182 MoveToEx (hdc
, x
, y
, NULL
);
183 LineTo (hdc
, x
+5, y
++); x
++;
184 MoveToEx (hdc
, x
, y
, NULL
);
185 LineTo (hdc
, x
+3, y
++); x
++;
186 MoveToEx (hdc
, x
, y
, NULL
);
187 LineTo (hdc
, x
+1, y
++);
191 * Draw the text string for this button.
192 * note: infoPtr->himlDis *SHOULD* be non-zero when infoPtr->himlDef
193 * is non-zero, so we can simply check himlDef to see if we have
197 TOOLBAR_DrawString (TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
,
198 HDC hdc
, INT nState
, DWORD dwStyle
)
200 RECT rcText
= btnPtr
->rect
;
204 LPWSTR lpText
= NULL
;
205 HIMAGELIST himl
= infoPtr
->himlDef
;
207 TRACE ("iString: %x\n", btnPtr
->iString
);
209 /* get a pointer to the text */
210 lpText
= TOOLBAR_GetText(infoPtr
, btnPtr
);
212 TRACE ("lpText: %s\n", debugstr_w(lpText
));
217 InflateRect (&rcText
, -3, -3);
219 if (himl
&& TOOLBAR_IsValidBitmapIndex(infoPtr
,btnPtr
->iBitmap
)) {
220 if ((dwStyle
& TBSTYLE_LIST
) &&
221 ((btnPtr
->fsStyle
& TBSTYLE_AUTOSIZE
) == 0) &&
222 (btnPtr
->iBitmap
!= I_IMAGENONE
)) {
223 rcText
.left
+= infoPtr
->nBitmapWidth
;
226 rcText
.top
+= infoPtr
->nBitmapHeight
;
230 if (nState
& (TBSTATE_PRESSED
| TBSTATE_CHECKED
))
231 OffsetRect (&rcText
, 1, 1);
233 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
234 nOldBkMode
= SetBkMode (hdc
, TRANSPARENT
);
235 if (!(nState
& TBSTATE_ENABLED
)) {
236 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_3DHILIGHT
));
237 OffsetRect (&rcText
, 1, 1);
238 DrawTextW (hdc
, lpText
, -1, &rcText
, infoPtr
->dwDTFlags
);
239 SetTextColor (hdc
, GetSysColor (COLOR_3DSHADOW
));
240 OffsetRect (&rcText
, -1, -1);
241 DrawTextW (hdc
, lpText
, -1, &rcText
, infoPtr
->dwDTFlags
);
243 else if (nState
& TBSTATE_INDETERMINATE
) {
244 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_3DSHADOW
));
245 DrawTextW (hdc
, lpText
, -1, &rcText
, infoPtr
->dwDTFlags
);
248 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
249 DrawTextW (hdc
, lpText
, -1, &rcText
, infoPtr
->dwDTFlags
);
252 SetTextColor (hdc
, clrOld
);
253 SelectObject (hdc
, hOldFont
);
254 if (nOldBkMode
!= TRANSPARENT
)
255 SetBkMode (hdc
, nOldBkMode
);
261 TOOLBAR_DrawPattern (HDC hdc
, LPRECT lpRect
)
263 HBRUSH hbr
= SelectObject (hdc
, COMCTL32_hPattern55AABrush
);
264 INT cx
= lpRect
->right
- lpRect
->left
;
265 INT cy
= lpRect
->bottom
- lpRect
->top
;
266 PatBlt (hdc
, lpRect
->left
, lpRect
->top
, cx
, cy
, 0x00FA0089);
267 SelectObject (hdc
, hbr
);
272 TOOLBAR_DrawMasked (TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
,
273 HDC hdc
, INT x
, INT y
)
275 /* FIXME: this function is a hack since it uses image list
276 internals directly */
278 HIMAGELIST himl
= infoPtr
->himlDef
;
286 /* create new dc's */
287 hdcImageList
= CreateCompatibleDC (0);
288 hdcMask
= CreateCompatibleDC (0);
290 /* create new bitmap */
291 hbmMask
= CreateBitmap (himl
->cx
, himl
->cy
, 1, 1, NULL
);
292 SelectObject (hdcMask
, hbmMask
);
294 /* copy the mask bitmap */
295 SelectObject (hdcImageList
, himl
->hbmMask
);
296 SetBkColor (hdcImageList
, RGB(255, 255, 255));
297 SetTextColor (hdcImageList
, RGB(0, 0, 0));
298 BitBlt (hdcMask
, 0, 0, himl
->cx
, himl
->cy
,
299 hdcImageList
, himl
->cx
* btnPtr
->iBitmap
, 0, SRCCOPY
);
301 /* draw the new mask */
302 SelectObject (hdc
, GetSysColorBrush (COLOR_3DHILIGHT
));
303 BitBlt (hdc
, x
+1, y
+1, himl
->cx
, himl
->cy
,
304 hdcMask
, 0, 0, 0xB8074A);
306 SelectObject (hdc
, GetSysColorBrush (COLOR_3DSHADOW
));
307 BitBlt (hdc
, x
, y
, himl
->cx
, himl
->cy
,
308 hdcMask
, 0, 0, 0xB8074A);
310 DeleteObject (hbmMask
);
312 DeleteDC (hdcImageList
);
317 TOOLBAR_DrawButton (HWND hwnd
, TBUTTON_INFO
*btnPtr
, HDC hdc
)
319 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
320 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
321 BOOL hasDropDownArrow
= TOOLBAR_HasDropDownArrows(infoPtr
->dwExStyle
) &&
322 (btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
);
323 RECT rc
, rcArrow
, rcBitmap
;
325 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
329 CopyRect (&rcArrow
, &rc
);
330 CopyRect(&rcBitmap
, &rc
);
332 FillRect( hdc
, &rc
, GetSysColorBrush(COLOR_BTNFACE
));
334 if (hasDropDownArrow
)
336 if (dwStyle
& TBSTYLE_FLAT
)
337 rc
.right
= max(rc
.left
, rc
.right
- DDARROW_WIDTH
);
339 rc
.right
= max(rc
.left
, rc
.right
- DDARROW_WIDTH
- 2);
340 rcArrow
.left
= rc
.right
;
343 /* Center the bitmap horizontally and vertically */
344 rcBitmap
.left
+=(infoPtr
->nButtonWidth
- infoPtr
->nBitmapWidth
) / 2;
346 if(TOOLBAR_HasText(infoPtr
, btnPtr
))
347 rcBitmap
.top
+=2; /* this looks to be the correct value from vmware comparison - cmm */
349 rcBitmap
.top
+=(infoPtr
->nButtonHeight
- infoPtr
->nBitmapHeight
) / 2;
351 TRACE("iBitmap: %d\n", btnPtr
->iBitmap
);
354 if (btnPtr
->fsStyle
& TBSTYLE_SEP
) {
355 /* with the FLAT style, iBitmap is the width and has already */
356 /* been taken into consideration in calculating the width */
357 /* so now we need to draw the vertical separator */
358 /* empirical tests show that iBitmap can/will be non-zero */
359 /* when drawing the vertical bar... */
360 if ((dwStyle
& TBSTYLE_FLAT
) /* && (btnPtr->iBitmap == 0) */)
361 TOOLBAR_DrawFlatSeparator (&rc
, hdc
);
366 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
)) {
367 if (!(dwStyle
& TBSTYLE_FLAT
))
369 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
370 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
371 if (hasDropDownArrow
)
372 DrawEdge (hdc
, &rcArrow
, EDGE_RAISED
,
373 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
376 if (hasDropDownArrow
)
378 TOOLBAR_DrawArrow(hdc
, rcArrow
.left
+1, rcArrow
.top
+1, COLOR_3DHIGHLIGHT
);
379 TOOLBAR_DrawArrow(hdc
, rcArrow
.left
, rcArrow
.top
, COLOR_3DSHADOW
);
382 if (infoPtr
->himlDis
&&
383 TOOLBAR_IsValidBitmapIndex(infoPtr
,btnPtr
->iBitmap
))
384 ImageList_Draw (infoPtr
->himlDis
, btnPtr
->iBitmap
, hdc
,
385 rcBitmap
.left
, rcBitmap
.top
, ILD_NORMAL
);
387 TOOLBAR_DrawMasked (infoPtr
, btnPtr
, hdc
, rcBitmap
.left
, rcBitmap
.top
);
389 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
);
393 /* pressed TBSTYLE_BUTTON */
394 if (btnPtr
->fsState
& TBSTATE_PRESSED
) {
395 if (dwStyle
& TBSTYLE_FLAT
)
397 DrawEdge (hdc
, &rc
, BDR_SUNKENOUTER
, BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
398 if (hasDropDownArrow
)
399 DrawEdge (hdc
, &rcArrow
, BDR_SUNKENOUTER
, BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
403 DrawEdge (hdc
, &rc
, EDGE_SUNKEN
, BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
404 if (hasDropDownArrow
)
405 DrawEdge (hdc
, &rcArrow
, EDGE_SUNKEN
, BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
408 if (hasDropDownArrow
)
409 TOOLBAR_DrawArrow(hdc
, rcArrow
.left
, rcArrow
.top
, COLOR_WINDOWFRAME
);
411 if (TOOLBAR_IsValidBitmapIndex(infoPtr
,btnPtr
->iBitmap
))
412 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
413 rcBitmap
.left
+ 1, rcBitmap
.top
+ 1, ILD_NORMAL
);
415 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
);
419 /* checked TBSTYLE_CHECK */
420 if ((btnPtr
->fsStyle
& TBSTYLE_CHECK
) &&
421 (btnPtr
->fsState
& TBSTATE_CHECKED
)) {
422 if (dwStyle
& TBSTYLE_FLAT
)
423 DrawEdge (hdc
, &rc
, BDR_SUNKENOUTER
,
424 BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
426 DrawEdge (hdc
, &rc
, EDGE_SUNKEN
,
427 BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
429 TOOLBAR_DrawPattern (hdc
, &rc
);
431 if (TOOLBAR_IsValidBitmapIndex(infoPtr
,btnPtr
->iBitmap
))
432 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
433 rcBitmap
.left
+ 1, rcBitmap
.top
+ 1, ILD_NORMAL
);
434 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
);
439 if (btnPtr
->fsState
& TBSTATE_INDETERMINATE
) {
440 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
441 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
443 TOOLBAR_DrawPattern (hdc
, &rc
);
444 TOOLBAR_DrawMasked (infoPtr
, btnPtr
, hdc
, rcBitmap
.left
, rcBitmap
.top
);
445 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
);
450 if (dwStyle
& TBSTYLE_FLAT
)
454 DrawEdge (hdc
, &rc
, BDR_RAISEDINNER
, BF_RECT
| BF_MIDDLE
);
455 if (hasDropDownArrow
)
456 DrawEdge (hdc
, &rcArrow
, BDR_RAISEDINNER
, BF_RECT
| BF_MIDDLE
);
460 FrameRect(hdc
, &rc
, GetSysColorBrush(COLOR_BTNFACE
));
461 if (hasDropDownArrow
)
462 FrameRect(hdc
, &rcArrow
, GetSysColorBrush(COLOR_BTNFACE
));
465 if (hasDropDownArrow
)
466 TOOLBAR_DrawArrow(hdc
, rcArrow
.left
+1, rcArrow
.top
, COLOR_WINDOWFRAME
);
468 if (btnPtr
->bHot
&& infoPtr
->himlHot
&&
469 TOOLBAR_IsValidBitmapIndex(infoPtr
,btnPtr
->iBitmap
))
470 ImageList_Draw (infoPtr
->himlHot
, btnPtr
->iBitmap
, hdc
,
471 rcBitmap
.left
, rcBitmap
.top
, ILD_NORMAL
);
472 else if (TOOLBAR_IsValidBitmapIndex(infoPtr
,btnPtr
->iBitmap
))
473 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
474 rcBitmap
.left
, rcBitmap
.top
, ILD_NORMAL
);
478 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
479 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
481 if (hasDropDownArrow
)
483 DrawEdge (hdc
, &rcArrow
, EDGE_RAISED
,
484 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
485 TOOLBAR_DrawArrow(hdc
, rcArrow
.left
, rcArrow
.top
, COLOR_WINDOWFRAME
);
488 if (TOOLBAR_IsValidBitmapIndex(infoPtr
,btnPtr
->iBitmap
))
489 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
490 rcBitmap
.left
, rcBitmap
.top
, ILD_NORMAL
);
493 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
);
498 TOOLBAR_Refresh (HWND hwnd
, HDC hdc
, PAINTSTRUCT
* ps
)
500 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
501 TBUTTON_INFO
*btnPtr
;
505 /* redraw necessary buttons */
506 btnPtr
= infoPtr
->buttons
;
507 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++)
509 if(IntersectRect(&rcTemp
, &(ps
->rcPaint
), &(btnPtr
->rect
)))
510 TOOLBAR_DrawButton (hwnd
, btnPtr
, hdc
);
515 TOOLBAR_MeasureString(HWND hwnd
, INT index
, LPSIZE lpSize
)
517 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
518 TBUTTON_INFO
*btnPtr
;
525 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
527 btnPtr
= &infoPtr
->buttons
[index
];
529 if (!(btnPtr
->fsState
& TBSTATE_HIDDEN
) &&
530 (btnPtr
->iString
> -1) &&
531 (btnPtr
->iString
< infoPtr
->nNumStrings
))
533 LPWSTR lpText
= infoPtr
->strings
[btnPtr
->iString
];
534 GetTextExtentPoint32W (hdc
, lpText
, strlenW (lpText
), lpSize
);
537 SelectObject (hdc
, hOldFont
);
540 TRACE("string size %ld x %ld!\n", lpSize
->cx
, lpSize
->cy
);
544 TOOLBAR_CalcStrings (HWND hwnd
, LPSIZE lpSize
)
546 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
547 TBUTTON_INFO
*btnPtr
;
555 btnPtr
= infoPtr
->buttons
;
556 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
557 if(TOOLBAR_HasText(infoPtr
, btnPtr
))
559 TOOLBAR_MeasureString(hwnd
,i
,&sz
);
560 if (sz
.cx
> lpSize
->cx
)
562 if (sz
.cy
> lpSize
->cy
)
567 TRACE("string size %ld x %ld!\n", lpSize
->cx
, lpSize
->cy
);
570 /***********************************************************************
571 * TOOLBAR_WrapToolbar
573 * This function walks through the buttons and seperators in the
574 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
575 * wrapping should occur based on the width of the toolbar window.
576 * It does *not* calculate button placement itself. That task
577 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
578 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
579 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
583 TOOLBAR_WrapToolbar( HWND hwnd
, DWORD dwStyle
)
585 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
586 TBUTTON_INFO
*btnPtr
;
589 BOOL bWrap
, bButtonWrap
;
591 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
592 /* no layout is necessary. Applications may use this style */
593 /* to perform their own layout on the toolbar. */
594 if( !(dwStyle
& TBSTYLE_WRAPABLE
) )
597 btnPtr
= infoPtr
->buttons
;
598 x
= infoPtr
->nIndent
;
600 /* this can get the parents width, to know how far we can extend
601 * this toolbar. We cannot use its height, as there may be multiple
602 * toolbars in a rebar control
604 GetClientRect( GetParent(hwnd
), &rc
);
605 infoPtr
->nWidth
= rc
.right
- rc
.left
;
608 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++ )
611 btnPtr
[i
].fsState
&= ~TBSTATE_WRAP
;
613 if (btnPtr
[i
].fsState
& TBSTATE_HIDDEN
)
616 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
617 /* it is the actual width of the separator. This is used for */
618 /* custom controls in toolbars. */
619 if (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
)
620 cx
= (btnPtr
[i
].iBitmap
> 0) ?
621 btnPtr
[i
].iBitmap
: SEPARATOR_WIDTH
;
623 cx
= infoPtr
->nButtonWidth
;
625 /* Two or more adjacent separators form a separator group. */
626 /* The first separator in a group should be wrapped to the */
627 /* next row if the previous wrapping is on a button. */
629 (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
) &&
630 (i
+ 1 < infoPtr
->nNumButtons
) &&
631 (btnPtr
[i
+ 1].fsStyle
& TBSTYLE_SEP
) )
633 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
634 x
= infoPtr
->nIndent
;
640 /* The layout makes sure the bitmap is visible, but not the button. */
641 if ( x
+ cx
- (infoPtr
->nButtonWidth
- infoPtr
->nBitmapWidth
) / 2
646 /* If the current button is a separator and not hidden, */
647 /* go to the next until it reaches a non separator. */
648 /* Wrap the last separator if it is before a button. */
649 while( ( (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
) ||
650 (btnPtr
[i
].fsState
& TBSTATE_HIDDEN
) ) &&
651 i
< infoPtr
->nNumButtons
)
657 if( bFound
&& i
< infoPtr
->nNumButtons
)
660 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
661 x
= infoPtr
->nIndent
;
665 else if ( i
>= infoPtr
->nNumButtons
)
668 /* If the current button is not a separator, find the last */
669 /* separator and wrap it. */
670 for ( j
= i
- 1; j
>= 0 && !(btnPtr
[j
].fsState
& TBSTATE_WRAP
); j
--)
672 if ((btnPtr
[j
].fsStyle
& TBSTYLE_SEP
) &&
673 !(btnPtr
[j
].fsState
& TBSTATE_HIDDEN
))
677 x
= infoPtr
->nIndent
;
678 btnPtr
[j
].fsState
|= TBSTATE_WRAP
;
684 /* If no separator available for wrapping, wrap one of */
685 /* non-hidden previous button. */
689 j
>= 0 && !(btnPtr
[j
].fsState
& TBSTATE_WRAP
); j
--)
691 if (btnPtr
[j
].fsState
& TBSTATE_HIDDEN
)
696 x
= infoPtr
->nIndent
;
697 btnPtr
[j
].fsState
|= TBSTATE_WRAP
;
703 /* If all above failed, wrap the current button. */
706 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
708 x
= infoPtr
->nIndent
;
709 if (btnPtr
[i
].fsState
& TBSTYLE_SEP
)
721 /***********************************************************************
722 * TOOLBAR_CalcToolbar
724 * This function calculates button and separator placement. It first
725 * calculates the button sizes, gets the toolbar window width and then
726 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
727 * on. It assigns a new location to each item and sends this location to
728 * the tooltip window if appropriate. Finally, it updates the rcBound
729 * rect and calculates the new required toolbar window height.
733 TOOLBAR_CalcToolbar (HWND hwnd
)
735 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
736 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
737 TBUTTON_INFO
*btnPtr
;
738 INT i
, nRows
, nSepRows
;
742 BOOL usesBitmaps
= FALSE
;
743 BOOL hasDropDownArrows
= TOOLBAR_HasDropDownArrows(infoPtr
->dwExStyle
);
745 TOOLBAR_CalcStrings (hwnd
, &sizeString
);
747 if (dwStyle
& TBSTYLE_LIST
)
749 infoPtr
->nButtonHeight
= max(infoPtr
->nBitmapHeight
, sizeString
.cy
) + 6;
750 infoPtr
->nButtonWidth
= infoPtr
->nBitmapWidth
+ sizeString
.cx
+ 6;
753 for (i
= 0; i
< infoPtr
->nNumButtons
&& !usesBitmaps
; i
++)
755 if (TOOLBAR_IsValidBitmapIndex(infoPtr
,infoPtr
->buttons
[i
].iBitmap
))
759 if (sizeString
.cy
> 0)
762 infoPtr
->nButtonHeight
= sizeString
.cy
+
763 infoPtr
->nBitmapHeight
+ 6;
765 infoPtr
->nButtonHeight
= sizeString
.cy
+ 6;
767 else if (infoPtr
->nButtonHeight
< infoPtr
->nBitmapHeight
+ 6)
768 infoPtr
->nButtonHeight
= infoPtr
->nBitmapHeight
+ 6;
770 if (sizeString
.cx
> infoPtr
->nBitmapWidth
)
771 infoPtr
->nButtonWidth
= sizeString
.cx
+ 6;
772 else if (infoPtr
->nButtonWidth
< infoPtr
->nBitmapWidth
+ 6)
773 infoPtr
->nButtonWidth
= infoPtr
->nBitmapWidth
+ 6;
776 if ( infoPtr
->cxMin
>= 0 && infoPtr
->nButtonWidth
< infoPtr
->cxMin
)
777 infoPtr
->nButtonWidth
= infoPtr
->cxMin
;
778 if ( infoPtr
->cxMax
>= 0 && infoPtr
->nButtonWidth
> infoPtr
->cxMax
)
779 infoPtr
->nButtonWidth
= infoPtr
->cxMax
;
781 TOOLBAR_WrapToolbar( hwnd
, dwStyle
);
783 x
= infoPtr
->nIndent
;
784 y
= (dwStyle
& TBSTYLE_FLAT
) ? 0 : TOP_BORDER
;
787 * We will set the height below, and we set the width on entry
788 * so we do not reset them here..
791 GetClientRect( hwnd
, &rc
);
792 /* get initial values for toolbar */
793 infoPtr
->nWidth
= rc
.right
- rc
.left
;
794 infoPtr
->nHeight
= rc
.bottom
- rc
.top
;
797 /* from above, minimum is a button, and possible text */
798 cx
= infoPtr
->nButtonWidth
;
800 /* cannot use just ButtonHeight, we may have no buttons! */
801 if (infoPtr
->nNumButtons
> 0)
802 infoPtr
->nHeight
= infoPtr
->nButtonHeight
;
804 cy
= infoPtr
->nHeight
;
806 nRows
= nSepRows
= 0;
808 infoPtr
->rcBound
.top
= y
;
809 infoPtr
->rcBound
.left
= x
;
810 infoPtr
->rcBound
.bottom
= y
+ cy
;
811 infoPtr
->rcBound
.right
= x
;
813 btnPtr
= infoPtr
->buttons
;
815 /* do not base height/width on parent, if the parent is a */
816 /* rebar control it could have multiple rows of toolbars */
817 /* GetClientRect( GetParent(hwnd), &rc ); */
818 /* cx = rc.right - rc.left; */
819 /* cy = rc.bottom - rc.top; */
821 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++ )
824 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
826 SetRectEmpty (&btnPtr
->rect
);
830 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
831 /* it is the actual width of the separator. This is used for */
832 /* custom controls in toolbars. */
833 if (btnPtr
->fsStyle
& TBSTYLE_SEP
)
834 cx
= (btnPtr
->iBitmap
> 0) ?
835 btnPtr
->iBitmap
: SEPARATOR_WIDTH
;
838 if (btnPtr
->fsStyle
& TBSTYLE_AUTOSIZE
)
841 TOOLBAR_MeasureString(hwnd
,i
,&sz
);
845 cx
= infoPtr
->nButtonWidth
;
847 if (hasDropDownArrows
&& (btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
))
850 cy
= infoPtr
->nHeight
;
852 if (btnPtr
->fsState
& TBSTATE_WRAP
)
855 SetRect (&btnPtr
->rect
, x
, y
, x
+ cx
, y
+ cy
);
857 if (infoPtr
->rcBound
.left
> x
)
858 infoPtr
->rcBound
.left
= x
;
859 if (infoPtr
->rcBound
.right
< x
+ cx
)
860 infoPtr
->rcBound
.right
= x
+ cx
;
861 if (infoPtr
->rcBound
.bottom
< y
+ cy
)
862 infoPtr
->rcBound
.bottom
= y
+ cy
;
864 /* Set the toolTip only for non-hidden, non-separator button */
865 if (infoPtr
->hwndToolTip
&& !(btnPtr
->fsStyle
& TBSTYLE_SEP
))
869 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
870 ti
.cbSize
= sizeof(TTTOOLINFOA
);
872 ti
.uId
= btnPtr
->idCommand
;
873 ti
.rect
= btnPtr
->rect
;
874 SendMessageA (infoPtr
->hwndToolTip
, TTM_NEWTOOLRECTA
,
878 /* btnPtr->nRow is zero based. The space between the rows is */
879 /* also considered as a row. */
880 btnPtr
->nRow
= nRows
+ nSepRows
;
883 if ( !(btnPtr
->fsStyle
& TBSTYLE_SEP
) )
887 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
888 /* it is the actual width of the separator. This is used for */
889 /* custom controls in toolbars. */
890 y
+= cy
+ ( (btnPtr
->iBitmap
> 0 ) ?
891 btnPtr
->iBitmap
: SEPARATOR_WIDTH
) * 2 /3;
893 /* nSepRows is used to calculate the extra height follwoing */
897 x
= infoPtr
->nIndent
;
904 /* infoPtr->nRows is the number of rows on the toolbar */
905 infoPtr
->nRows
= nRows
+ nSepRows
+ 1;
907 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
909 infoPtr
->nHeight
= TOP_BORDER
+ (nRows
+ 1) * infoPtr
->nButtonHeight
+
910 nSepRows
* (SEPARATOR_WIDTH
* 2 / 3) +
911 nSepRows
* (infoPtr
->nBitmapHeight
+ 1) +
913 TRACE("toolbar height %d, button width %d\n", infoPtr
->nHeight
, infoPtr
->nButtonWidth
);
918 TOOLBAR_InternalHitTest (HWND hwnd
, LPPOINT lpPt
)
920 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
921 TBUTTON_INFO
*btnPtr
;
924 btnPtr
= infoPtr
->buttons
;
925 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
926 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
929 if (btnPtr
->fsStyle
& TBSTYLE_SEP
) {
930 if (PtInRect (&btnPtr
->rect
, *lpPt
)) {
931 TRACE(" ON SEPARATOR %d!\n", i
);
936 if (PtInRect (&btnPtr
->rect
, *lpPt
)) {
937 TRACE(" ON BUTTON %d!\n", i
);
943 TRACE(" NOWHERE!\n");
949 TOOLBAR_GetButtonIndex (TOOLBAR_INFO
*infoPtr
, INT idCommand
)
951 TBUTTON_INFO
*btnPtr
;
954 btnPtr
= infoPtr
->buttons
;
955 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
956 if (btnPtr
->idCommand
== idCommand
) {
957 TRACE("command=%d index=%d\n", idCommand
, i
);
961 TRACE("no index found for command=%d\n", idCommand
);
967 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO
*infoPtr
, INT nIndex
)
969 TBUTTON_INFO
*btnPtr
;
972 if ((nIndex
< 0) || (nIndex
> infoPtr
->nNumButtons
))
975 /* check index button */
976 btnPtr
= &infoPtr
->buttons
[nIndex
];
977 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
978 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
982 /* check previous buttons */
983 nRunIndex
= nIndex
- 1;
984 while (nRunIndex
>= 0) {
985 btnPtr
= &infoPtr
->buttons
[nRunIndex
];
986 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
987 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
995 /* check next buttons */
996 nRunIndex
= nIndex
+ 1;
997 while (nRunIndex
< infoPtr
->nNumButtons
) {
998 btnPtr
= &infoPtr
->buttons
[nRunIndex
];
999 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
1000 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
1013 TOOLBAR_RelayEvent (HWND hwndTip
, HWND hwndMsg
, UINT uMsg
,
1014 WPARAM wParam
, LPARAM lParam
)
1020 msg
.wParam
= wParam
;
1021 msg
.lParam
= lParam
;
1022 msg
.time
= GetMessageTime ();
1023 msg
.pt
.x
= LOWORD(GetMessagePos ());
1024 msg
.pt
.y
= HIWORD(GetMessagePos ());
1026 SendMessageA (hwndTip
, TTM_RELAYEVENT
, 0, (LPARAM
)&msg
);
1030 /***********************************************************************
1031 * TOOLBAR_CustomizeDialogProc
1032 * This function implements the toolbar customization dialog.
1035 TOOLBAR_CustomizeDialogProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1037 PCUSTDLG_INFO custInfo
= (PCUSTDLG_INFO
)GetWindowLongA (hwnd
, DWL_USER
);
1038 PCUSTOMBUTTON btnInfo
;
1044 custInfo
= (PCUSTDLG_INFO
)lParam
;
1045 SetWindowLongA (hwnd
, DWL_USER
, (DWORD
)custInfo
);
1053 /* send TBN_QUERYINSERT notification */
1054 nmtb
.hdr
.hwndFrom
= hwnd
;
1055 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1056 nmtb
.hdr
.code
= TBN_QUERYINSERT
;
1057 nmtb
.iItem
= custInfo
->tbInfo
->nNumButtons
;
1059 if (!SendMessageA (custInfo
->tbInfo
->hwndNotify
, WM_NOTIFY
,
1060 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
))
1063 /* add items to 'toolbar buttons' list and check if removable */
1064 for (i
= 0; i
< custInfo
->tbInfo
->nNumButtons
; i
++)
1066 btnInfo
= (PCUSTOMBUTTON
)COMCTL32_Alloc(sizeof(CUSTOMBUTTON
));
1067 memset (&btnInfo
->btn
, 0, sizeof(TBBUTTON
));
1068 btnInfo
->btn
.fsStyle
= TBSTYLE_SEP
;
1069 btnInfo
->bVirtual
= FALSE
;
1070 LoadStringA (COMCTL32_hModule
, IDS_SEPARATOR
, btnInfo
->text
, 64);
1072 /* send TBN_QUERYDELETE notification */
1073 nmtb
.hdr
.hwndFrom
= hwnd
;
1074 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1075 nmtb
.hdr
.code
= TBN_QUERYDELETE
;
1078 btnInfo
->bRemovable
= SendMessageA (custInfo
->tbInfo
->hwndNotify
, WM_NOTIFY
,
1079 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
);
1081 index
= (int)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_ADDSTRING
, 0, 0);
1082 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1085 /* insert separator button into 'available buttons' list */
1086 btnInfo
= (PCUSTOMBUTTON
)COMCTL32_Alloc(sizeof(CUSTOMBUTTON
));
1087 memset (&btnInfo
->btn
, 0, sizeof(TBBUTTON
));
1088 btnInfo
->btn
.fsStyle
= TBSTYLE_SEP
;
1089 btnInfo
->bVirtual
= FALSE
;
1090 btnInfo
->bRemovable
= TRUE
;
1091 LoadStringA (COMCTL32_hModule
, IDS_SEPARATOR
, btnInfo
->text
, 64);
1092 index
= (int)SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_ADDSTRING
, 0, (LPARAM
)btnInfo
);
1093 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1095 /* insert all buttons into dsa */
1098 /* send TBN_GETBUTTONINFO notification */
1099 nmtb
.hdr
.hwndFrom
= hwnd
;
1100 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1101 nmtb
.hdr
.code
= TBN_GETBUTTONINFOA
;
1103 nmtb
.pszText
= Buffer
;
1106 if (!SendMessageA (custInfo
->tbInfo
->hwndNotify
, WM_NOTIFY
,
1107 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
))
1110 TRACE("style: %x\n", nmtb
.tbButton
.fsStyle
);
1112 /* insert button into the apropriate list */
1113 index
= TOOLBAR_GetButtonIndex (custInfo
->tbInfo
, nmtb
.tbButton
.idCommand
);
1116 btnInfo
= (PCUSTOMBUTTON
)COMCTL32_Alloc(sizeof(CUSTOMBUTTON
));
1117 memcpy (&btnInfo
->btn
, &nmtb
.tbButton
, sizeof(TBBUTTON
));
1118 btnInfo
->bVirtual
= FALSE
;
1119 btnInfo
->bRemovable
= TRUE
;
1120 if (!(nmtb
.tbButton
.fsStyle
& TBSTYLE_SEP
))
1121 strcpy (btnInfo
->text
, nmtb
.pszText
);
1123 index
= SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_ADDSTRING
, 0, 0);
1124 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1128 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1129 memcpy (&btnInfo
->btn
, &nmtb
.tbButton
, sizeof(TBBUTTON
));
1130 if (!(nmtb
.tbButton
.fsStyle
& TBSTYLE_SEP
))
1131 strcpy (btnInfo
->text
, nmtb
.pszText
);
1133 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1137 /* select first item in the 'available' list */
1138 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETCURSEL
, 0, 0);
1140 /* append 'virtual' separator button to the 'toolbar buttons' list */
1141 btnInfo
= (PCUSTOMBUTTON
)COMCTL32_Alloc(sizeof(CUSTOMBUTTON
));
1142 memset (&btnInfo
->btn
, 0, sizeof(TBBUTTON
));
1143 btnInfo
->btn
.fsStyle
= TBSTYLE_SEP
;
1144 btnInfo
->bVirtual
= TRUE
;
1145 btnInfo
->bRemovable
= FALSE
;
1146 LoadStringA (COMCTL32_hModule
, IDS_SEPARATOR
, btnInfo
->text
, 64);
1147 index
= (int)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_ADDSTRING
, 0, (LPARAM
)btnInfo
);
1148 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1150 /* select last item in the 'toolbar' list */
1151 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETCURSEL
, index
, 0);
1152 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETTOPINDEX
, index
, 0);
1154 /* set focus and disable buttons */
1155 PostMessageA (hwnd
, WM_USER
, 0, 0);
1160 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), FALSE
);
1161 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), FALSE
);
1162 EnableWindow (GetDlgItem (hwnd
,IDC_REMOVE_BTN
), FALSE
);
1163 SetFocus (GetDlgItem (hwnd
, IDC_TOOLBARBTN_LBOX
));
1167 EndDialog(hwnd
, FALSE
);
1171 switch (LOWORD(wParam
))
1173 case IDC_TOOLBARBTN_LBOX
:
1174 if (HIWORD(wParam
) == LBN_SELCHANGE
)
1176 PCUSTOMBUTTON btnInfo
;
1181 count
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1182 index
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1184 /* send TBN_QUERYINSERT notification */
1185 nmtb
.hdr
.hwndFrom
= hwnd
;
1186 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1187 nmtb
.hdr
.code
= TBN_QUERYINSERT
;
1190 SendMessageA (custInfo
->tbInfo
->hwndNotify
, WM_NOTIFY
,
1191 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
);
1193 /* get list box item */
1194 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1196 if (index
== (count
- 1))
1198 /* last item (virtual separator) */
1199 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), FALSE
);
1200 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), FALSE
);
1202 else if (index
== (count
- 2))
1204 /* second last item (last non-virtual item) */
1205 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), TRUE
);
1206 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), FALSE
);
1208 else if (index
== 0)
1211 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), FALSE
);
1212 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), TRUE
);
1216 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), TRUE
);
1217 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), TRUE
);
1220 EnableWindow (GetDlgItem (hwnd
,IDC_REMOVE_BTN
), btnInfo
->bRemovable
);
1224 case IDC_MOVEUP_BTN
:
1226 PCUSTOMBUTTON btnInfo
;
1230 count
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1231 index
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1232 TRACE("Move up: index %d\n", index
);
1234 /* send TBN_QUERYINSERT notification */
1235 nmtb
.hdr
.hwndFrom
= hwnd
;
1236 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1237 nmtb
.hdr
.code
= TBN_QUERYINSERT
;
1240 if (SendMessageA (custInfo
->tbInfo
->hwndNotify
, WM_NOTIFY
,
1241 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
))
1243 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1245 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_DELETESTRING
, index
, 0);
1246 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_INSERTSTRING
, index
-1, 0);
1247 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
-1, (LPARAM
)btnInfo
);
1248 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETCURSEL
, index
-1 , 0);
1251 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), FALSE
);
1252 else if (index
>= (count
- 3))
1253 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), TRUE
);
1255 SendMessageA (custInfo
->tbHwnd
, TB_DELETEBUTTON
, index
, 0);
1256 SendMessageA (custInfo
->tbHwnd
, TB_INSERTBUTTONA
, index
-1, (LPARAM
)&(btnInfo
->btn
));
1261 case IDC_MOVEDN_BTN
: /* move down */
1263 PCUSTOMBUTTON btnInfo
;
1267 count
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1268 index
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1269 TRACE("Move up: index %d\n", index
);
1271 /* send TBN_QUERYINSERT notification */
1272 nmtb
.hdr
.hwndFrom
= hwnd
;
1273 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1274 nmtb
.hdr
.code
= TBN_QUERYINSERT
;
1277 if (SendMessageA (custInfo
->tbInfo
->hwndNotify
, WM_NOTIFY
,
1278 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
))
1280 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1282 /* move button down */
1283 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_DELETESTRING
, index
, 0);
1284 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_INSERTSTRING
, index
+1, 0);
1285 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
+1, (LPARAM
)btnInfo
);
1286 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETCURSEL
, index
+1 , 0);
1289 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), TRUE
);
1290 else if (index
>= (count
- 3))
1291 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), FALSE
);
1293 SendMessageA (custInfo
->tbHwnd
, TB_DELETEBUTTON
, index
, 0);
1294 SendMessageA (custInfo
->tbHwnd
, TB_INSERTBUTTONA
, index
+1, (LPARAM
)&(btnInfo
->btn
));
1299 case IDC_REMOVE_BTN
: /* remove button */
1301 PCUSTOMBUTTON btnInfo
;
1304 index
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1305 TRACE("Remove: index %d\n", index
);
1307 /* send TBN_QUERYDELETE notification */
1308 nmtb
.hdr
.hwndFrom
= hwnd
;
1309 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1310 nmtb
.hdr
.code
= TBN_QUERYDELETE
;
1313 if (SendMessageA (custInfo
->tbInfo
->hwndNotify
, WM_NOTIFY
,
1314 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
))
1316 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1317 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_DELETESTRING
, index
, 0);
1318 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETCURSEL
, index
, 0);
1320 SendMessageA (custInfo
->tbHwnd
, TB_DELETEBUTTON
, index
, 0);
1322 /* insert into 'available button' list */
1323 if (!(btnInfo
->btn
.fsStyle
& TBSTYLE_SEP
))
1325 index
= (int)SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_ADDSTRING
, 0, 0);
1326 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1329 COMCTL32_Free (btnInfo
);
1334 case IDOK
: /* Add button */
1339 count
= SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1340 index
= SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1341 TRACE("Add: index %d\n", index
);
1343 /* send TBN_QUERYINSERT notification */
1344 nmtb
.hdr
.hwndFrom
= hwnd
;
1345 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1346 nmtb
.hdr
.code
= TBN_QUERYINSERT
;
1349 if (SendMessageA (custInfo
->tbInfo
->hwndNotify
, WM_NOTIFY
,
1350 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
))
1352 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1356 /* remove from 'available buttons' list */
1357 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_DELETESTRING
, index
, 0);
1358 if (index
== count
-1)
1359 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETCURSEL
, index
-1 , 0);
1361 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETCURSEL
, index
, 0);
1365 PCUSTOMBUTTON btnNew
;
1367 /* duplicate 'separator' button */
1368 btnNew
= (PCUSTOMBUTTON
)COMCTL32_Alloc (sizeof(CUSTOMBUTTON
));
1369 memcpy (btnNew
, btnInfo
, sizeof(CUSTOMBUTTON
));
1373 /* insert into 'toolbar button' list */
1374 index
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1375 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_INSERTSTRING
, index
, 0);
1376 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1378 SendMessageA (custInfo
->tbHwnd
, TB_INSERTBUTTONA
, index
, (LPARAM
)&(btnInfo
->btn
));
1384 EndDialog(hwnd
, FALSE
);
1394 /* delete items from 'toolbar buttons' listbox*/
1395 count
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1396 for (i
= 0; i
< count
; i
++)
1398 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, i
, 0);
1399 COMCTL32_Free(btnInfo
);
1400 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, 0, 0);
1402 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_RESETCONTENT
, 0, 0);
1405 /* delete items from 'available buttons' listbox*/
1406 count
= SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1407 for (i
= 0; i
< count
; i
++)
1409 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_GETITEMDATA
, i
, 0);
1410 COMCTL32_Free(btnInfo
);
1411 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETITEMDATA
, i
, 0);
1413 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_RESETCONTENT
, 0, 0);
1418 if (wParam
== IDC_AVAILBTN_LBOX
|| wParam
== IDC_TOOLBARBTN_LBOX
)
1420 LPDRAWITEMSTRUCT lpdis
= (LPDRAWITEMSTRUCT
)lParam
;
1425 COLORREF oldText
= 0;
1429 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, wParam
, LB_GETITEMDATA
, (WPARAM
)lpdis
->itemID
, 0);
1430 if (btnInfo
== NULL
)
1432 FIXME("btnInfo invalid!\n");
1436 /* set colors and select objects */
1437 oldBk
= SetBkColor (lpdis
->hDC
, GetSysColor((lpdis
->itemState
& ODS_FOCUS
)?COLOR_HIGHLIGHT
:COLOR_WINDOW
));
1438 if (btnInfo
->bVirtual
)
1439 oldText
= SetTextColor (lpdis
->hDC
, GetSysColor(COLOR_GRAYTEXT
));
1441 oldText
= SetTextColor (lpdis
->hDC
, GetSysColor((lpdis
->itemState
& ODS_FOCUS
)?COLOR_HIGHLIGHTTEXT
:COLOR_WINDOWTEXT
));
1442 hOldPen
= SelectObject (lpdis
->hDC
, GetSysColorPen ((lpdis
->itemState
& ODS_SELECTED
)?COLOR_HIGHLIGHT
:COLOR_WINDOW
));
1443 hOldBrush
= SelectObject (lpdis
->hDC
, GetSysColorBrush ((lpdis
->itemState
& ODS_FOCUS
)?COLOR_HIGHLIGHT
:COLOR_WINDOW
));
1445 /* fill background rectangle */
1446 Rectangle (lpdis
->hDC
, lpdis
->rcItem
.left
, lpdis
->rcItem
.top
,
1447 lpdis
->rcItem
.right
, lpdis
->rcItem
.bottom
);
1449 /* calculate button and text rectangles */
1450 CopyRect (&rcButton
, &lpdis
->rcItem
);
1451 InflateRect (&rcButton
, -1, -1);
1452 CopyRect (&rcText
, &rcButton
);
1453 rcButton
.right
= rcButton
.left
+ custInfo
->tbInfo
->nBitmapWidth
+ 6;
1454 rcText
.left
= rcButton
.right
+ 2;
1456 /* draw focus rectangle */
1457 if (lpdis
->itemState
& ODS_FOCUS
)
1458 DrawFocusRect (lpdis
->hDC
, &lpdis
->rcItem
);
1461 DrawEdge (lpdis
->hDC
, &rcButton
, EDGE_RAISED
, BF_RECT
|BF_MIDDLE
|BF_SOFT
);
1463 /* draw image and text */
1464 if ((btnInfo
->btn
.fsStyle
& TBSTYLE_SEP
) == 0)
1465 ImageList_Draw (custInfo
->tbInfo
->himlDef
, btnInfo
->btn
.iBitmap
, lpdis
->hDC
,
1466 rcButton
.left
+3, rcButton
.top
+3, ILD_NORMAL
);
1467 DrawTextA (lpdis
->hDC
, btnInfo
->text
, -1, &rcText
,
1468 DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
);
1470 /* delete objects and reset colors */
1471 SelectObject (lpdis
->hDC
, hOldBrush
);
1472 SelectObject (lpdis
->hDC
, hOldPen
);
1473 SetBkColor (lpdis
->hDC
, oldBk
);
1474 SetTextColor (lpdis
->hDC
, oldText
);
1480 case WM_MEASUREITEM
:
1481 if (wParam
== IDC_AVAILBTN_LBOX
|| wParam
== IDC_TOOLBARBTN_LBOX
)
1483 MEASUREITEMSTRUCT
*lpmis
= (MEASUREITEMSTRUCT
*)lParam
;
1485 if (custInfo
&& custInfo
->tbInfo
)
1486 lpmis
->itemHeight
= custInfo
->tbInfo
->nBitmapHeight
+ 8;
1488 lpmis
->itemHeight
= 15 + 8; /* default height */
1500 /***********************************************************************
1501 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1505 TOOLBAR_AddBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1507 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1508 LPTBADDBITMAP lpAddBmp
= (LPTBADDBITMAP
)lParam
;
1509 INT nIndex
= 0, nButtons
, nCount
;
1512 TRACE("hwnd=%x wParam=%x lParam=%lx\n", hwnd
, wParam
, lParam
);
1516 if (lpAddBmp
->hInst
== HINST_COMMCTRL
)
1518 if ((lpAddBmp
->nID
& ~1) == IDB_STD_SMALL_COLOR
)
1520 else if ((lpAddBmp
->nID
& ~1) == IDB_VIEW_SMALL_COLOR
)
1522 else if ((lpAddBmp
->nID
& ~1) == IDB_HIST_SMALL_COLOR
)
1527 TRACE ("adding %d internal bitmaps!\n", nButtons
);
1529 /* Windows resize all the buttons to the size of a newly added standard image */
1530 if (lpAddBmp
->nID
& 1)
1533 /* FIXME: on windows the size of the images is 25x24 but the size of the bitmap
1534 * in rsrc is only 24x24. Fix the bitmap (how?) and then fix this
1536 SendMessageA (hwnd
, TB_SETBITMAPSIZE
, 0,
1537 MAKELPARAM((WORD
)24, (WORD
)24));
1538 SendMessageA (hwnd
, TB_SETBUTTONSIZE
, 0,
1539 MAKELPARAM((WORD
)31, (WORD
)30));
1544 SendMessageA (hwnd
, TB_SETBITMAPSIZE
, 0,
1545 MAKELPARAM((WORD
)16, (WORD
)16));
1546 SendMessageA (hwnd
, TB_SETBUTTONSIZE
, 0,
1547 MAKELPARAM((WORD
)22, (WORD
)22));
1550 TOOLBAR_CalcToolbar (hwnd
);
1554 nButtons
= (INT
)wParam
;
1558 TRACE ("adding %d bitmaps!\n", nButtons
);
1561 if (!(infoPtr
->himlDef
)) {
1562 /* create new default image list */
1563 TRACE ("creating default image list!\n");
1566 ImageList_Create (infoPtr
->nBitmapWidth
, infoPtr
->nBitmapHeight
,
1567 ILC_COLOR
| ILC_MASK
, nButtons
, 2);
1568 infoPtr
->himlInt
= infoPtr
->himlDef
;
1571 nCount
= ImageList_GetImageCount(infoPtr
->himlDef
);
1573 /* Add bitmaps to the default image list */
1574 if (lpAddBmp
->hInst
== (HINSTANCE
)0)
1577 ImageList_AddMasked (infoPtr
->himlDef
, (HBITMAP
)lpAddBmp
->nID
,
1580 else if (lpAddBmp
->hInst
== HINST_COMMCTRL
)
1582 /* Add system bitmaps */
1583 switch (lpAddBmp
->nID
)
1585 case IDB_STD_SMALL_COLOR
:
1586 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1587 MAKEINTRESOURCEA(IDB_STD_SMALL
));
1588 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1589 hbmLoad
, CLR_DEFAULT
);
1590 DeleteObject (hbmLoad
);
1593 case IDB_STD_LARGE_COLOR
:
1594 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1595 MAKEINTRESOURCEA(IDB_STD_LARGE
));
1596 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1597 hbmLoad
, CLR_DEFAULT
);
1598 DeleteObject (hbmLoad
);
1601 case IDB_VIEW_SMALL_COLOR
:
1602 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1603 MAKEINTRESOURCEA(IDB_VIEW_SMALL
));
1604 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1605 hbmLoad
, CLR_DEFAULT
);
1606 DeleteObject (hbmLoad
);
1609 case IDB_VIEW_LARGE_COLOR
:
1610 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1611 MAKEINTRESOURCEA(IDB_VIEW_LARGE
));
1612 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1613 hbmLoad
, CLR_DEFAULT
);
1614 DeleteObject (hbmLoad
);
1617 case IDB_HIST_SMALL_COLOR
:
1618 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1619 MAKEINTRESOURCEA(IDB_HIST_SMALL
));
1620 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1621 hbmLoad
, CLR_DEFAULT
);
1622 DeleteObject (hbmLoad
);
1625 case IDB_HIST_LARGE_COLOR
:
1626 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1627 MAKEINTRESOURCEA(IDB_HIST_LARGE
));
1628 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1629 hbmLoad
, CLR_DEFAULT
);
1630 DeleteObject (hbmLoad
);
1634 nIndex
= ImageList_GetImageCount (infoPtr
->himlDef
);
1635 ERR ("invalid imagelist!\n");
1641 hbmLoad
= LoadBitmapA (lpAddBmp
->hInst
, (LPSTR
)lpAddBmp
->nID
);
1642 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
, hbmLoad
, CLR_DEFAULT
);
1643 DeleteObject (hbmLoad
);
1648 INT imagecount
= ImageList_GetImageCount(infoPtr
->himlDef
);
1650 if (infoPtr
->nNumBitmaps
+ nButtons
!= imagecount
)
1652 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",
1653 infoPtr
->nNumBitmaps
, nCount
, imagecount
- nCount
,
1654 infoPtr
->nNumBitmaps
+nButtons
,imagecount
);
1656 infoPtr
->nNumBitmaps
= imagecount
;
1659 infoPtr
->nNumBitmaps
+= nButtons
;
1662 InvalidateRect(hwnd
, NULL
, FALSE
);
1669 TOOLBAR_AddButtonsA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1671 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1672 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
1673 INT nOldButtons
, nNewButtons
, nAddButtons
, nCount
;
1675 TRACE("adding %d buttons!\n", wParam
);
1677 nAddButtons
= (UINT
)wParam
;
1678 nOldButtons
= infoPtr
->nNumButtons
;
1679 nNewButtons
= nOldButtons
+ nAddButtons
;
1681 if (infoPtr
->nNumButtons
== 0) {
1683 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1686 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
1688 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1689 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
1690 nOldButtons
* sizeof(TBUTTON_INFO
));
1691 COMCTL32_Free (oldButtons
);
1694 infoPtr
->nNumButtons
= nNewButtons
;
1696 /* insert new button data */
1697 for (nCount
= 0; nCount
< nAddButtons
; nCount
++) {
1698 TBUTTON_INFO
*btnPtr
= &infoPtr
->buttons
[nOldButtons
+nCount
];
1699 btnPtr
->iBitmap
= lpTbb
[nCount
].iBitmap
;
1700 btnPtr
->idCommand
= lpTbb
[nCount
].idCommand
;
1701 btnPtr
->fsState
= lpTbb
[nCount
].fsState
;
1702 btnPtr
->fsStyle
= lpTbb
[nCount
].fsStyle
;
1703 btnPtr
->dwData
= lpTbb
[nCount
].dwData
;
1704 btnPtr
->iString
= lpTbb
[nCount
].iString
;
1705 btnPtr
->bHot
= FALSE
;
1707 if ((infoPtr
->hwndToolTip
) && !(btnPtr
->fsStyle
& TBSTYLE_SEP
)) {
1710 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
1711 ti
.cbSize
= sizeof (TTTOOLINFOA
);
1713 ti
.uId
= btnPtr
->idCommand
;
1715 ti
.lpszText
= LPSTR_TEXTCALLBACKA
;
1717 SendMessageA (infoPtr
->hwndToolTip
, TTM_ADDTOOLA
,
1722 TOOLBAR_CalcToolbar (hwnd
);
1724 InvalidateRect(hwnd
, NULL
, FALSE
);
1731 TOOLBAR_AddButtonsW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1733 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1734 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
1735 INT nOldButtons
, nNewButtons
, nAddButtons
, nCount
;
1737 TRACE("adding %d buttons!\n", wParam
);
1739 nAddButtons
= (UINT
)wParam
;
1740 nOldButtons
= infoPtr
->nNumButtons
;
1741 nNewButtons
= nOldButtons
+ nAddButtons
;
1743 if (infoPtr
->nNumButtons
== 0) {
1745 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1748 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
1750 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1751 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
1752 nOldButtons
* sizeof(TBUTTON_INFO
));
1753 COMCTL32_Free (oldButtons
);
1756 infoPtr
->nNumButtons
= nNewButtons
;
1758 /* insert new button data */
1759 for (nCount
= 0; nCount
< nAddButtons
; nCount
++) {
1760 TBUTTON_INFO
*btnPtr
= &infoPtr
->buttons
[nOldButtons
+nCount
];
1761 btnPtr
->iBitmap
= lpTbb
[nCount
].iBitmap
;
1762 btnPtr
->idCommand
= lpTbb
[nCount
].idCommand
;
1763 btnPtr
->fsState
= lpTbb
[nCount
].fsState
;
1764 btnPtr
->fsStyle
= lpTbb
[nCount
].fsStyle
;
1765 btnPtr
->dwData
= lpTbb
[nCount
].dwData
;
1766 btnPtr
->iString
= lpTbb
[nCount
].iString
;
1767 btnPtr
->bHot
= FALSE
;
1769 if ((infoPtr
->hwndToolTip
) && !(btnPtr
->fsStyle
& TBSTYLE_SEP
)) {
1772 ZeroMemory (&ti
, sizeof(TTTOOLINFOW
));
1773 ti
.cbSize
= sizeof (TTTOOLINFOW
);
1775 ti
.uId
= btnPtr
->idCommand
;
1777 ti
.lpszText
= LPSTR_TEXTCALLBACKW
;
1779 SendMessageW (infoPtr
->hwndToolTip
, TTM_ADDTOOLW
,
1784 TOOLBAR_CalcToolbar (hwnd
);
1786 InvalidateRect(hwnd
, NULL
, FALSE
);
1793 TOOLBAR_AddStringA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1795 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1798 if ((wParam
) && (HIWORD(lParam
) == 0)) {
1801 TRACE("adding string from resource!\n");
1803 len
= LoadStringA ((HINSTANCE
)wParam
, (UINT
)lParam
,
1806 TRACE("len=%d \"%s\"\n", len
, szString
);
1807 nIndex
= infoPtr
->nNumStrings
;
1808 if (infoPtr
->nNumStrings
== 0) {
1810 COMCTL32_Alloc (sizeof(LPWSTR
));
1813 LPWSTR
*oldStrings
= infoPtr
->strings
;
1815 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1816 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1817 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1818 COMCTL32_Free (oldStrings
);
1821 lenW
= MultiByteToWideChar( CP_ACP
, 0, szString
, -1, NULL
, 0 );
1822 infoPtr
->strings
[infoPtr
->nNumStrings
] = COMCTL32_Alloc (sizeof(WCHAR
)*lenW
);
1823 MultiByteToWideChar( CP_ACP
, 0, szString
, -1,
1824 infoPtr
->strings
[infoPtr
->nNumStrings
], lenW
);
1825 infoPtr
->nNumStrings
++;
1828 LPSTR p
= (LPSTR
)lParam
;
1833 TRACE("adding string(s) from array!\n");
1835 nIndex
= infoPtr
->nNumStrings
;
1838 TRACE("len=%d \"%s\"\n", len
, p
);
1840 if (infoPtr
->nNumStrings
== 0) {
1842 COMCTL32_Alloc (sizeof(LPWSTR
));
1845 LPWSTR
*oldStrings
= infoPtr
->strings
;
1847 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1848 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1849 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1850 COMCTL32_Free (oldStrings
);
1853 lenW
= MultiByteToWideChar( CP_ACP
, 0, p
, -1, NULL
, 0 );
1854 infoPtr
->strings
[infoPtr
->nNumStrings
] = COMCTL32_Alloc (sizeof(WCHAR
)*lenW
);
1855 MultiByteToWideChar( CP_ACP
, 0, p
, -1,
1856 infoPtr
->strings
[infoPtr
->nNumStrings
], lenW
);
1857 infoPtr
->nNumStrings
++;
1868 TOOLBAR_AddStringW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1870 #define MAX_RESOURCE_STRING_LENGTH 512
1871 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1874 if ((wParam
) && (HIWORD(lParam
) == 0)) {
1875 WCHAR szString
[MAX_RESOURCE_STRING_LENGTH
];
1877 TRACE("adding string from resource!\n");
1879 len
= LoadStringW ((HINSTANCE
)wParam
, (UINT
)lParam
,
1880 szString
, MAX_RESOURCE_STRING_LENGTH
);
1882 TRACE("len=%d %s\n", len
, debugstr_w(szString
));
1883 TRACE("First char: 0x%x\n", *szString
);
1884 if (szString
[0] == L
'|')
1886 PWSTR p
= szString
+ 1;
1888 nIndex
= infoPtr
->nNumStrings
;
1889 while (*p
!= L
'|') {
1891 if (infoPtr
->nNumStrings
== 0) {
1893 COMCTL32_Alloc (sizeof(LPWSTR
));
1896 LPWSTR
*oldStrings
= infoPtr
->strings
;
1898 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1899 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1900 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1901 COMCTL32_Free (oldStrings
);
1904 len
= COMCTL32_StrChrW (p
, L
'|') - p
;
1905 TRACE("len=%d %s\n", len
, debugstr_w(p
));
1906 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1907 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1908 lstrcpynW (infoPtr
->strings
[infoPtr
->nNumStrings
], p
, len
);
1909 infoPtr
->nNumStrings
++;
1916 nIndex
= infoPtr
->nNumStrings
;
1917 if (infoPtr
->nNumStrings
== 0) {
1919 COMCTL32_Alloc (sizeof(LPWSTR
));
1922 LPWSTR
*oldStrings
= infoPtr
->strings
;
1924 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1925 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1926 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1927 COMCTL32_Free (oldStrings
);
1930 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1931 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1932 strcpyW (infoPtr
->strings
[infoPtr
->nNumStrings
], szString
);
1933 infoPtr
->nNumStrings
++;
1937 LPWSTR p
= (LPWSTR
)lParam
;
1942 TRACE("adding string(s) from array!\n");
1943 nIndex
= infoPtr
->nNumStrings
;
1947 TRACE("len=%d %s\n", len
, debugstr_w(p
));
1948 if (infoPtr
->nNumStrings
== 0) {
1950 COMCTL32_Alloc (sizeof(LPWSTR
));
1953 LPWSTR
*oldStrings
= infoPtr
->strings
;
1955 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1956 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1957 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1958 COMCTL32_Free (oldStrings
);
1961 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1962 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1963 strcpyW (infoPtr
->strings
[infoPtr
->nNumStrings
], p
);
1964 infoPtr
->nNumStrings
++;
1975 TOOLBAR_AutoSize (HWND hwnd
)
1977 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1978 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1984 UINT uPosFlags
= SWP_NOZORDER
;
1986 TRACE("resize forced, style=%lx!\n", dwStyle
);
1988 parent
= GetParent (hwnd
);
1989 GetClientRect(parent
, &parent_rect
);
1991 x
= parent_rect
.left
;
1992 y
= parent_rect
.top
;
1994 /* FIXME: we should be able to early out if nothing */
1995 /* has changed with nWidth != parent_rect width */
1997 if (dwStyle
& CCS_NORESIZE
) {
1998 uPosFlags
|= (SWP_NOSIZE
| SWP_NOMOVE
);
2003 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
2004 TOOLBAR_CalcToolbar (hwnd
);
2005 InvalidateRect( hwnd
, NULL
, TRUE
);
2006 cy
= infoPtr
->nHeight
;
2007 cx
= infoPtr
->nWidth
;
2009 if (dwStyle
& CCS_NOMOVEY
) {
2010 GetWindowRect(hwnd
, &window_rect
);
2011 ScreenToClient(parent
, (LPPOINT
)&window_rect
.left
);
2012 y
= window_rect
.top
;
2016 if (dwStyle
& CCS_NOPARENTALIGN
)
2017 uPosFlags
|= SWP_NOMOVE
;
2019 if (!(dwStyle
& CCS_NODIVIDER
))
2020 cy
+= GetSystemMetrics(SM_CYEDGE
);
2022 if (dwStyle
& WS_BORDER
)
2025 cy
+= GetSystemMetrics(SM_CYEDGE
);
2026 cx
+= GetSystemMetrics(SM_CYEDGE
);
2029 infoPtr
->bAutoSize
= TRUE
;
2030 SetWindowPos (hwnd
, HWND_TOP
, parent_rect
.left
- x
, parent_rect
.top
- y
,
2032 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
2033 * the setwindowpos calls */
2034 infoPtr
->bAutoSize
= FALSE
;
2041 TOOLBAR_ButtonCount (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2043 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2045 return infoPtr
->nNumButtons
;
2050 TOOLBAR_ButtonStructSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2052 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2054 if (infoPtr
== NULL
) {
2055 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd
, wParam
, lParam
);
2056 ERR("infoPtr == NULL!\n");
2060 infoPtr
->dwStructSize
= (DWORD
)wParam
;
2067 TOOLBAR_ChangeBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2069 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2070 TBUTTON_INFO
*btnPtr
;
2073 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2077 btnPtr
= &infoPtr
->buttons
[nIndex
];
2078 btnPtr
->iBitmap
= LOWORD(lParam
);
2080 /* we HAVE to erase the background, the new bitmap could be */
2082 InvalidateRect(hwnd
, &btnPtr
->rect
, TRUE
);
2089 TOOLBAR_CheckButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2091 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2092 TBUTTON_INFO
*btnPtr
;
2095 BOOL bChecked
= FALSE
;
2097 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2101 btnPtr
= &infoPtr
->buttons
[nIndex
];
2103 if (!(btnPtr
->fsStyle
& TBSTYLE_CHECK
))
2106 bChecked
= (btnPtr
->fsState
& TBSTATE_CHECKED
) ? TRUE
: FALSE
;
2108 if (LOWORD(lParam
) == FALSE
)
2109 btnPtr
->fsState
&= ~TBSTATE_CHECKED
;
2111 if (btnPtr
->fsStyle
& TBSTYLE_GROUP
) {
2113 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr
, nIndex
);
2114 if (nOldIndex
== nIndex
)
2116 if (nOldIndex
!= -1)
2117 infoPtr
->buttons
[nOldIndex
].fsState
&= ~TBSTATE_CHECKED
;
2119 btnPtr
->fsState
|= TBSTATE_CHECKED
;
2122 if( bChecked
!= LOWORD(lParam
) )
2124 if (nOldIndex
!= -1)
2126 InvalidateRect(hwnd
, &infoPtr
->buttons
[nOldIndex
].rect
,
2127 TOOLBAR_HasText(infoPtr
, &infoPtr
->buttons
[nOldIndex
]));
2129 InvalidateRect(hwnd
, &btnPtr
->rect
, TRUE
);
2132 /* FIXME: Send a WM_NOTIFY?? */
2139 TOOLBAR_CommandToIndex (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2141 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2143 return TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2148 TOOLBAR_Customize (HWND hwnd
)
2150 CUSTDLG_INFO custInfo
;
2156 custInfo
.tbInfo
= TOOLBAR_GetInfoPtr (hwnd
);
2157 custInfo
.tbHwnd
= hwnd
;
2159 /* send TBN_BEGINADJUST notification */
2160 nmhdr
.hwndFrom
= hwnd
;
2161 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
2162 nmhdr
.code
= TBN_BEGINADJUST
;
2164 SendMessageA (custInfo
.tbInfo
->hwndNotify
, WM_NOTIFY
,
2165 (WPARAM
)nmhdr
.idFrom
, (LPARAM
)&nmhdr
);
2167 if (!(hRes
= FindResourceA (COMCTL32_hModule
,
2168 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE
),
2172 if(!(template = (LPVOID
)LoadResource (COMCTL32_hModule
, hRes
)))
2175 ret
= DialogBoxIndirectParamA (GetWindowLongA (hwnd
, GWL_HINSTANCE
),
2176 (LPDLGTEMPLATEA
)template,
2178 (DLGPROC
)TOOLBAR_CustomizeDialogProc
,
2181 /* send TBN_ENDADJUST notification */
2182 nmhdr
.code
= TBN_ENDADJUST
;
2183 SendMessageA (custInfo
.tbInfo
->hwndNotify
, WM_NOTIFY
,
2184 (WPARAM
)nmhdr
.idFrom
, (LPARAM
)&nmhdr
);
2191 TOOLBAR_DeleteButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2193 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2194 INT nIndex
= (INT
)wParam
;
2196 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
2199 if ((infoPtr
->hwndToolTip
) &&
2200 !(infoPtr
->buttons
[nIndex
].fsStyle
& TBSTYLE_SEP
)) {
2203 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
2204 ti
.cbSize
= sizeof (TTTOOLINFOA
);
2206 ti
.uId
= infoPtr
->buttons
[nIndex
].idCommand
;
2208 SendMessageA (infoPtr
->hwndToolTip
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
2211 if (infoPtr
->nNumButtons
== 1) {
2212 TRACE(" simple delete!\n");
2213 COMCTL32_Free (infoPtr
->buttons
);
2214 infoPtr
->buttons
= NULL
;
2215 infoPtr
->nNumButtons
= 0;
2218 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
2219 TRACE("complex delete! [nIndex=%d]\n", nIndex
);
2221 infoPtr
->nNumButtons
--;
2222 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
2224 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
2225 nIndex
* sizeof(TBUTTON_INFO
));
2228 if (nIndex
< infoPtr
->nNumButtons
) {
2229 memcpy (&infoPtr
->buttons
[nIndex
], &oldButtons
[nIndex
+1],
2230 (infoPtr
->nNumButtons
- nIndex
) * sizeof(TBUTTON_INFO
));
2233 COMCTL32_Free (oldButtons
);
2236 TOOLBAR_CalcToolbar (hwnd
);
2238 InvalidateRect (hwnd
, NULL
, TRUE
);
2245 TOOLBAR_EnableButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2247 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2248 TBUTTON_INFO
*btnPtr
;
2252 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2256 btnPtr
= &infoPtr
->buttons
[nIndex
];
2258 bState
= btnPtr
->fsState
& TBSTATE_ENABLED
;
2260 /* update the toolbar button state */
2261 if(LOWORD(lParam
) == FALSE
) {
2262 btnPtr
->fsState
&= ~(TBSTATE_ENABLED
| TBSTATE_PRESSED
);
2264 btnPtr
->fsState
|= TBSTATE_ENABLED
;
2267 /* redraw the button only if the state of the button changed */
2268 if(bState
!= (btnPtr
->fsState
& TBSTATE_ENABLED
))
2270 InvalidateRect(hwnd
, &btnPtr
->rect
,
2271 TOOLBAR_HasText(infoPtr
, btnPtr
));
2278 static inline LRESULT
2279 TOOLBAR_GetAnchorHighlight (HWND hwnd
)
2281 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2283 return infoPtr
->bAnchor
;
2288 TOOLBAR_GetBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2290 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2293 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2297 return infoPtr
->buttons
[nIndex
].iBitmap
;
2301 static inline LRESULT
2302 TOOLBAR_GetBitmapFlags (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2304 return (GetDeviceCaps (0, LOGPIXELSX
) >= 120) ? TBBF_LARGE
: 0;
2309 TOOLBAR_GetButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2311 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2312 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
2313 INT nIndex
= (INT
)wParam
;
2314 TBUTTON_INFO
*btnPtr
;
2316 if (infoPtr
== NULL
)
2322 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
2325 btnPtr
= &infoPtr
->buttons
[nIndex
];
2326 lpTbb
->iBitmap
= btnPtr
->iBitmap
;
2327 lpTbb
->idCommand
= btnPtr
->idCommand
;
2328 lpTbb
->fsState
= btnPtr
->fsState
;
2329 lpTbb
->fsStyle
= btnPtr
->fsStyle
;
2330 lpTbb
->dwData
= btnPtr
->dwData
;
2331 lpTbb
->iString
= btnPtr
->iString
;
2338 TOOLBAR_GetButtonInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2340 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2341 LPTBBUTTONINFOA lpTbInfo
= (LPTBBUTTONINFOA
)lParam
;
2342 TBUTTON_INFO
*btnPtr
;
2345 if (infoPtr
== NULL
)
2347 if (lpTbInfo
== NULL
)
2349 if (lpTbInfo
->cbSize
< sizeof(TBBUTTONINFOA
))
2352 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2356 btnPtr
= &infoPtr
->buttons
[nIndex
];
2358 if (lpTbInfo
->dwMask
& TBIF_COMMAND
)
2359 lpTbInfo
->idCommand
= btnPtr
->idCommand
;
2360 if (lpTbInfo
->dwMask
& TBIF_IMAGE
)
2361 lpTbInfo
->iImage
= btnPtr
->iBitmap
;
2362 if (lpTbInfo
->dwMask
& TBIF_LPARAM
)
2363 lpTbInfo
->lParam
= btnPtr
->dwData
;
2364 if (lpTbInfo
->dwMask
& TBIF_SIZE
)
2365 lpTbInfo
->cx
= (WORD
)(btnPtr
->rect
.right
- btnPtr
->rect
.left
);
2366 if (lpTbInfo
->dwMask
& TBIF_STATE
)
2367 lpTbInfo
->fsState
= btnPtr
->fsState
;
2368 if (lpTbInfo
->dwMask
& TBIF_STYLE
)
2369 lpTbInfo
->fsStyle
= btnPtr
->fsStyle
;
2370 if (lpTbInfo
->dwMask
& TBIF_TEXT
) {
2371 if ((btnPtr
->iString
>= 0) && (btnPtr
->iString
< infoPtr
->nNumStrings
))
2373 if (!WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)infoPtr
->strings
[btnPtr
->iString
], -1,
2374 lpTbInfo
->pszText
, lpTbInfo
->cchText
, NULL
, NULL
))
2375 lpTbInfo
->pszText
[lpTbInfo
->cchText
-1] = 0;
2377 else lpTbInfo
->pszText
[0]=0;
2384 TOOLBAR_GetButtonInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2386 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2387 LPTBBUTTONINFOW lpTbInfo
= (LPTBBUTTONINFOW
)lParam
;
2388 TBUTTON_INFO
*btnPtr
;
2391 if (infoPtr
== NULL
)
2393 if (lpTbInfo
== NULL
)
2395 if (lpTbInfo
->cbSize
< sizeof(TBBUTTONINFOW
))
2398 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2402 btnPtr
= &infoPtr
->buttons
[nIndex
];
2404 if (lpTbInfo
->dwMask
& TBIF_COMMAND
)
2405 lpTbInfo
->idCommand
= btnPtr
->idCommand
;
2406 if (lpTbInfo
->dwMask
& TBIF_IMAGE
)
2407 lpTbInfo
->iImage
= btnPtr
->iBitmap
;
2408 if (lpTbInfo
->dwMask
& TBIF_LPARAM
)
2409 lpTbInfo
->lParam
= btnPtr
->dwData
;
2410 if (lpTbInfo
->dwMask
& TBIF_SIZE
)
2411 lpTbInfo
->cx
= (WORD
)(btnPtr
->rect
.right
- btnPtr
->rect
.left
);
2412 if (lpTbInfo
->dwMask
& TBIF_STATE
)
2413 lpTbInfo
->fsState
= btnPtr
->fsState
;
2414 if (lpTbInfo
->dwMask
& TBIF_STYLE
)
2415 lpTbInfo
->fsStyle
= btnPtr
->fsStyle
;
2416 if (lpTbInfo
->dwMask
& TBIF_TEXT
) {
2417 if ((btnPtr
->iString
>= 0) || (btnPtr
->iString
< infoPtr
->nNumStrings
))
2418 lstrcpynW (lpTbInfo
->pszText
,
2419 (LPWSTR
)infoPtr
->strings
[btnPtr
->iString
],
2428 TOOLBAR_GetButtonSize (HWND hwnd
)
2430 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2432 return MAKELONG((WORD
)infoPtr
->nButtonWidth
,
2433 (WORD
)infoPtr
->nButtonHeight
);
2438 TOOLBAR_GetButtonTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2440 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2441 INT nIndex
, nStringIndex
;
2443 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2447 nStringIndex
= infoPtr
->buttons
[nIndex
].iString
;
2449 TRACE("index=%d stringIndex=%d\n", nIndex
, nStringIndex
);
2451 if ((nStringIndex
< 0) || (nStringIndex
>= infoPtr
->nNumStrings
))
2457 return WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)infoPtr
->strings
[nStringIndex
], -1,
2458 (LPSTR
)lParam
, 0x7fffffff, NULL
, NULL
) - 1;
2463 TOOLBAR_GetButtonTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2465 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2466 INT nIndex
, nStringIndex
;
2468 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2472 nStringIndex
= infoPtr
->buttons
[nIndex
].iString
;
2474 TRACE("index=%d stringIndex=%d\n", nIndex
, nStringIndex
);
2476 if ((nStringIndex
< 0) || (nStringIndex
>= infoPtr
->nNumStrings
))
2482 strcpyW ((LPWSTR
)lParam
, (LPWSTR
)infoPtr
->strings
[nStringIndex
]);
2484 return strlenW ((LPWSTR
)infoPtr
->strings
[nStringIndex
]);
2488 /* << TOOLBAR_GetColorScheme >> */
2492 TOOLBAR_GetDisabledImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2494 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2496 return (LRESULT
)infoPtr
->himlDis
;
2500 inline static LRESULT
2501 TOOLBAR_GetExtendedStyle (HWND hwnd
)
2503 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2505 return infoPtr
->dwExStyle
;
2510 TOOLBAR_GetHotImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2512 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2514 return (LRESULT
)infoPtr
->himlHot
;
2519 TOOLBAR_GetHotItem (HWND hwnd
)
2521 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2523 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_FLAT
))
2526 if (infoPtr
->nHotItem
< 0)
2529 return (LRESULT
)infoPtr
->nHotItem
;
2534 TOOLBAR_GetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2536 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2538 return (LRESULT
)infoPtr
->himlDef
;
2542 /* << TOOLBAR_GetInsertMark >> */
2543 /* << TOOLBAR_GetInsertMarkColor >> */
2547 TOOLBAR_GetItemRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2549 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2550 TBUTTON_INFO
*btnPtr
;
2554 if (infoPtr
== NULL
)
2556 nIndex
= (INT
)wParam
;
2557 btnPtr
= &infoPtr
->buttons
[nIndex
];
2558 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
2560 lpRect
= (LPRECT
)lParam
;
2563 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
2566 lpRect
->left
= btnPtr
->rect
.left
;
2567 lpRect
->right
= btnPtr
->rect
.right
;
2568 lpRect
->bottom
= btnPtr
->rect
.bottom
;
2569 lpRect
->top
= btnPtr
->rect
.top
;
2576 TOOLBAR_GetMaxSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2578 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2579 LPSIZE lpSize
= (LPSIZE
)lParam
;
2584 lpSize
->cx
= infoPtr
->rcBound
.right
- infoPtr
->rcBound
.left
;
2585 lpSize
->cy
= infoPtr
->rcBound
.bottom
- infoPtr
->rcBound
.top
;
2587 TRACE("maximum size %d x %d\n",
2588 infoPtr
->rcBound
.right
- infoPtr
->rcBound
.left
,
2589 infoPtr
->rcBound
.bottom
- infoPtr
->rcBound
.top
);
2595 /* << TOOLBAR_GetObject >> */
2596 /* << TOOLBAR_GetPadding >> */
2600 TOOLBAR_GetRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2602 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2603 TBUTTON_INFO
*btnPtr
;
2607 if (infoPtr
== NULL
)
2609 nIndex
= (INT
)wParam
;
2610 btnPtr
= &infoPtr
->buttons
[nIndex
];
2611 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
2613 lpRect
= (LPRECT
)lParam
;
2617 lpRect
->left
= btnPtr
->rect
.left
;
2618 lpRect
->right
= btnPtr
->rect
.right
;
2619 lpRect
->bottom
= btnPtr
->rect
.bottom
;
2620 lpRect
->top
= btnPtr
->rect
.top
;
2627 TOOLBAR_GetRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2629 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2631 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_WRAPABLE
)
2632 return infoPtr
->nRows
;
2639 TOOLBAR_GetState (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2641 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2644 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2648 return infoPtr
->buttons
[nIndex
].fsState
;
2653 TOOLBAR_GetStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2655 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2658 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2662 return infoPtr
->buttons
[nIndex
].fsStyle
;
2667 TOOLBAR_GetTextRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2669 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2671 if (infoPtr
== NULL
)
2674 return infoPtr
->nMaxTextRows
;
2679 TOOLBAR_GetToolTips (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2681 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2683 if (infoPtr
== NULL
)
2685 return infoPtr
->hwndToolTip
;
2690 TOOLBAR_GetUnicodeFormat (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2692 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2694 TRACE("%s hwnd=0x%x stub!\n",
2695 infoPtr
->bUnicode
? "TRUE" : "FALSE", hwnd
);
2697 return infoPtr
->bUnicode
;
2701 inline static LRESULT
2702 TOOLBAR_GetVersion (HWND hwnd
)
2704 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2705 return infoPtr
->iVersion
;
2710 TOOLBAR_HideButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2712 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2713 TBUTTON_INFO
*btnPtr
;
2718 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2722 btnPtr
= &infoPtr
->buttons
[nIndex
];
2723 if (LOWORD(lParam
) == FALSE
)
2724 btnPtr
->fsState
&= ~TBSTATE_HIDDEN
;
2726 btnPtr
->fsState
|= TBSTATE_HIDDEN
;
2728 TOOLBAR_CalcToolbar (hwnd
);
2730 InvalidateRect (hwnd
, NULL
, TRUE
);
2736 inline static LRESULT
2737 TOOLBAR_HitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2739 return TOOLBAR_InternalHitTest (hwnd
, (LPPOINT
)lParam
);
2744 TOOLBAR_Indeterminate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2746 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2747 TBUTTON_INFO
*btnPtr
;
2750 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2754 btnPtr
= &infoPtr
->buttons
[nIndex
];
2755 if (LOWORD(lParam
) == FALSE
)
2756 btnPtr
->fsState
&= ~TBSTATE_INDETERMINATE
;
2758 btnPtr
->fsState
|= TBSTATE_INDETERMINATE
;
2760 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
, btnPtr
));
2767 TOOLBAR_InsertButtonA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2769 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2770 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
2771 INT nIndex
= (INT
)wParam
;
2772 TBUTTON_INFO
*oldButtons
;
2778 /* EPP: this seems to be an undocumented call (from my IE4)
2779 * I assume in that case that:
2780 * - lpTbb->iString is a string pointer (not a string index in strings[] table
2781 * - index of insertion is at the end of existing buttons
2782 * I only see this happen with nIndex == -1, but it could have a special
2783 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
2788 if(lpTbb
->iString
) {
2789 len
= strlen((char*)lpTbb
->iString
) + 2;
2790 ptr
= COMCTL32_Alloc(len
);
2791 nIndex
= infoPtr
->nNumButtons
;
2792 strcpy(ptr
, (char*)lpTbb
->iString
);
2793 ptr
[len
- 1] = 0; /* ended by two '\0' */
2794 lpTbb
->iString
= TOOLBAR_AddStringA(hwnd
, 0, (LPARAM
)ptr
);
2798 ERR("lpTbb->iString is NULL\n");
2802 } else if (nIndex
< 0)
2805 TRACE("inserting button index=%d\n", nIndex
);
2806 if (nIndex
> infoPtr
->nNumButtons
) {
2807 nIndex
= infoPtr
->nNumButtons
;
2808 TRACE("adjust index=%d\n", nIndex
);
2811 oldButtons
= infoPtr
->buttons
;
2812 infoPtr
->nNumButtons
++;
2813 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
2814 /* pre insert copy */
2816 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
2817 nIndex
* sizeof(TBUTTON_INFO
));
2820 /* insert new button */
2821 infoPtr
->buttons
[nIndex
].iBitmap
= lpTbb
->iBitmap
;
2822 infoPtr
->buttons
[nIndex
].idCommand
= lpTbb
->idCommand
;
2823 infoPtr
->buttons
[nIndex
].fsState
= lpTbb
->fsState
;
2824 infoPtr
->buttons
[nIndex
].fsStyle
= lpTbb
->fsStyle
;
2825 infoPtr
->buttons
[nIndex
].dwData
= lpTbb
->dwData
;
2826 infoPtr
->buttons
[nIndex
].iString
= lpTbb
->iString
;
2828 if ((infoPtr
->hwndToolTip
) && !(lpTbb
->fsStyle
& TBSTYLE_SEP
)) {
2831 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
2832 ti
.cbSize
= sizeof (TTTOOLINFOA
);
2834 ti
.uId
= lpTbb
->idCommand
;
2836 ti
.lpszText
= LPSTR_TEXTCALLBACKA
;
2838 SendMessageA (infoPtr
->hwndToolTip
, TTM_ADDTOOLA
,
2842 /* post insert copy */
2843 if (nIndex
< infoPtr
->nNumButtons
- 1) {
2844 memcpy (&infoPtr
->buttons
[nIndex
+1], &oldButtons
[nIndex
],
2845 (infoPtr
->nNumButtons
- nIndex
- 1) * sizeof(TBUTTON_INFO
));
2848 COMCTL32_Free (oldButtons
);
2850 TOOLBAR_CalcToolbar (hwnd
);
2852 InvalidateRect (hwnd
, NULL
, FALSE
);
2859 TOOLBAR_InsertButtonW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2861 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2862 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
2863 INT nIndex
= (INT
)wParam
;
2864 TBUTTON_INFO
*oldButtons
;
2871 TRACE("inserting button index=%d\n", nIndex
);
2872 if (nIndex
> infoPtr
->nNumButtons
) {
2873 nIndex
= infoPtr
->nNumButtons
;
2874 TRACE("adjust index=%d\n", nIndex
);
2877 oldButtons
= infoPtr
->buttons
;
2878 infoPtr
->nNumButtons
++;
2879 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
2880 /* pre insert copy */
2882 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
2883 nIndex
* sizeof(TBUTTON_INFO
));
2886 /* insert new button */
2887 infoPtr
->buttons
[nIndex
].iBitmap
= lpTbb
->iBitmap
;
2888 infoPtr
->buttons
[nIndex
].idCommand
= lpTbb
->idCommand
;
2889 infoPtr
->buttons
[nIndex
].fsState
= lpTbb
->fsState
;
2890 infoPtr
->buttons
[nIndex
].fsStyle
= lpTbb
->fsStyle
;
2891 infoPtr
->buttons
[nIndex
].dwData
= lpTbb
->dwData
;
2892 infoPtr
->buttons
[nIndex
].iString
= lpTbb
->iString
;
2894 if ((infoPtr
->hwndToolTip
) && !(lpTbb
->fsStyle
& TBSTYLE_SEP
)) {
2897 ZeroMemory (&ti
, sizeof(TTTOOLINFOW
));
2898 ti
.cbSize
= sizeof (TTTOOLINFOW
);
2900 ti
.uId
= lpTbb
->idCommand
;
2902 ti
.lpszText
= LPSTR_TEXTCALLBACKW
;
2904 SendMessageW (infoPtr
->hwndToolTip
, TTM_ADDTOOLW
,
2908 /* post insert copy */
2909 if (nIndex
< infoPtr
->nNumButtons
- 1) {
2910 memcpy (&infoPtr
->buttons
[nIndex
+1], &oldButtons
[nIndex
],
2911 (infoPtr
->nNumButtons
- nIndex
- 1) * sizeof(TBUTTON_INFO
));
2914 COMCTL32_Free (oldButtons
);
2916 InvalidateRect (hwnd
, NULL
, FALSE
);
2922 /* << TOOLBAR_InsertMarkHitTest >> */
2926 TOOLBAR_IsButtonChecked (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2928 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2931 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2935 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_CHECKED
);
2940 TOOLBAR_IsButtonEnabled (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2942 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2945 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2949 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_ENABLED
);
2954 TOOLBAR_IsButtonHidden (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2956 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2959 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2963 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_HIDDEN
);
2968 TOOLBAR_IsButtonHighlighted (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2970 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2973 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2977 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_MARKED
);
2982 TOOLBAR_IsButtonIndeterminate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2984 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2987 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2991 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_INDETERMINATE
);
2996 TOOLBAR_IsButtonPressed (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2998 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3001 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
3005 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_PRESSED
);
3009 /* << TOOLBAR_LoadImages >> */
3010 /* << TOOLBAR_MapAccelerator >> */
3011 /* << TOOLBAR_MarkButton >> */
3012 /* << TOOLBAR_MoveButton >> */
3016 TOOLBAR_PressButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3018 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3019 TBUTTON_INFO
*btnPtr
;
3022 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
3026 btnPtr
= &infoPtr
->buttons
[nIndex
];
3027 if (LOWORD(lParam
) == FALSE
)
3028 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
3030 btnPtr
->fsState
|= TBSTATE_PRESSED
;
3032 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
, btnPtr
));
3038 /* << TOOLBAR_ReplaceBitmap >> */
3042 TOOLBAR_SaveRestoreA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3045 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3046 LPTBSAVEPARAMSA lpSave
= (LPTBSAVEPARAMSA
)lParam
;
3048 if (lpSave
== NULL
) return 0;
3051 /* save toolbar information */
3052 FIXME("save to \"%s\" \"%s\"\n",
3053 lpSave
->pszSubKey
, lpSave
->pszValueName
);
3058 /* restore toolbar information */
3060 FIXME("restore from \"%s\" \"%s\"\n",
3061 lpSave
->pszSubKey
, lpSave
->pszValueName
);
3072 TOOLBAR_SaveRestoreW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3075 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3076 LPTBSAVEPARAMSW lpSave
= (LPTBSAVEPARAMSW
)lParam
;
3082 /* save toolbar information */
3083 FIXME("save to \"%s\" \"%s\"\n",
3084 lpSave
->pszSubKey
, lpSave
->pszValueName
);
3089 /* restore toolbar information */
3091 FIXME("restore from \"%s\" \"%s\"\n",
3092 lpSave
->pszSubKey
, lpSave
->pszValueName
);
3103 TOOLBAR_SetAnchorHighlight (HWND hwnd
, WPARAM wParam
)
3105 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3106 BOOL bOldAnchor
= infoPtr
->bAnchor
;
3108 infoPtr
->bAnchor
= (BOOL
)wParam
;
3110 return (LRESULT
)bOldAnchor
;
3115 TOOLBAR_SetBitmapSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3117 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3119 if ((LOWORD(lParam
) <= 0) || (HIWORD(lParam
)<=0))
3122 if (infoPtr
->nNumButtons
> 0)
3123 WARN("%d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n",
3124 infoPtr
->nNumButtons
,
3125 infoPtr
->nBitmapWidth
, infoPtr
->nBitmapHeight
,
3126 LOWORD(lParam
), HIWORD(lParam
));
3128 infoPtr
->nBitmapWidth
= (INT
)LOWORD(lParam
);
3129 infoPtr
->nBitmapHeight
= (INT
)HIWORD(lParam
);
3131 /* uses image list internals directly */
3132 if (infoPtr
->himlDef
) {
3133 infoPtr
->himlDef
->cx
= infoPtr
->nBitmapWidth
;
3134 infoPtr
->himlDef
->cy
= infoPtr
->nBitmapHeight
;
3142 TOOLBAR_SetButtonInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3144 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3145 LPTBBUTTONINFOA lptbbi
= (LPTBBUTTONINFOA
)lParam
;
3146 TBUTTON_INFO
*btnPtr
;
3151 if (lptbbi
->cbSize
< sizeof(TBBUTTONINFOA
))
3154 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
3158 btnPtr
= &infoPtr
->buttons
[nIndex
];
3159 if (lptbbi
->dwMask
& TBIF_COMMAND
)
3160 btnPtr
->idCommand
= lptbbi
->idCommand
;
3161 if (lptbbi
->dwMask
& TBIF_IMAGE
)
3162 btnPtr
->iBitmap
= lptbbi
->iImage
;
3163 if (lptbbi
->dwMask
& TBIF_LPARAM
)
3164 btnPtr
->dwData
= lptbbi
->lParam
;
3165 /* if (lptbbi->dwMask & TBIF_SIZE) */
3166 /* btnPtr->cx = lptbbi->cx; */
3167 if (lptbbi
->dwMask
& TBIF_STATE
)
3168 btnPtr
->fsState
= lptbbi
->fsState
;
3169 if (lptbbi
->dwMask
& TBIF_STYLE
)
3170 btnPtr
->fsStyle
= lptbbi
->fsStyle
;
3172 if (lptbbi
->dwMask
& TBIF_TEXT
) {
3173 if ((btnPtr
->iString
>= 0) ||
3174 (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
3175 TRACE("Ooooooch\n");
3177 WCHAR
**lpString
= &infoPtr
->strings
[btnPtr
->iString
];
3178 INT len
= lstrlenA (lptbbi
->pszText
);
3179 *lpString
= COMCTL32_ReAlloc (lpString
, sizeof(WCHAR
)*(len
+1));
3182 /* this is the ultimate sollution */
3183 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3192 TOOLBAR_SetButtonInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3194 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3195 LPTBBUTTONINFOW lptbbi
= (LPTBBUTTONINFOW
)lParam
;
3196 TBUTTON_INFO
*btnPtr
;
3201 if (lptbbi
->cbSize
< sizeof(TBBUTTONINFOW
))
3204 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
3208 btnPtr
= &infoPtr
->buttons
[nIndex
];
3209 if (lptbbi
->dwMask
& TBIF_COMMAND
)
3210 btnPtr
->idCommand
= lptbbi
->idCommand
;
3211 if (lptbbi
->dwMask
& TBIF_IMAGE
)
3212 btnPtr
->iBitmap
= lptbbi
->iImage
;
3213 if (lptbbi
->dwMask
& TBIF_LPARAM
)
3214 btnPtr
->dwData
= lptbbi
->lParam
;
3215 /* if (lptbbi->dwMask & TBIF_SIZE) */
3216 /* btnPtr->cx = lptbbi->cx; */
3217 if (lptbbi
->dwMask
& TBIF_STATE
)
3218 btnPtr
->fsState
= lptbbi
->fsState
;
3219 if (lptbbi
->dwMask
& TBIF_STYLE
)
3220 btnPtr
->fsStyle
= lptbbi
->fsStyle
;
3222 if (lptbbi
->dwMask
& TBIF_TEXT
) {
3223 if ((btnPtr
->iString
>= 0) ||
3224 (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
3226 WCHAR
**lpString
= &infoPtr
->strings
[btnPtr
->iString
];
3227 INT len
= lstrlenW (lptbbi
->pszText
);
3228 *lpString
= COMCTL32_ReAlloc (lpString
, sizeof(WCHAR
)*(len
+1));
3231 /* this is the ultimate solution */
3232 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3241 TOOLBAR_SetButtonSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3243 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3245 if ((LOWORD(lParam
) <= 0) || (HIWORD(lParam
)<=0))
3247 ERR("invalid parameter\n");
3251 /* The documentation claims you can only change the button size before
3252 * any button has been added. But this is wrong.
3253 * WINZIP32.EXE (ver 8) calls this on one of its buttons after adding
3254 * it to the toolbar, and it checks that the return value is nonzero - mjm
3255 * Further testing shows that we must actually perform the change too.
3257 infoPtr
->nButtonWidth
= (INT
)LOWORD(lParam
);
3258 infoPtr
->nButtonHeight
= (INT
)HIWORD(lParam
);
3264 TOOLBAR_SetButtonWidth (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3266 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3268 if (infoPtr
== NULL
)
3271 infoPtr
->cxMin
= (INT
)LOWORD(lParam
);
3272 infoPtr
->cxMax
= (INT
)HIWORD(lParam
);
3279 TOOLBAR_SetCmdId (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3281 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3282 INT nIndex
= (INT
)wParam
;
3284 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
3287 infoPtr
->buttons
[nIndex
].idCommand
= (INT
)lParam
;
3289 if (infoPtr
->hwndToolTip
) {
3291 FIXME("change tool tip!\n");
3299 /* << TOOLBAR_SetColorScheme >> */
3303 TOOLBAR_SetDisabledImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3305 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3306 HIMAGELIST himlTemp
;
3309 himlTemp
= infoPtr
->himlDis
;
3310 infoPtr
->himlDis
= (HIMAGELIST
)lParam
;
3312 /* FIXME: redraw ? */
3314 return (LRESULT
)himlTemp
;
3319 TOOLBAR_SetDrawTextFlags (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3321 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3324 dwTemp
= infoPtr
->dwDTFlags
;
3325 infoPtr
->dwDTFlags
=
3326 (infoPtr
->dwDTFlags
& (DWORD
)wParam
) | (DWORD
)lParam
;
3328 return (LRESULT
)dwTemp
;
3333 TOOLBAR_SetExtendedStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3335 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3338 dwTemp
= infoPtr
->dwExStyle
;
3339 infoPtr
->dwExStyle
= (DWORD
)lParam
;
3341 return (LRESULT
)dwTemp
;
3346 TOOLBAR_SetHotImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3348 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
3349 HIMAGELIST himlTemp
;
3351 himlTemp
= infoPtr
->himlHot
;
3352 infoPtr
->himlHot
= (HIMAGELIST
)lParam
;
3354 /* FIXME: redraw ? */
3356 return (LRESULT
)himlTemp
;
3361 TOOLBAR_SetHotItem (HWND hwnd
, WPARAM wParam
)
3363 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
3364 INT nOldHotItem
= infoPtr
->nHotItem
;
3365 TBUTTON_INFO
*btnPtr
;
3367 if ((INT
) wParam
< 0 || (INT
)wParam
> infoPtr
->nNumButtons
)
3370 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_FLAT
)
3373 infoPtr
->nHotItem
= (INT
)wParam
;
3376 btnPtr
= &infoPtr
->buttons
[(INT
)wParam
];
3377 btnPtr
->bHot
= TRUE
;
3378 InvalidateRect (hwnd
, &btnPtr
->rect
,
3379 TOOLBAR_HasText(infoPtr
, btnPtr
));
3383 btnPtr
= &infoPtr
->buttons
[nOldHotItem
];
3384 btnPtr
->bHot
= FALSE
;
3385 InvalidateRect (hwnd
, &btnPtr
->rect
,
3386 TOOLBAR_HasText(infoPtr
, btnPtr
));
3390 if (nOldHotItem
< 0)
3393 return (LRESULT
)nOldHotItem
;
3398 TOOLBAR_SetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3400 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3401 HIMAGELIST himlTemp
;
3403 himlTemp
= infoPtr
->himlDef
;
3404 infoPtr
->himlDef
= (HIMAGELIST
)lParam
;
3406 infoPtr
->nNumBitmaps
= ImageList_GetImageCount(infoPtr
->himlDef
);
3407 /* FIXME: redraw ? */
3409 return (LRESULT
)himlTemp
;
3414 TOOLBAR_SetIndent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3416 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3418 infoPtr
->nIndent
= (INT
)wParam
;
3422 /* process only on indent changing */
3423 if(infoPtr
->nIndent
!= (INT
)wParam
)
3425 infoPtr
->nIndent
= (INT
)wParam
;
3426 TOOLBAR_CalcToolbar (hwnd
);
3427 InvalidateRect(hwnd
, NULL
, FALSE
);
3434 /* << TOOLBAR_SetInsertMark >> */
3438 TOOLBAR_SetInsertMarkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3440 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3442 infoPtr
->clrInsertMark
= (COLORREF
)lParam
;
3444 /* FIXME : redraw ??*/
3451 TOOLBAR_SetMaxTextRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3453 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3455 if (infoPtr
== NULL
)
3458 infoPtr
->nMaxTextRows
= (INT
)wParam
;
3464 /* << TOOLBAR_SetPadding >> */
3468 TOOLBAR_SetParent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3470 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3475 if (infoPtr
== NULL
)
3477 hwndOldNotify
= infoPtr
->hwndNotify
;
3478 infoPtr
->hwndNotify
= (HWND
)wParam
;
3480 return hwndOldNotify
;
3485 TOOLBAR_SetRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3487 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3488 LPRECT lprc
= (LPRECT
)lParam
;
3492 if (LOWORD(wParam
) > 1) {
3493 FIXME("multiple rows not supported!\n");
3496 if(infoPtr
->nRows
!= LOWORD(wParam
))
3498 infoPtr
->nRows
= LOWORD(wParam
);
3500 /* recalculate toolbar */
3501 TOOLBAR_CalcToolbar (hwnd
);
3503 /* repaint toolbar */
3504 InvalidateRect(hwnd
, NULL
, FALSE
);
3507 /* return bounding rectangle */
3509 lprc
->left
= infoPtr
->rcBound
.left
;
3510 lprc
->right
= infoPtr
->rcBound
.right
;
3511 lprc
->top
= infoPtr
->rcBound
.top
;
3512 lprc
->bottom
= infoPtr
->rcBound
.bottom
;
3520 TOOLBAR_SetState (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3522 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3523 TBUTTON_INFO
*btnPtr
;
3526 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
3530 btnPtr
= &infoPtr
->buttons
[nIndex
];
3532 /* process state changing if current state doesn't match new state */
3533 if(btnPtr
->fsState
!= LOWORD(lParam
))
3535 btnPtr
->fsState
= LOWORD(lParam
);
3536 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
,
3545 TOOLBAR_SetStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3547 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3548 TBUTTON_INFO
*btnPtr
;
3551 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
3555 btnPtr
= &infoPtr
->buttons
[nIndex
];
3557 /* process style change if current style doesn't match new style */
3558 if(btnPtr
->fsStyle
!= LOWORD(lParam
))
3560 btnPtr
->fsStyle
= LOWORD(lParam
);
3561 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
,
3564 if (infoPtr
->hwndToolTip
) {
3565 FIXME("change tool tip!\n");
3573 inline static LRESULT
3574 TOOLBAR_SetToolTips (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3576 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3578 if (infoPtr
== NULL
)
3580 infoPtr
->hwndToolTip
= (HWND
)wParam
;
3586 TOOLBAR_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3588 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3591 TRACE("%s hwnd=0x%04x stub!\n",
3592 ((BOOL
)wParam
) ? "TRUE" : "FALSE", hwnd
);
3594 bTemp
= infoPtr
->bUnicode
;
3595 infoPtr
->bUnicode
= (BOOL
)wParam
;
3602 TOOLBAR_SetVersion (HWND hwnd
, INT iVersion
)
3604 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3605 INT iOldVersion
= infoPtr
->iVersion
;
3607 infoPtr
->iVersion
= iVersion
;
3614 TOOLBAR_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3616 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3617 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
3620 /* initialize info structure */
3621 infoPtr
->nButtonHeight
= 22;
3622 infoPtr
->nButtonWidth
= 24;
3623 infoPtr
->nBitmapHeight
= 15;
3624 infoPtr
->nBitmapWidth
= 16;
3626 infoPtr
->nHeight
= infoPtr
->nButtonHeight
+ TOP_BORDER
+ BOTTOM_BORDER
;
3628 infoPtr
->nMaxTextRows
= 1;
3629 infoPtr
->cxMin
= -1;
3630 infoPtr
->cxMax
= -1;
3631 infoPtr
->nNumBitmaps
= 0;
3632 infoPtr
->nNumStrings
= 0;
3634 infoPtr
->bCaptured
= FALSE
;
3635 infoPtr
->bUnicode
= IsWindowUnicode (hwnd
);
3636 infoPtr
->nButtonDown
= -1;
3637 infoPtr
->nOldHit
= -1;
3638 infoPtr
->nHotItem
= -2; /* It has to be initially different from nOldHit */
3639 infoPtr
->hwndNotify
= GetParent (hwnd
);
3640 infoPtr
->bTransparent
= (dwStyle
& TBSTYLE_FLAT
);
3641 infoPtr
->dwDTFlags
= (dwStyle
& TBSTYLE_LIST
) ? DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
: DT_CENTER
;
3642 infoPtr
->bAnchor
= FALSE
; /* no anchor highlighting */
3643 infoPtr
->iVersion
= 0;
3645 SystemParametersInfoA (SPI_GETICONTITLELOGFONT
, 0, &logFont
, 0);
3646 infoPtr
->hFont
= CreateFontIndirectA (&logFont
);
3648 if (dwStyle
& TBSTYLE_TOOLTIPS
) {
3649 /* Create tooltip control */
3650 infoPtr
->hwndToolTip
=
3651 CreateWindowExA (0, TOOLTIPS_CLASSA
, NULL
, 0,
3652 CW_USEDEFAULT
, CW_USEDEFAULT
,
3653 CW_USEDEFAULT
, CW_USEDEFAULT
,
3656 /* Send NM_TOOLTIPSCREATED notification */
3657 if (infoPtr
->hwndToolTip
) {
3658 NMTOOLTIPSCREATED nmttc
;
3660 nmttc
.hdr
.hwndFrom
= hwnd
;
3661 nmttc
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
3662 nmttc
.hdr
.code
= NM_TOOLTIPSCREATED
;
3663 nmttc
.hwndToolTips
= infoPtr
->hwndToolTip
;
3665 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
3666 (WPARAM
)nmttc
.hdr
.idFrom
, (LPARAM
)&nmttc
);
3670 TOOLBAR_CalcToolbar(hwnd
);
3677 TOOLBAR_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3679 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3681 /* delete tooltip control */
3682 if (infoPtr
->hwndToolTip
)
3683 DestroyWindow (infoPtr
->hwndToolTip
);
3685 /* delete button data */
3686 if (infoPtr
->buttons
)
3687 COMCTL32_Free (infoPtr
->buttons
);
3689 /* delete strings */
3690 if (infoPtr
->strings
) {
3692 for (i
= 0; i
< infoPtr
->nNumStrings
; i
++)
3693 if (infoPtr
->strings
[i
])
3694 COMCTL32_Free (infoPtr
->strings
[i
]);
3696 COMCTL32_Free (infoPtr
->strings
);
3699 /* destroy internal image list */
3700 if (infoPtr
->himlInt
)
3701 ImageList_Destroy (infoPtr
->himlInt
);
3703 /* delete default font */
3705 DeleteObject (infoPtr
->hFont
);
3707 /* free toolbar info data */
3708 COMCTL32_Free (infoPtr
);
3709 SetWindowLongA (hwnd
, 0, 0);
3716 TOOLBAR_EraseBackground (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3718 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3720 if (infoPtr
->bTransparent
)
3721 return SendMessageA (GetParent (hwnd
), WM_ERASEBKGND
, wParam
, lParam
);
3723 return DefWindowProcA (hwnd
, WM_ERASEBKGND
, wParam
, lParam
);
3728 TOOLBAR_GetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3730 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3732 return infoPtr
->hFont
;
3737 TOOLBAR_LButtonDblClk (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3739 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3740 TBUTTON_INFO
*btnPtr
;
3744 pt
.x
= (INT
)LOWORD(lParam
);
3745 pt
.y
= (INT
)HIWORD(lParam
);
3746 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3749 btnPtr
= &infoPtr
->buttons
[nHit
];
3750 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
))
3753 infoPtr
->bCaptured
= TRUE
;
3754 infoPtr
->nButtonDown
= nHit
;
3756 btnPtr
->fsState
|= TBSTATE_PRESSED
;
3758 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
,
3761 else if (GetWindowLongA (hwnd
, GWL_STYLE
) & CCS_ADJUSTABLE
)
3762 TOOLBAR_Customize (hwnd
);
3769 TOOLBAR_LButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3771 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3772 TBUTTON_INFO
*btnPtr
;
3776 if (infoPtr
->hwndToolTip
)
3777 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
3778 WM_LBUTTONDOWN
, wParam
, lParam
);
3780 pt
.x
= (INT
)LOWORD(lParam
);
3781 pt
.y
= (INT
)HIWORD(lParam
);
3782 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3786 btnPtr
= &infoPtr
->buttons
[nHit
];
3787 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
))
3790 infoPtr
->nOldHit
= nHit
;
3792 CopyRect(&arrowRect
, &btnPtr
->rect
);
3793 arrowRect
.left
= max(btnPtr
->rect
.left
, btnPtr
->rect
.right
- DDARROW_WIDTH
);
3795 /* for EX_DRAWDDARROWS style, click must be in the drop-down arrow rect */
3796 if ((btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
) &&
3797 ((TOOLBAR_HasDropDownArrows(infoPtr
->dwExStyle
) && PtInRect(&arrowRect
, pt
)) ||
3798 (!TOOLBAR_HasDropDownArrows(infoPtr
->dwExStyle
))))
3802 * this time we must force a Redraw, so the btn is
3803 * painted down before CaptureChanged repaints it up
3805 RedrawWindow(hwnd
,&btnPtr
->rect
,0,
3806 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3808 nmtb
.hdr
.hwndFrom
= hwnd
;
3809 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
3810 nmtb
.hdr
.code
= TBN_DROPDOWN
;
3811 nmtb
.iItem
= btnPtr
->idCommand
;
3813 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
3814 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
);
3819 infoPtr
->bCaptured
= TRUE
;
3820 infoPtr
->nButtonDown
= nHit
;
3822 btnPtr
->fsState
|= TBSTATE_PRESSED
;
3823 btnPtr
->bHot
= FALSE
;
3825 InvalidateRect(hwnd
, &btnPtr
->rect
,
3826 TOOLBAR_HasText(infoPtr
, btnPtr
));
3834 TOOLBAR_LButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3836 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3837 TBUTTON_INFO
*btnPtr
;
3841 BOOL bSendMessage
= TRUE
;
3843 if (infoPtr
->hwndToolTip
)
3844 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
3845 WM_LBUTTONUP
, wParam
, lParam
);
3847 pt
.x
= (INT
)LOWORD(lParam
);
3848 pt
.y
= (INT
)HIWORD(lParam
);
3849 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3851 /* restore hot effect to hot button disabled by TOOLBAR_LButtonDown() */
3852 /* if the cursor is still inside of the toolbar */
3853 if((infoPtr
->nHotItem
>= 0) && (nHit
!= -1))
3854 infoPtr
->buttons
[infoPtr
->nHotItem
].bHot
= TRUE
;
3856 if ((infoPtr
->bCaptured
) && (infoPtr
->nButtonDown
>= 0)) {
3857 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
3858 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
3860 if (nHit
== infoPtr
->nButtonDown
) {
3861 if (btnPtr
->fsStyle
& TBSTYLE_CHECK
) {
3862 if (btnPtr
->fsStyle
& TBSTYLE_GROUP
) {
3863 nOldIndex
= TOOLBAR_GetCheckedGroupButtonIndex (infoPtr
,
3864 infoPtr
->nButtonDown
);
3865 if (nOldIndex
== infoPtr
->nButtonDown
)
3866 bSendMessage
= FALSE
;
3867 if ((nOldIndex
!= infoPtr
->nButtonDown
) &&
3869 infoPtr
->buttons
[nOldIndex
].fsState
&= ~TBSTATE_CHECKED
;
3870 btnPtr
->fsState
|= TBSTATE_CHECKED
;
3873 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
3874 btnPtr
->fsState
&= ~TBSTATE_CHECKED
;
3876 btnPtr
->fsState
|= TBSTATE_CHECKED
;
3881 bSendMessage
= FALSE
;
3883 if (nOldIndex
!= -1)
3885 InvalidateRect(hwnd
, &infoPtr
->buttons
[nOldIndex
].rect
,
3886 TOOLBAR_HasText(infoPtr
, &infoPtr
->buttons
[nOldIndex
]));
3890 * now we can ReleaseCapture, which triggers CAPTURECHANGED msg,
3891 * that resets bCaptured and btn TBSTATE_PRESSED flags,
3892 * and obliterates nButtonDown and nOldHit (see TOOLBAR_CaptureChanged)
3897 SendMessageA (GetParent(hwnd
), WM_COMMAND
,
3898 MAKEWPARAM(btnPtr
->idCommand
, 0), (LPARAM
)hwnd
);
3905 TOOLBAR_CaptureChanged(HWND hwnd
)
3907 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3908 TBUTTON_INFO
*btnPtr
;
3910 infoPtr
->bCaptured
= FALSE
;
3912 if (infoPtr
->nButtonDown
>= 0)
3914 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
3915 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
3917 infoPtr
->nButtonDown
= -1;
3918 infoPtr
->nOldHit
= -1;
3920 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
,
3927 TOOLBAR_MouseLeave (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3929 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3930 TBUTTON_INFO
*hotBtnPtr
, *btnPtr
;
3932 if (infoPtr
->nOldHit
< 0)
3935 hotBtnPtr
= &infoPtr
->buttons
[infoPtr
->nOldHit
];
3937 /* Redraw the button if the last button we were over is the hot button and it
3939 if((infoPtr
->nOldHit
== infoPtr
->nHotItem
) && (hotBtnPtr
->fsState
& TBSTATE_ENABLED
))
3941 hotBtnPtr
->bHot
= FALSE
;
3943 InvalidateRect (hwnd
, &hotBtnPtr
->rect
, TOOLBAR_HasText(infoPtr
,
3947 /* If the last button we were over is depressed then make it not */
3948 /* depressed and redraw it */
3949 if(infoPtr
->nOldHit
== infoPtr
->nButtonDown
)
3951 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
3953 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
3955 InvalidateRect (hwnd
, &(btnPtr
->rect
), TRUE
);
3958 infoPtr
->nOldHit
= -1; /* reset the old hit index as we've left the toolbar */
3959 infoPtr
->nHotItem
= -2; /* It has to be initially different from nOldHit */
3965 TOOLBAR_MouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3967 TBUTTON_INFO
*btnPtr
, *oldBtnPtr
;
3968 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3971 TRACKMOUSEEVENT trackinfo
;
3973 /* fill in the TRACKMOUSEEVENT struct */
3974 trackinfo
.cbSize
= sizeof(TRACKMOUSEEVENT
);
3975 trackinfo
.dwFlags
= TME_QUERY
;
3976 trackinfo
.hwndTrack
= hwnd
;
3977 trackinfo
.dwHoverTime
= HOVER_DEFAULT
;
3979 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
3980 _TrackMouseEvent(&trackinfo
);
3982 /* Make sure tracking is enabled so we recieve a WM_MOUSELEAVE message */
3983 if(!(trackinfo
.dwFlags
& TME_LEAVE
)) {
3984 trackinfo
.dwFlags
= TME_LEAVE
; /* notify upon leaving */
3986 /* call TRACKMOUSEEVENT so we recieve a WM_MOUSELEAVE message */
3987 /* and can properly deactivate the hot toolbar button */
3988 _TrackMouseEvent(&trackinfo
);
3991 if (infoPtr
->hwndToolTip
)
3992 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
3993 WM_MOUSEMOVE
, wParam
, lParam
);
3995 pt
.x
= (INT
)LOWORD(lParam
);
3996 pt
.y
= (INT
)HIWORD(lParam
);
3998 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
4000 if (infoPtr
->nOldHit
!= nHit
)
4002 /* Remove the effect of an old hot button if the button was enabled and was
4003 drawn with the hot button effect */
4004 if(infoPtr
->nOldHit
>= 0 && infoPtr
->nOldHit
== infoPtr
->nHotItem
&&
4005 (infoPtr
->buttons
[infoPtr
->nOldHit
].fsState
& TBSTATE_ENABLED
))
4007 oldBtnPtr
= &infoPtr
->buttons
[infoPtr
->nOldHit
];
4008 oldBtnPtr
->bHot
= FALSE
;
4010 InvalidateRect (hwnd
, &oldBtnPtr
->rect
,
4011 TOOLBAR_HasText(infoPtr
, oldBtnPtr
));
4014 /* It's not a separator or in nowhere. It's a hot button. */
4017 btnPtr
= &infoPtr
->buttons
[nHit
];
4018 btnPtr
->bHot
= TRUE
;
4020 infoPtr
->nHotItem
= nHit
;
4022 /* only enabled buttons show hot effect */
4023 if(infoPtr
->buttons
[nHit
].fsState
& TBSTATE_ENABLED
)
4025 InvalidateRect(hwnd
, &btnPtr
->rect
,
4026 TOOLBAR_HasText(infoPtr
, btnPtr
));
4031 if (infoPtr
->bCaptured
) {
4032 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
4033 if (infoPtr
->nOldHit
== infoPtr
->nButtonDown
) {
4034 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
4035 InvalidateRect(hwnd
, &btnPtr
->rect
, TRUE
);
4037 else if (nHit
== infoPtr
->nButtonDown
) {
4038 btnPtr
->fsState
|= TBSTATE_PRESSED
;
4039 InvalidateRect(hwnd
, &btnPtr
->rect
, TRUE
);
4042 infoPtr
->nOldHit
= nHit
;
4048 inline static LRESULT
4049 TOOLBAR_NCActivate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4051 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
4052 return DefWindowProcA (hwnd
, WM_NCACTIVATE
, wParam
, lParam
);
4054 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
4058 inline static LRESULT
4059 TOOLBAR_NCCalcSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4061 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & CCS_NODIVIDER
))
4062 ((LPRECT
)lParam
)->top
+= GetSystemMetrics(SM_CYEDGE
);
4064 return DefWindowProcA (hwnd
, WM_NCCALCSIZE
, wParam
, lParam
);
4069 TOOLBAR_NCCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4071 TOOLBAR_INFO
*infoPtr
;
4073 /* allocate memory for info structure */
4074 infoPtr
= (TOOLBAR_INFO
*)COMCTL32_Alloc (sizeof(TOOLBAR_INFO
));
4075 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
4078 infoPtr
->dwStructSize
= sizeof(TBBUTTON
);
4080 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
4081 if (!GetWindowLongA (hwnd
, GWL_HINSTANCE
)) {
4082 HINSTANCE hInst
= (HINSTANCE
)GetWindowLongA (GetParent (hwnd
), GWL_HINSTANCE
);
4083 SetWindowLongA (hwnd
, GWL_HINSTANCE
, (DWORD
)hInst
);
4086 return DefWindowProcA (hwnd
, WM_NCCREATE
, wParam
, lParam
);
4091 TOOLBAR_NCPaint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4093 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
4097 if (dwStyle
& WS_MINIMIZE
)
4098 return 0; /* Nothing to do */
4100 DefWindowProcA (hwnd
, WM_NCPAINT
, wParam
, lParam
);
4102 if (!(hdc
= GetDCEx (hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
)))
4105 if (!(dwStyle
& CCS_NODIVIDER
))
4107 GetWindowRect (hwnd
, &rcWindow
);
4108 OffsetRect (&rcWindow
, -rcWindow
.left
, -rcWindow
.top
);
4109 if( dwStyle
& WS_BORDER
)
4110 OffsetRect (&rcWindow
, 1, 1);
4111 DrawEdge (hdc
, &rcWindow
, EDGE_ETCHED
, BF_TOP
);
4114 ReleaseDC( hwnd
, hdc
);
4120 inline static LRESULT
4121 TOOLBAR_Notify (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4123 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4124 LPNMHDR lpnmh
= (LPNMHDR
)lParam
;
4126 TRACE("passing WM_NOTIFY!\n");
4128 if ((infoPtr
->hwndToolTip
) && (lpnmh
->hwndFrom
== infoPtr
->hwndToolTip
)) {
4129 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
, wParam
, lParam
);
4132 if (lpnmh
->code
== TTN_GETDISPINFOA
) {
4133 LPNMTTDISPINFOA lpdi
= (LPNMTTDISPINFOA
)lParam
;
4135 FIXME("retrieving ASCII string\n");
4138 else if (lpnmh
->code
== TTN_GETDISPINFOW
) {
4139 LPNMTTDISPINFOW lpdi
= (LPNMTTDISPINFOW
)lParam
;
4141 FIXME("retrieving UNICODE string\n");
4152 TOOLBAR_Paint (HWND hwnd
, WPARAM wParam
)
4154 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
4160 /* fill ps.rcPaint with a default rect */
4161 memcpy(&(ps
.rcPaint
), &(infoPtr
->rcBound
), sizeof(infoPtr
->rcBound
));
4163 hdc
= wParam
==0 ? BeginPaint(hwnd
, &ps
) : (HDC
)wParam
;
4164 TOOLBAR_Refresh (hwnd
, hdc
, &ps
);
4165 if (!wParam
) EndPaint (hwnd
, &ps
);
4172 TOOLBAR_Size (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4174 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4175 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
4184 /* Resize deadlock check */
4185 if (infoPtr
->bAutoSize
) {
4186 infoPtr
->bAutoSize
= FALSE
;
4190 /* FIXME: optimize to only update size if the new size doesn't */
4191 /* match the current size */
4193 flags
= (INT
) wParam
;
4195 /* FIXME for flags =
4196 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
4199 TRACE("sizing toolbar!\n");
4201 if (flags
== SIZE_RESTORED
) {
4202 /* width and height don't apply */
4203 parent
= GetParent (hwnd
);
4204 GetClientRect(parent
, &parent_rect
);
4205 x
= parent_rect
.left
;
4206 y
= parent_rect
.top
;
4208 if (dwStyle
& CCS_NORESIZE
) {
4209 uPosFlags
|= (SWP_NOSIZE
| SWP_NOMOVE
);
4212 * this sets the working width of the toolbar, and
4213 * Calc Toolbar will not adjust it, only the height
4215 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
4216 cy
= infoPtr
->nHeight
;
4217 cx
= infoPtr
->nWidth
;
4218 TOOLBAR_CalcToolbar (hwnd
);
4219 infoPtr
->nWidth
= cx
;
4220 infoPtr
->nHeight
= cy
;
4223 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
4224 TOOLBAR_CalcToolbar (hwnd
);
4225 cy
= infoPtr
->nHeight
;
4226 cx
= infoPtr
->nWidth
;
4228 if (dwStyle
& CCS_NOMOVEY
) {
4229 GetWindowRect(hwnd
, &window_rect
);
4230 ScreenToClient(parent
, (LPPOINT
)&window_rect
.left
);
4231 y
= window_rect
.top
;
4235 if (dwStyle
& CCS_NOPARENTALIGN
) {
4236 uPosFlags
|= SWP_NOMOVE
;
4237 cy
= infoPtr
->nHeight
;
4238 cx
= infoPtr
->nWidth
;
4241 if (!(dwStyle
& CCS_NODIVIDER
))
4242 cy
+= GetSystemMetrics(SM_CYEDGE
);
4244 if (dwStyle
& WS_BORDER
)
4247 cy
+= GetSystemMetrics(SM_CYEDGE
);
4248 cx
+= GetSystemMetrics(SM_CYEDGE
);
4251 SetWindowPos (hwnd
, 0, parent_rect
.left
- x
, parent_rect
.top
- y
,
4252 cx
, cy
, uPosFlags
| SWP_NOZORDER
);
4259 TOOLBAR_StyleChanged (HWND hwnd
, INT nType
, LPSTYLESTRUCT lpStyle
)
4261 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4263 if (nType
== GWL_STYLE
) {
4264 if (lpStyle
->styleNew
& TBSTYLE_LIST
) {
4265 infoPtr
->dwDTFlags
= DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
;
4268 infoPtr
->dwDTFlags
= DT_CENTER
;
4272 TOOLBAR_AutoSize (hwnd
);
4274 InvalidateRect(hwnd
, NULL
, FALSE
);
4281 static LRESULT WINAPI
4282 ToolbarWindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
4284 if (!TOOLBAR_GetInfoPtr(hwnd
) && (uMsg
!= WM_NCCREATE
))
4285 return DefWindowProcA( hwnd
, uMsg
, wParam
, lParam
);
4290 return TOOLBAR_AddBitmap (hwnd
, wParam
, lParam
);
4292 case TB_ADDBUTTONSA
:
4293 return TOOLBAR_AddButtonsA (hwnd
, wParam
, lParam
);
4295 case TB_ADDBUTTONSW
:
4296 return TOOLBAR_AddButtonsW (hwnd
, wParam
, lParam
);
4299 return TOOLBAR_AddStringA (hwnd
, wParam
, lParam
);
4302 return TOOLBAR_AddStringW (hwnd
, wParam
, lParam
);
4305 return TOOLBAR_AutoSize (hwnd
);
4307 case TB_BUTTONCOUNT
:
4308 return TOOLBAR_ButtonCount (hwnd
, wParam
, lParam
);
4310 case TB_BUTTONSTRUCTSIZE
:
4311 return TOOLBAR_ButtonStructSize (hwnd
, wParam
, lParam
);
4313 case TB_CHANGEBITMAP
:
4314 return TOOLBAR_ChangeBitmap (hwnd
, wParam
, lParam
);
4316 case TB_CHECKBUTTON
:
4317 return TOOLBAR_CheckButton (hwnd
, wParam
, lParam
);
4319 case TB_COMMANDTOINDEX
:
4320 return TOOLBAR_CommandToIndex (hwnd
, wParam
, lParam
);
4323 return TOOLBAR_Customize (hwnd
);
4325 case TB_DELETEBUTTON
:
4326 return TOOLBAR_DeleteButton (hwnd
, wParam
, lParam
);
4328 case TB_ENABLEBUTTON
:
4329 return TOOLBAR_EnableButton (hwnd
, wParam
, lParam
);
4331 case TB_GETANCHORHIGHLIGHT
:
4332 return TOOLBAR_GetAnchorHighlight (hwnd
);
4335 return TOOLBAR_GetBitmap (hwnd
, wParam
, lParam
);
4337 case TB_GETBITMAPFLAGS
:
4338 return TOOLBAR_GetBitmapFlags (hwnd
, wParam
, lParam
);
4341 return TOOLBAR_GetButton (hwnd
, wParam
, lParam
);
4343 case TB_GETBUTTONINFOA
:
4344 return TOOLBAR_GetButtonInfoA (hwnd
, wParam
, lParam
);
4346 case TB_GETBUTTONINFOW
:
4347 return TOOLBAR_GetButtonInfoW (hwnd
, wParam
, lParam
);
4349 case TB_GETBUTTONSIZE
:
4350 return TOOLBAR_GetButtonSize (hwnd
);
4352 case TB_GETBUTTONTEXTA
:
4353 return TOOLBAR_GetButtonTextA (hwnd
, wParam
, lParam
);
4355 case TB_GETBUTTONTEXTW
:
4356 return TOOLBAR_GetButtonTextW (hwnd
, wParam
, lParam
);
4358 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
4360 case TB_GETDISABLEDIMAGELIST
:
4361 return TOOLBAR_GetDisabledImageList (hwnd
, wParam
, lParam
);
4363 case TB_GETEXTENDEDSTYLE
:
4364 return TOOLBAR_GetExtendedStyle (hwnd
);
4366 case TB_GETHOTIMAGELIST
:
4367 return TOOLBAR_GetHotImageList (hwnd
, wParam
, lParam
);
4370 return TOOLBAR_GetHotItem (hwnd
);
4372 case TB_GETIMAGELIST
:
4373 return TOOLBAR_GetImageList (hwnd
, wParam
, lParam
);
4375 /* case TB_GETINSERTMARK: */ /* 4.71 */
4376 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
4378 case TB_GETITEMRECT
:
4379 return TOOLBAR_GetItemRect (hwnd
, wParam
, lParam
);
4382 return TOOLBAR_GetMaxSize (hwnd
, wParam
, lParam
);
4384 /* case TB_GETOBJECT: */ /* 4.71 */
4385 /* case TB_GETPADDING: */ /* 4.71 */
4388 return TOOLBAR_GetRect (hwnd
, wParam
, lParam
);
4391 return TOOLBAR_GetRows (hwnd
, wParam
, lParam
);
4394 return TOOLBAR_GetState (hwnd
, wParam
, lParam
);
4397 return TOOLBAR_GetStyle (hwnd
, wParam
, lParam
);
4399 case TB_GETTEXTROWS
:
4400 return TOOLBAR_GetTextRows (hwnd
, wParam
, lParam
);
4402 case TB_GETTOOLTIPS
:
4403 return TOOLBAR_GetToolTips (hwnd
, wParam
, lParam
);
4405 case TB_GETUNICODEFORMAT
:
4406 return TOOLBAR_GetUnicodeFormat (hwnd
, wParam
, lParam
);
4408 case CCM_GETVERSION
:
4409 return TOOLBAR_GetVersion (hwnd
);
4412 return TOOLBAR_HideButton (hwnd
, wParam
, lParam
);
4415 return TOOLBAR_HitTest (hwnd
, wParam
, lParam
);
4417 case TB_INDETERMINATE
:
4418 return TOOLBAR_Indeterminate (hwnd
, wParam
, lParam
);
4420 case TB_INSERTBUTTONA
:
4421 return TOOLBAR_InsertButtonA (hwnd
, wParam
, lParam
);
4423 case TB_INSERTBUTTONW
:
4424 return TOOLBAR_InsertButtonW (hwnd
, wParam
, lParam
);
4426 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
4428 case TB_ISBUTTONCHECKED
:
4429 return TOOLBAR_IsButtonChecked (hwnd
, wParam
, lParam
);
4431 case TB_ISBUTTONENABLED
:
4432 return TOOLBAR_IsButtonEnabled (hwnd
, wParam
, lParam
);
4434 case TB_ISBUTTONHIDDEN
:
4435 return TOOLBAR_IsButtonHidden (hwnd
, wParam
, lParam
);
4437 case TB_ISBUTTONHIGHLIGHTED
:
4438 return TOOLBAR_IsButtonHighlighted (hwnd
, wParam
, lParam
);
4440 case TB_ISBUTTONINDETERMINATE
:
4441 return TOOLBAR_IsButtonIndeterminate (hwnd
, wParam
, lParam
);
4443 case TB_ISBUTTONPRESSED
:
4444 return TOOLBAR_IsButtonPressed (hwnd
, wParam
, lParam
);
4446 case TB_LOADIMAGES
: /* 4.70 */
4447 FIXME("missing standard imagelists\n");
4450 /* case TB_MAPACCELERATORA: */ /* 4.71 */
4451 /* case TB_MAPACCELERATORW: */ /* 4.71 */
4452 /* case TB_MARKBUTTON: */ /* 4.71 */
4453 /* case TB_MOVEBUTTON: */ /* 4.71 */
4455 case TB_PRESSBUTTON
:
4456 return TOOLBAR_PressButton (hwnd
, wParam
, lParam
);
4458 /* case TB_REPLACEBITMAP: */
4460 case TB_SAVERESTOREA
:
4461 return TOOLBAR_SaveRestoreA (hwnd
, wParam
, lParam
);
4463 case TB_SAVERESTOREW
:
4464 return TOOLBAR_SaveRestoreW (hwnd
, wParam
, lParam
);
4466 case TB_SETANCHORHIGHLIGHT
:
4467 return TOOLBAR_SetAnchorHighlight (hwnd
, wParam
);
4469 case TB_SETBITMAPSIZE
:
4470 return TOOLBAR_SetBitmapSize (hwnd
, wParam
, lParam
);
4472 case TB_SETBUTTONINFOA
:
4473 return TOOLBAR_SetButtonInfoA (hwnd
, wParam
, lParam
);
4475 case TB_SETBUTTONINFOW
:
4476 return TOOLBAR_SetButtonInfoW (hwnd
, wParam
, lParam
);
4478 case TB_SETBUTTONSIZE
:
4479 return TOOLBAR_SetButtonSize (hwnd
, wParam
, lParam
);
4481 case TB_SETBUTTONWIDTH
:
4482 return TOOLBAR_SetButtonWidth (hwnd
, wParam
, lParam
);
4485 return TOOLBAR_SetCmdId (hwnd
, wParam
, lParam
);
4487 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
4489 case TB_SETDISABLEDIMAGELIST
:
4490 return TOOLBAR_SetDisabledImageList (hwnd
, wParam
, lParam
);
4492 case TB_SETDRAWTEXTFLAGS
:
4493 return TOOLBAR_SetDrawTextFlags (hwnd
, wParam
, lParam
);
4495 case TB_SETEXTENDEDSTYLE
:
4496 return TOOLBAR_SetExtendedStyle (hwnd
, wParam
, lParam
);
4498 case TB_SETHOTIMAGELIST
:
4499 return TOOLBAR_SetHotImageList (hwnd
, wParam
, lParam
);
4502 return TOOLBAR_SetHotItem (hwnd
, wParam
);
4504 case TB_SETIMAGELIST
:
4505 return TOOLBAR_SetImageList (hwnd
, wParam
, lParam
);
4508 return TOOLBAR_SetIndent (hwnd
, wParam
, lParam
);
4510 /* case TB_SETINSERTMARK: */ /* 4.71 */
4512 case TB_SETINSERTMARKCOLOR
:
4513 return TOOLBAR_SetInsertMarkColor (hwnd
, wParam
, lParam
);
4515 case TB_SETMAXTEXTROWS
:
4516 return TOOLBAR_SetMaxTextRows (hwnd
, wParam
, lParam
);
4518 /* case TB_SETPADDING: */ /* 4.71 */
4521 return TOOLBAR_SetParent (hwnd
, wParam
, lParam
);
4524 return TOOLBAR_SetRows (hwnd
, wParam
, lParam
);
4527 return TOOLBAR_SetState (hwnd
, wParam
, lParam
);
4530 return TOOLBAR_SetStyle (hwnd
, wParam
, lParam
);
4532 case TB_SETTOOLTIPS
:
4533 return TOOLBAR_SetToolTips (hwnd
, wParam
, lParam
);
4535 case TB_SETUNICODEFORMAT
:
4536 return TOOLBAR_SetUnicodeFormat (hwnd
, wParam
, lParam
);
4538 case CCM_SETVERSION
:
4539 return TOOLBAR_SetVersion (hwnd
, (INT
)wParam
);
4545 return TOOLBAR_Create (hwnd
, wParam
, lParam
);
4548 return TOOLBAR_Destroy (hwnd
, wParam
, lParam
);
4551 return TOOLBAR_EraseBackground (hwnd
, wParam
, lParam
);
4554 return TOOLBAR_GetFont (hwnd
, wParam
, lParam
);
4556 /* case WM_KEYDOWN: */
4557 /* case WM_KILLFOCUS: */
4559 case WM_LBUTTONDBLCLK
:
4560 return TOOLBAR_LButtonDblClk (hwnd
, wParam
, lParam
);
4562 case WM_LBUTTONDOWN
:
4563 return TOOLBAR_LButtonDown (hwnd
, wParam
, lParam
);
4566 return TOOLBAR_LButtonUp (hwnd
, wParam
, lParam
);
4569 return TOOLBAR_MouseMove (hwnd
, wParam
, lParam
);
4572 return TOOLBAR_MouseLeave (hwnd
, wParam
, lParam
);
4574 case WM_CAPTURECHANGED
:
4575 return TOOLBAR_CaptureChanged(hwnd
);
4578 return TOOLBAR_NCActivate (hwnd
, wParam
, lParam
);
4581 return TOOLBAR_NCCalcSize (hwnd
, wParam
, lParam
);
4584 return TOOLBAR_NCCreate (hwnd
, wParam
, lParam
);
4587 return TOOLBAR_NCPaint (hwnd
, wParam
, lParam
);
4590 return TOOLBAR_Notify (hwnd
, wParam
, lParam
);
4592 /* case WM_NOTIFYFORMAT: */
4595 return TOOLBAR_Paint (hwnd
, wParam
);
4598 return TOOLBAR_Size (hwnd
, wParam
, lParam
);
4600 case WM_STYLECHANGED
:
4601 return TOOLBAR_StyleChanged (hwnd
, (INT
)wParam
, (LPSTYLESTRUCT
)lParam
);
4603 /* case WM_SYSCOLORCHANGE: */
4605 /* case WM_WININICHANGE: */
4610 case WM_MEASUREITEM
:
4612 return SendMessageA (GetParent (hwnd
), uMsg
, wParam
, lParam
);
4615 if (uMsg
>= WM_USER
)
4616 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
4617 uMsg
, wParam
, lParam
);
4618 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
4625 TOOLBAR_Register (void)
4629 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
4630 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
;
4631 wndClass
.lpfnWndProc
= (WNDPROC
)ToolbarWindowProc
;
4632 wndClass
.cbClsExtra
= 0;
4633 wndClass
.cbWndExtra
= sizeof(TOOLBAR_INFO
*);
4634 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
4635 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_3DFACE
+ 1);
4636 wndClass
.lpszClassName
= TOOLBARCLASSNAMEA
;
4638 RegisterClassA (&wndClass
);
4643 TOOLBAR_Unregister (void)
4645 UnregisterClassA (TOOLBARCLASSNAMEA
, (HINSTANCE
)NULL
);