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);
84 if (himl
&& btnPtr
->iBitmap
>=0) {
85 if (dwStyle
& TBSTYLE_LIST
) {
86 rcText
.left
+= infoPtr
->nBitmapWidth
;
89 rcText
.top
+= infoPtr
->nBitmapHeight
;
93 if (nState
& (TBSTATE_PRESSED
| TBSTATE_CHECKED
))
94 OffsetRect (&rcText
, 1, 1);
96 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
97 nOldBkMode
= SetBkMode (hdc
, TRANSPARENT
);
98 if (!(nState
& TBSTATE_ENABLED
)) {
99 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_3DHILIGHT
));
100 OffsetRect (&rcText
, 1, 1);
101 DrawTextW (hdc
, infoPtr
->strings
[btnPtr
->iString
], -1,
102 &rcText
, infoPtr
->dwDTFlags
);
103 SetTextColor (hdc
, GetSysColor (COLOR_3DSHADOW
));
104 OffsetRect (&rcText
, -1, -1);
105 DrawTextW (hdc
, infoPtr
->strings
[btnPtr
->iString
], -1,
106 &rcText
, infoPtr
->dwDTFlags
);
108 else if (nState
& TBSTATE_INDETERMINATE
) {
109 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_3DSHADOW
));
110 DrawTextW (hdc
, infoPtr
->strings
[btnPtr
->iString
], -1,
111 &rcText
, infoPtr
->dwDTFlags
);
114 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
115 DrawTextW (hdc
, infoPtr
->strings
[btnPtr
->iString
], -1,
116 &rcText
, infoPtr
->dwDTFlags
);
119 SetTextColor (hdc
, clrOld
);
120 SelectObject (hdc
, hOldFont
);
121 if (nOldBkMode
!= TRANSPARENT
)
122 SetBkMode (hdc
, nOldBkMode
);
128 TOOLBAR_DrawPattern (HDC hdc
, LPRECT lpRect
)
130 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
131 INT cx
= lpRect
->right
- lpRect
->left
;
132 INT cy
= lpRect
->bottom
- lpRect
->top
;
133 PatBlt (hdc
, lpRect
->left
, lpRect
->top
, cx
, cy
, 0x00FA0089);
134 SelectObject (hdc
, hbr
);
139 TOOLBAR_DrawMasked (TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
,
140 HDC hdc
, INT x
, INT y
)
142 /* FIXME: this function is a hack since it uses image list
143 internals directly */
145 HIMAGELIST himl
= infoPtr
->himlDef
;
153 /* create new dc's */
154 hdcImageList
= CreateCompatibleDC (0);
155 hdcMask
= CreateCompatibleDC (0);
157 /* create new bitmap */
158 hbmMask
= CreateBitmap (himl
->cx
, himl
->cy
, 1, 1, NULL
);
159 SelectObject (hdcMask
, hbmMask
);
161 /* copy the mask bitmap */
162 SelectObject (hdcImageList
, himl
->hbmMask
);
163 SetBkColor (hdcImageList
, RGB(255, 255, 255));
164 SetTextColor (hdcImageList
, RGB(0, 0, 0));
165 BitBlt (hdcMask
, 0, 0, himl
->cx
, himl
->cy
,
166 hdcImageList
, himl
->cx
* btnPtr
->iBitmap
, 0, SRCCOPY
);
169 /* add white mask from image */
170 SelectObject (hdcImageList
, himl
->hbmImage
);
171 SetBkColor (hdcImageList
, RGB(0, 0, 0));
172 BitBlt (hdcMask
, 0, 0, himl
->cx
, himl
->cy
,
173 hdcImageList
, himl
->cx
* btnPtr
->iBitmap
, 0, MERGEPAINT
);
176 /* draw the new mask */
177 SelectObject (hdc
, GetSysColorBrush (COLOR_3DHILIGHT
));
178 BitBlt (hdc
, x
+1, y
+1, himl
->cx
, himl
->cy
,
179 hdcMask
, 0, 0, 0xB8074A);
181 SelectObject (hdc
, GetSysColorBrush (COLOR_3DSHADOW
));
182 BitBlt (hdc
, x
, y
, himl
->cx
, himl
->cy
,
183 hdcMask
, 0, 0, 0xB8074A);
185 DeleteObject (hbmMask
);
187 DeleteDC (hdcImageList
);
192 TOOLBAR_DrawButton (HWND hwnd
, TBUTTON_INFO
*btnPtr
, HDC hdc
)
194 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
195 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
198 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
204 if (btnPtr
->fsStyle
& TBSTYLE_SEP
) {
205 if ((dwStyle
& TBSTYLE_FLAT
) && (btnPtr
->iBitmap
== 0))
206 TOOLBAR_DrawFlatSeparator (&rc
, hdc
);
211 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
)) {
212 if (!(dwStyle
& TBSTYLE_FLAT
))
213 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
214 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
216 if (infoPtr
->himlDis
&& btnPtr
->iBitmap
>=0)
217 ImageList_Draw (infoPtr
->himlDis
, btnPtr
->iBitmap
, hdc
,
218 rc
.left
+1, rc
.top
+1, ILD_NORMAL
);
220 TOOLBAR_DrawMasked (infoPtr
, btnPtr
, hdc
, rc
.left
+1, rc
.top
+1);
222 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
,
227 /* pressed TBSTYLE_BUTTON */
228 if (btnPtr
->fsState
& TBSTATE_PRESSED
) {
229 if (dwStyle
& TBSTYLE_FLAT
)
230 DrawEdge (hdc
, &rc
, BDR_SUNKENOUTER
, BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
232 DrawEdge (hdc
, &rc
, EDGE_SUNKEN
, BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
233 if (btnPtr
->iBitmap
>=0)
234 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
235 rc
.left
+2, rc
.top
+2, ILD_NORMAL
);
236 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
,
241 /* checked TBSTYLE_CHECK */
242 if ((btnPtr
->fsStyle
& TBSTYLE_CHECK
) &&
243 (btnPtr
->fsState
& TBSTATE_CHECKED
)) {
244 if (dwStyle
& TBSTYLE_FLAT
)
245 DrawEdge (hdc
, &rc
, BDR_SUNKENOUTER
,
246 BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
248 DrawEdge (hdc
, &rc
, EDGE_SUNKEN
,
249 BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
251 TOOLBAR_DrawPattern (hdc
, &rc
);
253 if (btnPtr
->iBitmap
>=0)
254 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
255 rc
.left
+2, rc
.top
+2, ILD_NORMAL
);
257 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
,
263 if (btnPtr
->fsState
& TBSTATE_INDETERMINATE
) {
264 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
265 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
267 TOOLBAR_DrawPattern (hdc
, &rc
);
268 TOOLBAR_DrawMasked (infoPtr
, btnPtr
, hdc
, rc
.left
+1, rc
.top
+1);
269 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
,
275 if (dwStyle
& TBSTYLE_FLAT
)
278 DrawEdge (hdc
, &rc
, BDR_RAISEDINNER
, BF_RECT
| BF_MIDDLE
);
279 if (btnPtr
->bHot
&& infoPtr
->himlHot
&& btnPtr
->iBitmap
>=0)
280 ImageList_Draw (infoPtr
->himlHot
, btnPtr
->iBitmap
, hdc
,
281 rc
.left
+2, rc
.top
+2, ILD_NORMAL
);
282 else if (btnPtr
->iBitmap
>=0)
283 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
284 rc
.left
+2, rc
.top
+2, ILD_NORMAL
);
288 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
289 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
291 if (btnPtr
->iBitmap
>=0)
292 ImageList_Draw (infoPtr
->himlDef
, btnPtr
->iBitmap
, hdc
,
293 rc
.left
+1, rc
.top
+1, ILD_NORMAL
);
296 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
,
302 TOOLBAR_Refresh (HWND hwnd
, HDC hdc
)
304 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
305 TBUTTON_INFO
*btnPtr
;
309 btnPtr
= infoPtr
->buttons
;
310 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++)
311 TOOLBAR_DrawButton (hwnd
, btnPtr
, hdc
);
316 TOOLBAR_CalcStrings (HWND hwnd
, LPSIZE lpSize
)
318 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
319 TBUTTON_INFO
*btnPtr
;
329 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
331 btnPtr
= infoPtr
->buttons
;
332 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
333 if (!(btnPtr
->fsState
& TBSTATE_HIDDEN
) &&
334 (btnPtr
->iString
> -1) &&
335 (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
336 LPWSTR lpText
= infoPtr
->strings
[btnPtr
->iString
];
337 GetTextExtentPoint32W (hdc
, lpText
, lstrlenW (lpText
), &sz
);
338 if (sz
.cx
> lpSize
->cx
)
340 if (sz
.cy
> lpSize
->cy
)
345 SelectObject (hdc
, hOldFont
);
348 TRACE("string size %d x %d!\n", lpSize
->cx
, lpSize
->cy
);
351 /***********************************************************************
352 * TOOLBAR_WrapToolbar
354 * This function walks through the buttons and seperators in the
355 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
356 * wrapping should occur based on the width of the toolbar window.
357 * It does *not* calculate button placement itself. That task
358 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
359 * the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
360 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
364 TOOLBAR_WrapToolbar( HWND hwnd
, DWORD dwStyle
)
366 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
367 TBUTTON_INFO
*btnPtr
;
370 BOOL bWrap
, bButtonWrap
;
372 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
373 /* no layout is necessary. Applications may use this style */
374 /* to perform their own layout on the toolbar. */
375 if( !(dwStyle
& TBSTYLE_WRAPABLE
) )
378 btnPtr
= infoPtr
->buttons
;
379 x
= infoPtr
->nIndent
;
381 /* this can get the parents width, to know how far we can extend
382 * this toolbar. We cannot use its height, as there may be multiple
383 * toolbars in a rebar control
385 GetClientRect( GetParent(hwnd
), &rc
);
386 infoPtr
->nWidth
= rc
.right
- rc
.left
;
389 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++ )
392 btnPtr
[i
].fsState
&= ~TBSTATE_WRAP
;
394 if (btnPtr
[i
].fsState
& TBSTATE_HIDDEN
)
397 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
398 /* it is the actual width of the separator. This is used for */
399 /* custom controls in toolbars. */
400 if (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
)
401 cx
= (btnPtr
[i
].iBitmap
> 0) ?
402 btnPtr
[i
].iBitmap
: SEPARATOR_WIDTH
;
404 cx
= infoPtr
->nButtonWidth
;
406 /* Two or more adjacent separators form a separator group. */
407 /* The first separator in a group should be wrapped to the */
408 /* next row if the previous wrapping is on a button. */
410 (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
) &&
411 (i
+ 1 < infoPtr
->nNumButtons
) &&
412 (btnPtr
[i
+ 1].fsStyle
& TBSTYLE_SEP
) )
414 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
415 x
= infoPtr
->nIndent
;
421 /* The layout makes sure the bitmap is visible, but not the button. */
422 if ( x
+ cx
- (infoPtr
->nButtonWidth
- infoPtr
->nBitmapWidth
) / 2
427 /* If the current button is a separator and not hidden, */
428 /* go to the next until it reaches a non separator. */
429 /* Wrap the last separator if it is before a button. */
430 while( ( (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
) ||
431 (btnPtr
[i
].fsState
& TBSTATE_HIDDEN
) ) &&
432 i
< infoPtr
->nNumButtons
)
438 if( bFound
&& i
< infoPtr
->nNumButtons
)
441 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
442 x
= infoPtr
->nIndent
;
446 else if ( i
>= infoPtr
->nNumButtons
)
449 /* If the current button is not a separator, find the last */
450 /* separator and wrap it. */
451 for ( j
= i
- 1; j
>= 0 && !(btnPtr
[j
].fsState
& TBSTATE_WRAP
); j
--)
453 if ((btnPtr
[j
].fsStyle
& TBSTYLE_SEP
) &&
454 !(btnPtr
[j
].fsState
& TBSTATE_HIDDEN
))
458 x
= infoPtr
->nIndent
;
459 btnPtr
[j
].fsState
|= TBSTATE_WRAP
;
465 /* If no separator available for wrapping, wrap one of */
466 /* non-hidden previous button. */
470 j
>= 0 && !(btnPtr
[j
].fsState
& TBSTATE_WRAP
); j
--)
472 if (btnPtr
[j
].fsState
& TBSTATE_HIDDEN
)
477 x
= infoPtr
->nIndent
;
478 btnPtr
[j
].fsState
|= TBSTATE_WRAP
;
484 /* If all above failed, wrap the current button. */
487 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
489 x
= infoPtr
->nIndent
;
490 if (btnPtr
[i
].fsState
& TBSTYLE_SEP
)
501 /***********************************************************************
502 * TOOLBAR_CalcToolbar
504 * This function calculates button and separator placement. It first
505 * calculates the button sizes, gets the toolbar window width and then
506 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
507 * on. It assigns a new location to each item and sends this location to
508 * the tooltip window if appropriate. Finally, it updates the rcBound
509 * rect and calculates the new required toolbar window height.
513 TOOLBAR_CalcToolbar (HWND hwnd
)
515 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
516 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
517 TBUTTON_INFO
*btnPtr
;
518 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 BOOL usesBitmaps
= FALSE
;
533 for (i
= 0; i
< infoPtr
->nNumButtons
&& !usesBitmaps
; i
++)
534 if (infoPtr
->buttons
[i
].iBitmap
>=0)
537 if (sizeString
.cy
> 0)
539 infoPtr
->nButtonHeight
= sizeString
.cy
+ infoPtr
->nBitmapHeight
+ 6;
541 infoPtr
->nButtonHeight
= sizeString
.cy
+ 6;
542 else if (infoPtr
->nButtonHeight
< infoPtr
->nBitmapHeight
+ 6)
543 infoPtr
->nButtonHeight
= infoPtr
->nBitmapHeight
+ 6;
545 if (sizeString
.cx
> infoPtr
->nBitmapWidth
)
546 infoPtr
->nButtonWidth
= sizeString
.cx
+ 6;
547 else if (infoPtr
->nButtonWidth
< infoPtr
->nBitmapWidth
+ 6)
548 infoPtr
->nButtonWidth
= infoPtr
->nBitmapWidth
+ 6;
551 if ( infoPtr
->cxMin
>= 0 && infoPtr
->nButtonWidth
< infoPtr
->cxMin
)
552 infoPtr
->nButtonWidth
= infoPtr
->cxMin
;
553 if ( infoPtr
->cxMax
>= 0 && infoPtr
->nButtonWidth
> infoPtr
->cxMax
)
554 infoPtr
->nButtonWidth
= infoPtr
->cxMax
;
556 TOOLBAR_WrapToolbar( hwnd
, dwStyle
);
558 x
= infoPtr
->nIndent
;
559 y
= (dwStyle
& TBSTYLE_FLAT
) ? 0 : TOP_BORDER
;
562 * We wills et the height below, and we set the width on entry
563 * so we do not reset them here..
566 GetClientRect( hwnd
, &rc
);
567 /* get initial values for toolbar */
568 infoPtr
->nWidth
= rc
.right
- rc
.left
;
569 infoPtr
->nHeight
= rc
.bottom
- rc
.top
;
572 /* from above, minimum is a button, and possible text */
573 cx
= infoPtr
->nButtonWidth
;
574 /* cannot use just ButtonHeight, we may have no buttons! */
575 if (infoPtr
->nNumButtons
> 0)
576 infoPtr
->nHeight
= infoPtr
->nButtonHeight
;
577 cy
= infoPtr
->nHeight
;
579 nRows
= nSepRows
= 0;
581 infoPtr
->rcBound
.top
= y
;
582 infoPtr
->rcBound
.left
= x
;
583 infoPtr
->rcBound
.bottom
= y
+ cy
;
584 infoPtr
->rcBound
.right
= x
;
586 btnPtr
= infoPtr
->buttons
;
588 /* do not base height/width on parent, if the parent is a */
589 /* rebar control it could have multiple rows of toolbars */
590 /* GetClientRect( GetParent(hwnd), &rc ); */
591 /* cx = rc.right - rc.left; */
592 /* cy = rc.bottom - rc.top; */
594 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++ )
597 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
599 SetRectEmpty (&btnPtr
->rect
);
603 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
604 /* it is the actual width of the separator. This is used for */
605 /* custom controls in toolbars. */
606 if (btnPtr
->fsStyle
& TBSTYLE_SEP
)
607 cx
= (btnPtr
->iBitmap
> 0) ?
608 btnPtr
->iBitmap
: SEPARATOR_WIDTH
;
610 cx
= infoPtr
->nButtonWidth
;
612 cy
= infoPtr
->nHeight
;
614 if (btnPtr
->fsState
& TBSTATE_WRAP
)
617 SetRect (&btnPtr
->rect
, x
, y
, x
+ cx
, y
+ cy
);
619 if (infoPtr
->rcBound
.left
> x
)
620 infoPtr
->rcBound
.left
= x
;
621 if (infoPtr
->rcBound
.right
< x
+ cx
)
622 infoPtr
->rcBound
.right
= x
+ cx
;
623 if (infoPtr
->rcBound
.bottom
< y
+ cy
)
624 infoPtr
->rcBound
.bottom
= y
+ cy
;
626 /* Set the toolTip only for non-hidden, non-separator button */
627 if (infoPtr
->hwndToolTip
&& !(btnPtr
->fsStyle
& TBSTYLE_SEP
))
631 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
632 ti
.cbSize
= sizeof(TTTOOLINFOA
);
634 ti
.uId
= btnPtr
->idCommand
;
635 ti
.rect
= btnPtr
->rect
;
636 SendMessageA (infoPtr
->hwndToolTip
, TTM_NEWTOOLRECTA
,
640 /* btnPtr->nRow is zero based. The space between the rows is */
641 /* also considered as a row. */
642 btnPtr
->nRow
= nRows
+ nSepRows
;
645 if ( !(btnPtr
->fsStyle
& TBSTYLE_SEP
) )
649 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
650 /* it is the actual width of the separator. This is used for */
651 /* custom controls in toolbars. */
652 y
+= cy
+ ( (btnPtr
->iBitmap
> 0 ) ?
653 btnPtr
->iBitmap
: SEPARATOR_WIDTH
) * 2 /3;
655 /* nSepRows is used to calculate the extra height follwoing */
659 x
= infoPtr
->nIndent
;
666 /* infoPtr->nRows is the number of rows on the toolbar */
667 infoPtr
->nRows
= nRows
+ nSepRows
+ 1;
669 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
671 infoPtr
->nHeight
= TOP_BORDER
+ (nRows
+ 1) * infoPtr
->nButtonHeight
+
672 nSepRows
* (SEPARATOR_WIDTH
* 2 / 3) +
673 nSepRows
* (infoPtr
->nBitmapHeight
+ 1) +
675 TRACE("toolbar height %d\n", infoPtr
->nHeight
);
680 TOOLBAR_InternalHitTest (HWND hwnd
, LPPOINT lpPt
)
682 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
683 TBUTTON_INFO
*btnPtr
;
686 btnPtr
= infoPtr
->buttons
;
687 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
688 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
691 if (btnPtr
->fsStyle
& TBSTYLE_SEP
) {
692 if (PtInRect (&btnPtr
->rect
, *lpPt
)) {
693 TRACE(" ON SEPARATOR %d!\n", i
);
698 if (PtInRect (&btnPtr
->rect
, *lpPt
)) {
699 TRACE(" ON BUTTON %d!\n", i
);
705 TRACE(" NOWHERE!\n");
711 TOOLBAR_GetButtonIndex (TOOLBAR_INFO
*infoPtr
, INT idCommand
)
713 TBUTTON_INFO
*btnPtr
;
716 btnPtr
= infoPtr
->buttons
;
717 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
718 if (btnPtr
->idCommand
== idCommand
) {
719 TRACE("command=%d index=%d\n", idCommand
, i
);
723 TRACE("no index found for command=%d\n", idCommand
);
729 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO
*infoPtr
, INT nIndex
)
731 TBUTTON_INFO
*btnPtr
;
734 if ((nIndex
< 0) || (nIndex
> infoPtr
->nNumButtons
))
737 /* check index button */
738 btnPtr
= &infoPtr
->buttons
[nIndex
];
739 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
740 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
744 /* check previous buttons */
745 nRunIndex
= nIndex
- 1;
746 while (nRunIndex
>= 0) {
747 btnPtr
= &infoPtr
->buttons
[nRunIndex
];
748 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
749 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
757 /* check next buttons */
758 nRunIndex
= nIndex
+ 1;
759 while (nRunIndex
< infoPtr
->nNumButtons
) {
760 btnPtr
= &infoPtr
->buttons
[nRunIndex
];
761 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
762 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
775 TOOLBAR_RelayEvent (HWND hwndTip
, HWND hwndMsg
, UINT uMsg
,
776 WPARAM wParam
, LPARAM lParam
)
784 msg
.time
= GetMessageTime ();
785 msg
.pt
.x
= LOWORD(GetMessagePos ());
786 msg
.pt
.y
= HIWORD(GetMessagePos ());
788 SendMessageA (hwndTip
, TTM_RELAYEVENT
, 0, (LPARAM
)&msg
);
792 /***********************************************************************
793 * TOOLBAR_CustomizeDialogProc
794 * This function implements the toolbar customization dialog.
797 TOOLBAR_CustomizeDialogProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
799 TOOLBAR_INFO
*infoPtr
= (TOOLBAR_INFO
*)GetWindowLongA (hwnd
, DWL_USER
);
800 static HDSA hDsa
= NULL
;
805 infoPtr
= (TOOLBAR_INFO
*)lParam
;
806 SetWindowLongA (hwnd
, DWL_USER
, (DWORD
)infoPtr
);
808 hDsa
= DSA_Create (sizeof(TBUTTON_INFO
), 5);
812 TBUTTON_INFO
*btnPtr
;
815 /* insert 'virtual' separator button into 'available buttons' list */
816 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_ADDSTRING
, 0, (LPARAM
)"");
818 /* copy all buttons and append them to the right listbox */
819 btnPtr
= infoPtr
->buttons
;
820 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++)
822 DSA_InsertItem (hDsa
, i
, btnPtr
);
824 /* FIXME: hidden buttons appear in the 'toolbar buttons' list too */
825 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
827 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_ADDSTRING
, 0, (LPARAM
)"");
831 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_ADDSTRING
, 0, (LPARAM
)"");
835 /* append 'virtual' separator button to the 'toolbar buttons' list */
841 EndDialog(hwnd
, FALSE
);
845 switch (LOWORD(wParam
))
848 EndDialog(hwnd
, FALSE
);
859 if (wParam
== IDC_AVAILBTN_LBOX
|| wParam
== IDC_TOOLBARBTN_LBOX
)
861 LPDRAWITEMSTRUCT lpdis
= (LPDRAWITEMSTRUCT
)lParam
;
867 COLORREF oldText
= 0;
870 FIXME("action: %x itemState: %x\n",
871 lpdis
->itemAction
, lpdis
->itemState
);
873 DSA_GetItem (hDsa
, 0 /*lpdis->itemID*/, &btnPtr
);
875 if (lpdis
->itemState
& ODS_FOCUS
)
877 oldBk
= SetBkColor (lpdis
->hDC
, GetSysColor(COLOR_HIGHLIGHT
));
878 oldText
= SetTextColor (lpdis
->hDC
, GetSysColor(COLOR_HIGHLIGHTTEXT
));
881 hOldPen
= SelectObject (lpdis
->hDC
, GetSysColorPen ((lpdis
->itemState
& ODS_SELECTED
)?COLOR_HIGHLIGHT
:COLOR_WINDOW
));
882 hOldBrush
= SelectObject (lpdis
->hDC
, GetSysColorBrush ((lpdis
->itemState
& ODS_FOCUS
)?COLOR_HIGHLIGHT
:COLOR_WINDOW
));
884 /* fill background rectangle */
885 Rectangle (lpdis
->hDC
, lpdis
->rcItem
.left
, lpdis
->rcItem
.top
,
886 lpdis
->rcItem
.right
, lpdis
->rcItem
.bottom
);
888 /* calculate button and text rectangles */
889 CopyRect (&rcButton
, &lpdis
->rcItem
);
890 InflateRect (&rcButton
, -1, -1);
891 CopyRect (&rcText
, &rcButton
);
892 rcButton
.right
= rcButton
.left
+ infoPtr
->nBitmapWidth
+ 6;
893 rcText
.left
= rcButton
.right
+ 2;
895 /* draw focus rectangle */
896 if (lpdis
->itemState
& ODS_FOCUS
)
897 DrawFocusRect (lpdis
->hDC
, &lpdis
->rcItem
);
900 DrawEdge (lpdis
->hDC
, &rcButton
, EDGE_RAISED
, BF_RECT
|BF_MIDDLE
|BF_SOFT
);
902 /* draw image and text */
903 if (wParam
== IDC_AVAILBTN_LBOX
&& lpdis
->itemID
== 0)
905 /* virtual separator in the 'available' list */
906 DrawTextA (lpdis
->hDC
, "Separator", -1, &rcText
,
907 DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
);
913 ImageList_Draw (infoPtr
->himlDef
, btnPtr
.iBitmap
, lpdis
->hDC
,
914 rcButton
.left
+1, rcButton
.top
+1, ILD_NORMAL
);
916 DrawTextW (lpdis
->hDC
, infoPtr
->strings
[btnPtr
.iString
], -1, &rcText
,
917 DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
);
921 if (lpdis
->itemState
& ODS_FOCUS
)
923 SetBkColor (lpdis
->hDC
, oldBk
);
924 SetTextColor (lpdis
->hDC
, oldText
);
927 SelectObject (lpdis
->hDC
, hOldBrush
);
928 SelectObject (lpdis
->hDC
, hOldPen
);
935 if (wParam
== IDC_AVAILBTN_LBOX
|| wParam
== IDC_TOOLBARBTN_LBOX
)
937 MEASUREITEMSTRUCT
*lpmis
= (MEASUREITEMSTRUCT
*)lParam
;
940 lpmis
->itemHeight
= infoPtr
->nBitmapHeight
+ 8;
942 lpmis
->itemHeight
= 15 + 8; /* default height */
954 /***********************************************************************
955 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
959 TOOLBAR_AddBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
961 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
962 LPTBADDBITMAP lpAddBmp
= (LPTBADDBITMAP
)lParam
;
963 INT nIndex
= 0, nButtons
;
969 if (lpAddBmp
->hInst
== HINST_COMMCTRL
)
971 if ((lpAddBmp
->nID
& ~1) == IDB_STD_SMALL_COLOR
)
973 else if ((lpAddBmp
->nID
& ~1) == IDB_VIEW_SMALL_COLOR
)
975 else if ((lpAddBmp
->nID
& ~1) == IDB_HIST_SMALL_COLOR
)
980 TRACE ("adding %d internal bitmaps!\n", nButtons
);
982 /* Windows resize all the buttons to the size of a newly added standard image */
983 if (lpAddBmp
->nID
& 1)
986 SendMessageA (hwnd
, TB_SETBITMAPSIZE
, 0,
987 MAKELPARAM((WORD
)26, (WORD
)26));
988 SendMessageA (hwnd
, TB_SETBUTTONSIZE
, 0,
989 MAKELPARAM((WORD
)33, (WORD
)33));
994 SendMessageA (hwnd
, TB_SETBITMAPSIZE
, 0,
995 MAKELPARAM((WORD
)16, (WORD
)16));
996 SendMessageA (hwnd
, TB_SETBUTTONSIZE
, 0,
997 MAKELPARAM((WORD
)22, (WORD
)22));
1000 TOOLBAR_CalcToolbar (hwnd
);
1004 nButtons
= (INT
)wParam
;
1008 TRACE ("adding %d bitmaps!\n", nButtons
);
1011 if (!(infoPtr
->himlDef
)) {
1012 /* create new default image list */
1013 TRACE ("creating default image list!\n");
1016 ImageList_Create (infoPtr
->nBitmapWidth
, infoPtr
->nBitmapHeight
,
1017 ILC_COLOR
| ILC_MASK
, nButtons
, 2);
1018 infoPtr
->himlInt
= infoPtr
->himlDef
;
1021 /* Add bitmaps to the default image list */
1022 if (lpAddBmp
->hInst
== (HINSTANCE
)0)
1025 ImageList_AddMasked (infoPtr
->himlDef
, (HBITMAP
)lpAddBmp
->nID
,
1028 else if (lpAddBmp
->hInst
== HINST_COMMCTRL
)
1030 /* Add system bitmaps */
1031 switch (lpAddBmp
->nID
)
1033 case IDB_STD_SMALL_COLOR
:
1034 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1035 MAKEINTRESOURCEA(IDB_STD_SMALL
));
1036 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1037 hbmLoad
, CLR_DEFAULT
);
1038 DeleteObject (hbmLoad
);
1041 case IDB_STD_LARGE_COLOR
:
1042 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1043 MAKEINTRESOURCEA(IDB_STD_LARGE
));
1044 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1045 hbmLoad
, CLR_DEFAULT
);
1046 DeleteObject (hbmLoad
);
1049 case IDB_VIEW_SMALL_COLOR
:
1050 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1051 MAKEINTRESOURCEA(IDB_VIEW_SMALL
));
1052 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1053 hbmLoad
, CLR_DEFAULT
);
1054 DeleteObject (hbmLoad
);
1057 case IDB_VIEW_LARGE_COLOR
:
1058 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1059 MAKEINTRESOURCEA(IDB_VIEW_LARGE
));
1060 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1061 hbmLoad
, CLR_DEFAULT
);
1062 DeleteObject (hbmLoad
);
1065 case IDB_HIST_SMALL_COLOR
:
1066 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1067 MAKEINTRESOURCEA(IDB_HIST_SMALL
));
1068 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1069 hbmLoad
, CLR_DEFAULT
);
1070 DeleteObject (hbmLoad
);
1073 case IDB_HIST_LARGE_COLOR
:
1074 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1075 MAKEINTRESOURCEA(IDB_HIST_LARGE
));
1076 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1077 hbmLoad
, CLR_DEFAULT
);
1078 DeleteObject (hbmLoad
);
1082 nIndex
= ImageList_GetImageCount (infoPtr
->himlDef
);
1083 ERR ("invalid imagelist!\n");
1089 hbmLoad
= LoadBitmapA (lpAddBmp
->hInst
, (LPSTR
)lpAddBmp
->nID
);
1090 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
, hbmLoad
, CLR_DEFAULT
);
1091 DeleteObject (hbmLoad
);
1094 infoPtr
->nNumBitmaps
+= nButtons
;
1101 TOOLBAR_AddButtonsA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1103 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1104 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
1105 INT nOldButtons
, nNewButtons
, nAddButtons
, nCount
;
1107 TRACE("adding %d buttons!\n", wParam
);
1109 nAddButtons
= (UINT
)wParam
;
1110 nOldButtons
= infoPtr
->nNumButtons
;
1111 nNewButtons
= nOldButtons
+ nAddButtons
;
1113 if (infoPtr
->nNumButtons
== 0) {
1115 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1118 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
1120 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1121 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
1122 nOldButtons
* sizeof(TBUTTON_INFO
));
1123 COMCTL32_Free (oldButtons
);
1126 infoPtr
->nNumButtons
= nNewButtons
;
1128 /* insert new button data */
1129 for (nCount
= 0; nCount
< nAddButtons
; nCount
++) {
1130 TBUTTON_INFO
*btnPtr
= &infoPtr
->buttons
[nOldButtons
+nCount
];
1131 btnPtr
->iBitmap
= lpTbb
[nCount
].iBitmap
;
1132 btnPtr
->idCommand
= lpTbb
[nCount
].idCommand
;
1133 btnPtr
->fsState
= lpTbb
[nCount
].fsState
;
1134 btnPtr
->fsStyle
= lpTbb
[nCount
].fsStyle
;
1135 btnPtr
->dwData
= lpTbb
[nCount
].dwData
;
1136 btnPtr
->iString
= lpTbb
[nCount
].iString
;
1137 btnPtr
->bHot
= FALSE
;
1139 if ((infoPtr
->hwndToolTip
) && !(btnPtr
->fsStyle
& TBSTYLE_SEP
)) {
1142 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
1143 ti
.cbSize
= sizeof (TTTOOLINFOA
);
1145 ti
.uId
= btnPtr
->idCommand
;
1147 ti
.lpszText
= LPSTR_TEXTCALLBACKA
;
1149 SendMessageA (infoPtr
->hwndToolTip
, TTM_ADDTOOLA
,
1154 TOOLBAR_CalcToolbar (hwnd
);
1156 InvalidateRect(hwnd
, NULL
, FALSE
);
1163 TOOLBAR_AddButtonsW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1165 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1166 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
1167 INT nOldButtons
, nNewButtons
, nAddButtons
, nCount
;
1169 TRACE("adding %d buttons!\n", wParam
);
1171 nAddButtons
= (UINT
)wParam
;
1172 nOldButtons
= infoPtr
->nNumButtons
;
1173 nNewButtons
= nOldButtons
+ nAddButtons
;
1175 if (infoPtr
->nNumButtons
== 0) {
1177 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1180 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
1182 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
1183 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
1184 nOldButtons
* sizeof(TBUTTON_INFO
));
1185 COMCTL32_Free (oldButtons
);
1188 infoPtr
->nNumButtons
= nNewButtons
;
1190 /* insert new button data */
1191 for (nCount
= 0; nCount
< nAddButtons
; nCount
++) {
1192 TBUTTON_INFO
*btnPtr
= &infoPtr
->buttons
[nOldButtons
+nCount
];
1193 btnPtr
->iBitmap
= lpTbb
[nCount
].iBitmap
;
1194 btnPtr
->idCommand
= lpTbb
[nCount
].idCommand
;
1195 btnPtr
->fsState
= lpTbb
[nCount
].fsState
;
1196 btnPtr
->fsStyle
= lpTbb
[nCount
].fsStyle
;
1197 btnPtr
->dwData
= lpTbb
[nCount
].dwData
;
1198 btnPtr
->iString
= lpTbb
[nCount
].iString
;
1199 btnPtr
->bHot
= FALSE
;
1201 if ((infoPtr
->hwndToolTip
) && !(btnPtr
->fsStyle
& TBSTYLE_SEP
)) {
1204 ZeroMemory (&ti
, sizeof(TTTOOLINFOW
));
1205 ti
.cbSize
= sizeof (TTTOOLINFOW
);
1207 ti
.uId
= btnPtr
->idCommand
;
1209 ti
.lpszText
= LPSTR_TEXTCALLBACKW
;
1211 SendMessageW (infoPtr
->hwndToolTip
, TTM_ADDTOOLW
,
1216 TOOLBAR_CalcToolbar (hwnd
);
1218 InvalidateRect(hwnd
, NULL
, FALSE
);
1225 TOOLBAR_AddStringA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1227 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1230 if ((wParam
) && (HIWORD(lParam
) == 0)) {
1233 TRACE("adding string from resource!\n");
1235 len
= LoadStringA ((HINSTANCE
)wParam
, (UINT
)lParam
,
1238 TRACE("len=%d \"%s\"\n", len
, szString
);
1239 nIndex
= infoPtr
->nNumStrings
;
1240 if (infoPtr
->nNumStrings
== 0) {
1242 COMCTL32_Alloc (sizeof(LPWSTR
));
1245 LPWSTR
*oldStrings
= infoPtr
->strings
;
1247 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1248 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1249 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1250 COMCTL32_Free (oldStrings
);
1253 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1254 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1255 lstrcpyAtoW (infoPtr
->strings
[infoPtr
->nNumStrings
], szString
);
1256 infoPtr
->nNumStrings
++;
1259 LPSTR p
= (LPSTR
)lParam
;
1264 TRACE("adding string(s) from array!\n");
1265 nIndex
= infoPtr
->nNumStrings
;
1268 TRACE("len=%d \"%s\"\n", len
, p
);
1270 if (infoPtr
->nNumStrings
== 0) {
1272 COMCTL32_Alloc (sizeof(LPWSTR
));
1275 LPWSTR
*oldStrings
= infoPtr
->strings
;
1277 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1278 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1279 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1280 COMCTL32_Free (oldStrings
);
1283 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1284 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1285 lstrcpyAtoW (infoPtr
->strings
[infoPtr
->nNumStrings
], p
);
1286 infoPtr
->nNumStrings
++;
1297 TOOLBAR_AddStringW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1299 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1302 if ((wParam
) && (HIWORD(lParam
) == 0)) {
1303 WCHAR szString
[256];
1305 TRACE("adding string from resource!\n");
1307 len
= LoadStringW ((HINSTANCE
)wParam
, (UINT
)lParam
,
1310 TRACE("len=%d \"%s\"\n", len
, debugstr_w(szString
));
1311 nIndex
= infoPtr
->nNumStrings
;
1312 if (infoPtr
->nNumStrings
== 0) {
1314 COMCTL32_Alloc (sizeof(LPWSTR
));
1317 LPWSTR
*oldStrings
= infoPtr
->strings
;
1319 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1320 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1321 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1322 COMCTL32_Free (oldStrings
);
1325 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1326 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1327 lstrcpyW (infoPtr
->strings
[infoPtr
->nNumStrings
], szString
);
1328 infoPtr
->nNumStrings
++;
1331 LPWSTR p
= (LPWSTR
)lParam
;
1336 TRACE("adding string(s) from array!\n");
1337 nIndex
= infoPtr
->nNumStrings
;
1340 TRACE("len=%d \"%s\"\n", len
, debugstr_w(p
));
1342 if (infoPtr
->nNumStrings
== 0) {
1344 COMCTL32_Alloc (sizeof(LPWSTR
));
1347 LPWSTR
*oldStrings
= infoPtr
->strings
;
1349 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
1350 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
1351 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
1352 COMCTL32_Free (oldStrings
);
1355 infoPtr
->strings
[infoPtr
->nNumStrings
] =
1356 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
1357 lstrcpyW (infoPtr
->strings
[infoPtr
->nNumStrings
], p
);
1358 infoPtr
->nNumStrings
++;
1369 TOOLBAR_AutoSize (HWND hwnd
)
1371 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1372 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1380 TRACE("resize forced!\n");
1382 parent
= GetParent (hwnd
);
1383 GetClientRect(parent
, &parent_rect
);
1385 x
= parent_rect
.left
;
1386 y
= parent_rect
.top
;
1388 if (dwStyle
& CCS_NORESIZE
) {
1389 uPosFlags
|= (SWP_NOSIZE
| SWP_NOMOVE
);
1394 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
1395 TOOLBAR_CalcToolbar (hwnd
);
1396 InvalidateRect( hwnd
, NULL
, TRUE
);
1397 cy
= infoPtr
->nHeight
;
1398 cx
= infoPtr
->nWidth
;
1400 if (dwStyle
& CCS_NOMOVEY
) {
1401 GetWindowRect(hwnd
, &window_rect
);
1402 ScreenToClient(parent
, (LPPOINT
)&window_rect
.left
);
1403 y
= window_rect
.top
;
1407 if (dwStyle
& CCS_NOPARENTALIGN
)
1408 uPosFlags
|= SWP_NOMOVE
;
1410 if (!(dwStyle
& CCS_NODIVIDER
))
1411 cy
+= GetSystemMetrics(SM_CYEDGE
);
1413 if (dwStyle
& WS_BORDER
)
1416 cy
+= GetSystemMetrics(SM_CYEDGE
);
1417 cx
+= GetSystemMetrics(SM_CYEDGE
);
1420 infoPtr
->bAutoSize
= TRUE
;
1421 SetWindowPos (hwnd
, HWND_TOP
, parent_rect
.left
- x
, parent_rect
.top
- y
,
1423 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
1424 * the setwindowpos calls */
1425 infoPtr
->bAutoSize
= FALSE
;
1432 TOOLBAR_ButtonCount (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1434 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1436 return infoPtr
->nNumButtons
;
1441 TOOLBAR_ButtonStructSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1443 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1445 if (infoPtr
== NULL
) {
1446 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd
, wParam
, lParam
);
1447 ERR("infoPtr == NULL!\n");
1451 infoPtr
->dwStructSize
= (DWORD
)wParam
;
1458 TOOLBAR_ChangeBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1460 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1461 TBUTTON_INFO
*btnPtr
;
1464 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1468 btnPtr
= &infoPtr
->buttons
[nIndex
];
1469 btnPtr
->iBitmap
= LOWORD(lParam
);
1471 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,RDW_ERASE
|RDW_INVALIDATE
);
1478 TOOLBAR_CheckButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1480 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1481 TBUTTON_INFO
*btnPtr
;
1484 BOOL bChecked
= FALSE
;
1486 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1490 btnPtr
= &infoPtr
->buttons
[nIndex
];
1492 if (!(btnPtr
->fsStyle
& TBSTYLE_CHECK
))
1495 bChecked
= (btnPtr
->fsState
& TBSTATE_CHECKED
) ? TRUE
: FALSE
;
1497 if (LOWORD(lParam
) == FALSE
)
1498 btnPtr
->fsState
&= ~TBSTATE_CHECKED
;
1500 if (btnPtr
->fsStyle
& TBSTYLE_GROUP
) {
1502 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr
, nIndex
);
1503 if (nOldIndex
== nIndex
)
1505 if (nOldIndex
!= -1)
1506 infoPtr
->buttons
[nOldIndex
].fsState
&= ~TBSTATE_CHECKED
;
1508 btnPtr
->fsState
|= TBSTATE_CHECKED
;
1511 if( bChecked
!= LOWORD(lParam
) )
1513 if (nOldIndex
!= -1)
1514 RedrawWindow(hwnd
,&infoPtr
->buttons
[nOldIndex
].rect
,NULL
,
1515 RDW_ERASE
|RDW_INVALIDATE
);
1516 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
1519 /* FIXME: Send a WM_NOTIFY?? */
1526 TOOLBAR_CommandToIndex (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1528 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1530 return TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1535 TOOLBAR_Customize (HWND hwnd
)
1537 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1543 /* send TBN_BEGINADJUST notification */
1544 nmhdr
.hwndFrom
= hwnd
;
1545 nmhdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
1546 nmhdr
.code
= TBN_BEGINADJUST
;
1548 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
1549 (WPARAM
)nmhdr
.idFrom
, (LPARAM
)&nmhdr
);
1551 if (!(hRes
= FindResourceA (COMCTL32_hModule
,
1552 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE
),
1556 if(!(template = (LPVOID
)LoadResource (COMCTL32_hModule
, hRes
)))
1559 ret
= DialogBoxIndirectParamA (GetWindowLongA (hwnd
, GWL_HINSTANCE
),
1560 (LPDLGTEMPLATEA
)template,
1562 (DLGPROC
)TOOLBAR_CustomizeDialogProc
,
1565 /* send TBN_ENDADJUST notification */
1566 nmhdr
.code
= TBN_ENDADJUST
;
1568 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
1569 (WPARAM
)nmhdr
.idFrom
, (LPARAM
)&nmhdr
);
1576 TOOLBAR_DeleteButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1578 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1579 INT nIndex
= (INT
)wParam
;
1581 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
1584 if ((infoPtr
->hwndToolTip
) &&
1585 !(infoPtr
->buttons
[nIndex
].fsStyle
& TBSTYLE_SEP
)) {
1588 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
1589 ti
.cbSize
= sizeof (TTTOOLINFOA
);
1591 ti
.uId
= infoPtr
->buttons
[nIndex
].idCommand
;
1593 SendMessageA (infoPtr
->hwndToolTip
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
1596 if (infoPtr
->nNumButtons
== 1) {
1597 TRACE(" simple delete!\n");
1598 COMCTL32_Free (infoPtr
->buttons
);
1599 infoPtr
->buttons
= NULL
;
1600 infoPtr
->nNumButtons
= 0;
1603 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
1604 TRACE("complex delete! [nIndex=%d]\n", nIndex
);
1606 infoPtr
->nNumButtons
--;
1607 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
1609 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
1610 nIndex
* sizeof(TBUTTON_INFO
));
1613 if (nIndex
< infoPtr
->nNumButtons
) {
1614 memcpy (&infoPtr
->buttons
[nIndex
], &oldButtons
[nIndex
+1],
1615 (infoPtr
->nNumButtons
- nIndex
) * sizeof(TBUTTON_INFO
));
1618 COMCTL32_Free (oldButtons
);
1621 TOOLBAR_CalcToolbar (hwnd
);
1623 InvalidateRect (hwnd
, NULL
, TRUE
);
1630 TOOLBAR_EnableButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1632 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1633 TBUTTON_INFO
*btnPtr
;
1637 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1641 btnPtr
= &infoPtr
->buttons
[nIndex
];
1643 bState
= btnPtr
->fsState
& TBSTATE_ENABLED
;
1645 /* update the toolbar button state */
1646 if(LOWORD(lParam
) == FALSE
) {
1647 btnPtr
->fsState
&= ~(TBSTATE_ENABLED
| TBSTATE_PRESSED
);
1649 btnPtr
->fsState
|= TBSTATE_ENABLED
;
1652 /* redraw the button only if the state of the button changed */
1653 if(bState
!= (btnPtr
->fsState
& TBSTATE_ENABLED
)) {
1654 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
1661 static inline LRESULT
1662 TOOLBAR_GetAnchorHighlight (HWND hwnd
)
1664 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1666 return infoPtr
->bAnchor
;
1671 TOOLBAR_GetBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1673 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1676 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1680 return infoPtr
->buttons
[nIndex
].iBitmap
;
1684 static inline LRESULT
1685 TOOLBAR_GetBitmapFlags (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1687 return (GetDeviceCaps (0, LOGPIXELSX
) >= 120) ? TBBF_LARGE
: 0;
1692 TOOLBAR_GetButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1694 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1695 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
1696 INT nIndex
= (INT
)wParam
;
1697 TBUTTON_INFO
*btnPtr
;
1699 if (infoPtr
== NULL
)
1705 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
1708 btnPtr
= &infoPtr
->buttons
[nIndex
];
1709 lpTbb
->iBitmap
= btnPtr
->iBitmap
;
1710 lpTbb
->idCommand
= btnPtr
->idCommand
;
1711 lpTbb
->fsState
= btnPtr
->fsState
;
1712 lpTbb
->fsStyle
= btnPtr
->fsStyle
;
1713 lpTbb
->dwData
= btnPtr
->dwData
;
1714 lpTbb
->iString
= btnPtr
->iString
;
1721 TOOLBAR_GetButtonInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1723 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1724 LPTBBUTTONINFOA lpTbInfo
= (LPTBBUTTONINFOA
)lParam
;
1725 TBUTTON_INFO
*btnPtr
;
1728 if (infoPtr
== NULL
)
1730 if (lpTbInfo
== NULL
)
1732 if (lpTbInfo
->cbSize
< sizeof(TBBUTTONINFOA
))
1735 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1739 btnPtr
= &infoPtr
->buttons
[nIndex
];
1741 if (lpTbInfo
->dwMask
& TBIF_COMMAND
)
1742 lpTbInfo
->idCommand
= btnPtr
->idCommand
;
1743 if (lpTbInfo
->dwMask
& TBIF_IMAGE
)
1744 lpTbInfo
->iImage
= btnPtr
->iBitmap
;
1745 if (lpTbInfo
->dwMask
& TBIF_LPARAM
)
1746 lpTbInfo
->lParam
= btnPtr
->dwData
;
1747 if (lpTbInfo
->dwMask
& TBIF_SIZE
)
1748 lpTbInfo
->cx
= (WORD
)(btnPtr
->rect
.right
- btnPtr
->rect
.left
);
1749 if (lpTbInfo
->dwMask
& TBIF_STATE
)
1750 lpTbInfo
->fsState
= btnPtr
->fsState
;
1751 if (lpTbInfo
->dwMask
& TBIF_STYLE
)
1752 lpTbInfo
->fsStyle
= btnPtr
->fsStyle
;
1753 if (lpTbInfo
->dwMask
& TBIF_TEXT
) {
1754 if ((btnPtr
->iString
>= 0) || (btnPtr
->iString
< infoPtr
->nNumStrings
))
1755 lstrcpynWtoA (lpTbInfo
->pszText
,
1756 (LPWSTR
)infoPtr
->strings
[btnPtr
->iString
],
1765 TOOLBAR_GetButtonInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1767 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1768 LPTBBUTTONINFOW lpTbInfo
= (LPTBBUTTONINFOW
)lParam
;
1769 TBUTTON_INFO
*btnPtr
;
1772 if (infoPtr
== NULL
)
1774 if (lpTbInfo
== NULL
)
1776 if (lpTbInfo
->cbSize
< sizeof(TBBUTTONINFOW
))
1779 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1783 btnPtr
= &infoPtr
->buttons
[nIndex
];
1785 if (lpTbInfo
->dwMask
& TBIF_COMMAND
)
1786 lpTbInfo
->idCommand
= btnPtr
->idCommand
;
1787 if (lpTbInfo
->dwMask
& TBIF_IMAGE
)
1788 lpTbInfo
->iImage
= btnPtr
->iBitmap
;
1789 if (lpTbInfo
->dwMask
& TBIF_LPARAM
)
1790 lpTbInfo
->lParam
= btnPtr
->dwData
;
1791 if (lpTbInfo
->dwMask
& TBIF_SIZE
)
1792 lpTbInfo
->cx
= (WORD
)(btnPtr
->rect
.right
- btnPtr
->rect
.left
);
1793 if (lpTbInfo
->dwMask
& TBIF_STATE
)
1794 lpTbInfo
->fsState
= btnPtr
->fsState
;
1795 if (lpTbInfo
->dwMask
& TBIF_STYLE
)
1796 lpTbInfo
->fsStyle
= btnPtr
->fsStyle
;
1797 if (lpTbInfo
->dwMask
& TBIF_TEXT
) {
1798 if ((btnPtr
->iString
>= 0) || (btnPtr
->iString
< infoPtr
->nNumStrings
))
1799 lstrcpynW (lpTbInfo
->pszText
,
1800 (LPWSTR
)infoPtr
->strings
[btnPtr
->iString
],
1809 TOOLBAR_GetButtonSize (HWND hwnd
)
1811 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1813 return MAKELONG((WORD
)infoPtr
->nButtonWidth
,
1814 (WORD
)infoPtr
->nButtonHeight
);
1819 TOOLBAR_GetButtonTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1821 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1822 INT nIndex
, nStringIndex
;
1824 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1828 nStringIndex
= infoPtr
->buttons
[nIndex
].iString
;
1830 TRACE("index=%d stringIndex=%d\n", nIndex
, nStringIndex
);
1832 if ((nStringIndex
< 0) || (nStringIndex
>= infoPtr
->nNumStrings
))
1838 lstrcpyWtoA ((LPSTR
)lParam
, (LPWSTR
)infoPtr
->strings
[nStringIndex
]);
1840 return lstrlenW ((LPWSTR
)infoPtr
->strings
[nStringIndex
]);
1845 TOOLBAR_GetButtonTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1847 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1848 INT nIndex
, nStringIndex
;
1850 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
1854 nStringIndex
= infoPtr
->buttons
[nIndex
].iString
;
1856 TRACE("index=%d stringIndex=%d\n", nIndex
, nStringIndex
);
1858 if ((nStringIndex
< 0) || (nStringIndex
>= infoPtr
->nNumStrings
))
1864 lstrcpyW ((LPWSTR
)lParam
, (LPWSTR
)infoPtr
->strings
[nStringIndex
]);
1866 return lstrlenW ((LPWSTR
)infoPtr
->strings
[nStringIndex
]);
1870 /* << TOOLBAR_GetColorScheme >> */
1874 TOOLBAR_GetDisabledImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1876 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1878 return (LRESULT
)infoPtr
->himlDis
;
1882 inline static LRESULT
1883 TOOLBAR_GetExtendedStyle (HWND hwnd
)
1885 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1887 return infoPtr
->dwExStyle
;
1892 TOOLBAR_GetHotImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1894 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1896 return (LRESULT
)infoPtr
->himlHot
;
1901 TOOLBAR_GetHotItem (HWND hwnd
)
1903 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1905 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_FLAT
))
1908 if (infoPtr
->nHotItem
< 0)
1911 return (LRESULT
)infoPtr
->nHotItem
;
1916 TOOLBAR_GetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1918 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1920 return (LRESULT
)infoPtr
->himlDef
;
1924 /* << TOOLBAR_GetInsertMark >> */
1925 /* << TOOLBAR_GetInsertMarkColor >> */
1929 TOOLBAR_GetItemRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1931 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1932 TBUTTON_INFO
*btnPtr
;
1936 if (infoPtr
== NULL
)
1938 nIndex
= (INT
)wParam
;
1939 btnPtr
= &infoPtr
->buttons
[nIndex
];
1940 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
1942 lpRect
= (LPRECT
)lParam
;
1945 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
1948 TOOLBAR_CalcToolbar( hwnd
);
1950 lpRect
->left
= btnPtr
->rect
.left
;
1951 lpRect
->right
= btnPtr
->rect
.right
;
1952 lpRect
->bottom
= btnPtr
->rect
.bottom
;
1953 lpRect
->top
= btnPtr
->rect
.top
;
1960 TOOLBAR_GetMaxSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1962 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1963 LPSIZE lpSize
= (LPSIZE
)lParam
;
1968 lpSize
->cx
= infoPtr
->rcBound
.right
- infoPtr
->rcBound
.left
;
1969 lpSize
->cy
= infoPtr
->rcBound
.bottom
- infoPtr
->rcBound
.top
;
1971 TRACE("maximum size %d x %d\n",
1972 infoPtr
->rcBound
.right
- infoPtr
->rcBound
.left
,
1973 infoPtr
->rcBound
.bottom
- infoPtr
->rcBound
.top
);
1979 /* << TOOLBAR_GetObject >> */
1980 /* << TOOLBAR_GetPadding >> */
1984 TOOLBAR_GetRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1986 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1987 TBUTTON_INFO
*btnPtr
;
1991 if (infoPtr
== NULL
)
1993 nIndex
= (INT
)wParam
;
1994 btnPtr
= &infoPtr
->buttons
[nIndex
];
1995 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
1997 lpRect
= (LPRECT
)lParam
;
2001 lpRect
->left
= btnPtr
->rect
.left
;
2002 lpRect
->right
= btnPtr
->rect
.right
;
2003 lpRect
->bottom
= btnPtr
->rect
.bottom
;
2004 lpRect
->top
= btnPtr
->rect
.top
;
2011 TOOLBAR_GetRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2013 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2015 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_WRAPABLE
)
2016 return infoPtr
->nRows
;
2023 TOOLBAR_GetState (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2025 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2028 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2032 return infoPtr
->buttons
[nIndex
].fsState
;
2037 TOOLBAR_GetStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2039 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2042 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2046 return infoPtr
->buttons
[nIndex
].fsStyle
;
2051 TOOLBAR_GetTextRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2053 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2055 if (infoPtr
== NULL
)
2058 return infoPtr
->nMaxTextRows
;
2063 TOOLBAR_GetToolTips (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2065 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2067 if (infoPtr
== NULL
)
2069 return infoPtr
->hwndToolTip
;
2074 TOOLBAR_GetUnicodeFormat (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2076 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2078 TRACE("%s hwnd=0x%x stub!\n",
2079 infoPtr
->bUnicode
? "TRUE" : "FALSE", hwnd
);
2081 return infoPtr
->bUnicode
;
2085 inline static LRESULT
2086 TOOLBAR_GetVersion (HWND hwnd
)
2088 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2089 return infoPtr
->iVersion
;
2094 TOOLBAR_HideButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2096 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2097 TBUTTON_INFO
*btnPtr
;
2100 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2104 btnPtr
= &infoPtr
->buttons
[nIndex
];
2105 if (LOWORD(lParam
) == FALSE
)
2106 btnPtr
->fsState
&= ~TBSTATE_HIDDEN
;
2108 btnPtr
->fsState
|= TBSTATE_HIDDEN
;
2110 TOOLBAR_CalcToolbar (hwnd
);
2112 InvalidateRect (hwnd
, NULL
, TRUE
);
2118 inline static LRESULT
2119 TOOLBAR_HitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2121 return TOOLBAR_InternalHitTest (hwnd
, (LPPOINT
)lParam
);
2126 TOOLBAR_Indeterminate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2128 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2129 TBUTTON_INFO
*btnPtr
;
2132 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2136 btnPtr
= &infoPtr
->buttons
[nIndex
];
2137 if (LOWORD(lParam
) == FALSE
)
2138 btnPtr
->fsState
&= ~TBSTATE_INDETERMINATE
;
2140 btnPtr
->fsState
|= TBSTATE_INDETERMINATE
;
2142 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
2143 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
2150 TOOLBAR_InsertButtonA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2152 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2153 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
2154 INT nIndex
= (INT
)wParam
;
2155 TBUTTON_INFO
*oldButtons
;
2161 /* EPP: this seems to be an undocumented call (from my IE4)
2162 * I assume in that case that:
2163 * - lpTbb->iString is a string pointer (not a string index in strings[] table
2164 * - index of insertion is at the end of existing buttons
2165 * I only see this happen with nIndex == -1, but it could have a special
2166 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
2168 int len
= lstrlenA((char*)lpTbb
->iString
) + 2;
2169 LPSTR ptr
= COMCTL32_Alloc(len
);
2171 nIndex
= infoPtr
->nNumButtons
;
2172 strcpy(ptr
, (char*)lpTbb
->iString
);
2173 ptr
[len
- 1] = 0; /* ended by two '\0' */
2174 lpTbb
->iString
= TOOLBAR_AddStringA(hwnd
, 0, (LPARAM
)ptr
);
2177 } else if (nIndex
< 0)
2180 TRACE("inserting button index=%d\n", nIndex
);
2181 if (nIndex
> infoPtr
->nNumButtons
) {
2182 nIndex
= infoPtr
->nNumButtons
;
2183 TRACE("adjust index=%d\n", nIndex
);
2186 oldButtons
= infoPtr
->buttons
;
2187 infoPtr
->nNumButtons
++;
2188 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
2189 /* pre insert copy */
2191 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
2192 nIndex
* sizeof(TBUTTON_INFO
));
2195 /* insert new button */
2196 infoPtr
->buttons
[nIndex
].iBitmap
= lpTbb
->iBitmap
;
2197 infoPtr
->buttons
[nIndex
].idCommand
= lpTbb
->idCommand
;
2198 infoPtr
->buttons
[nIndex
].fsState
= lpTbb
->fsState
;
2199 infoPtr
->buttons
[nIndex
].fsStyle
= lpTbb
->fsStyle
;
2200 infoPtr
->buttons
[nIndex
].dwData
= lpTbb
->dwData
;
2201 infoPtr
->buttons
[nIndex
].iString
= lpTbb
->iString
;
2203 if ((infoPtr
->hwndToolTip
) && !(lpTbb
->fsStyle
& TBSTYLE_SEP
)) {
2206 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
2207 ti
.cbSize
= sizeof (TTTOOLINFOA
);
2209 ti
.uId
= lpTbb
->idCommand
;
2211 ti
.lpszText
= LPSTR_TEXTCALLBACKA
;
2213 SendMessageA (infoPtr
->hwndToolTip
, TTM_ADDTOOLA
,
2217 /* post insert copy */
2218 if (nIndex
< infoPtr
->nNumButtons
- 1) {
2219 memcpy (&infoPtr
->buttons
[nIndex
+1], &oldButtons
[nIndex
],
2220 (infoPtr
->nNumButtons
- nIndex
- 1) * sizeof(TBUTTON_INFO
));
2223 COMCTL32_Free (oldButtons
);
2225 TOOLBAR_CalcToolbar (hwnd
);
2227 InvalidateRect (hwnd
, NULL
, FALSE
);
2234 TOOLBAR_InsertButtonW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2236 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2237 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
2238 INT nIndex
= (INT
)wParam
;
2239 TBUTTON_INFO
*oldButtons
;
2246 TRACE("inserting button index=%d\n", nIndex
);
2247 if (nIndex
> infoPtr
->nNumButtons
) {
2248 nIndex
= infoPtr
->nNumButtons
;
2249 TRACE("adjust index=%d\n", nIndex
);
2252 oldButtons
= infoPtr
->buttons
;
2253 infoPtr
->nNumButtons
++;
2254 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
2255 /* pre insert copy */
2257 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
2258 nIndex
* sizeof(TBUTTON_INFO
));
2261 /* insert new button */
2262 infoPtr
->buttons
[nIndex
].iBitmap
= lpTbb
->iBitmap
;
2263 infoPtr
->buttons
[nIndex
].idCommand
= lpTbb
->idCommand
;
2264 infoPtr
->buttons
[nIndex
].fsState
= lpTbb
->fsState
;
2265 infoPtr
->buttons
[nIndex
].fsStyle
= lpTbb
->fsStyle
;
2266 infoPtr
->buttons
[nIndex
].dwData
= lpTbb
->dwData
;
2267 infoPtr
->buttons
[nIndex
].iString
= lpTbb
->iString
;
2269 if ((infoPtr
->hwndToolTip
) && !(lpTbb
->fsStyle
& TBSTYLE_SEP
)) {
2272 ZeroMemory (&ti
, sizeof(TTTOOLINFOW
));
2273 ti
.cbSize
= sizeof (TTTOOLINFOW
);
2275 ti
.uId
= lpTbb
->idCommand
;
2277 ti
.lpszText
= LPSTR_TEXTCALLBACKW
;
2279 SendMessageW (infoPtr
->hwndToolTip
, TTM_ADDTOOLW
,
2283 /* post insert copy */
2284 if (nIndex
< infoPtr
->nNumButtons
- 1) {
2285 memcpy (&infoPtr
->buttons
[nIndex
+1], &oldButtons
[nIndex
],
2286 (infoPtr
->nNumButtons
- nIndex
- 1) * sizeof(TBUTTON_INFO
));
2289 COMCTL32_Free (oldButtons
);
2291 TOOLBAR_CalcToolbar (hwnd
);
2293 InvalidateRect (hwnd
, NULL
, FALSE
);
2299 /* << TOOLBAR_InsertMarkHitTest >> */
2303 TOOLBAR_IsButtonChecked (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2305 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2308 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2312 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_CHECKED
);
2317 TOOLBAR_IsButtonEnabled (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2319 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2322 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2326 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_ENABLED
);
2331 TOOLBAR_IsButtonHidden (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2333 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2336 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2340 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_HIDDEN
);
2345 TOOLBAR_IsButtonHighlighted (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2347 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2350 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2354 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_MARKED
);
2359 TOOLBAR_IsButtonIndeterminate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2361 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2364 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2368 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_INDETERMINATE
);
2373 TOOLBAR_IsButtonPressed (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2375 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2378 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2382 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_PRESSED
);
2386 /* << TOOLBAR_LoadImages >> */
2387 /* << TOOLBAR_MapAccelerator >> */
2388 /* << TOOLBAR_MarkButton >> */
2389 /* << TOOLBAR_MoveButton >> */
2393 TOOLBAR_PressButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2395 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2396 TBUTTON_INFO
*btnPtr
;
2399 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2403 btnPtr
= &infoPtr
->buttons
[nIndex
];
2404 if (LOWORD(lParam
) == FALSE
)
2405 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
2407 btnPtr
->fsState
|= TBSTATE_PRESSED
;
2409 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
2410 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
2416 /* << TOOLBAR_ReplaceBitmap >> */
2420 TOOLBAR_SaveRestoreA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2423 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2424 LPTBSAVEPARAMSA lpSave
= (LPTBSAVEPARAMSA
)lParam
;
2426 if (lpSave
== NULL
) return 0;
2429 /* save toolbar information */
2430 FIXME("save to \"%s\" \"%s\"\n",
2431 lpSave
->pszSubKey
, lpSave
->pszValueName
);
2436 /* restore toolbar information */
2438 FIXME("restore from \"%s\" \"%s\"\n",
2439 lpSave
->pszSubKey
, lpSave
->pszValueName
);
2450 TOOLBAR_SaveRestoreW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2453 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2454 LPTBSAVEPARAMSW lpSave
= (LPTBSAVEPARAMSW
)lParam
;
2460 /* save toolbar information */
2461 FIXME("save to \"%s\" \"%s\"\n",
2462 lpSave
->pszSubKey
, lpSave
->pszValueName
);
2467 /* restore toolbar information */
2469 FIXME("restore from \"%s\" \"%s\"\n",
2470 lpSave
->pszSubKey
, lpSave
->pszValueName
);
2481 TOOLBAR_SetAnchorHighlight (HWND hwnd
, WPARAM wParam
)
2483 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2484 BOOL bOldAnchor
= infoPtr
->bAnchor
;
2486 infoPtr
->bAnchor
= (BOOL
)wParam
;
2488 return (LRESULT
)bOldAnchor
;
2493 TOOLBAR_SetBitmapSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2495 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2497 if ((LOWORD(lParam
) <= 0) || (HIWORD(lParam
)<=0))
2500 /* Bitmap size can only be set before adding any button to the toolbar
2501 according to the documentation. */
2502 if( infoPtr
->nNumButtons
!= 0 )
2505 infoPtr
->nBitmapWidth
= (INT
)LOWORD(lParam
);
2506 infoPtr
->nBitmapHeight
= (INT
)HIWORD(lParam
);
2513 TOOLBAR_SetButtonInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2515 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2516 LPTBBUTTONINFOA lptbbi
= (LPTBBUTTONINFOA
)lParam
;
2517 TBUTTON_INFO
*btnPtr
;
2522 if (lptbbi
->cbSize
< sizeof(TBBUTTONINFOA
))
2525 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2529 btnPtr
= &infoPtr
->buttons
[nIndex
];
2530 if (lptbbi
->dwMask
& TBIF_COMMAND
)
2531 btnPtr
->idCommand
= lptbbi
->idCommand
;
2532 if (lptbbi
->dwMask
& TBIF_IMAGE
)
2533 btnPtr
->iBitmap
= lptbbi
->iImage
;
2534 if (lptbbi
->dwMask
& TBIF_LPARAM
)
2535 btnPtr
->dwData
= lptbbi
->lParam
;
2536 /* if (lptbbi->dwMask & TBIF_SIZE) */
2537 /* btnPtr->cx = lptbbi->cx; */
2538 if (lptbbi
->dwMask
& TBIF_STATE
)
2539 btnPtr
->fsState
= lptbbi
->fsState
;
2540 if (lptbbi
->dwMask
& TBIF_STYLE
)
2541 btnPtr
->fsStyle
= lptbbi
->fsStyle
;
2543 if (lptbbi
->dwMask
& TBIF_TEXT
) {
2544 if ((btnPtr
->iString
>= 0) ||
2545 (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
2546 TRACE("Ooooooch\n");
2548 WCHAR
**lpString
= &infoPtr
->strings
[btnPtr
->iString
];
2549 INT len
= lstrlenA (lptbbi
->pszText
);
2550 *lpString
= COMCTL32_ReAlloc (lpString
, sizeof(WCHAR
)*(len
+1));
2553 /* this is the ultimate sollution */
2554 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2563 TOOLBAR_SetButtonInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2565 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2566 LPTBBUTTONINFOW lptbbi
= (LPTBBUTTONINFOW
)lParam
;
2567 TBUTTON_INFO
*btnPtr
;
2572 if (lptbbi
->cbSize
< sizeof(TBBUTTONINFOW
))
2575 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2579 btnPtr
= &infoPtr
->buttons
[nIndex
];
2580 if (lptbbi
->dwMask
& TBIF_COMMAND
)
2581 btnPtr
->idCommand
= lptbbi
->idCommand
;
2582 if (lptbbi
->dwMask
& TBIF_IMAGE
)
2583 btnPtr
->iBitmap
= lptbbi
->iImage
;
2584 if (lptbbi
->dwMask
& TBIF_LPARAM
)
2585 btnPtr
->dwData
= lptbbi
->lParam
;
2586 /* if (lptbbi->dwMask & TBIF_SIZE) */
2587 /* btnPtr->cx = lptbbi->cx; */
2588 if (lptbbi
->dwMask
& TBIF_STATE
)
2589 btnPtr
->fsState
= lptbbi
->fsState
;
2590 if (lptbbi
->dwMask
& TBIF_STYLE
)
2591 btnPtr
->fsStyle
= lptbbi
->fsStyle
;
2593 if (lptbbi
->dwMask
& TBIF_TEXT
) {
2594 if ((btnPtr
->iString
>= 0) ||
2595 (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
2597 WCHAR
**lpString
= &infoPtr
->strings
[btnPtr
->iString
];
2598 INT len
= lstrlenW (lptbbi
->pszText
);
2599 *lpString
= COMCTL32_ReAlloc (lpString
, sizeof(WCHAR
)*(len
+1));
2602 /* this is the ultimate sollution */
2603 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2612 TOOLBAR_SetButtonSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2614 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2616 if ((LOWORD(lParam
) <= 0) || (HIWORD(lParam
)<=0))
2619 /* Button size can only be set before adding any button to the toolbar
2620 according to the documentation. */
2621 if( infoPtr
->nNumButtons
!= 0 )
2624 infoPtr
->nButtonWidth
= (INT
)LOWORD(lParam
);
2625 infoPtr
->nButtonHeight
= (INT
)HIWORD(lParam
);
2631 TOOLBAR_SetButtonWidth (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2633 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2635 if (infoPtr
== NULL
)
2638 infoPtr
->cxMin
= (INT
)LOWORD(lParam
);
2639 infoPtr
->cxMax
= (INT
)HIWORD(lParam
);
2646 TOOLBAR_SetCmdId (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2648 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2649 INT nIndex
= (INT
)wParam
;
2651 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
2654 infoPtr
->buttons
[nIndex
].idCommand
= (INT
)lParam
;
2656 if (infoPtr
->hwndToolTip
) {
2658 FIXME("change tool tip!\n");
2666 /* << TOOLBAR_SetColorScheme >> */
2670 TOOLBAR_SetDisabledImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2672 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2673 HIMAGELIST himlTemp
;
2676 himlTemp
= infoPtr
->himlDis
;
2677 infoPtr
->himlDis
= (HIMAGELIST
)lParam
;
2679 /* FIXME: redraw ? */
2681 return (LRESULT
)himlTemp
;
2686 TOOLBAR_SetDrawTextFlags (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2688 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2691 dwTemp
= infoPtr
->dwDTFlags
;
2692 infoPtr
->dwDTFlags
=
2693 (infoPtr
->dwDTFlags
& (DWORD
)wParam
) | (DWORD
)lParam
;
2695 return (LRESULT
)dwTemp
;
2700 TOOLBAR_SetExtendedStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2702 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2705 dwTemp
= infoPtr
->dwExStyle
;
2706 infoPtr
->dwExStyle
= (DWORD
)lParam
;
2708 return (LRESULT
)dwTemp
;
2713 TOOLBAR_SetHotImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2715 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
2716 HIMAGELIST himlTemp
;
2718 himlTemp
= infoPtr
->himlHot
;
2719 infoPtr
->himlHot
= (HIMAGELIST
)lParam
;
2721 /* FIXME: redraw ? */
2723 return (LRESULT
)himlTemp
;
2728 TOOLBAR_SetHotItem (HWND hwnd
, WPARAM wParam
)
2730 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
2731 INT nOldHotItem
= infoPtr
->nHotItem
;
2733 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_FLAT
)
2735 infoPtr
->nHotItem
= (INT
)wParam
;
2737 /* FIXME: What else must be done ??? */
2741 if (nOldHotItem
< 0)
2744 return (LRESULT
)nOldHotItem
;
2749 TOOLBAR_SetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2751 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2752 HIMAGELIST himlTemp
;
2754 himlTemp
= infoPtr
->himlDef
;
2755 infoPtr
->himlDef
= (HIMAGELIST
)lParam
;
2757 /* FIXME: redraw ? */
2759 return (LRESULT
)himlTemp
;
2764 TOOLBAR_SetIndent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2766 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2768 infoPtr
->nIndent
= (INT
)wParam
;
2770 TOOLBAR_CalcToolbar (hwnd
);
2772 InvalidateRect(hwnd
, NULL
, FALSE
);
2778 /* << TOOLBAR_SetInsertMark >> */
2782 TOOLBAR_SetInsertMarkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2784 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2786 infoPtr
->clrInsertMark
= (COLORREF
)lParam
;
2788 /* FIXME : redraw ??*/
2795 TOOLBAR_SetMaxTextRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2797 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2799 if (infoPtr
== NULL
)
2802 infoPtr
->nMaxTextRows
= (INT
)wParam
;
2808 /* << TOOLBAR_SetPadding >> */
2812 TOOLBAR_SetParent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2814 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2817 if (infoPtr
== NULL
)
2819 hwndOldNotify
= infoPtr
->hwndNotify
;
2820 infoPtr
->hwndNotify
= (HWND
)wParam
;
2822 return hwndOldNotify
;
2827 TOOLBAR_SetRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2829 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2830 LPRECT lprc
= (LPRECT
)lParam
;
2832 if (LOWORD(wParam
) > 1) {
2834 FIXME("multiple rows not supported!\n");
2838 /* recalculate toolbar */
2839 TOOLBAR_CalcToolbar (hwnd
);
2841 /* return bounding rectangle */
2843 lprc
->left
= infoPtr
->rcBound
.left
;
2844 lprc
->right
= infoPtr
->rcBound
.right
;
2845 lprc
->top
= infoPtr
->rcBound
.top
;
2846 lprc
->bottom
= infoPtr
->rcBound
.bottom
;
2849 /* repaint toolbar */
2850 InvalidateRect(hwnd
, NULL
, FALSE
);
2857 TOOLBAR_SetState (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2859 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2860 TBUTTON_INFO
*btnPtr
;
2863 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2867 btnPtr
= &infoPtr
->buttons
[nIndex
];
2868 btnPtr
->fsState
= LOWORD(lParam
);
2870 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
2871 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
2878 TOOLBAR_SetStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2880 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2881 TBUTTON_INFO
*btnPtr
;
2884 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
);
2888 btnPtr
= &infoPtr
->buttons
[nIndex
];
2889 btnPtr
->fsStyle
= LOWORD(lParam
);
2891 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
2892 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
2894 if (infoPtr
->hwndToolTip
) {
2896 FIXME("change tool tip!\n");
2904 inline static LRESULT
2905 TOOLBAR_SetToolTips (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2907 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2909 if (infoPtr
== NULL
)
2911 infoPtr
->hwndToolTip
= (HWND
)wParam
;
2917 TOOLBAR_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2919 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2922 TRACE("%s hwnd=0x%04x stub!\n",
2923 ((BOOL
)wParam
) ? "TRUE" : "FALSE", hwnd
);
2925 bTemp
= infoPtr
->bUnicode
;
2926 infoPtr
->bUnicode
= (BOOL
)wParam
;
2933 TOOLBAR_SetVersion (HWND hwnd
, INT iVersion
)
2935 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2936 INT iOldVersion
= infoPtr
->iVersion
;
2938 infoPtr
->iVersion
= iVersion
;
2945 TOOLBAR_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2947 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2948 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
2951 /* initialize info structure */
2952 infoPtr
->nButtonHeight
= 22;
2953 infoPtr
->nButtonWidth
= 24;
2954 infoPtr
->nBitmapHeight
= 15;
2955 infoPtr
->nBitmapWidth
= 16;
2957 infoPtr
->nHeight
= infoPtr
->nButtonHeight
+ TOP_BORDER
+ BOTTOM_BORDER
;
2959 infoPtr
->nMaxTextRows
= 1;
2960 infoPtr
->cxMin
= -1;
2961 infoPtr
->cxMax
= -1;
2963 infoPtr
->bCaptured
= FALSE
;
2964 infoPtr
->bUnicode
= IsWindowUnicode (hwnd
);
2965 infoPtr
->nButtonDown
= -1;
2966 infoPtr
->nOldHit
= -1;
2967 infoPtr
->nHotItem
= -2; /* It has to be initially different from nOldHit */
2968 infoPtr
->hwndNotify
= GetParent (hwnd
);
2969 infoPtr
->bTransparent
= (dwStyle
& TBSTYLE_FLAT
);
2970 infoPtr
->dwDTFlags
= (dwStyle
& TBSTYLE_LIST
) ? DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
: DT_CENTER
;
2971 infoPtr
->bAnchor
= FALSE
; /* no anchor highlighting */
2972 infoPtr
->iVersion
= 0;
2974 SystemParametersInfoA (SPI_GETICONTITLELOGFONT
, 0, &logFont
, 0);
2975 infoPtr
->hFont
= CreateFontIndirectA (&logFont
);
2977 if (dwStyle
& TBSTYLE_TOOLTIPS
) {
2978 /* Create tooltip control */
2979 infoPtr
->hwndToolTip
=
2980 CreateWindowExA (0, TOOLTIPS_CLASSA
, NULL
, 0,
2981 CW_USEDEFAULT
, CW_USEDEFAULT
,
2982 CW_USEDEFAULT
, CW_USEDEFAULT
,
2985 /* Send NM_TOOLTIPSCREATED notification */
2986 if (infoPtr
->hwndToolTip
) {
2987 NMTOOLTIPSCREATED nmttc
;
2989 nmttc
.hdr
.hwndFrom
= hwnd
;
2990 nmttc
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
2991 nmttc
.hdr
.code
= NM_TOOLTIPSCREATED
;
2992 nmttc
.hwndToolTips
= infoPtr
->hwndToolTip
;
2994 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
2995 (WPARAM
)nmttc
.hdr
.idFrom
, (LPARAM
)&nmttc
);
3004 TOOLBAR_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3006 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3008 /* delete tooltip control */
3009 if (infoPtr
->hwndToolTip
)
3010 DestroyWindow (infoPtr
->hwndToolTip
);
3012 /* delete button data */
3013 if (infoPtr
->buttons
)
3014 COMCTL32_Free (infoPtr
->buttons
);
3016 /* delete strings */
3017 if (infoPtr
->strings
) {
3019 for (i
= 0; i
< infoPtr
->nNumStrings
; i
++)
3020 if (infoPtr
->strings
[i
])
3021 COMCTL32_Free (infoPtr
->strings
[i
]);
3023 COMCTL32_Free (infoPtr
->strings
);
3026 /* destroy internal image list */
3027 if (infoPtr
->himlInt
)
3028 ImageList_Destroy (infoPtr
->himlInt
);
3030 /* delete default font */
3032 DeleteObject (infoPtr
->hFont
);
3034 /* free toolbar info data */
3035 COMCTL32_Free (infoPtr
);
3036 SetWindowLongA (hwnd
, 0, 0);
3043 TOOLBAR_EraseBackground (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3045 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3047 if (infoPtr
->bTransparent
)
3048 return SendMessageA (GetParent (hwnd
), WM_ERASEBKGND
, wParam
, lParam
);
3050 return DefWindowProcA (hwnd
, WM_ERASEBKGND
, wParam
, lParam
);
3055 TOOLBAR_GetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3057 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3059 return infoPtr
->hFont
;
3064 TOOLBAR_LButtonDblClk (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3066 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3067 TBUTTON_INFO
*btnPtr
;
3071 pt
.x
= (INT
)LOWORD(lParam
);
3072 pt
.y
= (INT
)HIWORD(lParam
);
3073 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3076 btnPtr
= &infoPtr
->buttons
[nHit
];
3077 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
))
3080 infoPtr
->bCaptured
= TRUE
;
3081 infoPtr
->nButtonDown
= nHit
;
3083 btnPtr
->fsState
|= TBSTATE_PRESSED
;
3085 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3086 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3088 else if (GetWindowLongA (hwnd
, GWL_STYLE
) & CCS_ADJUSTABLE
)
3089 TOOLBAR_Customize (hwnd
);
3096 TOOLBAR_LButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3098 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3099 TBUTTON_INFO
*btnPtr
;
3103 if (infoPtr
->hwndToolTip
)
3104 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
3105 WM_LBUTTONDOWN
, wParam
, lParam
);
3107 pt
.x
= (INT
)LOWORD(lParam
);
3108 pt
.y
= (INT
)HIWORD(lParam
);
3109 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3112 btnPtr
= &infoPtr
->buttons
[nHit
];
3113 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
))
3116 if (btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
)
3120 nmtb
.hdr
.hwndFrom
= hwnd
;
3121 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
3122 nmtb
.hdr
.code
= TBN_DROPDOWN
;
3123 nmtb
.iItem
= btnPtr
->idCommand
;
3125 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
3126 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
);
3130 infoPtr
->bCaptured
= TRUE
;
3131 infoPtr
->nButtonDown
= nHit
;
3132 infoPtr
->nOldHit
= nHit
;
3134 btnPtr
->fsState
|= TBSTATE_PRESSED
;
3135 btnPtr
->bHot
= FALSE
;
3137 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3138 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3145 TOOLBAR_LButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3147 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3148 TBUTTON_INFO
*btnPtr
;
3152 BOOL bSendMessage
= TRUE
;
3154 if (infoPtr
->hwndToolTip
)
3155 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
3156 WM_LBUTTONUP
, wParam
, lParam
);
3158 pt
.x
= (INT
)LOWORD(lParam
);
3159 pt
.y
= (INT
)HIWORD(lParam
);
3160 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3162 if ((infoPtr
->bCaptured
) && (infoPtr
->nButtonDown
>= 0)) {
3163 infoPtr
->bCaptured
= FALSE
;
3165 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
3166 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
3168 if (nHit
== infoPtr
->nButtonDown
) {
3169 if (btnPtr
->fsStyle
& TBSTYLE_CHECK
) {
3170 if (btnPtr
->fsStyle
& TBSTYLE_GROUP
) {
3171 nOldIndex
= TOOLBAR_GetCheckedGroupButtonIndex (infoPtr
,
3172 infoPtr
->nButtonDown
);
3173 if (nOldIndex
== infoPtr
->nButtonDown
)
3174 bSendMessage
= FALSE
;
3175 if ((nOldIndex
!= infoPtr
->nButtonDown
) &&
3177 infoPtr
->buttons
[nOldIndex
].fsState
&= ~TBSTATE_CHECKED
;
3178 btnPtr
->fsState
|= TBSTATE_CHECKED
;
3181 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
3182 btnPtr
->fsState
&= ~TBSTATE_CHECKED
;
3184 btnPtr
->fsState
|= TBSTATE_CHECKED
;
3189 bSendMessage
= FALSE
;
3191 if (nOldIndex
!= -1)
3192 RedrawWindow(hwnd
,&infoPtr
->buttons
[nOldIndex
].rect
,NULL
,
3193 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3194 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3195 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3198 SendMessageA (GetParent(hwnd
), WM_COMMAND
,
3199 MAKEWPARAM(btnPtr
->idCommand
, 0), (LPARAM
)hwnd
);
3201 // if ((GetWindowLongA(hwnd, GWL_STYLE) & TBSTYLE_DROPDOWN) ||
3202 // (btnPtr->fsStyle & 0x08/* BTNS_DROPDOWN */)) {
3204 * This appears to be an error. Instead of checking the style of the
3205 * button in question wine was checking the style of the toolbar
3206 * itself. This caused a number of strange behaviors. In my
3207 * invistigation i think the whole dropdown thing is still fairly
3208 * broken. but this helps fix some of the problems.
3211 if (btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
) {
3214 nmtb
.hdr
.hwndFrom
= hwnd
;
3215 nmtb
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
3216 nmtb
.hdr
.code
= TBN_DROPDOWN
;
3218 /* nmtb.tbButton not used with TBN_DROPDOWN */
3219 if ((btnPtr
->iString
>= 0) && (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
3220 nmtb
.pszText
= infoPtr
->strings
[btnPtr
->iString
];
3221 nmtb
.cchText
= lstrlenW(nmtb
.pszText
);
3223 nmtb
.pszText
= NULL
;
3226 nmtb
.rcButton
= btnPtr
->rect
;
3228 SendMessageW(infoPtr
->hwndNotify
, WM_NOTIFY
,
3229 (WPARAM
)nmtb
.hdr
.idFrom
, (LPARAM
)&nmtb
);
3232 infoPtr
->nButtonDown
= -1;
3233 infoPtr
->nOldHit
= -1;
3240 TOOLBAR_MouseLeave (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3242 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3243 TBUTTON_INFO
*hotBtnPtr
;
3245 hotBtnPtr
= &infoPtr
->buttons
[infoPtr
->nOldHit
];
3247 /* Redraw the button if the last button we were over is the hot button and it
3249 if((infoPtr
->nOldHit
== infoPtr
->nHotItem
) && (hotBtnPtr
->fsState
& TBSTATE_ENABLED
))
3251 hotBtnPtr
->bHot
= FALSE
;
3253 InvalidateRect (hwnd
, &hotBtnPtr
->rect
, TRUE
);
3256 infoPtr
->nOldHit
= -1; /* reset the old hit index as we've left the toolbar */
3257 infoPtr
->nHotItem
= -2; /* It has to be initially different from nOldHit */
3263 TOOLBAR_MouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3265 TBUTTON_INFO
*btnPtr
, *oldBtnPtr
;
3266 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3269 TRACKMOUSEEVENT trackinfo
;
3271 /* fill in the TRACKMOUSEEVENT struct */
3272 trackinfo
.cbSize
= sizeof(TRACKMOUSEEVENT
);
3273 trackinfo
.dwFlags
= TME_QUERY
;
3274 trackinfo
.hwndTrack
= hwnd
;
3275 trackinfo
.dwHoverTime
= HOVER_DEFAULT
;
3277 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
3278 _TrackMouseEvent(&trackinfo
);
3280 /* Make sure tracking is enabled so we recieve a WM_MOUSELEAVE message */
3281 if(!(trackinfo
.dwFlags
& TME_LEAVE
)) {
3282 trackinfo
.dwFlags
= TME_LEAVE
; /* notify upon leaving */
3284 /* call TRACKMOUSEEVENT so we recieve a WM_MOUSELEAVE message */
3285 /* and can properly deactivate the hot toolbar button */
3286 _TrackMouseEvent(&trackinfo
);
3289 if (infoPtr
->hwndToolTip
)
3290 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
3291 WM_MOUSEMOVE
, wParam
, lParam
);
3293 pt
.x
= (INT
)LOWORD(lParam
);
3294 pt
.y
= (INT
)HIWORD(lParam
);
3296 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
3298 if (infoPtr
->nOldHit
!= nHit
)
3300 /* Remove the effect of an old hot button if the button was enabled and was
3301 drawn with the hot button effect */
3302 if(infoPtr
->nOldHit
== infoPtr
->nHotItem
&&
3303 (infoPtr
->buttons
[infoPtr
->nOldHit
].fsState
& TBSTATE_ENABLED
))
3305 oldBtnPtr
= &infoPtr
->buttons
[infoPtr
->nOldHit
];
3306 oldBtnPtr
->bHot
= FALSE
;
3308 InvalidateRect (hwnd
, &oldBtnPtr
->rect
, TRUE
);
3311 /* It's not a separator or in nowhere. It's a hot button. */
3314 btnPtr
= &infoPtr
->buttons
[nHit
];
3315 btnPtr
->bHot
= TRUE
;
3317 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3318 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3320 infoPtr
->nHotItem
= nHit
;
3323 if (infoPtr
->bCaptured
) {
3324 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
3325 if (infoPtr
->nOldHit
== infoPtr
->nButtonDown
) {
3326 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
3327 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3328 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3330 else if (nHit
== infoPtr
->nButtonDown
) {
3331 btnPtr
->fsState
|= TBSTATE_PRESSED
;
3332 RedrawWindow(hwnd
,&btnPtr
->rect
,NULL
,
3333 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
3336 infoPtr
->nOldHit
= nHit
;
3342 inline static LRESULT
3343 TOOLBAR_NCActivate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3345 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
3346 return DefWindowProcA (hwnd
, WM_NCACTIVATE
, wParam
, lParam
);
3348 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
3352 inline static LRESULT
3353 TOOLBAR_NCCalcSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3355 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & CCS_NODIVIDER
))
3356 ((LPRECT
)lParam
)->top
+= GetSystemMetrics(SM_CYEDGE
);
3358 return DefWindowProcA (hwnd
, WM_NCCALCSIZE
, wParam
, lParam
);
3363 TOOLBAR_NCCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3365 TOOLBAR_INFO
*infoPtr
;
3367 /* allocate memory for info structure */
3368 infoPtr
= (TOOLBAR_INFO
*)COMCTL32_Alloc (sizeof(TOOLBAR_INFO
));
3369 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
3372 infoPtr
->dwStructSize
= sizeof(TBBUTTON
);
3374 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
3375 if (!GetWindowLongA (hwnd
, GWL_HINSTANCE
)) {
3376 HINSTANCE hInst
= (HINSTANCE
)GetWindowLongA (GetParent (hwnd
), GWL_HINSTANCE
);
3377 SetWindowLongA (hwnd
, GWL_HINSTANCE
, (DWORD
)hInst
);
3380 return DefWindowProcA (hwnd
, WM_NCCREATE
, wParam
, lParam
);
3385 TOOLBAR_NCPaint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3387 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
3391 if (dwStyle
& WS_MINIMIZE
)
3392 return 0; /* Nothing to do */
3394 DefWindowProcA (hwnd
, WM_NCPAINT
, wParam
, lParam
);
3396 if (!(hdc
= GetDCEx (hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
)))
3399 if (!(dwStyle
& CCS_NODIVIDER
))
3401 GetWindowRect (hwnd
, &rcWindow
);
3402 OffsetRect (&rcWindow
, -rcWindow
.left
, -rcWindow
.top
);
3403 if( dwStyle
& WS_BORDER
)
3404 OffsetRect (&rcWindow
, 1, 1);
3405 DrawEdge (hdc
, &rcWindow
, EDGE_ETCHED
, BF_TOP
);
3408 ReleaseDC( hwnd
, hdc
);
3414 inline static LRESULT
3415 TOOLBAR_Notify (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3417 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3418 LPNMHDR lpnmh
= (LPNMHDR
)lParam
;
3420 TRACE("passing WM_NOTIFY!\n");
3422 if ((infoPtr
->hwndToolTip
) && (lpnmh
->hwndFrom
== infoPtr
->hwndToolTip
)) {
3423 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
, wParam
, lParam
);
3426 if (lpnmh
->code
== TTN_GETDISPINFOA
) {
3427 LPNMTTDISPINFOA lpdi
= (LPNMTTDISPINFOA
)lParam
;
3429 FIXME("retrieving ASCII string\n");
3432 else if (lpnmh
->code
== TTN_GETDISPINFOW
) {
3433 LPNMTTDISPINFOW lpdi
= (LPNMTTDISPINFOW
)lParam
;
3435 FIXME("retrieving UNICODE string\n");
3446 TOOLBAR_Paint (HWND hwnd
, WPARAM wParam
)
3451 TOOLBAR_CalcToolbar( hwnd
);
3452 hdc
= wParam
==0 ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
3453 TOOLBAR_Refresh (hwnd
, hdc
);
3455 EndPaint (hwnd
, &ps
);
3461 TOOLBAR_Size (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3463 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3464 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
3473 /* Resize deadlock check */
3474 if (infoPtr
->bAutoSize
) {
3475 infoPtr
->bAutoSize
= FALSE
;
3479 flags
= (INT
) wParam
;
3481 /* FIXME for flags =
3482 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
3485 TRACE("sizing toolbar!\n");
3487 if (flags
== SIZE_RESTORED
) {
3488 /* width and height don't apply */
3489 parent
= GetParent (hwnd
);
3490 GetClientRect(parent
, &parent_rect
);
3491 x
= parent_rect
.left
;
3492 y
= parent_rect
.top
;
3494 if (dwStyle
& CCS_NORESIZE
) {
3495 uPosFlags
|= (SWP_NOSIZE
| SWP_NOMOVE
);
3498 * this sets the working width of the toolbar, and
3499 * Calc Toolbar will not adjust it, only the height
3501 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
3502 cy
= infoPtr
->nHeight
;
3503 cx
= infoPtr
->nWidth
;
3504 TOOLBAR_CalcToolbar (hwnd
);
3505 infoPtr
->nWidth
= cx
;
3506 infoPtr
->nHeight
= cy
;
3509 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
3510 TOOLBAR_CalcToolbar (hwnd
);
3511 cy
= infoPtr
->nHeight
;
3512 cx
= infoPtr
->nWidth
;
3514 if (dwStyle
& CCS_NOMOVEY
) {
3515 GetWindowRect(hwnd
, &window_rect
);
3516 ScreenToClient(parent
, (LPPOINT
)&window_rect
.left
);
3517 y
= window_rect
.top
;
3521 if (dwStyle
& CCS_NOPARENTALIGN
) {
3522 uPosFlags
|= SWP_NOMOVE
;
3523 cy
= infoPtr
->nHeight
;
3524 cx
= infoPtr
->nWidth
;
3527 if (!(dwStyle
& CCS_NODIVIDER
))
3528 cy
+= GetSystemMetrics(SM_CYEDGE
);
3530 if (dwStyle
& WS_BORDER
)
3533 cy
+= GetSystemMetrics(SM_CYEDGE
);
3534 cx
+= GetSystemMetrics(SM_CYEDGE
);
3537 SetWindowPos (hwnd
, 0, parent_rect
.left
- x
, parent_rect
.top
- y
,
3538 cx
, cy
, uPosFlags
| SWP_NOZORDER
);
3545 TOOLBAR_StyleChanged (HWND hwnd
, INT nType
, LPSTYLESTRUCT lpStyle
)
3547 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3549 if (nType
== GWL_STYLE
) {
3550 if (lpStyle
->styleNew
& TBSTYLE_LIST
) {
3551 infoPtr
->dwDTFlags
= DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
;
3554 infoPtr
->dwDTFlags
= DT_CENTER
;
3558 TOOLBAR_AutoSize (hwnd
);
3560 InvalidateRect(hwnd
, NULL
, FALSE
);
3567 static LRESULT WINAPI
3568 ToolbarWindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3574 return TOOLBAR_Destroy (hwnd
, wParam
, lParam
);
3577 return TOOLBAR_NCCreate (hwnd
, wParam
, lParam
);
3580 if (!TOOLBAR_GetInfoPtr (hwnd
))
3582 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
3588 return TOOLBAR_AddBitmap (hwnd
, wParam
, lParam
);
3590 case TB_ADDBUTTONSA
:
3591 return TOOLBAR_AddButtonsA (hwnd
, wParam
, lParam
);
3593 case TB_ADDBUTTONSW
:
3594 return TOOLBAR_AddButtonsW (hwnd
, wParam
, lParam
);
3597 return TOOLBAR_AddStringA (hwnd
, wParam
, lParam
);
3600 return TOOLBAR_AddStringW (hwnd
, wParam
, lParam
);
3603 return TOOLBAR_AutoSize (hwnd
);
3605 case TB_BUTTONCOUNT
:
3606 return TOOLBAR_ButtonCount (hwnd
, wParam
, lParam
);
3608 case TB_BUTTONSTRUCTSIZE
:
3609 return TOOLBAR_ButtonStructSize (hwnd
, wParam
, lParam
);
3611 case TB_CHANGEBITMAP
:
3612 return TOOLBAR_ChangeBitmap (hwnd
, wParam
, lParam
);
3614 case TB_CHECKBUTTON
:
3615 return TOOLBAR_CheckButton (hwnd
, wParam
, lParam
);
3617 case TB_COMMANDTOINDEX
:
3618 return TOOLBAR_CommandToIndex (hwnd
, wParam
, lParam
);
3621 return TOOLBAR_Customize (hwnd
);
3623 case TB_DELETEBUTTON
:
3624 return TOOLBAR_DeleteButton (hwnd
, wParam
, lParam
);
3626 case TB_ENABLEBUTTON
:
3627 return TOOLBAR_EnableButton (hwnd
, wParam
, lParam
);
3629 case TB_GETANCHORHIGHLIGHT
:
3630 return TOOLBAR_GetAnchorHighlight (hwnd
);
3633 return TOOLBAR_GetBitmap (hwnd
, wParam
, lParam
);
3635 case TB_GETBITMAPFLAGS
:
3636 return TOOLBAR_GetBitmapFlags (hwnd
, wParam
, lParam
);
3639 return TOOLBAR_GetButton (hwnd
, wParam
, lParam
);
3641 case TB_GETBUTTONINFOA
:
3642 return TOOLBAR_GetButtonInfoA (hwnd
, wParam
, lParam
);
3644 case TB_GETBUTTONINFOW
:
3645 return TOOLBAR_GetButtonInfoW (hwnd
, wParam
, lParam
);
3647 case TB_GETBUTTONSIZE
:
3648 return TOOLBAR_GetButtonSize (hwnd
);
3650 case TB_GETBUTTONTEXTA
:
3651 return TOOLBAR_GetButtonTextA (hwnd
, wParam
, lParam
);
3653 case TB_GETBUTTONTEXTW
:
3654 return TOOLBAR_GetButtonTextW (hwnd
, wParam
, lParam
);
3656 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
3658 case TB_GETDISABLEDIMAGELIST
:
3659 return TOOLBAR_GetDisabledImageList (hwnd
, wParam
, lParam
);
3661 case TB_GETEXTENDEDSTYLE
:
3662 return TOOLBAR_GetExtendedStyle (hwnd
);
3664 case TB_GETHOTIMAGELIST
:
3665 return TOOLBAR_GetHotImageList (hwnd
, wParam
, lParam
);
3668 return TOOLBAR_GetHotItem (hwnd
);
3670 case TB_GETIMAGELIST
:
3671 return TOOLBAR_GetImageList (hwnd
, wParam
, lParam
);
3673 /* case TB_GETINSERTMARK: */ /* 4.71 */
3674 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
3676 case TB_GETITEMRECT
:
3677 return TOOLBAR_GetItemRect (hwnd
, wParam
, lParam
);
3680 return TOOLBAR_GetMaxSize (hwnd
, wParam
, lParam
);
3682 /* case TB_GETOBJECT: */ /* 4.71 */
3683 /* case TB_GETPADDING: */ /* 4.71 */
3686 return TOOLBAR_GetRect (hwnd
, wParam
, lParam
);
3689 return TOOLBAR_GetRows (hwnd
, wParam
, lParam
);
3692 return TOOLBAR_GetState (hwnd
, wParam
, lParam
);
3695 return TOOLBAR_GetStyle (hwnd
, wParam
, lParam
);
3697 case TB_GETTEXTROWS
:
3698 return TOOLBAR_GetTextRows (hwnd
, wParam
, lParam
);
3700 case TB_GETTOOLTIPS
:
3701 return TOOLBAR_GetToolTips (hwnd
, wParam
, lParam
);
3703 case TB_GETUNICODEFORMAT
:
3704 return TOOLBAR_GetUnicodeFormat (hwnd
, wParam
, lParam
);
3706 case CCM_GETVERSION
:
3707 return TOOLBAR_GetVersion (hwnd
);
3710 return TOOLBAR_HideButton (hwnd
, wParam
, lParam
);
3713 return TOOLBAR_HitTest (hwnd
, wParam
, lParam
);
3715 case TB_INDETERMINATE
:
3716 return TOOLBAR_Indeterminate (hwnd
, wParam
, lParam
);
3718 case TB_INSERTBUTTONA
:
3719 return TOOLBAR_InsertButtonA (hwnd
, wParam
, lParam
);
3721 case TB_INSERTBUTTONW
:
3722 return TOOLBAR_InsertButtonW (hwnd
, wParam
, lParam
);
3724 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
3726 case TB_ISBUTTONCHECKED
:
3727 return TOOLBAR_IsButtonChecked (hwnd
, wParam
, lParam
);
3729 case TB_ISBUTTONENABLED
:
3730 return TOOLBAR_IsButtonEnabled (hwnd
, wParam
, lParam
);
3732 case TB_ISBUTTONHIDDEN
:
3733 return TOOLBAR_IsButtonHidden (hwnd
, wParam
, lParam
);
3735 case TB_ISBUTTONHIGHLIGHTED
:
3736 return TOOLBAR_IsButtonHighlighted (hwnd
, wParam
, lParam
);
3738 case TB_ISBUTTONINDETERMINATE
:
3739 return TOOLBAR_IsButtonIndeterminate (hwnd
, wParam
, lParam
);
3741 case TB_ISBUTTONPRESSED
:
3742 return TOOLBAR_IsButtonPressed (hwnd
, wParam
, lParam
);
3744 case TB_LOADIMAGES
: /* 4.70 */
3745 FIXME("missing standard imagelists\n");
3748 /* case TB_MAPACCELERATORA: */ /* 4.71 */
3749 /* case TB_MAPACCELERATORW: */ /* 4.71 */
3750 /* case TB_MARKBUTTON: */ /* 4.71 */
3751 /* case TB_MOVEBUTTON: */ /* 4.71 */
3753 case TB_PRESSBUTTON
:
3754 return TOOLBAR_PressButton (hwnd
, wParam
, lParam
);
3756 /* case TB_REPLACEBITMAP: */
3758 case TB_SAVERESTOREA
:
3759 return TOOLBAR_SaveRestoreA (hwnd
, wParam
, lParam
);
3761 case TB_SAVERESTOREW
:
3762 return TOOLBAR_SaveRestoreW (hwnd
, wParam
, lParam
);
3764 case TB_SETANCHORHIGHLIGHT
:
3765 return TOOLBAR_SetAnchorHighlight (hwnd
, wParam
);
3767 case TB_SETBITMAPSIZE
:
3768 return TOOLBAR_SetBitmapSize (hwnd
, wParam
, lParam
);
3770 case TB_SETBUTTONINFOA
:
3771 return TOOLBAR_SetButtonInfoA (hwnd
, wParam
, lParam
);
3773 case TB_SETBUTTONINFOW
:
3774 return TOOLBAR_SetButtonInfoW (hwnd
, wParam
, lParam
);
3776 case TB_SETBUTTONSIZE
:
3777 return TOOLBAR_SetButtonSize (hwnd
, wParam
, lParam
);
3779 case TB_SETBUTTONWIDTH
:
3780 return TOOLBAR_SetButtonWidth (hwnd
, wParam
, lParam
);
3783 return TOOLBAR_SetCmdId (hwnd
, wParam
, lParam
);
3785 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
3787 case TB_SETDISABLEDIMAGELIST
:
3788 return TOOLBAR_SetDisabledImageList (hwnd
, wParam
, lParam
);
3790 case TB_SETDRAWTEXTFLAGS
:
3791 return TOOLBAR_SetDrawTextFlags (hwnd
, wParam
, lParam
);
3793 case TB_SETEXTENDEDSTYLE
:
3794 return TOOLBAR_SetExtendedStyle (hwnd
, wParam
, lParam
);
3796 case TB_SETHOTIMAGELIST
:
3797 return TOOLBAR_SetHotImageList (hwnd
, wParam
, lParam
);
3800 return TOOLBAR_SetHotItem (hwnd
, wParam
);
3802 case TB_SETIMAGELIST
:
3803 return TOOLBAR_SetImageList (hwnd
, wParam
, lParam
);
3806 return TOOLBAR_SetIndent (hwnd
, wParam
, lParam
);
3808 /* case TB_SETINSERTMARK: */ /* 4.71 */
3810 case TB_SETINSERTMARKCOLOR
:
3811 return TOOLBAR_SetInsertMarkColor (hwnd
, wParam
, lParam
);
3813 case TB_SETMAXTEXTROWS
:
3814 return TOOLBAR_SetMaxTextRows (hwnd
, wParam
, lParam
);
3816 /* case TB_SETPADDING: */ /* 4.71 */
3819 return TOOLBAR_SetParent (hwnd
, wParam
, lParam
);
3822 return TOOLBAR_SetRows (hwnd
, wParam
, lParam
);
3825 return TOOLBAR_SetState (hwnd
, wParam
, lParam
);
3828 return TOOLBAR_SetStyle (hwnd
, wParam
, lParam
);
3830 case TB_SETTOOLTIPS
:
3831 return TOOLBAR_SetToolTips (hwnd
, wParam
, lParam
);
3833 case TB_SETUNICODEFORMAT
:
3834 return TOOLBAR_SetUnicodeFormat (hwnd
, wParam
, lParam
);
3836 case CCM_SETVERSION
:
3837 return TOOLBAR_SetVersion (hwnd
, (INT
)wParam
);
3843 return TOOLBAR_Create (hwnd
, wParam
, lParam
);
3846 return TOOLBAR_EraseBackground (hwnd
, wParam
, lParam
);
3849 return TOOLBAR_GetFont (hwnd
, wParam
, lParam
);
3851 /* case WM_KEYDOWN: */
3852 /* case WM_KILLFOCUS: */
3854 case WM_LBUTTONDBLCLK
:
3855 return TOOLBAR_LButtonDblClk (hwnd
, wParam
, lParam
);
3857 case WM_LBUTTONDOWN
:
3858 return TOOLBAR_LButtonDown (hwnd
, wParam
, lParam
);
3861 return TOOLBAR_LButtonUp (hwnd
, wParam
, lParam
);
3864 return TOOLBAR_MouseMove (hwnd
, wParam
, lParam
);
3867 return TOOLBAR_MouseLeave (hwnd
, wParam
, lParam
);
3870 return TOOLBAR_NCActivate (hwnd
, wParam
, lParam
);
3873 return TOOLBAR_NCCalcSize (hwnd
, wParam
, lParam
);
3876 return TOOLBAR_NCPaint (hwnd
, wParam
, lParam
);
3879 return TOOLBAR_Notify (hwnd
, wParam
, lParam
);
3881 /* case WM_NOTIFYFORMAT: */
3884 return TOOLBAR_Paint (hwnd
, wParam
);
3887 return TOOLBAR_Size (hwnd
, wParam
, lParam
);
3889 case WM_STYLECHANGED
:
3890 return TOOLBAR_StyleChanged (hwnd
, (INT
)wParam
, (LPSTYLESTRUCT
)lParam
);
3892 /* case WM_SYSCOLORCHANGE: */
3894 /* case WM_WININICHANGE: */
3899 case WM_MEASUREITEM
:
3901 return SendMessageA (GetParent (hwnd
), uMsg
, wParam
, lParam
);
3904 if (uMsg
>= WM_USER
)
3905 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
3906 uMsg
, wParam
, lParam
);
3907 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
3914 TOOLBAR_Register (void)
3918 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
3919 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
;
3920 wndClass
.lpfnWndProc
= (WNDPROC
)ToolbarWindowProc
;
3921 wndClass
.cbClsExtra
= 0;
3922 wndClass
.cbWndExtra
= sizeof(TOOLBAR_INFO
*);
3923 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
3924 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_3DFACE
+ 1);
3925 wndClass
.lpszClassName
= TOOLBARCLASSNAMEA
;
3927 RegisterClassA (&wndClass
);
3932 TOOLBAR_Unregister (void)
3934 UnregisterClassA (TOOLBARCLASSNAMEA
, (HINSTANCE
)NULL
);