4 * Copyright 1998,1999 Eric Kohl
7 * - A little bug in TOOLBAR_DrawMasked()
8 * - Button wrapping (under construction).
10 * - Notifications (under construction).
12 * - Tooltip support (almost complete).
13 * - Unicode suppport (under construction).
14 * - Fix TOOLBAR_SetButtonInfo32A/W.
15 * - Customize dialog (under construction).
18 * - Run tests using Waite Group Windows95 API Bible Volume 2.
19 * The second cdrom contains executables addstr.exe, btncount.exe,
20 * btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
21 * enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
22 * indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
23 * setparnt.exe, setrows.exe, toolwnd.exe.
24 * - Microsofts controlspy examples.
37 #include "debugtools.h"
39 DEFAULT_DEBUG_CHANNEL(toolbar
)
41 #define SEPARATOR_WIDTH 8
43 #define BOTTOM_BORDER 2
45 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
49 TOOLBAR_DrawFlatSeparator (LPRECT lpRect
, HDC hdc
)
51 INT x
= (lpRect
->left
+ lpRect
->right
) / 2 - 1;
52 INT yBottom
= lpRect
->bottom
- 3;
53 INT yTop
= lpRect
->top
+ 1;
55 SelectObject ( hdc
, GetSysColorPen (COLOR_3DSHADOW
));
56 MoveToEx (hdc
, x
, yBottom
, NULL
);
57 LineTo (hdc
, x
, yTop
);
59 SelectObject ( hdc
, GetSysColorPen (COLOR_3DHILIGHT
));
60 MoveToEx (hdc
, x
, yBottom
, NULL
);
61 LineTo (hdc
, x
, yTop
);
65 * Draw the text string for this button.
66 * note: himl is not used, except to determine whether this button has
67 * an associated bitmap. If so, the text is drawn below it, otherwise
68 * the text is drawn within the rectangle of the button itself.
71 TOOLBAR_DrawString (TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
,
72 HDC hdc
, INT nState
, DWORD dwStyle
, HIMAGELIST himl
)
74 RECT rcText
= btnPtr
->rect
;
80 if ((btnPtr
->iString
> -1) && (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
82 InflateRect (&rcText
, -3, -3);
83 if (himl
&& btnPtr
->iBitmap
>0) {
84 if (dwStyle
& TBSTYLE_LIST
) {
85 rcText
.left
+= infoPtr
->nBitmapWidth
;
88 rcText
.top
+= infoPtr
->nBitmapHeight
;
92 if (nState
& (TBSTATE_PRESSED
| TBSTATE_CHECKED
))
93 OffsetRect (&rcText
, 1, 1);
95 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
96 nOldBkMode
= SetBkMode (hdc
, TRANSPARENT
);
97 if (!(nState
& TBSTATE_ENABLED
)) {
98 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_3DHILIGHT
));
99 OffsetRect (&rcText
, 1, 1);
100 DrawTextW (hdc
, infoPtr
->strings
[btnPtr
->iString
], -1,
101 &rcText
, infoPtr
->dwDTFlags
);
102 SetTextColor (hdc
, GetSysColor (COLOR_3DSHADOW
));
103 OffsetRect (&rcText
, -1, -1);
104 DrawTextW (hdc
, infoPtr
->strings
[btnPtr
->iString
], -1,
105 &rcText
, infoPtr
->dwDTFlags
);
107 else if (nState
& TBSTATE_INDETERMINATE
) {
108 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_3DSHADOW
));
109 DrawTextW (hdc
, infoPtr
->strings
[btnPtr
->iString
], -1,
110 &rcText
, infoPtr
->dwDTFlags
);
113 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
114 DrawTextW (hdc
, infoPtr
->strings
[btnPtr
->iString
], -1,
115 &rcText
, infoPtr
->dwDTFlags
);
118 SetTextColor (hdc
, clrOld
);
119 SelectObject (hdc
, hOldFont
);
120 if (nOldBkMode
!= TRANSPARENT
)
121 SetBkMode (hdc
, nOldBkMode
);
127 TOOLBAR_DrawPattern (HDC hdc
, LPRECT lpRect
)
129 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
130 INT cx
= lpRect
->right
- lpRect
->left
;
131 INT cy
= lpRect
->bottom
- lpRect
->top
;
132 PatBlt (hdc
, lpRect
->left
, lpRect
->top
, cx
, cy
, 0x00FA0089);
133 SelectObject (hdc
, hbr
);
138 TOOLBAR_DrawMasked (TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
,
139 HDC hdc
, INT x
, INT y
)
141 /* FIXME: this function is a hack since it uses image list
142 internals directly */
144 HIMAGELIST himl
= infoPtr
->himlDef
;
152 /* create new dc's */
153 hdcImageList
= CreateCompatibleDC (0);
154 hdcMask
= CreateCompatibleDC (0);
156 /* create new bitmap */
157 hbmMask
= CreateBitmap (himl
->cx
, himl
->cy
, 1, 1, NULL
);
158 SelectObject (hdcMask
, hbmMask
);
160 /* copy the mask bitmap */
161 SelectObject (hdcImageList
, himl
->hbmMask
);
162 SetBkColor (hdcImageList
, RGB(255, 255, 255));
163 SetTextColor (hdcImageList
, RGB(0, 0, 0));
164 BitBlt (hdcMask
, 0, 0, himl
->cx
, himl
->cy
,
165 hdcImageList
, himl
->cx
* btnPtr
->iBitmap
, 0, SRCCOPY
);
168 /* add white mask from image */
169 SelectObject (hdcImageList
, himl
->hbmImage
);
170 SetBkColor (hdcImageList
, RGB(0, 0, 0));
171 BitBlt (hdcMask
, 0, 0, himl
->cx
, himl
->cy
,
172 hdcImageList
, himl
->cx
* btnPtr
->iBitmap
, 0, MERGEPAINT
);
175 /* draw the new mask */
176 SelectObject (hdc
, GetSysColorBrush (COLOR_3DHILIGHT
));
177 BitBlt (hdc
, x
+1, y
+1, himl
->cx
, himl
->cy
,
178 hdcMask
, 0, 0, 0xB8074A);
180 SelectObject (hdc
, GetSysColorBrush (COLOR_3DSHADOW
));
181 BitBlt (hdc
, x
, y
, himl
->cx
, himl
->cy
,
182 hdcMask
, 0, 0, 0xB8074A);
184 DeleteObject (hbmMask
);
186 DeleteDC (hdcImageList
);
191 TOOLBAR_DrawButton (HWND hwnd
, TBUTTON_INFO
*btnPtr
, HDC hdc
)
193 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
194 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
197 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
203 if (btnPtr
->fsStyle
& TBSTYLE_SEP
) {
204 if ((dwStyle
& TBSTYLE_FLAT
) && (btnPtr
->iBitmap
== 0))
205 TOOLBAR_DrawFlatSeparator (&rc
, hdc
);
210 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
)) {
211 if (!(dwStyle
& TBSTYLE_FLAT
))
212 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
213 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
215 if (infoPtr
->himlDis
&& btnPtr
->iBitmap
>=0)
216 ImageList_Draw (infoPtr
->himlDis
, btnPtr
->iBitmap
, hdc
,
217 rc
.left
+1, rc
.top
+1, ILD_NORMAL
);
219 TOOLBAR_DrawMasked (infoPtr
, btnPtr
, hdc
, rc
.left
+1, rc
.top
+1);
221 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
,
226 /* pressed TBSTYLE_BUTTON */
227 if (btnPtr
->fsState
& TBSTATE_PRESSED
) {
228 if (dwStyle
& TBSTYLE_FLAT
)
229 DrawEdge (hdc
, &rc
, BDR_SUNKENOUTER
, BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
231 DrawEdge (hdc
, &rc
, EDGE_SUNKEN
, BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
232 if (btnPtr
->iBitmap
>0)
233 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
234 rc
.left
+2, rc
.top
+2, ILD_NORMAL
);
235 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
,
240 /* checked TBSTYLE_CHECK */
241 if ((btnPtr
->fsStyle
& TBSTYLE_CHECK
) &&
242 (btnPtr
->fsState
& TBSTATE_CHECKED
)) {
243 if (dwStyle
& TBSTYLE_FLAT
)
244 DrawEdge (hdc
, &rc
, BDR_SUNKENOUTER
,
245 BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
247 DrawEdge (hdc
, &rc
, EDGE_SUNKEN
,
248 BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
250 TOOLBAR_DrawPattern (hdc
, &rc
);
252 if (btnPtr
->iBitmap
>0)
253 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
254 rc
.left
+2, rc
.top
+2, ILD_NORMAL
);
256 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
,
262 if (btnPtr
->fsState
& TBSTATE_INDETERMINATE
) {
263 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
264 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
266 TOOLBAR_DrawPattern (hdc
, &rc
);
267 TOOLBAR_DrawMasked (infoPtr
, btnPtr
, hdc
, rc
.left
+1, rc
.top
+1);
268 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
,
274 if (dwStyle
& TBSTYLE_FLAT
)
277 DrawEdge (hdc
, &rc
, BDR_RAISEDINNER
, BF_RECT
| BF_MIDDLE
);
278 if (btnPtr
->bHot
&& infoPtr
->himlHot
&& btnPtr
->iBitmap
>0)
279 ImageList_Draw (infoPtr
->himlHot
, btnPtr
->iBitmap
, hdc
,
280 rc
.left
+2, rc
.top
+2, ILD_NORMAL
);
281 else if (btnPtr
->iBitmap
>0)
282 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
283 rc
.left
+2, rc
.top
+2, ILD_NORMAL
);
287 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
288 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
290 if (btnPtr
->iBitmap
>0)
291 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
292 rc
.left
+1, rc
.top
+1, ILD_NORMAL
);
295 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
,
301 TOOLBAR_Refresh (HWND hwnd
, HDC hdc
)
303 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
304 TBUTTON_INFO
*btnPtr
;
308 btnPtr
= infoPtr
->buttons
;
309 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++)
310 TOOLBAR_DrawButton (hwnd
, btnPtr
, hdc
);
315 TOOLBAR_CalcStrings (HWND hwnd
, LPSIZE lpSize
)
317 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
318 TBUTTON_INFO
*btnPtr
;
328 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
330 btnPtr
= infoPtr
->buttons
;
331 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
332 if (!(btnPtr
->fsState
& TBSTATE_HIDDEN
) &&
333 (btnPtr
->iString
> -1) &&
334 (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
335 LPWSTR lpText
= infoPtr
->strings
[btnPtr
->iString
];
336 GetTextExtentPoint32W (hdc
, lpText
, lstrlenW (lpText
), &sz
);
337 if (sz
.cx
> lpSize
->cx
)
339 if (sz
.cy
> lpSize
->cy
)
344 SelectObject (hdc
, hOldFont
);
347 TRACE("string size %d x %d!\n", lpSize
->cx
, lpSize
->cy
);
350 /***********************************************************************
351 * TOOLBAR_WrapToolbar
353 * This function walks through the buttons and seperators in the
354 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
355 * wrapping should occur based on the width of the toolbar window.
356 * It does *not* calculate button placement itself. That task
357 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
358 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
359 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
363 TOOLBAR_WrapToolbar( HWND hwnd
, DWORD dwStyle
)
365 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
366 TBUTTON_INFO
*btnPtr
;
369 BOOL bWrap
, bButtonWrap
;
371 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
372 /* no layout is necessary. Applications may use this style */
373 /* to perform their own layout on the toolbar. */
374 if( !(dwStyle
& TBSTYLE_WRAPABLE
) )
377 btnPtr
= infoPtr
->buttons
;
378 x
= infoPtr
->nIndent
;
380 /* this can get the parents width, to know how far we can extend
381 * this toolbar. We cannot use its height, as there may be multiple
382 * toolbars in a rebar control
384 GetClientRect( GetParent(hwnd
), &rc
);
385 infoPtr
->nWidth
= rc
.right
- rc
.left
;
388 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++ )
391 btnPtr
[i
].fsState
&= ~TBSTATE_WRAP
;
393 if (btnPtr
[i
].fsState
& TBSTATE_HIDDEN
)
396 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
397 /* it is the actual width of the separator. This is used for */
398 /* custom controls in toolbars. */
399 if (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
)
400 cx
= (btnPtr
[i
].iBitmap
> 0) ?
401 btnPtr
[i
].iBitmap
: SEPARATOR_WIDTH
;
403 cx
= infoPtr
->nButtonWidth
;
405 /* Two or more adjacent separators form a separator group. */
406 /* The first separator in a group should be wrapped to the */
407 /* next row if the previous wrapping is on a button. */
409 (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
) &&
410 (i
+ 1 < infoPtr
->nNumButtons
) &&
411 (btnPtr
[i
+ 1].fsStyle
& TBSTYLE_SEP
) )
413 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
414 x
= infoPtr
->nIndent
;
420 /* The layout makes sure the bitmap is visible, but not the button. */
421 if ( x
+ cx
- (infoPtr
->nButtonWidth
- infoPtr
->nBitmapWidth
) / 2
426 /* If the current button is a separator and not hidden, */
427 /* go to the next until it reaches a non separator. */
428 /* Wrap the last separator if it is before a button. */
429 while( ( (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
) ||
430 (btnPtr
[i
].fsState
& TBSTATE_HIDDEN
) ) &&
431 i
< infoPtr
->nNumButtons
)
437 if( bFound
&& i
< infoPtr
->nNumButtons
)
440 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
441 x
= infoPtr
->nIndent
;
445 else if ( i
>= infoPtr
->nNumButtons
)
448 /* If the current button is not a separator, find the last */
449 /* separator and wrap it. */
450 for ( j
= i
- 1; j
>= 0 && !(btnPtr
[j
].fsState
& TBSTATE_WRAP
); j
--)
452 if ((btnPtr
[j
].fsStyle
& TBSTYLE_SEP
) &&
453 !(btnPtr
[j
].fsState
& TBSTATE_HIDDEN
))
457 x
= infoPtr
->nIndent
;
458 btnPtr
[j
].fsState
|= TBSTATE_WRAP
;
464 /* If no separator available for wrapping, wrap one of */
465 /* non-hidden previous button. */
469 j
>= 0 && !(btnPtr
[j
].fsState
& TBSTATE_WRAP
); j
--)
471 if (btnPtr
[j
].fsState
& TBSTATE_HIDDEN
)
476 x
= infoPtr
->nIndent
;
477 btnPtr
[j
].fsState
|= TBSTATE_WRAP
;
483 /* If all above failed, wrap the current button. */
486 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
488 x
= infoPtr
->nIndent
;
489 if (btnPtr
[i
].fsState
& TBSTYLE_SEP
)
500 /***********************************************************************
501 * TOOLBAR_CalcToolbar
503 * This function calculates button and separator placement. It first
504 * calculates the button sizes, gets the toolbar window width and then
505 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
506 * on. It assigns a new location to each item and sends this location to
507 * the tooltip window if appropriate. Finally, it updates the rcBound
508 * rect and calculates the new required toolbar window height.
512 TOOLBAR_CalcToolbar (HWND hwnd
)
514 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
515 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
516 TBUTTON_INFO
*btnPtr
;
517 INT i
, nRows
, nSepRows
;
523 TOOLBAR_CalcStrings (hwnd
, &sizeString
);
525 if (dwStyle
& TBSTYLE_LIST
) {
526 infoPtr
->nButtonHeight
= max(infoPtr
->nBitmapHeight
, sizeString
.cy
) + 6;
527 infoPtr
->nButtonWidth
= infoPtr
->nBitmapWidth
+ sizeString
.cx
+ 6;
530 if (sizeString
.cy
> 0)
531 infoPtr
->nButtonHeight
= sizeString
.cy
+ infoPtr
->nBitmapHeight
+ 6;
532 else if (infoPtr
->nButtonHeight
< infoPtr
->nBitmapHeight
+ 6)
533 infoPtr
->nButtonHeight
= infoPtr
->nBitmapHeight
+ 6;
535 if (sizeString
.cx
> infoPtr
->nBitmapWidth
)
536 infoPtr
->nButtonWidth
= sizeString
.cx
+ 6;
537 else if (infoPtr
->nButtonWidth
< infoPtr
->nBitmapWidth
+ 6)
538 infoPtr
->nButtonWidth
= infoPtr
->nBitmapWidth
+ 6;
541 if ( infoPtr
->cxMin
>= 0 && infoPtr
->nButtonWidth
< infoPtr
->cxMin
)
542 infoPtr
->nButtonWidth
= infoPtr
->cxMin
;
543 if ( infoPtr
->cxMax
>= 0 && infoPtr
->nButtonWidth
> infoPtr
->cxMax
)
544 infoPtr
->nButtonWidth
= infoPtr
->cxMax
;
546 TOOLBAR_WrapToolbar( hwnd
, dwStyle
);
548 x
= infoPtr
->nIndent
;
549 y
= (dwStyle
& TBSTYLE_FLAT
) ? 0 : TOP_BORDER
;
551 GetClientRect( hwnd
, &rc
);
552 /* get initial values for toolbar */
553 infoPtr
->nWidth
= rc
.right
- rc
.left
;
554 infoPtr
->nHeight
= rc
.bottom
- rc
.top
;
556 /* from above, minimum is a button, and possible text */
557 cx
= infoPtr
->nButtonWidth
;
558 /* cannot use just ButtonHeight, we may have no buttons! */
559 cy
= infoPtr
->nHeight
;
561 nRows
= nSepRows
= 0;
563 infoPtr
->rcBound
.top
= y
;
564 infoPtr
->rcBound
.left
= x
;
565 infoPtr
->rcBound
.bottom
= y
+ cy
;
566 infoPtr
->rcBound
.right
= x
;
568 btnPtr
= infoPtr
->buttons
;
570 /* do not base height/width on parent, if the parent is a */
571 /* rebar control it could have multiple rows of toolbars */
572 /* GetClientRect( GetParent(hwnd), &rc ); */
573 /* cx = rc.right - rc.left; */
574 /* cy = rc.bottom - rc.top; */
576 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++ )
579 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
581 SetRectEmpty (&btnPtr
->rect
);
585 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
586 /* it is the actual width of the separator. This is used for */
587 /* custom controls in toolbars. */
588 if (btnPtr
->fsStyle
& TBSTYLE_SEP
)
589 cx
= (btnPtr
->iBitmap
> 0) ?
590 btnPtr
->iBitmap
: SEPARATOR_WIDTH
;
592 cx
= infoPtr
->nButtonWidth
;
594 cy
= infoPtr
->nHeight
;
596 if (btnPtr
->fsState
& TBSTATE_WRAP
)
599 SetRect (&btnPtr
->rect
, x
, y
, x
+ cx
, y
+ cy
);
601 if (infoPtr
->rcBound
.left
> x
)
602 infoPtr
->rcBound
.left
= x
;
603 if (infoPtr
->rcBound
.right
< x
+ cx
)
604 infoPtr
->rcBound
.right
= x
+ cx
;
605 if (infoPtr
->rcBound
.bottom
< y
+ cy
)
606 infoPtr
->rcBound
.bottom
= y
+ cy
;
608 /* Set the toolTip only for non-hidden, non-separator button */
609 if (infoPtr
->hwndToolTip
&& !(btnPtr
->fsStyle
& TBSTYLE_SEP
))
613 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
614 ti
.cbSize
= sizeof(TTTOOLINFOA
);
616 ti
.uId
= btnPtr
->idCommand
;
617 ti
.rect
= btnPtr
->rect
;
618 SendMessageA (infoPtr
->hwndToolTip
, TTM_NEWTOOLRECTA
,
622 /* btnPtr->nRow is zero based. The space between the rows is */
623 /* also considered as a row. */
624 btnPtr
->nRow
= nRows
+ nSepRows
;
627 if ( !(btnPtr
->fsStyle
& TBSTYLE_SEP
) )
631 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
632 /* it is the actual width of the separator. This is used for */
633 /* custom controls in toolbars. */
634 y
+= cy
+ ( (btnPtr
->iBitmap
> 0 ) ?
635 btnPtr
->iBitmap
: SEPARATOR_WIDTH
) * 2 /3;
637 /* nSepRows is used to calculate the extra height follwoing */
641 x
= infoPtr
->nIndent
;
648 /* infoPtr->nRows is the number of rows on the toolbar */
649 infoPtr
->nRows
= nRows
+ nSepRows
+ 1;
651 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
653 infoPtr
->nHeight
= TOP_BORDER
+ (nRows
+ 1) * infoPtr
->nButtonHeight
+
654 nSepRows
* (SEPARATOR_WIDTH
* 2 / 3) +
655 nSepRows
* (infoPtr
->nBitmapHeight
+ 1) +
657 TRACE("toolbar height %d\n", infoPtr
->nHeight
);
662 TOOLBAR_InternalHitTest (HWND hwnd
, LPPOINT lpPt
)
664 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
665 TBUTTON_INFO
*btnPtr
;
668 btnPtr
= infoPtr
->buttons
;
669 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
670 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
673 if (btnPtr
->fsStyle
& TBSTYLE_SEP
) {
674 if (PtInRect (&btnPtr
->rect
, *lpPt
)) {
675 TRACE(" ON SEPARATOR %d!\n", i
);
680 if (PtInRect (&btnPtr
->rect
, *lpPt
)) {
681 TRACE(" ON BUTTON %d!\n", i
);
687 TRACE(" NOWHERE!\n");
693 TOOLBAR_GetButtonIndex (TOOLBAR_INFO
*infoPtr
, INT idCommand
)
695 TBUTTON_INFO
*btnPtr
;
698 btnPtr
= infoPtr
->buttons
;
699 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
700 if (btnPtr
->idCommand
== idCommand
) {
701 TRACE("command=%d index=%d\n", idCommand
, i
);
705 TRACE("no index found for command=%d\n", idCommand
);
711 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO
*infoPtr
, INT nIndex
)
713 TBUTTON_INFO
*btnPtr
;
716 if ((nIndex
< 0) || (nIndex
> infoPtr
->nNumButtons
))
719 /* check index button */
720 btnPtr
= &infoPtr
->buttons
[nIndex
];
721 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
722 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
726 /* check previous buttons */
727 nRunIndex
= nIndex
- 1;
728 while (nRunIndex
>= 0) {
729 btnPtr
= &infoPtr
->buttons
[nRunIndex
];
730 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
731 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
739 /* check next buttons */
740 nRunIndex
= nIndex
+ 1;
741 while (nRunIndex
< infoPtr
->nNumButtons
) {
742 btnPtr
= &infoPtr
->buttons
[nRunIndex
];
743 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
744 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
757 TOOLBAR_RelayEvent (HWND hwndTip
, HWND hwndMsg
, UINT uMsg
,
758 WPARAM wParam
, LPARAM lParam
)
766 msg
.time
= GetMessageTime ();
767 msg
.pt
.x
= LOWORD(GetMessagePos ());
768 msg
.pt
.y
= HIWORD(GetMessagePos ());
770 SendMessageA (hwndTip
, TTM_RELAYEVENT
, 0, (LPARAM
)&msg
);
774 /***********************************************************************
775 * TOOLBAR_CustomizeDialogProc
776 * This function implements the toolbar customization dialog.
779 TOOLBAR_CustomizeDialogProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
781 TOOLBAR_INFO
*infoPtr
= (TOOLBAR_INFO
*)GetWindowLongA (hwnd
, DWL_USER
);
782 static HDSA hDsa
= NULL
;
787 infoPtr
= (TOOLBAR_INFO
*)lParam
;
788 SetWindowLongA (hwnd
, DWL_USER
, (DWORD
)infoPtr
);
790 hDsa
= DSA_Create (sizeof(TBUTTON_INFO
), 5);
794 TBUTTON_INFO
*btnPtr
;
797 /* insert 'virtual' separator button into 'available buttons' list */
798 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_ADDSTRING
, 0, (LPARAM
)"");
800 /* copy all buttons and append them to the right listbox */
801 btnPtr
= infoPtr
->buttons
;
802 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++)
804 DSA_InsertItem (hDsa
, i
, btnPtr
);
806 /* FIXME: hidden buttons appear in the 'toolbar buttons' list too */
807 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
809 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_ADDSTRING
, 0, (LPARAM
)"");
813 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_ADDSTRING
, 0, (LPARAM
)"");
817 /* append 'virtual' separator button to the 'toolbar buttons' list */
823 EndDialog(hwnd
, FALSE
);
827 switch (LOWORD(wParam
))
830 EndDialog(hwnd
, FALSE
);
841 if (wParam
== IDC_AVAILBTN_LBOX
|| wParam
== IDC_TOOLBARBTN_LBOX
)
843 LPDRAWITEMSTRUCT lpdis
= (LPDRAWITEMSTRUCT
)lParam
;
849 COLORREF oldText
= 0;
852 FIXME("action: %x itemState: %x\n",
853 lpdis
->itemAction
, lpdis
->itemState
);
855 DSA_GetItem (hDsa
, 0 /*lpdis->itemID*/, &btnPtr
);
857 if (lpdis
->itemState
& ODS_FOCUS
)
859 oldBk
= SetBkColor (lpdis
->hDC
, GetSysColor(COLOR_HIGHLIGHT
));
860 oldText
= SetTextColor (lpdis
->hDC
, GetSysColor(COLOR_HIGHLIGHTTEXT
));
863 hOldPen
= SelectObject (lpdis
->hDC
, GetSysColorPen ((lpdis
->itemState
& ODS_SELECTED
)?COLOR_HIGHLIGHT
:COLOR_WINDOW
));
864 hOldBrush
= SelectObject (lpdis
->hDC
, GetSysColorBrush ((lpdis
->itemState
& ODS_FOCUS
)?COLOR_HIGHLIGHT
:COLOR_WINDOW
));
866 /* fill background rectangle */
867 Rectangle (lpdis
->hDC
, lpdis
->rcItem
.left
, lpdis
->rcItem
.top
,
868 lpdis
->rcItem
.right
, lpdis
->rcItem
.bottom
);
870 /* calculate button and text rectangles */
871 CopyRect (&rcButton
, &lpdis
->rcItem
);
872 InflateRect (&rcButton
, -1, -1);
873 CopyRect (&rcText
, &rcButton
);
874 rcButton
.right
= rcButton
.left
+ infoPtr
->nBitmapWidth
+ 6;
875 rcText
.left
= rcButton
.right
+ 2;
877 /* draw focus rectangle */
878 if (lpdis
->itemState
& ODS_FOCUS
)
879 DrawFocusRect (lpdis
->hDC
, &lpdis
->rcItem
);
882 DrawEdge (lpdis
->hDC
, &rcButton
, EDGE_RAISED
, BF_RECT
|BF_MIDDLE
|BF_SOFT
);
884 /* draw image and text */
885 if (wParam
== IDC_AVAILBTN_LBOX
&& lpdis
->itemID
== 0)
887 /* virtual separator in the 'available' list */
888 DrawTextA (lpdis
->hDC
, "Separator", -1, &rcText
,
889 DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
);
895 ImageList_Draw (infoPtr
->himlDef
, btnPtr
.iBitmap
, lpdis
->hDC
,
896 rcButton
.left
+1, rcButton
.top
+1, ILD_NORMAL
);
898 DrawTextW (lpdis
->hDC
, infoPtr
->strings
[btnPtr
.iString
], -1, &rcText
,
899 DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
);
903 if (lpdis
->itemState
& ODS_FOCUS
)
905 SetBkColor (lpdis
->hDC
, oldBk
);
906 SetTextColor (lpdis
->hDC
, oldText
);
909 SelectObject (lpdis
->hDC
, hOldBrush
);
910 SelectObject (lpdis
->hDC
, hOldPen
);
917 if (wParam
== IDC_AVAILBTN_LBOX
|| wParam
== IDC_TOOLBARBTN_LBOX
)
919 MEASUREITEMSTRUCT
*lpmis
= (MEASUREITEMSTRUCT
*)lParam
;
922 lpmis
->itemHeight
= infoPtr
->nBitmapHeight
+ 8;
924 lpmis
->itemHeight
= 15 + 8; /* default height */
936 /***********************************************************************
937 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
941 TOOLBAR_AddBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
943 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
944 LPTBADDBITMAP lpAddBmp
= (LPTBADDBITMAP
)lParam
;
945 INT nIndex
= 0, nButtons
;
951 if (lpAddBmp
->hInst
== HINST_COMMCTRL
)
953 if ((lpAddBmp
->nID
& ~1) == IDB_STD_SMALL_COLOR
)
955 else if ((lpAddBmp
->nID
& ~1) == IDB_VIEW_SMALL_COLOR
)
957 else if ((lpAddBmp
->nID
& ~1) == IDB_HIST_SMALL_COLOR
)
962 TRACE ("adding %d internal bitmaps!\n", nButtons
);
964 /* Windows resize all the buttons to the size of a newly added standard image */
965 if (lpAddBmp
->nID
& 1)
968 SendMessageA (hwnd
, TB_SETBITMAPSIZE
, 0,
969 MAKELPARAM((WORD
)26, (WORD
)26));
970 SendMessageA (hwnd
, TB_SETBUTTONSIZE
, 0,
971 MAKELPARAM((WORD
)33, (WORD
)33));
976 SendMessageA (hwnd
, TB_SETBITMAPSIZE
, 0,
977 MAKELPARAM((WORD
)16, (WORD
)16));
978 SendMessageA (hwnd
, TB_SETBUTTONSIZE
, 0,
979 MAKELPARAM((WORD
)22, (WORD
)22));
982 TOOLBAR_CalcToolbar (hwnd
);
986 nButtons
= (INT
)wParam
;
990 TRACE ("adding %d bitmaps!\n", nButtons
);
993 if (!(infoPtr
->himlDef
)) {
994 /* create new default image list */
995 TRACE ("creating default image list!\n");
998 ImageList_Create (infoPtr
->nBitmapWidth
, infoPtr
->nBitmapHeight
+ 1,
999 ILC_COLOR
| ILC_MASK
, nButtons
, 2);
1000 infoPtr
->himlInt
= infoPtr
->himlDef
;
1003 /* Add bitmaps to the default image list */
1004 if (lpAddBmp
->hInst
== (HINSTANCE
)0)
1007 ImageList_AddMasked (infoPtr
->himlDef
, (HBITMAP
)lpAddBmp
->nID
,
1010 else if (lpAddBmp
->hInst
== HINST_COMMCTRL
)
1012 /* Add system bitmaps */
1013 switch (lpAddBmp
->nID
)
1015 case IDB_STD_SMALL_COLOR
:
1016 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1017 MAKEINTRESOURCEA(IDB_STD_SMALL
));
1018 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1019 hbmLoad
, CLR_DEFAULT
);
1020 DeleteObject (hbmLoad
);
1023 case IDB_STD_LARGE_COLOR
:
1024 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1025 MAKEINTRESOURCEA(IDB_STD_LARGE
));
1026 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1027 hbmLoad
, CLR_DEFAULT
);
1028 DeleteObject (hbmLoad
);
1031 case IDB_VIEW_SMALL_COLOR
:
1032 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1033 MAKEINTRESOURCEA(IDB_VIEW_SMALL
));
1034 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1035 hbmLoad
, CLR_DEFAULT
);
1036 DeleteObject (hbmLoad
);
1039 case IDB_VIEW_LARGE_COLOR
:
1040 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1041 MAKEINTRESOURCEA(IDB_VIEW_LARGE
));
1042 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1043 hbmLoad
, CLR_DEFAULT
);
1044 DeleteObject (hbmLoad
);
1047 case IDB_HIST_SMALL_COLOR
:
1048 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1049 MAKEINTRESOURCEA(IDB_HIST_SMALL
));
1050 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1051 hbmLoad
, CLR_DEFAULT
);
1052 DeleteObject (hbmLoad
);
1055 case IDB_HIST_LARGE_COLOR
:
1056 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1057 MAKEINTRESOURCEA(IDB_HIST_LARGE
));
1058 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1059 hbmLoad
, CLR_DEFAULT
);
1060 DeleteObject (hbmLoad
);
1064 nIndex
= ImageList_GetImageCount (infoPtr
->himlDef
);
1065 ERR ("invalid imagelist!\n");
1071 hbmLoad
= LoadBitmapA (lpAddBmp
->hInst
, (LPSTR
)lpAddBmp
->nID
);
1072 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
, hbmLoad
, CLR_DEFAULT
);
1073 DeleteObject (hbmLoad
);
1076 infoPtr
->nNumBitmaps
+= nButtons
;
1083 TOOLBAR_AddButtonsA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1085 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1086 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
1087 INT nOldButtons
, nNewButtons
, nAddButtons
, nCount
;
1089 TRACE("adding %d buttons!\n", wParam
);
1091 nAddButtons
= (UINT
)wParam
;
1092 nOldButtons
= infoPtr
->nNumButtons
;
1093 nNewButtons
= nOldButtons
+ nAddButtons
;
1095 if (infoPtr
->nNumButtons
== 0) {
1097 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1100 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
1102 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1103 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
1104 nOldButtons
* sizeof(TBUTTON_INFO
));
1105 COMCTL32_Free (oldButtons
);
1108 infoPtr
->nNumButtons
= nNewButtons
;
1110 /* insert new button data */
1111 for (nCount
= 0; nCount
< nAddButtons
; nCount
++) {
1112 TBUTTON_INFO
*btnPtr
= &infoPtr
->buttons
[nOldButtons
+nCount
];
1113 btnPtr
->iBitmap
= lpTbb
[nCount
].iBitmap
;
1114 btnPtr
->idCommand
= lpTbb
[nCount
].idCommand
;
1115 btnPtr
->fsState
= lpTbb
[nCount
].fsState
;
1116 btnPtr
->fsStyle
= lpTbb
[nCount
].fsStyle
;
1117 btnPtr
->dwData
= lpTbb
[nCount
].dwData
;
1118 btnPtr
->iString
= lpTbb
[nCount
].iString
;
1119 btnPtr
->bHot
= FALSE
;
1121 if ((infoPtr
->hwndToolTip
) && !(btnPtr
->fsStyle
& TBSTYLE_SEP
)) {
1124 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
1125 ti
.cbSize
= sizeof (TTTOOLINFOA
);
1127 ti
.uId
= btnPtr
->idCommand
;
1129 ti
.lpszText
= LPSTR_TEXTCALLBACKA
;
1131 SendMessageA (infoPtr
->hwndToolTip
, TTM_ADDTOOLA
,
1136 TOOLBAR_CalcToolbar (hwnd
);
1138 InvalidateRect(hwnd
, NULL
, FALSE
);
1145 TOOLBAR_AddButtonsW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1147 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1148 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
1149 INT nOldButtons
, nNewButtons
, nAddButtons
, nCount
;
1151 TRACE("adding %d buttons!\n", wParam
);
1153 nAddButtons
= (UINT
)wParam
;
1154 nOldButtons
= infoPtr
->nNumButtons
;
1155 nNewButtons
= nOldButtons
+ nAddButtons
;
1157 if (infoPtr
->nNumButtons
== 0) {
1159 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1162 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
1164 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1165 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
1166 nOldButtons
* sizeof(TBUTTON_INFO
));
1167 COMCTL32_Free (oldButtons
);
1170 infoPtr
->nNumButtons
= nNewButtons
;
1172 /* insert new button data */
1173 for (nCount
= 0; nCount
< nAddButtons
; nCount
++) {
1174 TBUTTON_INFO
*btnPtr
= &infoPtr
->buttons
[nOldButtons
+nCount
];
1175 btnPtr
->iBitmap
= lpTbb
[nCount
].iBitmap
;
1176 btnPtr
->idCommand
= lpTbb
[nCount
].idCommand
;
1177 btnPtr
->fsState
= lpTbb
[nCount
].fsState
;
1178 btnPtr
->fsStyle
= lpTbb
[nCount
].fsStyle
;
1179 btnPtr
->dwData
= lpTbb
[nCount
].dwData
;
1180 btnPtr
->iString
= lpTbb
[nCount
].iString
;
1181 btnPtr
->bHot
= FALSE
;
1183 if ((infoPtr
->hwndToolTip
) && !(btnPtr
->fsStyle
& TBSTYLE_SEP
)) {
1186 ZeroMemory (&ti
, sizeof(TTTOOLINFOW
));
1187 ti
.cbSize
= sizeof (TTTOOLINFOW
);
1189 ti
.uId
= btnPtr
->idCommand
;
1191 ti
.lpszText
= LPSTR_TEXTCALLBACKW
;
1193 SendMessageW (infoPtr
->hwndToolTip
, TTM_ADDTOOLW
,
1198 TOOLBAR_CalcToolbar (hwnd
);
1200 InvalidateRect(hwnd
, NULL
, FALSE
);
1207 TOOLBAR_AddStringA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1209 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1212 if ((wParam
) && (HIWORD(lParam
) == 0)) {
1215 TRACE("adding string from resource!\n");
1217 len
= LoadStringA ((HINSTANCE
)wParam
, (UINT
)lParam
,
1220 TRACE("len=%d \"%s\"\n", len
, szString
);
1221 nIndex
= infoPtr
->nNumStrings
;
1222 if (infoPtr
->nNumStrings
== 0) {
1224 COMCTL32_Alloc (sizeof(LPWSTR
));
1227 LPWSTR
*oldStrings
= infoPtr
->strings
;
1229 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1230 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1231 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1232 COMCTL32_Free (oldStrings
);
1235 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1236 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1237 lstrcpyAtoW (infoPtr
->strings
[infoPtr
->nNumStrings
], szString
);
1238 infoPtr
->nNumStrings
++;
1241 LPSTR p
= (LPSTR
)lParam
;
1246 TRACE("adding string(s) from array!\n");
1247 nIndex
= infoPtr
->nNumStrings
;
1250 TRACE("len=%d \"%s\"\n", len
, p
);
1252 if (infoPtr
->nNumStrings
== 0) {
1254 COMCTL32_Alloc (sizeof(LPWSTR
));
1257 LPWSTR
*oldStrings
= infoPtr
->strings
;
1259 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1260 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1261 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1262 COMCTL32_Free (oldStrings
);
1265 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1266 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1267 lstrcpyAtoW (infoPtr
->strings
[infoPtr
->nNumStrings
], p
);
1268 infoPtr
->nNumStrings
++;
1279 TOOLBAR_AddStringW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1281 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1284 if ((wParam
) && (HIWORD(lParam
) == 0)) {
1285 WCHAR szString
[256];
1287 TRACE("adding string from resource!\n");
1289 len
= LoadStringW ((HINSTANCE
)wParam
, (UINT
)lParam
,
1292 TRACE("len=%d \"%s\"\n", len
, debugstr_w(szString
));
1293 nIndex
= infoPtr
->nNumStrings
;
1294 if (infoPtr
->nNumStrings
== 0) {
1296 COMCTL32_Alloc (sizeof(LPWSTR
));
1299 LPWSTR
*oldStrings
= infoPtr
->strings
;
1301 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1302 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1303 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1304 COMCTL32_Free (oldStrings
);
1307 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1308 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1309 lstrcpyW (infoPtr
->strings
[infoPtr
->nNumStrings
], szString
);
1310 infoPtr
->nNumStrings
++;
1313 LPWSTR p
= (LPWSTR
)lParam
;
1318 TRACE("adding string(s) from array!\n");
1319 nIndex
= infoPtr
->nNumStrings
;
1322 TRACE("len=%d \"%s\"\n", len
, debugstr_w(p
));
1324 if (infoPtr
->nNumStrings
== 0) {
1326 COMCTL32_Alloc (sizeof(LPWSTR
));
1329 LPWSTR
*oldStrings
= infoPtr
->strings
;
1331 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1332 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1333 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1334 COMCTL32_Free (oldStrings
);
1337 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1338 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1339 lstrcpyW (infoPtr
->strings
[infoPtr
->nNumStrings
], p
);
1340 infoPtr
->nNumStrings
++;
1351 TOOLBAR_AutoSize (HWND hwnd
)
1353 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1354 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1362 TRACE("resize forced!\n");
1364 parent
= GetParent (hwnd
);
1365 GetClientRect(parent
, &parent_rect
);
1367 x
= parent_rect
.left
;
1368 y
= parent_rect
.top
;
1370 if (dwStyle
& CCS_NORESIZE
) {
1371 uPosFlags
|= (SWP_NOSIZE
| SWP_NOMOVE
);
1376 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
1377 TOOLBAR_CalcToolbar (hwnd
);
1378 InvalidateRect( hwnd
, NULL
, TRUE
);
1379 cy
= infoPtr
->nHeight
;
1380 cx
= infoPtr
->nWidth
;
1382 if (dwStyle
& CCS_NOMOVEY
) {
1383 GetWindowRect(hwnd
, &window_rect
);
1384 ScreenToClient(parent
, (LPPOINT
)&window_rect
.left
);
1385 y
= window_rect
.top
;
1389 if (dwStyle
& CCS_NOPARENTALIGN
)
1390 uPosFlags
|= SWP_NOMOVE
;
1392 if (!(dwStyle
& CCS_NODIVIDER
))
1393 cy
+= GetSystemMetrics(SM_CYEDGE
);
1395 if (dwStyle
& WS_BORDER
)
1398 cy
+= GetSystemMetrics(SM_CYEDGE
);
1399 cx
+= GetSystemMetrics(SM_CYEDGE
);
1402 infoPtr
->bAutoSize
= TRUE
;
1403 SetWindowPos (hwnd
, HWND_TOP
, parent_rect
.left
- x
, parent_rect
.top
- y
,
1405 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
1406 * the setwindowpos calls */
1407 infoPtr
->bAutoSize
= FALSE
;
1414 TOOLBAR_ButtonCount (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1416 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1418 return infoPtr
->nNumButtons
;
1423 TOOLBAR_ButtonStructSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1425 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1427 if (infoPtr
== NULL
) {
1428 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd
, wParam
, lParam
);
1429 ERR("infoPtr == NULL!\n");
1433 infoPtr
->dwStructSize
= (DWORD
)wParam
;
1440 TOOLBAR_ChangeBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1442 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1443 TBUTTON_INFO
*btnPtr
;
1446 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1450 btnPtr
= &infoPtr
->buttons
[nIndex
];
1451 btnPtr
->iBitmap
= LOWORD(lParam
);
1453 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,RDW_ERASE
|RDW_INVALIDATE
);
1460 TOOLBAR_CheckButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1462 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1463 TBUTTON_INFO
*btnPtr
;
1466 BOOL bChecked
= FALSE
;
1468 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1472 btnPtr
= &infoPtr
->buttons
[nIndex
];
1474 if (!(btnPtr
->fsStyle
& TBSTYLE_CHECK
))
1477 bChecked
= (btnPtr
->fsState
& TBSTATE_CHECKED
) ? TRUE
: FALSE
;
1479 if (LOWORD(lParam
) == FALSE
)
1480 btnPtr
->fsState
&= ~TBSTATE_CHECKED
;
1482 if (btnPtr
->fsStyle
& TBSTYLE_GROUP
) {
1484 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr
, nIndex
);
1485 if (nOldIndex
== nIndex
)
1487 if (nOldIndex
!= -1)
1488 infoPtr
->buttons
[nOldIndex
].fsState
&= ~TBSTATE_CHECKED
;
1490 btnPtr
->fsState
|= TBSTATE_CHECKED
;
1493 if( bChecked
!= LOWORD(lParam
) )
1495 if (nOldIndex
!= -1)
1496 RedrawWindow(hwnd
,&infoPtr
->buttons
[nOldIndex
].rect
,NULL
,
1497 RDW_ERASE
|RDW_INVALIDATE
);
1498 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
1501 /* FIXME: Send a WM_NOTIFY?? */
1508 TOOLBAR_CommandToIndex (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1510 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1512 return TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1517 TOOLBAR_Customize (HWND hwnd
)
1519 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1525 /* send TBN_BEGINADJUST notification */
1526 nmhdr
.hwndFrom
= hwnd
;
1527 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1528 nmhdr
.code
= TBN_BEGINADJUST
;
1530 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
1531 (WPARAM
)nmhdr
.idFrom
, (LPARAM
)&nmhdr
);
1533 if (!(hRes
= FindResourceA (COMCTL32_hModule
,
1534 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE
),
1538 if(!(template = (LPVOID
)LoadResource (COMCTL32_hModule
, hRes
)))
1541 ret
= DialogBoxIndirectParamA (GetWindowLongA (hwnd
, GWL_HINSTANCE
),
1542 (LPDLGTEMPLATEA
)template,
1544 (DLGPROC
)TOOLBAR_CustomizeDialogProc
,
1547 /* send TBN_ENDADJUST notification */
1548 nmhdr
.code
= TBN_ENDADJUST
;
1550 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
1551 (WPARAM
)nmhdr
.idFrom
, (LPARAM
)&nmhdr
);
1558 TOOLBAR_DeleteButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1560 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1561 INT nIndex
= (INT
)wParam
;
1563 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
1566 if ((infoPtr
->hwndToolTip
) &&
1567 !(infoPtr
->buttons
[nIndex
].fsStyle
& TBSTYLE_SEP
)) {
1570 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
1571 ti
.cbSize
= sizeof (TTTOOLINFOA
);
1573 ti
.uId
= infoPtr
->buttons
[nIndex
].idCommand
;
1575 SendMessageA (infoPtr
->hwndToolTip
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
1578 if (infoPtr
->nNumButtons
== 1) {
1579 TRACE(" simple delete!\n");
1580 COMCTL32_Free (infoPtr
->buttons
);
1581 infoPtr
->buttons
= NULL
;
1582 infoPtr
->nNumButtons
= 0;
1585 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
1586 TRACE("complex delete! [nIndex=%d]\n", nIndex
);
1588 infoPtr
->nNumButtons
--;
1589 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
1591 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
1592 nIndex
* sizeof(TBUTTON_INFO
));
1595 if (nIndex
< infoPtr
->nNumButtons
) {
1596 memcpy (&infoPtr
->buttons
[nIndex
], &oldButtons
[nIndex
+1],
1597 (infoPtr
->nNumButtons
- nIndex
) * sizeof(TBUTTON_INFO
));
1600 COMCTL32_Free (oldButtons
);
1603 TOOLBAR_CalcToolbar (hwnd
);
1605 InvalidateRect (hwnd
, NULL
, TRUE
);
1612 TOOLBAR_EnableButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1614 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1615 TBUTTON_INFO
*btnPtr
;
1619 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1623 btnPtr
= &infoPtr
->buttons
[nIndex
];
1625 bState
= btnPtr
->fsState
& TBSTATE_ENABLED
;
1627 /* update the toolbar button state */
1628 if(LOWORD(lParam
) == FALSE
) {
1629 btnPtr
->fsState
&= ~(TBSTATE_ENABLED
| TBSTATE_PRESSED
);
1631 btnPtr
->fsState
|= TBSTATE_ENABLED
;
1634 /* redraw the button only if the state of the button changed */
1635 if(bState
!= (btnPtr
->fsState
& TBSTATE_ENABLED
)) {
1636 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
1643 static inline LRESULT
1644 TOOLBAR_GetAnchorHighlight (HWND hwnd
)
1646 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1648 return infoPtr
->bAnchor
;
1653 TOOLBAR_GetBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1655 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1658 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1662 return infoPtr
->buttons
[nIndex
].iBitmap
;
1666 static inline LRESULT
1667 TOOLBAR_GetBitmapFlags (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1669 return (GetDeviceCaps (0, LOGPIXELSX
) >= 120) ? TBBF_LARGE
: 0;
1674 TOOLBAR_GetButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1676 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1677 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
1678 INT nIndex
= (INT
)wParam
;
1679 TBUTTON_INFO
*btnPtr
;
1681 if (infoPtr
== NULL
)
1687 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
1690 btnPtr
= &infoPtr
->buttons
[nIndex
];
1691 lpTbb
->iBitmap
= btnPtr
->iBitmap
;
1692 lpTbb
->idCommand
= btnPtr
->idCommand
;
1693 lpTbb
->fsState
= btnPtr
->fsState
;
1694 lpTbb
->fsStyle
= btnPtr
->fsStyle
;
1695 lpTbb
->dwData
= btnPtr
->dwData
;
1696 lpTbb
->iString
= btnPtr
->iString
;
1703 TOOLBAR_GetButtonInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1705 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1706 LPTBBUTTONINFOA lpTbInfo
= (LPTBBUTTONINFOA
)lParam
;
1707 TBUTTON_INFO
*btnPtr
;
1710 if (infoPtr
== NULL
)
1712 if (lpTbInfo
== NULL
)
1714 if (lpTbInfo
->cbSize
< sizeof(TBBUTTONINFOA
))
1717 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1721 btnPtr
= &infoPtr
->buttons
[nIndex
];
1723 if (lpTbInfo
->dwMask
& TBIF_COMMAND
)
1724 lpTbInfo
->idCommand
= btnPtr
->idCommand
;
1725 if (lpTbInfo
->dwMask
& TBIF_IMAGE
)
1726 lpTbInfo
->iImage
= btnPtr
->iBitmap
;
1727 if (lpTbInfo
->dwMask
& TBIF_LPARAM
)
1728 lpTbInfo
->lParam
= btnPtr
->dwData
;
1729 if (lpTbInfo
->dwMask
& TBIF_SIZE
)
1730 lpTbInfo
->cx
= (WORD
)(btnPtr
->rect
.right
- btnPtr
->rect
.left
);
1731 if (lpTbInfo
->dwMask
& TBIF_STATE
)
1732 lpTbInfo
->fsState
= btnPtr
->fsState
;
1733 if (lpTbInfo
->dwMask
& TBIF_STYLE
)
1734 lpTbInfo
->fsStyle
= btnPtr
->fsStyle
;
1735 if (lpTbInfo
->dwMask
& TBIF_TEXT
) {
1736 if ((btnPtr
->iString
>= 0) || (btnPtr
->iString
< infoPtr
->nNumStrings
))
1737 lstrcpynWtoA (lpTbInfo
->pszText
,
1738 (LPWSTR
)infoPtr
->strings
[btnPtr
->iString
],
1747 TOOLBAR_GetButtonInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1749 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1750 LPTBBUTTONINFOW lpTbInfo
= (LPTBBUTTONINFOW
)lParam
;
1751 TBUTTON_INFO
*btnPtr
;
1754 if (infoPtr
== NULL
)
1756 if (lpTbInfo
== NULL
)
1758 if (lpTbInfo
->cbSize
< sizeof(TBBUTTONINFOW
))
1761 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1765 btnPtr
= &infoPtr
->buttons
[nIndex
];
1767 if (lpTbInfo
->dwMask
& TBIF_COMMAND
)
1768 lpTbInfo
->idCommand
= btnPtr
->idCommand
;
1769 if (lpTbInfo
->dwMask
& TBIF_IMAGE
)
1770 lpTbInfo
->iImage
= btnPtr
->iBitmap
;
1771 if (lpTbInfo
->dwMask
& TBIF_LPARAM
)
1772 lpTbInfo
->lParam
= btnPtr
->dwData
;
1773 if (lpTbInfo
->dwMask
& TBIF_SIZE
)
1774 lpTbInfo
->cx
= (WORD
)(btnPtr
->rect
.right
- btnPtr
->rect
.left
);
1775 if (lpTbInfo
->dwMask
& TBIF_STATE
)
1776 lpTbInfo
->fsState
= btnPtr
->fsState
;
1777 if (lpTbInfo
->dwMask
& TBIF_STYLE
)
1778 lpTbInfo
->fsStyle
= btnPtr
->fsStyle
;
1779 if (lpTbInfo
->dwMask
& TBIF_TEXT
) {
1780 if ((btnPtr
->iString
>= 0) || (btnPtr
->iString
< infoPtr
->nNumStrings
))
1781 lstrcpynW (lpTbInfo
->pszText
,
1782 (LPWSTR
)infoPtr
->strings
[btnPtr
->iString
],
1791 TOOLBAR_GetButtonSize (HWND hwnd
)
1793 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1795 return MAKELONG((WORD
)infoPtr
->nButtonWidth
,
1796 (WORD
)infoPtr
->nButtonHeight
);
1801 TOOLBAR_GetButtonTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1803 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1804 INT nIndex
, nStringIndex
;
1806 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1810 nStringIndex
= infoPtr
->buttons
[nIndex
].iString
;
1812 TRACE("index=%d stringIndex=%d\n", nIndex
, nStringIndex
);
1814 if ((nStringIndex
< 0) || (nStringIndex
>= infoPtr
->nNumStrings
))
1820 lstrcpyWtoA ((LPSTR
)lParam
, (LPWSTR
)infoPtr
->strings
[nStringIndex
]);
1822 return lstrlenW ((LPWSTR
)infoPtr
->strings
[nStringIndex
]);
1827 TOOLBAR_GetButtonTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1829 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1830 INT nIndex
, nStringIndex
;
1832 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1836 nStringIndex
= infoPtr
->buttons
[nIndex
].iString
;
1838 TRACE("index=%d stringIndex=%d\n", nIndex
, nStringIndex
);
1840 if ((nStringIndex
< 0) || (nStringIndex
>= infoPtr
->nNumStrings
))
1846 lstrcpyW ((LPWSTR
)lParam
, (LPWSTR
)infoPtr
->strings
[nStringIndex
]);
1848 return lstrlenW ((LPWSTR
)infoPtr
->strings
[nStringIndex
]);
1852 /* << TOOLBAR_GetColorScheme >> */
1856 TOOLBAR_GetDisabledImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1858 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1860 return (LRESULT
)infoPtr
->himlDis
;
1864 inline static LRESULT
1865 TOOLBAR_GetExtendedStyle (HWND hwnd
)
1867 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1869 return infoPtr
->dwExStyle
;
1874 TOOLBAR_GetHotImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1876 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1878 return (LRESULT
)infoPtr
->himlHot
;
1883 TOOLBAR_GetHotItem (HWND hwnd
)
1885 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1887 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_FLAT
))
1890 if (infoPtr
->nHotItem
< 0)
1893 return (LRESULT
)infoPtr
->nHotItem
;
1898 TOOLBAR_GetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1900 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1902 return (LRESULT
)infoPtr
->himlDef
;
1906 /* << TOOLBAR_GetInsertMark >> */
1907 /* << TOOLBAR_GetInsertMarkColor >> */
1911 TOOLBAR_GetItemRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1913 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1914 TBUTTON_INFO
*btnPtr
;
1918 if (infoPtr
== NULL
)
1920 nIndex
= (INT
)wParam
;
1921 btnPtr
= &infoPtr
->buttons
[nIndex
];
1922 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
1924 lpRect
= (LPRECT
)lParam
;
1927 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
1930 TOOLBAR_CalcToolbar( hwnd
);
1932 lpRect
->left
= btnPtr
->rect
.left
;
1933 lpRect
->right
= btnPtr
->rect
.right
;
1934 lpRect
->bottom
= btnPtr
->rect
.bottom
;
1935 lpRect
->top
= btnPtr
->rect
.top
;
1942 TOOLBAR_GetMaxSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1944 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1945 LPSIZE lpSize
= (LPSIZE
)lParam
;
1950 lpSize
->cx
= infoPtr
->rcBound
.right
- infoPtr
->rcBound
.left
;
1951 lpSize
->cy
= infoPtr
->rcBound
.bottom
- infoPtr
->rcBound
.top
;
1953 TRACE("maximum size %d x %d\n",
1954 infoPtr
->rcBound
.right
- infoPtr
->rcBound
.left
,
1955 infoPtr
->rcBound
.bottom
- infoPtr
->rcBound
.top
);
1961 /* << TOOLBAR_GetObject >> */
1962 /* << TOOLBAR_GetPadding >> */
1966 TOOLBAR_GetRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1968 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1969 TBUTTON_INFO
*btnPtr
;
1973 if (infoPtr
== NULL
)
1975 nIndex
= (INT
)wParam
;
1976 btnPtr
= &infoPtr
->buttons
[nIndex
];
1977 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
1979 lpRect
= (LPRECT
)lParam
;
1983 lpRect
->left
= btnPtr
->rect
.left
;
1984 lpRect
->right
= btnPtr
->rect
.right
;
1985 lpRect
->bottom
= btnPtr
->rect
.bottom
;
1986 lpRect
->top
= btnPtr
->rect
.top
;
1993 TOOLBAR_GetRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1995 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1997 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_WRAPABLE
)
1998 return infoPtr
->nRows
;
2005 TOOLBAR_GetState (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2007 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2010 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2014 return infoPtr
->buttons
[nIndex
].fsState
;
2019 TOOLBAR_GetStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2021 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2024 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2028 return infoPtr
->buttons
[nIndex
].fsStyle
;
2033 TOOLBAR_GetTextRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2035 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2037 if (infoPtr
== NULL
)
2040 return infoPtr
->nMaxTextRows
;
2045 TOOLBAR_GetToolTips (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2047 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2049 if (infoPtr
== NULL
)
2051 return infoPtr
->hwndToolTip
;
2056 TOOLBAR_GetUnicodeFormat (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2058 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2060 TRACE("%s hwnd=0x%x stub!\n",
2061 infoPtr
->bUnicode
? "TRUE" : "FALSE", hwnd
);
2063 return infoPtr
->bUnicode
;
2067 inline static LRESULT
2068 TOOLBAR_GetVersion (HWND hwnd
)
2070 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2071 return infoPtr
->iVersion
;
2076 TOOLBAR_HideButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2078 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2079 TBUTTON_INFO
*btnPtr
;
2082 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2086 btnPtr
= &infoPtr
->buttons
[nIndex
];
2087 if (LOWORD(lParam
) == FALSE
)
2088 btnPtr
->fsState
&= ~TBSTATE_HIDDEN
;
2090 btnPtr
->fsState
|= TBSTATE_HIDDEN
;
2092 TOOLBAR_CalcToolbar (hwnd
);
2094 InvalidateRect (hwnd
, NULL
, TRUE
);
2100 inline static LRESULT
2101 TOOLBAR_HitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2103 return TOOLBAR_InternalHitTest (hwnd
, (LPPOINT
)lParam
);
2108 TOOLBAR_Indeterminate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2110 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2111 TBUTTON_INFO
*btnPtr
;
2114 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2118 btnPtr
= &infoPtr
->buttons
[nIndex
];
2119 if (LOWORD(lParam
) == FALSE
)
2120 btnPtr
->fsState
&= ~TBSTATE_INDETERMINATE
;
2122 btnPtr
->fsState
|= TBSTATE_INDETERMINATE
;
2124 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
2125 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
2132 TOOLBAR_InsertButtonA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2134 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2135 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
2136 INT nIndex
= (INT
)wParam
;
2137 TBUTTON_INFO
*oldButtons
;
2143 /* EPP: this seems to be an undocumented call (from my IE4)
2144 * I assume in that case that:
2145 * - lpTbb->iString is a string pointer (not a string index in strings[] table
2146 * - index of insertion is at the end of existing buttons
2147 * I only see this happen with nIndex == -1, but it could have a special
2148 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
2150 int len
= lstrlenA((char*)lpTbb
->iString
) + 2;
2151 LPSTR ptr
= COMCTL32_Alloc(len
);
2153 nIndex
= infoPtr
->nNumButtons
;
2154 strcpy(ptr
, (char*)lpTbb
->iString
);
2155 ptr
[len
- 1] = 0; /* ended by two '\0' */
2156 lpTbb
->iString
= TOOLBAR_AddStringA(hwnd
, 0, (LPARAM
)ptr
);
2159 } else if (nIndex
< 0)
2162 TRACE("inserting button index=%d\n", nIndex
);
2163 if (nIndex
> infoPtr
->nNumButtons
) {
2164 nIndex
= infoPtr
->nNumButtons
;
2165 TRACE("adjust index=%d\n", nIndex
);
2168 oldButtons
= infoPtr
->buttons
;
2169 infoPtr
->nNumButtons
++;
2170 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
2171 /* pre insert copy */
2173 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
2174 nIndex
* sizeof(TBUTTON_INFO
));
2177 /* insert new button */
2178 infoPtr
->buttons
[nIndex
].iBitmap
= lpTbb
->iBitmap
;
2179 infoPtr
->buttons
[nIndex
].idCommand
= lpTbb
->idCommand
;
2180 infoPtr
->buttons
[nIndex
].fsState
= lpTbb
->fsState
;
2181 infoPtr
->buttons
[nIndex
].fsStyle
= lpTbb
->fsStyle
;
2182 infoPtr
->buttons
[nIndex
].dwData
= lpTbb
->dwData
;
2183 infoPtr
->buttons
[nIndex
].iString
= lpTbb
->iString
;
2185 if ((infoPtr
->hwndToolTip
) && !(lpTbb
->fsStyle
& TBSTYLE_SEP
)) {
2188 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
2189 ti
.cbSize
= sizeof (TTTOOLINFOA
);
2191 ti
.uId
= lpTbb
->idCommand
;
2193 ti
.lpszText
= LPSTR_TEXTCALLBACKA
;
2195 SendMessageA (infoPtr
->hwndToolTip
, TTM_ADDTOOLA
,
2199 /* post insert copy */
2200 if (nIndex
< infoPtr
->nNumButtons
- 1) {
2201 memcpy (&infoPtr
->buttons
[nIndex
+1], &oldButtons
[nIndex
],
2202 (infoPtr
->nNumButtons
- nIndex
- 1) * sizeof(TBUTTON_INFO
));
2205 COMCTL32_Free (oldButtons
);
2207 TOOLBAR_CalcToolbar (hwnd
);
2209 InvalidateRect (hwnd
, NULL
, FALSE
);
2216 TOOLBAR_InsertButtonW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2218 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2219 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
2220 INT nIndex
= (INT
)wParam
;
2221 TBUTTON_INFO
*oldButtons
;
2228 TRACE("inserting button index=%d\n", nIndex
);
2229 if (nIndex
> infoPtr
->nNumButtons
) {
2230 nIndex
= infoPtr
->nNumButtons
;
2231 TRACE("adjust index=%d\n", nIndex
);
2234 oldButtons
= infoPtr
->buttons
;
2235 infoPtr
->nNumButtons
++;
2236 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
2237 /* pre insert copy */
2239 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
2240 nIndex
* sizeof(TBUTTON_INFO
));
2243 /* insert new button */
2244 infoPtr
->buttons
[nIndex
].iBitmap
= lpTbb
->iBitmap
;
2245 infoPtr
->buttons
[nIndex
].idCommand
= lpTbb
->idCommand
;
2246 infoPtr
->buttons
[nIndex
].fsState
= lpTbb
->fsState
;
2247 infoPtr
->buttons
[nIndex
].fsStyle
= lpTbb
->fsStyle
;
2248 infoPtr
->buttons
[nIndex
].dwData
= lpTbb
->dwData
;
2249 infoPtr
->buttons
[nIndex
].iString
= lpTbb
->iString
;
2251 if ((infoPtr
->hwndToolTip
) && !(lpTbb
->fsStyle
& TBSTYLE_SEP
)) {
2254 ZeroMemory (&ti
, sizeof(TTTOOLINFOW
));
2255 ti
.cbSize
= sizeof (TTTOOLINFOW
);
2257 ti
.uId
= lpTbb
->idCommand
;
2259 ti
.lpszText
= LPSTR_TEXTCALLBACKW
;
2261 SendMessageW (infoPtr
->hwndToolTip
, TTM_ADDTOOLW
,
2265 /* post insert copy */
2266 if (nIndex
< infoPtr
->nNumButtons
- 1) {
2267 memcpy (&infoPtr
->buttons
[nIndex
+1], &oldButtons
[nIndex
],
2268 (infoPtr
->nNumButtons
- nIndex
- 1) * sizeof(TBUTTON_INFO
));
2271 COMCTL32_Free (oldButtons
);
2273 TOOLBAR_CalcToolbar (hwnd
);
2275 InvalidateRect (hwnd
, NULL
, FALSE
);
2281 /* << TOOLBAR_InsertMarkHitTest >> */
2285 TOOLBAR_IsButtonChecked (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2287 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2290 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2294 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_CHECKED
);
2299 TOOLBAR_IsButtonEnabled (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2301 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2304 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2308 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_ENABLED
);
2313 TOOLBAR_IsButtonHidden (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2315 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2318 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2322 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_HIDDEN
);
2327 TOOLBAR_IsButtonHighlighted (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2329 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2332 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2336 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_MARKED
);
2341 TOOLBAR_IsButtonIndeterminate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2343 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2346 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2350 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_INDETERMINATE
);
2355 TOOLBAR_IsButtonPressed (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2357 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2360 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2364 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_PRESSED
);
2368 /* << TOOLBAR_LoadImages >> */
2369 /* << TOOLBAR_MapAccelerator >> */
2370 /* << TOOLBAR_MarkButton >> */
2371 /* << TOOLBAR_MoveButton >> */
2375 TOOLBAR_PressButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2377 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2378 TBUTTON_INFO
*btnPtr
;
2381 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2385 btnPtr
= &infoPtr
->buttons
[nIndex
];
2386 if (LOWORD(lParam
) == FALSE
)
2387 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
2389 btnPtr
->fsState
|= TBSTATE_PRESSED
;
2391 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
2392 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
2398 /* << TOOLBAR_ReplaceBitmap >> */
2402 TOOLBAR_SaveRestoreA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2405 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2406 LPTBSAVEPARAMSA lpSave
= (LPTBSAVEPARAMSA
)lParam
;
2408 if (lpSave
== NULL
) return 0;
2411 /* save toolbar information */
2412 FIXME("save to \"%s\" \"%s\"\n",
2413 lpSave
->pszSubKey
, lpSave
->pszValueName
);
2418 /* restore toolbar information */
2420 FIXME("restore from \"%s\" \"%s\"\n",
2421 lpSave
->pszSubKey
, lpSave
->pszValueName
);
2432 TOOLBAR_SaveRestoreW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2435 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2436 LPTBSAVEPARAMSW lpSave
= (LPTBSAVEPARAMSW
)lParam
;
2442 /* save toolbar information */
2443 FIXME("save to \"%s\" \"%s\"\n",
2444 lpSave
->pszSubKey
, lpSave
->pszValueName
);
2449 /* restore toolbar information */
2451 FIXME("restore from \"%s\" \"%s\"\n",
2452 lpSave
->pszSubKey
, lpSave
->pszValueName
);
2463 TOOLBAR_SetAnchorHighlight (HWND hwnd
, WPARAM wParam
)
2465 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2466 BOOL bOldAnchor
= infoPtr
->bAnchor
;
2468 infoPtr
->bAnchor
= (BOOL
)wParam
;
2470 return (LRESULT
)bOldAnchor
;
2475 TOOLBAR_SetBitmapSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2477 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2479 if ((LOWORD(lParam
) <= 0) || (HIWORD(lParam
)<=0))
2482 /* Bitmap size can only be set before adding any button to the toolbar
2483 according to the documentation. */
2484 if( infoPtr
->nNumButtons
!= 0 )
2487 infoPtr
->nBitmapWidth
= (INT
)LOWORD(lParam
);
2488 infoPtr
->nBitmapHeight
= (INT
)HIWORD(lParam
);
2495 TOOLBAR_SetButtonInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2497 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2498 LPTBBUTTONINFOA lptbbi
= (LPTBBUTTONINFOA
)lParam
;
2499 TBUTTON_INFO
*btnPtr
;
2504 if (lptbbi
->cbSize
< sizeof(TBBUTTONINFOA
))
2507 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2511 btnPtr
= &infoPtr
->buttons
[nIndex
];
2512 if (lptbbi
->dwMask
& TBIF_COMMAND
)
2513 btnPtr
->idCommand
= lptbbi
->idCommand
;
2514 if (lptbbi
->dwMask
& TBIF_IMAGE
)
2515 btnPtr
->iBitmap
= lptbbi
->iImage
;
2516 if (lptbbi
->dwMask
& TBIF_LPARAM
)
2517 btnPtr
->dwData
= lptbbi
->lParam
;
2518 /* if (lptbbi->dwMask & TBIF_SIZE) */
2519 /* btnPtr->cx = lptbbi->cx; */
2520 if (lptbbi
->dwMask
& TBIF_STATE
)
2521 btnPtr
->fsState
= lptbbi
->fsState
;
2522 if (lptbbi
->dwMask
& TBIF_STYLE
)
2523 btnPtr
->fsStyle
= lptbbi
->fsStyle
;
2525 if (lptbbi
->dwMask
& TBIF_TEXT
) {
2526 if ((btnPtr
->iString
>= 0) ||
2527 (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
2528 TRACE("Ooooooch\n");
2530 WCHAR
**lpString
= &infoPtr
->strings
[btnPtr
->iString
];
2531 INT len
= lstrlenA (lptbbi
->pszText
);
2532 *lpString
= COMCTL32_ReAlloc (lpString
, sizeof(WCHAR
)*(len
+1));
2535 /* this is the ultimate sollution */
2536 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2545 TOOLBAR_SetButtonInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2547 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2548 LPTBBUTTONINFOW lptbbi
= (LPTBBUTTONINFOW
)lParam
;
2549 TBUTTON_INFO
*btnPtr
;
2554 if (lptbbi
->cbSize
< sizeof(TBBUTTONINFOW
))
2557 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2561 btnPtr
= &infoPtr
->buttons
[nIndex
];
2562 if (lptbbi
->dwMask
& TBIF_COMMAND
)
2563 btnPtr
->idCommand
= lptbbi
->idCommand
;
2564 if (lptbbi
->dwMask
& TBIF_IMAGE
)
2565 btnPtr
->iBitmap
= lptbbi
->iImage
;
2566 if (lptbbi
->dwMask
& TBIF_LPARAM
)
2567 btnPtr
->dwData
= lptbbi
->lParam
;
2568 /* if (lptbbi->dwMask & TBIF_SIZE) */
2569 /* btnPtr->cx = lptbbi->cx; */
2570 if (lptbbi
->dwMask
& TBIF_STATE
)
2571 btnPtr
->fsState
= lptbbi
->fsState
;
2572 if (lptbbi
->dwMask
& TBIF_STYLE
)
2573 btnPtr
->fsStyle
= lptbbi
->fsStyle
;
2575 if (lptbbi
->dwMask
& TBIF_TEXT
) {
2576 if ((btnPtr
->iString
>= 0) ||
2577 (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
2579 WCHAR
**lpString
= &infoPtr
->strings
[btnPtr
->iString
];
2580 INT len
= lstrlenW (lptbbi
->pszText
);
2581 *lpString
= COMCTL32_ReAlloc (lpString
, sizeof(WCHAR
)*(len
+1));
2584 /* this is the ultimate sollution */
2585 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2594 TOOLBAR_SetButtonSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2596 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2598 if ((LOWORD(lParam
) <= 0) || (HIWORD(lParam
)<=0))
2601 /* Button size can only be set before adding any button to the toolbar
2602 according to the documentation. */
2603 if( infoPtr
->nNumButtons
!= 0 )
2606 infoPtr
->nButtonWidth
= (INT
)LOWORD(lParam
);
2607 infoPtr
->nButtonHeight
= (INT
)HIWORD(lParam
);
2613 TOOLBAR_SetButtonWidth (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2615 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2617 if (infoPtr
== NULL
)
2620 infoPtr
->cxMin
= (INT
)LOWORD(lParam
);
2621 infoPtr
->cxMax
= (INT
)HIWORD(lParam
);
2628 TOOLBAR_SetCmdId (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2630 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2631 INT nIndex
= (INT
)wParam
;
2633 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
2636 infoPtr
->buttons
[nIndex
].idCommand
= (INT
)lParam
;
2638 if (infoPtr
->hwndToolTip
) {
2640 FIXME("change tool tip!\n");
2648 /* << TOOLBAR_SetColorScheme >> */
2652 TOOLBAR_SetDisabledImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2654 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2655 HIMAGELIST himlTemp
;
2658 himlTemp
= infoPtr
->himlDis
;
2659 infoPtr
->himlDis
= (HIMAGELIST
)lParam
;
2661 /* FIXME: redraw ? */
2663 return (LRESULT
)himlTemp
;
2668 TOOLBAR_SetDrawTextFlags (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2670 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2673 dwTemp
= infoPtr
->dwDTFlags
;
2674 infoPtr
->dwDTFlags
=
2675 (infoPtr
->dwDTFlags
& (DWORD
)wParam
) | (DWORD
)lParam
;
2677 return (LRESULT
)dwTemp
;
2682 TOOLBAR_SetExtendedStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2684 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2687 dwTemp
= infoPtr
->dwExStyle
;
2688 infoPtr
->dwExStyle
= (DWORD
)lParam
;
2690 return (LRESULT
)dwTemp
;
2695 TOOLBAR_SetHotImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2697 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
2698 HIMAGELIST himlTemp
;
2700 himlTemp
= infoPtr
->himlHot
;
2701 infoPtr
->himlHot
= (HIMAGELIST
)lParam
;
2703 /* FIXME: redraw ? */
2705 return (LRESULT
)himlTemp
;
2710 TOOLBAR_SetHotItem (HWND hwnd
, WPARAM wParam
)
2712 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
2713 INT nOldHotItem
= infoPtr
->nHotItem
;
2715 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_FLAT
)
2717 infoPtr
->nHotItem
= (INT
)wParam
;
2719 /* FIXME: What else must be done ??? */
2723 if (nOldHotItem
< 0)
2726 return (LRESULT
)nOldHotItem
;
2731 TOOLBAR_SetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2733 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2734 HIMAGELIST himlTemp
;
2736 himlTemp
= infoPtr
->himlDef
;
2737 infoPtr
->himlDef
= (HIMAGELIST
)lParam
;
2739 /* FIXME: redraw ? */
2741 return (LRESULT
)himlTemp
;
2746 TOOLBAR_SetIndent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2748 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2750 infoPtr
->nIndent
= (INT
)wParam
;
2752 TOOLBAR_CalcToolbar (hwnd
);
2754 InvalidateRect(hwnd
, NULL
, FALSE
);
2760 /* << TOOLBAR_SetInsertMark >> */
2764 TOOLBAR_SetInsertMarkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2766 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2768 infoPtr
->clrInsertMark
= (COLORREF
)lParam
;
2770 /* FIXME : redraw ??*/
2777 TOOLBAR_SetMaxTextRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2779 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2781 if (infoPtr
== NULL
)
2784 infoPtr
->nMaxTextRows
= (INT
)wParam
;
2790 /* << TOOLBAR_SetPadding >> */
2794 TOOLBAR_SetParent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2796 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2799 if (infoPtr
== NULL
)
2801 hwndOldNotify
= infoPtr
->hwndNotify
;
2802 infoPtr
->hwndNotify
= (HWND
)wParam
;
2804 return hwndOldNotify
;
2809 TOOLBAR_SetRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2811 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2812 LPRECT lprc
= (LPRECT
)lParam
;
2814 if (LOWORD(wParam
) > 1) {
2816 FIXME("multiple rows not supported!\n");
2820 /* recalculate toolbar */
2821 TOOLBAR_CalcToolbar (hwnd
);
2823 /* return bounding rectangle */
2825 lprc
->left
= infoPtr
->rcBound
.left
;
2826 lprc
->right
= infoPtr
->rcBound
.right
;
2827 lprc
->top
= infoPtr
->rcBound
.top
;
2828 lprc
->bottom
= infoPtr
->rcBound
.bottom
;
2831 /* repaint toolbar */
2832 InvalidateRect(hwnd
, NULL
, FALSE
);
2839 TOOLBAR_SetState (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2841 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2842 TBUTTON_INFO
*btnPtr
;
2845 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2849 btnPtr
= &infoPtr
->buttons
[nIndex
];
2850 btnPtr
->fsState
= LOWORD(lParam
);
2852 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
2853 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
2860 TOOLBAR_SetStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2862 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2863 TBUTTON_INFO
*btnPtr
;
2866 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2870 btnPtr
= &infoPtr
->buttons
[nIndex
];
2871 btnPtr
->fsStyle
= LOWORD(lParam
);
2873 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
2874 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
2876 if (infoPtr
->hwndToolTip
) {
2878 FIXME("change tool tip!\n");
2886 inline static LRESULT
2887 TOOLBAR_SetToolTips (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2889 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2891 if (infoPtr
== NULL
)
2893 infoPtr
->hwndToolTip
= (HWND
)wParam
;
2899 TOOLBAR_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2901 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2904 TRACE("%s hwnd=0x%04x stub!\n",
2905 ((BOOL
)wParam
) ? "TRUE" : "FALSE", hwnd
);
2907 bTemp
= infoPtr
->bUnicode
;
2908 infoPtr
->bUnicode
= (BOOL
)wParam
;
2915 TOOLBAR_SetVersion (HWND hwnd
, INT iVersion
)
2917 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2918 INT iOldVersion
= infoPtr
->iVersion
;
2920 infoPtr
->iVersion
= iVersion
;
2927 TOOLBAR_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2929 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2930 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
2933 /* initialize info structure */
2934 infoPtr
->nButtonHeight
= 22;
2935 infoPtr
->nButtonWidth
= 24;
2936 infoPtr
->nBitmapHeight
= 15;
2937 infoPtr
->nBitmapWidth
= 16;
2939 infoPtr
->nHeight
= infoPtr
->nButtonHeight
+ TOP_BORDER
+ BOTTOM_BORDER
;
2941 infoPtr
->nMaxTextRows
= 1;
2942 infoPtr
->cxMin
= -1;
2943 infoPtr
->cxMax
= -1;
2945 infoPtr
->bCaptured
= FALSE
;
2946 infoPtr
->bUnicode
= IsWindowUnicode (hwnd
);
2947 infoPtr
->nButtonDown
= -1;
2948 infoPtr
->nOldHit
= -1;
2949 infoPtr
->nHotItem
= -2; /* It has to be initially different from nOldHit */
2950 infoPtr
->hwndNotify
= GetParent (hwnd
);
2951 infoPtr
->bTransparent
= (dwStyle
& TBSTYLE_FLAT
);
2952 infoPtr
->dwDTFlags
= (dwStyle
& TBSTYLE_LIST
) ? DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
: DT_CENTER
;
2953 infoPtr
->bAnchor
= FALSE
; /* no anchor highlighting */
2954 infoPtr
->iVersion
= 0;
2956 SystemParametersInfoA (SPI_GETICONTITLELOGFONT
, 0, &logFont
, 0);
2957 infoPtr
->hFont
= CreateFontIndirectA (&logFont
);
2959 if (dwStyle
& TBSTYLE_TOOLTIPS
) {
2960 /* Create tooltip control */
2961 infoPtr
->hwndToolTip
=
2962 CreateWindowExA (0, TOOLTIPS_CLASSA
, NULL
, 0,
2963 CW_USEDEFAULT
, CW_USEDEFAULT
,
2964 CW_USEDEFAULT
, CW_USEDEFAULT
,
2967 /* Send NM_TOOLTIPSCREATED notification */
2968 if (infoPtr
->hwndToolTip
) {
2969 NMTOOLTIPSCREATED nmttc
;
2971 nmttc
.hdr
.hwndFrom
= hwnd
;
2972 nmttc
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
2973 nmttc
.hdr
.code
= NM_TOOLTIPSCREATED
;
2974 nmttc
.hwndToolTips
= infoPtr
->hwndToolTip
;
2976 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
2977 (WPARAM
)nmttc
.hdr
.idFrom
, (LPARAM
)&nmttc
);
2986 TOOLBAR_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2988 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2990 /* delete tooltip control */
2991 if (infoPtr
->hwndToolTip
)
2992 DestroyWindow (infoPtr
->hwndToolTip
);
2994 /* delete button data */
2995 if (infoPtr
->buttons
)
2996 COMCTL32_Free (infoPtr
->buttons
);
2998 /* delete strings */
2999 if (infoPtr
->strings
) {
3001 for (i
= 0; i
< infoPtr
->nNumStrings
; i
++)
3002 if (infoPtr
->strings
[i
])
3003 COMCTL32_Free (infoPtr
->strings
[i
]);
3005 COMCTL32_Free (infoPtr
->strings
);
3008 /* destroy internal image list */
3009 if (infoPtr
->himlInt
)
3010 ImageList_Destroy (infoPtr
->himlInt
);
3012 /* delete default font */
3014 DeleteObject (infoPtr
->hFont
);
3016 /* free toolbar info data */
3017 COMCTL32_Free (infoPtr
);
3018 SetWindowLongA (hwnd
, 0, 0);
3025 TOOLBAR_EraseBackground (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3027 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3029 if (infoPtr
->bTransparent
)
3030 return SendMessageA (GetParent (hwnd
), WM_ERASEBKGND
, wParam
, lParam
);
3032 return DefWindowProcA (hwnd
, WM_ERASEBKGND
, wParam
, lParam
);
3037 TOOLBAR_GetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3039 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3041 return infoPtr
->hFont
;
3046 TOOLBAR_LButtonDblClk (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3048 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3049 TBUTTON_INFO
*btnPtr
;
3053 pt
.x
= (INT
)LOWORD(lParam
);
3054 pt
.y
= (INT
)HIWORD(lParam
);
3055 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3058 btnPtr
= &infoPtr
->buttons
[nHit
];
3059 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
))
3062 infoPtr
->bCaptured
= TRUE
;
3063 infoPtr
->nButtonDown
= nHit
;
3065 btnPtr
->fsState
|= TBSTATE_PRESSED
;
3067 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3068 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3070 else if (GetWindowLongA (hwnd
, GWL_STYLE
) & CCS_ADJUSTABLE
)
3071 TOOLBAR_Customize (hwnd
);
3078 TOOLBAR_LButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3080 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3081 TBUTTON_INFO
*btnPtr
;
3085 if (infoPtr
->hwndToolTip
)
3086 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
3087 WM_LBUTTONDOWN
, wParam
, lParam
);
3089 pt
.x
= (INT
)LOWORD(lParam
);
3090 pt
.y
= (INT
)HIWORD(lParam
);
3091 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3094 btnPtr
= &infoPtr
->buttons
[nHit
];
3095 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
))
3098 if (btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
)
3102 nmtb
.hdr
.hwndFrom
= hwnd
;
3103 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
3104 nmtb
.hdr
.code
= TBN_DROPDOWN
;
3105 nmtb
.iItem
= btnPtr
->idCommand
;
3107 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
3108 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
);
3112 infoPtr
->bCaptured
= TRUE
;
3113 infoPtr
->nButtonDown
= nHit
;
3114 infoPtr
->nOldHit
= nHit
;
3116 btnPtr
->fsState
|= TBSTATE_PRESSED
;
3117 btnPtr
->bHot
= FALSE
;
3119 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3120 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3127 TOOLBAR_LButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3129 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3130 TBUTTON_INFO
*btnPtr
;
3134 BOOL bSendMessage
= TRUE
;
3136 if (infoPtr
->hwndToolTip
)
3137 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
3138 WM_LBUTTONUP
, wParam
, lParam
);
3140 pt
.x
= (INT
)LOWORD(lParam
);
3141 pt
.y
= (INT
)HIWORD(lParam
);
3142 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3144 if ((infoPtr
->bCaptured
) && (infoPtr
->nButtonDown
>= 0)) {
3145 infoPtr
->bCaptured
= FALSE
;
3147 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
3148 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
3150 if (nHit
== infoPtr
->nButtonDown
) {
3151 if (btnPtr
->fsStyle
& TBSTYLE_CHECK
) {
3152 if (btnPtr
->fsStyle
& TBSTYLE_GROUP
) {
3153 nOldIndex
= TOOLBAR_GetCheckedGroupButtonIndex (infoPtr
,
3154 infoPtr
->nButtonDown
);
3155 if (nOldIndex
== infoPtr
->nButtonDown
)
3156 bSendMessage
= FALSE
;
3157 if ((nOldIndex
!= infoPtr
->nButtonDown
) &&
3159 infoPtr
->buttons
[nOldIndex
].fsState
&= ~TBSTATE_CHECKED
;
3160 btnPtr
->fsState
|= TBSTATE_CHECKED
;
3163 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
3164 btnPtr
->fsState
&= ~TBSTATE_CHECKED
;
3166 btnPtr
->fsState
|= TBSTATE_CHECKED
;
3171 bSendMessage
= FALSE
;
3173 if (nOldIndex
!= -1)
3174 RedrawWindow(hwnd
,&infoPtr
->buttons
[nOldIndex
].rect
,NULL
,
3175 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3176 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3177 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3180 SendMessageA (GetParent(hwnd
), WM_COMMAND
,
3181 MAKEWPARAM(btnPtr
->idCommand
, 0), (LPARAM
)hwnd
);
3183 // if ((GetWindowLongA(hwnd, GWL_STYLE) & TBSTYLE_DROPDOWN) ||
3184 // (btnPtr->fsStyle & 0x08/* BTNS_DROPDOWN */)) {
3186 * This appears to be an error. Instead of checking the style of the
3187 * button in question wine was checking the style of the toolbar
3188 * itself. This caused a number of strange behaviors. In my
3189 * invistigation i think the whole dropdown thing is still fairly
3190 * broken. but this helps fix some of the problems.
3193 if (btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
) {
3196 nmtb
.hdr
.hwndFrom
= hwnd
;
3197 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
3198 nmtb
.hdr
.code
= TBN_DROPDOWN
;
3200 /* nmtb.tbButton not used with TBN_DROPDOWN */
3201 if ((btnPtr
->iString
>= 0) && (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
3202 nmtb
.pszText
= infoPtr
->strings
[btnPtr
->iString
];
3203 nmtb
.cchText
= lstrlenW(nmtb
.pszText
);
3205 nmtb
.pszText
= NULL
;
3208 nmtb
.rcButton
= btnPtr
->rect
;
3210 SendMessageW(infoPtr
->hwndNotify
, WM_NOTIFY
,
3211 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
);
3214 infoPtr
->nButtonDown
= -1;
3215 infoPtr
->nOldHit
= -1;
3222 TOOLBAR_MouseLeave (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3224 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3225 TBUTTON_INFO
*hotBtnPtr
;
3227 hotBtnPtr
= &infoPtr
->buttons
[infoPtr
->nOldHit
];
3229 /* Redraw the button if the last button we were over is the hot button and it
3231 if((infoPtr
->nOldHit
== infoPtr
->nHotItem
) && (hotBtnPtr
->fsState
& TBSTATE_ENABLED
))
3233 hotBtnPtr
->bHot
= FALSE
;
3235 InvalidateRect (hwnd
, &hotBtnPtr
->rect
, TRUE
);
3238 infoPtr
->nOldHit
= -1; /* reset the old hit index as we've left the toolbar */
3239 infoPtr
->nHotItem
= -2; /* It has to be initially different from nOldHit */
3245 TOOLBAR_MouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3247 TBUTTON_INFO
*btnPtr
, *oldBtnPtr
;
3248 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3251 TRACKMOUSEEVENT trackinfo
;
3253 /* fill in the TRACKMOUSEEVENT struct */
3254 trackinfo
.cbSize
= sizeof(TRACKMOUSEEVENT
);
3255 trackinfo
.dwFlags
= TME_QUERY
;
3256 trackinfo
.hwndTrack
= hwnd
;
3257 trackinfo
.dwHoverTime
= HOVER_DEFAULT
;
3259 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
3260 _TrackMouseEvent(&trackinfo
);
3262 /* Make sure tracking is enabled so we recieve a WM_MOUSELEAVE message */
3263 if(!(trackinfo
.dwFlags
& TME_LEAVE
)) {
3264 trackinfo
.dwFlags
= TME_LEAVE
; /* notify upon leaving */
3266 /* call TRACKMOUSEEVENT so we recieve a WM_MOUSELEAVE message */
3267 /* and can properly deactivate the hot toolbar button */
3268 _TrackMouseEvent(&trackinfo
);
3271 if (infoPtr
->hwndToolTip
)
3272 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
3273 WM_MOUSEMOVE
, wParam
, lParam
);
3275 pt
.x
= (INT
)LOWORD(lParam
);
3276 pt
.y
= (INT
)HIWORD(lParam
);
3278 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3280 if (infoPtr
->nOldHit
!= nHit
)
3282 /* Remove the effect of an old hot button if the button was enabled and was
3283 drawn with the hot button effect */
3284 if(infoPtr
->nOldHit
== infoPtr
->nHotItem
&&
3285 (infoPtr
->buttons
[infoPtr
->nOldHit
].fsState
& TBSTATE_ENABLED
))
3287 oldBtnPtr
= &infoPtr
->buttons
[infoPtr
->nOldHit
];
3288 oldBtnPtr
->bHot
= FALSE
;
3290 InvalidateRect (hwnd
, &oldBtnPtr
->rect
, TRUE
);
3293 /* It's not a separator or in nowhere. It's a hot button. */
3296 btnPtr
= &infoPtr
->buttons
[nHit
];
3297 btnPtr
->bHot
= TRUE
;
3299 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3300 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3302 infoPtr
->nHotItem
= nHit
;
3305 if (infoPtr
->bCaptured
) {
3306 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
3307 if (infoPtr
->nOldHit
== infoPtr
->nButtonDown
) {
3308 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
3309 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3310 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3312 else if (nHit
== infoPtr
->nButtonDown
) {
3313 btnPtr
->fsState
|= TBSTATE_PRESSED
;
3314 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3315 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3318 infoPtr
->nOldHit
= nHit
;
3324 inline static LRESULT
3325 TOOLBAR_NCActivate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3327 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
3328 return DefWindowProcA (hwnd
, WM_NCACTIVATE
, wParam
, lParam
);
3330 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
3334 inline static LRESULT
3335 TOOLBAR_NCCalcSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3337 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & CCS_NODIVIDER
))
3338 ((LPRECT
)lParam
)->top
+= GetSystemMetrics(SM_CYEDGE
);
3340 return DefWindowProcA (hwnd
, WM_NCCALCSIZE
, wParam
, lParam
);
3345 TOOLBAR_NCCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3347 TOOLBAR_INFO
*infoPtr
;
3349 /* allocate memory for info structure */
3350 infoPtr
= (TOOLBAR_INFO
*)COMCTL32_Alloc (sizeof(TOOLBAR_INFO
));
3351 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
3354 infoPtr
->dwStructSize
= sizeof(TBBUTTON
);
3356 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
3357 if (!GetWindowLongA (hwnd
, GWL_HINSTANCE
)) {
3358 HINSTANCE hInst
= (HINSTANCE
)GetWindowLongA (GetParent (hwnd
), GWL_HINSTANCE
);
3359 SetWindowLongA (hwnd
, GWL_HINSTANCE
, (DWORD
)hInst
);
3362 return DefWindowProcA (hwnd
, WM_NCCREATE
, wParam
, lParam
);
3367 TOOLBAR_NCPaint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3369 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
3373 if (dwStyle
& WS_MINIMIZE
)
3374 return 0; /* Nothing to do */
3376 DefWindowProcA (hwnd
, WM_NCPAINT
, wParam
, lParam
);
3378 if (!(hdc
= GetDCEx (hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
)))
3381 if (!(dwStyle
& CCS_NODIVIDER
))
3383 GetWindowRect (hwnd
, &rcWindow
);
3384 OffsetRect (&rcWindow
, -rcWindow
.left
, -rcWindow
.top
);
3385 if( dwStyle
& WS_BORDER
)
3386 OffsetRect (&rcWindow
, 1, 1);
3387 DrawEdge (hdc
, &rcWindow
, EDGE_ETCHED
, BF_TOP
);
3390 ReleaseDC( hwnd
, hdc
);
3396 inline static LRESULT
3397 TOOLBAR_Notify (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3399 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3400 LPNMHDR lpnmh
= (LPNMHDR
)lParam
;
3402 TRACE("passing WM_NOTIFY!\n");
3404 if ((infoPtr
->hwndToolTip
) && (lpnmh
->hwndFrom
== infoPtr
->hwndToolTip
)) {
3405 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
, wParam
, lParam
);
3408 if (lpnmh
->code
== TTN_GETDISPINFOA
) {
3409 LPNMTTDISPINFOA lpdi
= (LPNMTTDISPINFOA
)lParam
;
3411 FIXME("retrieving ASCII string\n");
3414 else if (lpnmh
->code
== TTN_GETDISPINFOW
) {
3415 LPNMTTDISPINFOW lpdi
= (LPNMTTDISPINFOW
)lParam
;
3417 FIXME("retrieving UNICODE string\n");
3428 TOOLBAR_Paint (HWND hwnd
, WPARAM wParam
)
3433 TOOLBAR_CalcToolbar( hwnd
);
3434 hdc
= wParam
==0 ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
3435 TOOLBAR_Refresh (hwnd
, hdc
);
3437 EndPaint (hwnd
, &ps
);
3443 TOOLBAR_Size (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3445 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3446 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
3455 /* Resize deadlock check */
3456 if (infoPtr
->bAutoSize
) {
3457 infoPtr
->bAutoSize
= FALSE
;
3461 flags
= (INT
) wParam
;
3463 /* FIXME for flags =
3464 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
3467 TRACE("sizing toolbar!\n");
3469 if (flags
== SIZE_RESTORED
) {
3470 /* width and height don't apply */
3471 parent
= GetParent (hwnd
);
3472 GetClientRect(parent
, &parent_rect
);
3473 x
= parent_rect
.left
;
3474 y
= parent_rect
.top
;
3476 if (dwStyle
& CCS_NORESIZE
) {
3477 uPosFlags
|= (SWP_NOSIZE
| SWP_NOMOVE
);
3480 /* infoPtr->nWidth = parent_rect.right - parent_rect.left; */
3481 cy
= infoPtr
->nHeight
;
3482 cx
= infoPtr
->nWidth
;
3483 TOOLBAR_CalcToolbar (hwnd
);
3484 infoPtr
->nWidth
= cx
;
3485 infoPtr
->nHeight
= cy
;
3488 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
3489 TOOLBAR_CalcToolbar (hwnd
);
3490 cy
= infoPtr
->nHeight
;
3491 cx
= infoPtr
->nWidth
;
3493 if (dwStyle
& CCS_NOMOVEY
) {
3494 GetWindowRect(hwnd
, &window_rect
);
3495 ScreenToClient(parent
, (LPPOINT
)&window_rect
.left
);
3496 y
= window_rect
.top
;
3500 if (dwStyle
& CCS_NOPARENTALIGN
) {
3501 uPosFlags
|= SWP_NOMOVE
;
3502 cy
= infoPtr
->nHeight
;
3503 cx
= infoPtr
->nWidth
;
3506 if (!(dwStyle
& CCS_NODIVIDER
))
3507 cy
+= GetSystemMetrics(SM_CYEDGE
);
3509 if (dwStyle
& WS_BORDER
)
3512 cy
+= GetSystemMetrics(SM_CYEDGE
);
3513 cx
+= GetSystemMetrics(SM_CYEDGE
);
3516 SetWindowPos (hwnd
, 0, parent_rect
.left
- x
, parent_rect
.top
- y
,
3517 cx
, cy
, uPosFlags
| SWP_NOZORDER
);
3524 TOOLBAR_StyleChanged (HWND hwnd
, INT nType
, LPSTYLESTRUCT lpStyle
)
3526 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3528 if (nType
== GWL_STYLE
) {
3529 if (lpStyle
->styleNew
& TBSTYLE_LIST
) {
3530 infoPtr
->dwDTFlags
= DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
;
3533 infoPtr
->dwDTFlags
= DT_CENTER
;
3537 TOOLBAR_AutoSize (hwnd
);
3539 InvalidateRect(hwnd
, NULL
, FALSE
);
3546 static LRESULT WINAPI
3547 ToolbarWindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3553 return TOOLBAR_Destroy (hwnd
, wParam
, lParam
);
3556 return TOOLBAR_NCCreate (hwnd
, wParam
, lParam
);
3559 if (!TOOLBAR_GetInfoPtr (hwnd
))
3561 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
3567 return TOOLBAR_AddBitmap (hwnd
, wParam
, lParam
);
3569 case TB_ADDBUTTONSA
:
3570 return TOOLBAR_AddButtonsA (hwnd
, wParam
, lParam
);
3572 case TB_ADDBUTTONSW
:
3573 return TOOLBAR_AddButtonsW (hwnd
, wParam
, lParam
);
3576 return TOOLBAR_AddStringA (hwnd
, wParam
, lParam
);
3579 return TOOLBAR_AddStringW (hwnd
, wParam
, lParam
);
3582 return TOOLBAR_AutoSize (hwnd
);
3584 case TB_BUTTONCOUNT
:
3585 return TOOLBAR_ButtonCount (hwnd
, wParam
, lParam
);
3587 case TB_BUTTONSTRUCTSIZE
:
3588 return TOOLBAR_ButtonStructSize (hwnd
, wParam
, lParam
);
3590 case TB_CHANGEBITMAP
:
3591 return TOOLBAR_ChangeBitmap (hwnd
, wParam
, lParam
);
3593 case TB_CHECKBUTTON
:
3594 return TOOLBAR_CheckButton (hwnd
, wParam
, lParam
);
3596 case TB_COMMANDTOINDEX
:
3597 return TOOLBAR_CommandToIndex (hwnd
, wParam
, lParam
);
3600 return TOOLBAR_Customize (hwnd
);
3602 case TB_DELETEBUTTON
:
3603 return TOOLBAR_DeleteButton (hwnd
, wParam
, lParam
);
3605 case TB_ENABLEBUTTON
:
3606 return TOOLBAR_EnableButton (hwnd
, wParam
, lParam
);
3608 case TB_GETANCHORHIGHLIGHT
:
3609 return TOOLBAR_GetAnchorHighlight (hwnd
);
3612 return TOOLBAR_GetBitmap (hwnd
, wParam
, lParam
);
3614 case TB_GETBITMAPFLAGS
:
3615 return TOOLBAR_GetBitmapFlags (hwnd
, wParam
, lParam
);
3618 return TOOLBAR_GetButton (hwnd
, wParam
, lParam
);
3620 case TB_GETBUTTONINFOA
:
3621 return TOOLBAR_GetButtonInfoA (hwnd
, wParam
, lParam
);
3623 case TB_GETBUTTONINFOW
:
3624 return TOOLBAR_GetButtonInfoW (hwnd
, wParam
, lParam
);
3626 case TB_GETBUTTONSIZE
:
3627 return TOOLBAR_GetButtonSize (hwnd
);
3629 case TB_GETBUTTONTEXTA
:
3630 return TOOLBAR_GetButtonTextA (hwnd
, wParam
, lParam
);
3632 case TB_GETBUTTONTEXTW
:
3633 return TOOLBAR_GetButtonTextW (hwnd
, wParam
, lParam
);
3635 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
3637 case TB_GETDISABLEDIMAGELIST
:
3638 return TOOLBAR_GetDisabledImageList (hwnd
, wParam
, lParam
);
3640 case TB_GETEXTENDEDSTYLE
:
3641 return TOOLBAR_GetExtendedStyle (hwnd
);
3643 case TB_GETHOTIMAGELIST
:
3644 return TOOLBAR_GetHotImageList (hwnd
, wParam
, lParam
);
3647 return TOOLBAR_GetHotItem (hwnd
);
3649 case TB_GETIMAGELIST
:
3650 return TOOLBAR_GetImageList (hwnd
, wParam
, lParam
);
3652 /* case TB_GETINSERTMARK: */ /* 4.71 */
3653 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
3655 case TB_GETITEMRECT
:
3656 return TOOLBAR_GetItemRect (hwnd
, wParam
, lParam
);
3659 return TOOLBAR_GetMaxSize (hwnd
, wParam
, lParam
);
3661 /* case TB_GETOBJECT: */ /* 4.71 */
3662 /* case TB_GETPADDING: */ /* 4.71 */
3665 return TOOLBAR_GetRect (hwnd
, wParam
, lParam
);
3668 return TOOLBAR_GetRows (hwnd
, wParam
, lParam
);
3671 return TOOLBAR_GetState (hwnd
, wParam
, lParam
);
3674 return TOOLBAR_GetStyle (hwnd
, wParam
, lParam
);
3676 case TB_GETTEXTROWS
:
3677 return TOOLBAR_GetTextRows (hwnd
, wParam
, lParam
);
3679 case TB_GETTOOLTIPS
:
3680 return TOOLBAR_GetToolTips (hwnd
, wParam
, lParam
);
3682 case TB_GETUNICODEFORMAT
:
3683 return TOOLBAR_GetUnicodeFormat (hwnd
, wParam
, lParam
);
3685 case CCM_GETVERSION
:
3686 return TOOLBAR_GetVersion (hwnd
);
3689 return TOOLBAR_HideButton (hwnd
, wParam
, lParam
);
3692 return TOOLBAR_HitTest (hwnd
, wParam
, lParam
);
3694 case TB_INDETERMINATE
:
3695 return TOOLBAR_Indeterminate (hwnd
, wParam
, lParam
);
3697 case TB_INSERTBUTTONA
:
3698 return TOOLBAR_InsertButtonA (hwnd
, wParam
, lParam
);
3700 case TB_INSERTBUTTONW
:
3701 return TOOLBAR_InsertButtonW (hwnd
, wParam
, lParam
);
3703 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
3705 case TB_ISBUTTONCHECKED
:
3706 return TOOLBAR_IsButtonChecked (hwnd
, wParam
, lParam
);
3708 case TB_ISBUTTONENABLED
:
3709 return TOOLBAR_IsButtonEnabled (hwnd
, wParam
, lParam
);
3711 case TB_ISBUTTONHIDDEN
:
3712 return TOOLBAR_IsButtonHidden (hwnd
, wParam
, lParam
);
3714 case TB_ISBUTTONHIGHLIGHTED
:
3715 return TOOLBAR_IsButtonHighlighted (hwnd
, wParam
, lParam
);
3717 case TB_ISBUTTONINDETERMINATE
:
3718 return TOOLBAR_IsButtonIndeterminate (hwnd
, wParam
, lParam
);
3720 case TB_ISBUTTONPRESSED
:
3721 return TOOLBAR_IsButtonPressed (hwnd
, wParam
, lParam
);
3723 case TB_LOADIMAGES
: /* 4.70 */
3724 FIXME("missing standard imagelists\n");
3727 /* case TB_MAPACCELERATORA: */ /* 4.71 */
3728 /* case TB_MAPACCELERATORW: */ /* 4.71 */
3729 /* case TB_MARKBUTTON: */ /* 4.71 */
3730 /* case TB_MOVEBUTTON: */ /* 4.71 */
3732 case TB_PRESSBUTTON
:
3733 return TOOLBAR_PressButton (hwnd
, wParam
, lParam
);
3735 /* case TB_REPLACEBITMAP: */
3737 case TB_SAVERESTOREA
:
3738 return TOOLBAR_SaveRestoreA (hwnd
, wParam
, lParam
);
3740 case TB_SAVERESTOREW
:
3741 return TOOLBAR_SaveRestoreW (hwnd
, wParam
, lParam
);
3743 case TB_SETANCHORHIGHLIGHT
:
3744 return TOOLBAR_SetAnchorHighlight (hwnd
, wParam
);
3746 case TB_SETBITMAPSIZE
:
3747 return TOOLBAR_SetBitmapSize (hwnd
, wParam
, lParam
);
3749 case TB_SETBUTTONINFOA
:
3750 return TOOLBAR_SetButtonInfoA (hwnd
, wParam
, lParam
);
3752 case TB_SETBUTTONINFOW
:
3753 return TOOLBAR_SetButtonInfoW (hwnd
, wParam
, lParam
);
3755 case TB_SETBUTTONSIZE
:
3756 return TOOLBAR_SetButtonSize (hwnd
, wParam
, lParam
);
3758 case TB_SETBUTTONWIDTH
:
3759 return TOOLBAR_SetButtonWidth (hwnd
, wParam
, lParam
);
3762 return TOOLBAR_SetCmdId (hwnd
, wParam
, lParam
);
3764 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
3766 case TB_SETDISABLEDIMAGELIST
:
3767 return TOOLBAR_SetDisabledImageList (hwnd
, wParam
, lParam
);
3769 case TB_SETDRAWTEXTFLAGS
:
3770 return TOOLBAR_SetDrawTextFlags (hwnd
, wParam
, lParam
);
3772 case TB_SETEXTENDEDSTYLE
:
3773 return TOOLBAR_SetExtendedStyle (hwnd
, wParam
, lParam
);
3775 case TB_SETHOTIMAGELIST
:
3776 return TOOLBAR_SetHotImageList (hwnd
, wParam
, lParam
);
3779 return TOOLBAR_SetHotItem (hwnd
, wParam
);
3781 case TB_SETIMAGELIST
:
3782 return TOOLBAR_SetImageList (hwnd
, wParam
, lParam
);
3785 return TOOLBAR_SetIndent (hwnd
, wParam
, lParam
);
3787 /* case TB_SETINSERTMARK: */ /* 4.71 */
3789 case TB_SETINSERTMARKCOLOR
:
3790 return TOOLBAR_SetInsertMarkColor (hwnd
, wParam
, lParam
);
3792 case TB_SETMAXTEXTROWS
:
3793 return TOOLBAR_SetMaxTextRows (hwnd
, wParam
, lParam
);
3795 /* case TB_SETPADDING: */ /* 4.71 */
3798 return TOOLBAR_SetParent (hwnd
, wParam
, lParam
);
3801 return TOOLBAR_SetRows (hwnd
, wParam
, lParam
);
3804 return TOOLBAR_SetState (hwnd
, wParam
, lParam
);
3807 return TOOLBAR_SetStyle (hwnd
, wParam
, lParam
);
3809 case TB_SETTOOLTIPS
:
3810 return TOOLBAR_SetToolTips (hwnd
, wParam
, lParam
);
3812 case TB_SETUNICODEFORMAT
:
3813 return TOOLBAR_SetUnicodeFormat (hwnd
, wParam
, lParam
);
3815 case CCM_SETVERSION
:
3816 return TOOLBAR_SetVersion (hwnd
, (INT
)wParam
);
3822 return TOOLBAR_Create (hwnd
, wParam
, lParam
);
3825 return TOOLBAR_EraseBackground (hwnd
, wParam
, lParam
);
3828 return TOOLBAR_GetFont (hwnd
, wParam
, lParam
);
3830 /* case WM_KEYDOWN: */
3831 /* case WM_KILLFOCUS: */
3833 case WM_LBUTTONDBLCLK
:
3834 return TOOLBAR_LButtonDblClk (hwnd
, wParam
, lParam
);
3836 case WM_LBUTTONDOWN
:
3837 return TOOLBAR_LButtonDown (hwnd
, wParam
, lParam
);
3840 return TOOLBAR_LButtonUp (hwnd
, wParam
, lParam
);
3843 return TOOLBAR_MouseMove (hwnd
, wParam
, lParam
);
3846 return TOOLBAR_MouseLeave (hwnd
, wParam
, lParam
);
3849 return TOOLBAR_NCActivate (hwnd
, wParam
, lParam
);
3852 return TOOLBAR_NCCalcSize (hwnd
, wParam
, lParam
);
3855 return TOOLBAR_NCPaint (hwnd
, wParam
, lParam
);
3858 return TOOLBAR_Notify (hwnd
, wParam
, lParam
);
3860 /* case WM_NOTIFYFORMAT: */
3863 return TOOLBAR_Paint (hwnd
, wParam
);
3866 return TOOLBAR_Size (hwnd
, wParam
, lParam
);
3868 case WM_STYLECHANGED
:
3869 return TOOLBAR_StyleChanged (hwnd
, (INT
)wParam
, (LPSTYLESTRUCT
)lParam
);
3871 /* case WM_SYSCOLORCHANGE: */
3873 /* case WM_WININICHANGE: */
3878 case WM_MEASUREITEM
:
3880 return SendMessageA (GetParent (hwnd
), uMsg
, wParam
, lParam
);
3883 if (uMsg
>= WM_USER
)
3884 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
3885 uMsg
, wParam
, lParam
);
3886 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
3893 TOOLBAR_Register (void)
3897 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
3898 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
;
3899 wndClass
.lpfnWndProc
= (WNDPROC
)ToolbarWindowProc
;
3900 wndClass
.cbClsExtra
= 0;
3901 wndClass
.cbWndExtra
= sizeof(TOOLBAR_INFO
*);
3902 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
3903 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_3DFACE
+ 1);
3904 wndClass
.lpszClassName
= TOOLBARCLASSNAMEA
;
3906 RegisterClassA (&wndClass
);
3911 TOOLBAR_Unregister (void)
3913 UnregisterClassA (TOOLBARCLASSNAMEA
, (HINSTANCE
)NULL
);