4 * Copyright 1998,1999 Eric Kohl
5 * Copyright 2000 Eric Kohl for CodeWeavers
7 * Differences between MSDN and actual native control operation:
8 * 1. MSDN says: "TBSTYLE_LIST: Creates a flat toolbar with button text
9 * to the right of the bitmap. Otherwise, this style is
10 * identical to TBSTYLE_FLAT."
11 * As implemented by both v4.71 and v5.80 of the native COMCTL32.DLL
12 * you can create a TBSTYLE_LIST without TBSTYLE_FLAT and the result
13 * is non-flat non-transparent buttons. Therefore TBSTYLE_LIST does
14 * *not* imply TBSTYLE_FLAT as documented. (GA 8/2001)
18 * - A little bug in TOOLBAR_DrawMasked()
19 * - Button wrapping (under construction).
21 * - Notifications (under construction).
23 * - Tooltip support (almost complete).
24 * - Unicode suppport (under construction).
25 * - Fix TOOLBAR_SetButtonInfo32A/W.
26 * - TBSTYLE_AUTOSIZE for toolbar and buttons.
27 * - I_IMAGECALLBACK support.
28 * - iString of -1 is undocumented
29 * - Customization dialog:
31 * - Minor buglet in 'available buttons' list:
32 * Buttons are not listed in M$-like order. M$ seems to use a single
33 * internal list to store the button information of both listboxes.
34 * - Drag list support.
35 * - Help and Reset button support.
38 * - Run tests using Waite Group Windows95 API Bible Volume 2.
39 * The second cdrom contains executables addstr.exe, btncount.exe,
40 * btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
41 * enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
42 * indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
43 * setparnt.exe, setrows.exe, toolwnd.exe.
44 * - Microsofts controlspy examples.
45 * - Charles Petzold's 'Programming Windows': gadgets.exe
54 #include "wine/unicode.h"
56 #include "imagelist.h"
58 #include "debugtools.h"
60 DEFAULT_DEBUG_CHANNEL(toolbar
);
78 DWORD dwStructSize
; /* size of TBBUTTON struct */
79 INT nHeight
; /* height of the toolbar */
80 INT nWidth
; /* width of the toolbar */
86 INT nRows
; /* number of button rows */
87 INT nMaxTextRows
; /* maximum number of text rows */
88 INT cxMin
; /* minimum button width */
89 INT cxMax
; /* maximum button width */
90 INT nNumButtons
; /* number of buttons */
91 INT nNumBitmaps
; /* number of bitmaps */
92 INT nNumStrings
; /* number of strings */
93 BOOL bUnicode
; /* ASCII (FALSE) or Unicode (TRUE)? */
94 BOOL bCaptured
; /* mouse captured? */
97 INT nHotItem
; /* index of the "hot" item */
99 HFONT hFont
; /* text font */
100 HIMAGELIST himlInt
; /* image list created internally */
101 HIMAGELIST himlDef
; /* default image list */
102 HIMAGELIST himlHot
; /* hot image list */
103 HIMAGELIST himlDis
; /* disabled image list */
104 HWND hwndToolTip
; /* handle to tool tip control */
105 HWND hwndNotify
; /* handle to the window that gets notifications */
106 HWND hwndSelf
; /* my own handle */
107 BOOL bTransparent
; /* background transparency flag */
108 BOOL bBtnTranspnt
; /* button transparency flag */
109 BOOL bAutoSize
; /* auto size deadlock indicator */
110 BOOL bAnchor
; /* anchor highlight enabled */
111 BOOL bNtfUnicode
; /* TRUE if NOTIFYs use {W} */
112 DWORD dwExStyle
; /* extended toolbar style */
113 DWORD dwDTFlags
; /* DrawText flags */
115 COLORREF clrInsertMark
; /* insert mark color */
116 RECT rcBound
; /* bounding rectangle */
119 TBUTTON_INFO
*buttons
; /* pointer to button array */
120 LPWSTR
*strings
; /* pointer to string array */
121 } TOOLBAR_INFO
, *PTOOLBAR_INFO
;
124 /* used by customization dialog */
127 PTOOLBAR_INFO tbInfo
;
129 } CUSTDLG_INFO
, *PCUSTDLG_INFO
;
137 } CUSTOMBUTTON
, *PCUSTOMBUTTON
;
140 #define SEPARATOR_WIDTH 8
142 #define BOTTOM_BORDER 2
143 #define DDARROW_WIDTH 11
145 #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
146 #define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE)
147 #define TOOLBAR_HasDropDownArrows(exStyle) ((exStyle & TBSTYLE_EX_DRAWDDARROWS) ? TRUE : FALSE)
151 TOOLBAR_DumpButton(TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*bP
, INT btn_num
, BOOL internal
)
153 if (TRACE_ON(toolbar
)){
154 TRACE("button %d id %d, bitmap=%d, state=%02x, style=%02x, data=%08lx, string=%d\n",
155 btn_num
, bP
->idCommand
,
156 bP
->iBitmap
, bP
->fsState
, bP
->fsStyle
, bP
->dwData
, bP
->iString
);
158 TRACE("button %d id %d, hot=%s, row=%d, rect=(%d,%d)-(%d,%d)\n",
159 btn_num
, bP
->idCommand
,
160 (bP
->bHot
) ? "TRUE":"FALSE", bP
->nRow
,
161 bP
->rect
.left
, bP
->rect
.top
,
162 bP
->rect
.right
, bP
->rect
.bottom
);
168 TOOLBAR_DumpToolbar(TOOLBAR_INFO
*iP
, INT line
)
170 if (TRACE_ON(toolbar
)) {
174 dwStyle
= GetWindowLongA (iP
->hwndSelf
, GWL_STYLE
);
175 TRACE("toolbar %08x at line %d, exStyle=%08lx, buttons=%d, bitmaps=%d, strings=%d, style=%08lx\n",
177 iP
->dwExStyle
, iP
->nNumButtons
, iP
->nNumBitmaps
,
178 iP
->nNumStrings
, dwStyle
);
179 TRACE("toolbar %08x at line %d, himlInt=%p, himlDef=%p, himlHot=%p, himlDis=%p\n",
181 iP
->himlInt
, iP
->himlDef
, iP
->himlHot
, iP
->himlDis
);
182 for(i
=0; i
<iP
->nNumButtons
; i
++) {
183 TOOLBAR_DumpButton(iP
, &iP
->buttons
[i
], i
, TRUE
);
189 /***********************************************************************
192 * This function validates that the styles set are implemented and
193 * issues FIXME's warning of possible problems. In a perfect world this
194 * function should be null.
197 TOOLBAR_CheckStyle (HWND hwnd
, DWORD dwStyle
)
199 if (dwStyle
& TBSTYLE_ALTDRAG
)
200 FIXME("[%04x] TBSTYLE_ALTDRAG not implemented\n", hwnd
);
201 if (dwStyle
& TBSTYLE_REGISTERDROP
)
202 FIXME("[%04x] TBSTYLE_REGISTERDROP not implemented\n", hwnd
);
207 TOOLBAR_SendNotify (NMHDR
*nmhdr
, TOOLBAR_INFO
*infoPtr
, UINT code
)
209 if(!IsWindow(infoPtr
->hwndSelf
))
210 return 0; /* we have just been destroyed */
212 nmhdr
->idFrom
= GetDlgCtrlID (infoPtr
->hwndSelf
);
213 nmhdr
->hwndFrom
= infoPtr
->hwndSelf
;
216 TRACE("to window %04x, code=%08x, %s\n", infoPtr
->hwndNotify
, code
,
217 (infoPtr
->bNtfUnicode
) ? "via Unicode" : "via ANSI");
219 if (infoPtr
->bNtfUnicode
)
220 return SendMessageW (infoPtr
->hwndNotify
, WM_NOTIFY
,
221 (WPARAM
) nmhdr
->idFrom
, (LPARAM
)nmhdr
);
223 return SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
,
224 (WPARAM
) nmhdr
->idFrom
, (LPARAM
)nmhdr
);
228 TOOLBAR_GetText(TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
)
230 LPWSTR lpText
= NULL
;
232 /* FIXME: iString == -1 is undocumented */
233 if ((HIWORD(btnPtr
->iString
) != 0) && (btnPtr
->iString
!= -1))
234 lpText
= (LPWSTR
)btnPtr
->iString
;
235 else if ((btnPtr
->iString
>= 0) && (btnPtr
->iString
< infoPtr
->nNumStrings
))
236 lpText
= infoPtr
->strings
[btnPtr
->iString
];
241 /***********************************************************************
242 * TOOLBAR_GetBitmapIndex
244 * This function returns the bitmap index associated with a button.
245 * If the button specifies I_IMAGECALLBACK, then the TBN_GETDISPINFO
246 * is issued to retrieve the index.
249 TOOLBAR_GetBitmapIndex(TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
)
251 INT ret
= btnPtr
->iBitmap
;
253 if (ret
== I_IMAGECALLBACK
) {
254 /* issue TBN_GETDISPINFO */
257 nmgd
.idCommand
= btnPtr
->idCommand
;
258 nmgd
.lParam
= btnPtr
->dwData
;
259 nmgd
.dwMask
= TBNF_IMAGE
;
260 TOOLBAR_SendNotify ((NMHDR
*) &nmgd
, infoPtr
,
261 (infoPtr
->bNtfUnicode
) ? TBN_GETDISPINFOW
:
263 if (nmgd
.dwMask
& TBNF_DI_SETITEM
) {
264 btnPtr
->iBitmap
= nmgd
.iImage
;
267 TRACE("TBN_GETDISPINFOA returned bitmap id %d, mask=%08lx, nNumBitmaps=%d\n",
268 ret
, nmgd
.dwMask
, infoPtr
->nNumBitmaps
);
275 TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO
*infoPtr
, INT index
)
277 if (((index
>=0) && (index
<= infoPtr
->nNumBitmaps
)) ||
278 (index
== I_IMAGECALLBACK
))
285 /***********************************************************************
286 * TOOLBAR_DrawImageList
288 * This function validates the bitmap index (including I_IMAGECALLBACK
289 * functionality). It then draws the image via the ImageList_Draw
290 * function. It returns TRUE if the image was drawn, FALSE otherwise.
293 TOOLBAR_DrawImageList (TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
, HIMAGELIST himl
,
294 HDC hdc
, UINT left
, UINT top
, UINT draw_flags
)
298 if (!himl
) return FALSE
;
300 if (!TOOLBAR_IsValidBitmapIndex(infoPtr
,btnPtr
->iBitmap
)) {
301 ERR("index %d is not valid, max %d\n",
302 btnPtr
->iBitmap
, infoPtr
->nNumBitmaps
);
306 if ((index
= TOOLBAR_GetBitmapIndex(infoPtr
, btnPtr
)) < 0) {
307 if (index
== -1) return FALSE
;
308 ERR("TBN_GETDISPINFO returned invalid index %d\n",
312 TRACE("drawing index=%d, himl=%p, left=%d, top=%d, flags=%08x\n",
313 index
, himl
, left
, top
, draw_flags
);
315 ImageList_Draw (himl
, index
, hdc
, left
, top
, draw_flags
);
320 /***********************************************************************
321 * TOOLBAR_TestImageExist
323 * This function is similar to TOOLBAR_DrawImageList, except it does not
324 * draw the image. The I_IMAGECALLBACK functionality is implemented.
327 TOOLBAR_TestImageExist (TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
, HIMAGELIST himl
)
331 if (!himl
) return FALSE
;
333 if (!TOOLBAR_IsValidBitmapIndex(infoPtr
,btnPtr
->iBitmap
)) {
334 ERR("index %d is not valid, max %d\n",
335 btnPtr
->iBitmap
, infoPtr
->nNumBitmaps
);
339 if ((index
= TOOLBAR_GetBitmapIndex(infoPtr
, btnPtr
)) < 0) {
340 if (index
== -1) return FALSE
;
341 ERR("TBN_GETDISPINFO returned invalid index %d\n",
350 TOOLBAR_DrawFlatSeparator (LPRECT lpRect
, HDC hdc
)
352 INT x
= (lpRect
->left
+ lpRect
->right
) / 2 - 1;
353 INT yBottom
= lpRect
->bottom
- 3;
354 INT yTop
= lpRect
->top
+ 1;
356 SelectObject ( hdc
, GetSysColorPen (COLOR_3DSHADOW
));
357 MoveToEx (hdc
, x
, yBottom
, NULL
);
358 LineTo (hdc
, x
, yTop
);
360 SelectObject ( hdc
, GetSysColorPen (COLOR_3DHILIGHT
));
361 MoveToEx (hdc
, x
, yBottom
, NULL
);
362 LineTo (hdc
, x
, yTop
);
366 /***********************************************************************
367 * TOOLBAR_DrawDDFlatSeparator
369 * This function draws the separator that was flaged as TBSTYLE_DROPDOWN.
370 * In this case, the separator is a pixel high line of COLOR_BTNSHADOW,
371 * followed by a pixel high line of COLOR_BTNHIGHLIGHT. These separators
372 * are horizontal as opposed to the vertical separators for not dropdown
375 * FIXME: It is possible that the height of each line is really SM_CYBORDER.
378 TOOLBAR_DrawDDFlatSeparator (LPRECT lpRect
, HDC hdc
, TBUTTON_INFO
*btnPtr
)
381 COLORREF oldcolor
, newcolor
;
383 myrect
.left
= lpRect
->left
;
384 myrect
.right
= lpRect
->right
;
385 myrect
.top
= lpRect
->top
+ (lpRect
->bottom
- lpRect
->top
- 2)/2;
386 myrect
.bottom
= myrect
.top
+ 1;
388 InflateRect (&myrect
, -2, 0);
390 TRACE("rect=(%d,%d)-(%d,%d)\n",
391 myrect
.left
, myrect
.top
, myrect
.right
, myrect
.bottom
);
393 newcolor
= GetSysColor (COLOR_BTNSHADOW
);
394 oldcolor
= SetBkColor (hdc
, newcolor
);
395 ExtTextOutA (hdc
, 0, 0, ETO_OPAQUE
, &myrect
, 0, 0, 0);
397 myrect
.top
= myrect
.bottom
;
398 myrect
.bottom
= myrect
.top
+ 1;
400 newcolor
= GetSysColor (COLOR_BTNHIGHLIGHT
);
401 SetBkColor (hdc
, newcolor
);
402 ExtTextOutA (hdc
, 0, 0, ETO_OPAQUE
, &myrect
, 0, 0, 0);
404 SetBkColor (hdc
, oldcolor
);
409 TOOLBAR_DrawArrow (HDC hdc
, INT left
, INT top
, INT colorRef
)
412 SelectObject ( hdc
, GetSysColorPen (colorRef
));
415 MoveToEx (hdc
, x
, y
, NULL
);
416 LineTo (hdc
, x
+5, y
++); x
++;
417 MoveToEx (hdc
, x
, y
, NULL
);
418 LineTo (hdc
, x
+3, y
++); x
++;
419 MoveToEx (hdc
, x
, y
, NULL
);
420 LineTo (hdc
, x
+1, y
++);
424 * Draw the text string for this button.
425 * note: infoPtr->himlDis *SHOULD* be non-zero when infoPtr->himlDef
426 * is non-zero, so we can simply check himlDef to see if we have
430 TOOLBAR_DrawString (TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
,
431 HDC hdc
, INT nState
, DWORD dwStyle
)
433 RECT rcText
= btnPtr
->rect
;
436 LPWSTR lpText
= NULL
;
437 HIMAGELIST himl
= infoPtr
->himlDef
;
439 TRACE ("iString: %x\n", btnPtr
->iString
);
441 /* get a pointer to the text */
442 lpText
= TOOLBAR_GetText(infoPtr
, btnPtr
);
444 TRACE ("lpText: %s\n", debugstr_w(lpText
));
449 InflateRect (&rcText
, -3, -3);
451 if (himl
&& TOOLBAR_IsValidBitmapIndex(infoPtr
,btnPtr
->iBitmap
)) {
452 /* The following test looked like this before
453 * I changed it. IE4 "Links" toolbar would not
454 * draw correctly with the original code. - GA 8/01
455 * ((dwStyle & TBSTYLE_LIST) &&
456 * ((btnPtr->fsStyle & TBSTYLE_AUTOSIZE) == 0) &&
457 * (btnPtr->iBitmap != I_IMAGENONE))
459 if (dwStyle
& TBSTYLE_LIST
) {
460 /* LIST style w/ ICON offset is by matching native. */
461 /* Matches IE4 "Links" bar. - GA 8/01 */
462 rcText
.left
+= (infoPtr
->nBitmapWidth
+ 2);
465 rcText
.top
+= infoPtr
->nBitmapHeight
+ 1;
469 if (dwStyle
& TBSTYLE_LIST
) {
470 /* LIST style w/o ICON offset is by matching native. */
471 /* Matches IE4 "menu" bar. - GA 8/01 */
476 if (nState
& (TBSTATE_PRESSED
| TBSTATE_CHECKED
))
477 OffsetRect (&rcText
, 1, 1);
479 TRACE("string rect=(%d,%d)-(%d,%d)\n",
480 rcText
.left
, rcText
.top
, rcText
.right
, rcText
.bottom
);
482 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
483 if (!(nState
& TBSTATE_ENABLED
)) {
484 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_3DHILIGHT
));
485 OffsetRect (&rcText
, 1, 1);
486 DrawTextW (hdc
, lpText
, -1, &rcText
, infoPtr
->dwDTFlags
);
487 SetTextColor (hdc
, GetSysColor (COLOR_3DSHADOW
));
488 OffsetRect (&rcText
, -1, -1);
489 DrawTextW (hdc
, lpText
, -1, &rcText
, infoPtr
->dwDTFlags
);
491 else if (nState
& TBSTATE_INDETERMINATE
) {
492 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_3DSHADOW
));
493 DrawTextW (hdc
, lpText
, -1, &rcText
, infoPtr
->dwDTFlags
);
496 clrOld
= SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
497 DrawTextW (hdc
, lpText
, -1, &rcText
, infoPtr
->dwDTFlags
);
500 SetTextColor (hdc
, clrOld
);
501 SelectObject (hdc
, hOldFont
);
507 TOOLBAR_DrawPattern (HDC hdc
, LPRECT lpRect
)
509 HBRUSH hbr
= SelectObject (hdc
, COMCTL32_hPattern55AABrush
);
510 INT cx
= lpRect
->right
- lpRect
->left
;
511 INT cy
= lpRect
->bottom
- lpRect
->top
;
512 PatBlt (hdc
, lpRect
->left
, lpRect
->top
, cx
, cy
, 0x00FA0089);
513 SelectObject (hdc
, hbr
);
518 TOOLBAR_DrawMasked (TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
,
519 HDC hdc
, INT x
, INT y
)
521 /* FIXME: this function is a hack since it uses image list
522 internals directly */
524 HIMAGELIST himl
= infoPtr
->himlDef
;
532 /* create new dc's */
533 hdcImageList
= CreateCompatibleDC (0);
534 hdcMask
= CreateCompatibleDC (0);
536 /* create new bitmap */
537 hbmMask
= CreateBitmap (himl
->cx
, himl
->cy
, 1, 1, NULL
);
538 SelectObject (hdcMask
, hbmMask
);
540 /* copy the mask bitmap */
541 SelectObject (hdcImageList
, himl
->hbmMask
);
542 SetBkColor (hdcImageList
, RGB(255, 255, 255));
543 SetTextColor (hdcImageList
, RGB(0, 0, 0));
544 BitBlt (hdcMask
, 0, 0, himl
->cx
, himl
->cy
,
545 hdcImageList
, himl
->cx
* btnPtr
->iBitmap
, 0, SRCCOPY
);
547 /* draw the new mask */
548 SelectObject (hdc
, GetSysColorBrush (COLOR_3DHILIGHT
));
549 BitBlt (hdc
, x
+1, y
+1, himl
->cx
, himl
->cy
,
550 hdcMask
, 0, 0, 0xB8074A);
552 SelectObject (hdc
, GetSysColorBrush (COLOR_3DSHADOW
));
553 BitBlt (hdc
, x
, y
, himl
->cx
, himl
->cy
,
554 hdcMask
, 0, 0, 0xB8074A);
556 DeleteObject (hbmMask
);
558 DeleteDC (hdcImageList
);
563 TOOLBAR_DrawButton (HWND hwnd
, TBUTTON_INFO
*btnPtr
, HDC hdc
)
565 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
566 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
567 BOOL hasDropDownArrow
= TOOLBAR_HasDropDownArrows(infoPtr
->dwExStyle
) &&
568 (btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
);
569 RECT rc
, rcArrow
, rcBitmap
;
571 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
575 CopyRect (&rcArrow
, &rc
);
576 CopyRect(&rcBitmap
, &rc
);
578 if (!infoPtr
->bBtnTranspnt
)
579 FillRect( hdc
, &rc
, GetSysColorBrush(COLOR_BTNFACE
));
581 if (hasDropDownArrow
)
583 if (dwStyle
& TBSTYLE_FLAT
)
584 rc
.right
= max(rc
.left
, rc
.right
- DDARROW_WIDTH
);
586 rc
.right
= max(rc
.left
, rc
.right
- DDARROW_WIDTH
- 2);
587 rcArrow
.left
= rc
.right
;
590 /* Center the bitmap horizontally and vertically */
591 if (dwStyle
& TBSTYLE_LIST
)
594 rcBitmap
.left
+=(infoPtr
->nButtonWidth
- infoPtr
->nBitmapWidth
) / 2;
596 if(TOOLBAR_HasText(infoPtr
, btnPtr
))
597 rcBitmap
.top
+=2; /* this looks to be the correct value from vmware comparison - cmm */
599 rcBitmap
.top
+=(infoPtr
->nButtonHeight
- infoPtr
->nBitmapHeight
) / 2;
601 TRACE("iBitmap: %d, start=(%d,%d) w=%d, h=%d\n",
602 btnPtr
->iBitmap
, rcBitmap
.left
, rcBitmap
.top
,
603 infoPtr
->nBitmapWidth
, infoPtr
->nBitmapHeight
);
606 if (btnPtr
->fsStyle
& TBSTYLE_SEP
) {
607 /* with the FLAT style, iBitmap is the width and has already */
608 /* been taken into consideration in calculating the width */
609 /* so now we need to draw the vertical separator */
610 /* empirical tests show that iBitmap can/will be non-zero */
611 /* when drawing the vertical bar... */
612 if ((dwStyle
& TBSTYLE_FLAT
) /* && (btnPtr->iBitmap == 0) */) {
613 if (btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
)
614 TOOLBAR_DrawDDFlatSeparator (&rc
, hdc
, btnPtr
);
616 TOOLBAR_DrawFlatSeparator (&rc
, hdc
);
622 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
)) {
623 if (!(dwStyle
& TBSTYLE_FLAT
))
625 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
626 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
627 if (hasDropDownArrow
)
628 DrawEdge (hdc
, &rcArrow
, EDGE_RAISED
,
629 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
632 if (hasDropDownArrow
)
634 TOOLBAR_DrawArrow(hdc
, rcArrow
.left
+1, rcArrow
.top
+1, COLOR_3DHIGHLIGHT
);
635 TOOLBAR_DrawArrow(hdc
, rcArrow
.left
, rcArrow
.top
, COLOR_3DSHADOW
);
638 if (!TOOLBAR_DrawImageList (infoPtr
, btnPtr
, infoPtr
->himlDis
,
639 hdc
, rcBitmap
.left
, rcBitmap
.top
,
641 TOOLBAR_DrawMasked (infoPtr
, btnPtr
, hdc
, rcBitmap
.left
, rcBitmap
.top
);
643 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
);
647 /* pressed TBSTYLE_BUTTON */
648 if (btnPtr
->fsState
& TBSTATE_PRESSED
) {
649 if (dwStyle
& TBSTYLE_FLAT
)
651 DrawEdge (hdc
, &rc
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
652 if (hasDropDownArrow
)
653 DrawEdge (hdc
, &rcArrow
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
657 DrawEdge (hdc
, &rc
, EDGE_SUNKEN
, BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
658 if (hasDropDownArrow
)
659 DrawEdge (hdc
, &rcArrow
, EDGE_SUNKEN
, BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
662 if (hasDropDownArrow
)
663 TOOLBAR_DrawArrow(hdc
, rcArrow
.left
, rcArrow
.top
, COLOR_WINDOWFRAME
);
665 TOOLBAR_DrawImageList (infoPtr
, btnPtr
, infoPtr
->himlDef
,
666 hdc
, rcBitmap
.left
+1, rcBitmap
.top
+1,
669 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
);
673 /* checked TBSTYLE_CHECK */
674 if ((btnPtr
->fsStyle
& TBSTYLE_CHECK
) &&
675 (btnPtr
->fsState
& TBSTATE_CHECKED
)) {
676 if (dwStyle
& TBSTYLE_FLAT
)
677 DrawEdge (hdc
, &rc
, BDR_SUNKENOUTER
,
678 BF_RECT
| BF_ADJUST
);
680 DrawEdge (hdc
, &rc
, EDGE_SUNKEN
,
681 BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
683 TOOLBAR_DrawPattern (hdc
, &rc
);
685 TOOLBAR_DrawImageList (infoPtr
, btnPtr
, infoPtr
->himlDef
,
686 hdc
, rcBitmap
.left
+1, rcBitmap
.top
+1,
689 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
);
694 if (btnPtr
->fsState
& TBSTATE_INDETERMINATE
) {
695 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
696 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
698 TOOLBAR_DrawPattern (hdc
, &rc
);
699 TOOLBAR_DrawMasked (infoPtr
, btnPtr
, hdc
, rcBitmap
.left
, rcBitmap
.top
);
700 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
);
705 if (dwStyle
& TBSTYLE_FLAT
)
709 DrawEdge (hdc
, &rc
, BDR_RAISEDINNER
, BF_RECT
);
710 if (hasDropDownArrow
)
711 DrawEdge (hdc
, &rcArrow
, BDR_RAISEDINNER
, BF_RECT
);
714 else /* The following code needs to be removed after
715 * "hot item" support has been implemented for the
716 * case where it is being de-selected.
719 FrameRect(hdc
, &rc
, GetSysColorBrush(COLOR_BTNFACE
));
720 if (hasDropDownArrow
)
721 FrameRect(hdc
, &rcArrow
, GetSysColorBrush(COLOR_BTNFACE
));
725 if (hasDropDownArrow
)
726 TOOLBAR_DrawArrow(hdc
, rcArrow
.left
+1, rcArrow
.top
, COLOR_WINDOWFRAME
);
729 /* if hot, attempt to draw with himlHot, if fails, use himlDef */
730 if (!TOOLBAR_DrawImageList (infoPtr
, btnPtr
,
733 rcBitmap
.top
, ILD_NORMAL
))
734 TOOLBAR_DrawImageList (infoPtr
, btnPtr
, infoPtr
->himlDef
,
735 hdc
, rcBitmap
.left
, rcBitmap
.top
,
739 TOOLBAR_DrawImageList (infoPtr
, btnPtr
, infoPtr
->himlDef
,
740 hdc
, rcBitmap
.left
, rcBitmap
.top
,
745 DrawEdge (hdc
, &rc
, EDGE_RAISED
,
746 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
748 if (hasDropDownArrow
)
750 DrawEdge (hdc
, &rcArrow
, EDGE_RAISED
,
751 BF_SOFT
| BF_RECT
| BF_MIDDLE
| BF_ADJUST
);
752 TOOLBAR_DrawArrow(hdc
, rcArrow
.left
, rcArrow
.top
, COLOR_WINDOWFRAME
);
755 TOOLBAR_DrawImageList (infoPtr
, btnPtr
, infoPtr
->himlDef
,
756 hdc
, rcBitmap
.left
, rcBitmap
.top
,
760 TOOLBAR_DrawString (infoPtr
, btnPtr
, hdc
, btnPtr
->fsState
, dwStyle
);
765 TOOLBAR_Refresh (HWND hwnd
, HDC hdc
, PAINTSTRUCT
* ps
)
767 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
768 TBUTTON_INFO
*btnPtr
;
769 INT i
, oldBKmode
= 0;
772 /* if imagelist belongs to the app, it can be changed
773 by the app after setting it */
774 if (infoPtr
->himlDef
!= infoPtr
->himlInt
)
775 infoPtr
->nNumBitmaps
= ImageList_GetImageCount(infoPtr
->himlDef
);
777 TOOLBAR_DumpToolbar (infoPtr
, __LINE__
);
779 if (infoPtr
->bBtnTranspnt
)
780 oldBKmode
= SetBkMode (hdc
, TRANSPARENT
);
782 /* redraw necessary buttons */
783 btnPtr
= infoPtr
->buttons
;
784 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++)
786 if(IntersectRect(&rcTemp
, &(ps
->rcPaint
), &(btnPtr
->rect
)))
787 TOOLBAR_DrawButton (hwnd
, btnPtr
, hdc
);
790 if (infoPtr
->bBtnTranspnt
&& (oldBKmode
!= TRANSPARENT
))
791 SetBkMode (hdc
, oldBKmode
);
794 /***********************************************************************
795 * TOOLBAR_MeasureString
797 * This function gets the width and height of a string in pixels. This
798 * is done first by using GetTextExtentPoint to get the basic width
799 * and height. The DrawText is called with DT_CALCRECT to get the exact
800 * width. The reason is because the text may have more than one "&" (or
801 * prefix characters as M$ likes to call them). The prefix character
802 * indicates where the underline goes, except for the string "&&" which
803 * is reduced to a single "&". GetTextExtentPoint does not process these
804 * only DrawText does. Note that the TBSTYLE_NOPREFIX is handled here.
807 TOOLBAR_MeasureString(TOOLBAR_INFO
*infoPtr
, TBUTTON_INFO
*btnPtr
,
808 HDC hdc
, LPSIZE lpSize
)
815 if (!(btnPtr
->fsState
& TBSTATE_HIDDEN
) &&
816 (btnPtr
->iString
> -1) &&
817 (btnPtr
->iString
< infoPtr
->nNumStrings
))
819 LPWSTR lpText
= infoPtr
->strings
[btnPtr
->iString
];
821 /* first get size of all the text */
822 GetTextExtentPoint32W (hdc
, lpText
, strlenW (lpText
), lpSize
);
824 /* feed above size into the rectangle for DrawText */
825 myrect
.left
= myrect
.top
= 0;
826 myrect
.right
= lpSize
->cx
;
827 myrect
.bottom
= lpSize
->cy
;
829 /* Use DrawText to get true size as drawn (less pesky "&") */
830 DrawTextW (hdc
, lpText
, -1, &myrect
, DT_VCENTER
| DT_SINGLELINE
|
831 DT_CALCRECT
| ((btnPtr
->fsStyle
& TBSTYLE_NOPREFIX
) ?
834 /* feed back to caller */
835 lpSize
->cx
= myrect
.right
;
836 lpSize
->cy
= myrect
.bottom
;
839 TRACE("string size %ld x %ld!\n", lpSize
->cx
, lpSize
->cy
);
842 /***********************************************************************
843 * TOOLBAR_CalcStrings
845 * This function walks through each string and measures it and returns
846 * the largest height and width to caller.
849 TOOLBAR_CalcStrings (HWND hwnd
, LPSIZE lpSize
)
851 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
852 TBUTTON_INFO
*btnPtr
;
862 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
864 btnPtr
= infoPtr
->buttons
;
865 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
866 if(TOOLBAR_HasText(infoPtr
, btnPtr
))
868 TOOLBAR_MeasureString(infoPtr
, btnPtr
, hdc
, &sz
);
869 if (sz
.cx
> lpSize
->cx
)
871 if (sz
.cy
> lpSize
->cy
)
876 SelectObject (hdc
, hOldFont
);
877 ReleaseDC (hwnd
, hdc
);
879 TRACE("max string size %ld x %ld!\n", lpSize
->cx
, lpSize
->cy
);
882 /***********************************************************************
883 * TOOLBAR_WrapToolbar
885 * This function walks through the buttons and seperators in the
886 * toolbar, and sets the TBSTATE_WRAP flag only on those items where
887 * wrapping should occur based on the width of the toolbar window.
888 * It does *not* calculate button placement itself. That task
889 * takes place in TOOLBAR_CalcToolbar. If the program wants to manage
890 * the toolbar wrapping on its own, it can use the TBSTYLE_WRAPABLE
891 * flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
895 TOOLBAR_WrapToolbar( HWND hwnd
, DWORD dwStyle
)
897 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
898 TBUTTON_INFO
*btnPtr
;
901 BOOL bWrap
, bButtonWrap
;
903 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
904 /* no layout is necessary. Applications may use this style */
905 /* to perform their own layout on the toolbar. */
906 if( !(dwStyle
& TBSTYLE_WRAPABLE
) )
909 btnPtr
= infoPtr
->buttons
;
910 x
= infoPtr
->nIndent
;
912 /* this can get the parents width, to know how far we can extend
913 * this toolbar. We cannot use its height, as there may be multiple
914 * toolbars in a rebar control
916 GetClientRect( GetParent(hwnd
), &rc
);
917 infoPtr
->nWidth
= rc
.right
- rc
.left
;
920 TRACE("start ButtonWidth=%d, BitmapWidth=%d, nWidth=%d, nIndent=%d\n",
921 infoPtr
->nButtonWidth
, infoPtr
->nBitmapWidth
, infoPtr
->nWidth
,
924 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++ )
927 btnPtr
[i
].fsState
&= ~TBSTATE_WRAP
;
929 if (btnPtr
[i
].fsState
& TBSTATE_HIDDEN
)
932 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
933 /* it is the actual width of the separator. This is used for */
934 /* custom controls in toolbars. */
936 /* TBSTYLE_DROPDOWN separators are treated as buttons for */
937 /* width. - GA 8/01 */
938 if ((btnPtr
[i
].fsStyle
& TBSTYLE_SEP
) &&
939 !(btnPtr
[i
].fsStyle
& TBSTYLE_DROPDOWN
))
940 cx
= (btnPtr
[i
].iBitmap
> 0) ?
941 btnPtr
[i
].iBitmap
: SEPARATOR_WIDTH
;
943 cx
= infoPtr
->nButtonWidth
;
945 /* Two or more adjacent separators form a separator group. */
946 /* The first separator in a group should be wrapped to the */
947 /* next row if the previous wrapping is on a button. */
949 (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
) &&
950 (i
+ 1 < infoPtr
->nNumButtons
) &&
951 (btnPtr
[i
+ 1].fsStyle
& TBSTYLE_SEP
) )
953 TRACE("wrap point 1 btn %d style %02x\n", i
, btnPtr
[i
].fsStyle
);
954 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
955 x
= infoPtr
->nIndent
;
961 /* The layout makes sure the bitmap is visible, but not the button. */
962 /* Test added to also wrap after a button that starts a row but */
963 /* is bigger than the area. - GA 8/01 */
964 if (( x
+ cx
- (infoPtr
->nButtonWidth
- infoPtr
->nBitmapWidth
) / 2
965 > infoPtr
->nWidth
) ||
966 ((x
== infoPtr
->nIndent
) && (cx
> infoPtr
->nWidth
)))
970 /* If the current button is a separator and not hidden, */
971 /* go to the next until it reaches a non separator. */
972 /* Wrap the last separator if it is before a button. */
973 while( ( (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
) ||
974 (btnPtr
[i
].fsState
& TBSTATE_HIDDEN
) ) &&
975 i
< infoPtr
->nNumButtons
)
981 if( bFound
&& i
< infoPtr
->nNumButtons
)
984 TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n",
985 i
, btnPtr
[i
].fsStyle
, x
, cx
);
986 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
987 x
= infoPtr
->nIndent
;
991 else if ( i
>= infoPtr
->nNumButtons
)
994 /* If the current button is not a separator, find the last */
995 /* separator and wrap it. */
996 for ( j
= i
- 1; j
>= 0 && !(btnPtr
[j
].fsState
& TBSTATE_WRAP
); j
--)
998 if ((btnPtr
[j
].fsStyle
& TBSTYLE_SEP
) &&
999 !(btnPtr
[j
].fsState
& TBSTATE_HIDDEN
))
1003 TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n",
1004 i
, btnPtr
[i
].fsStyle
, x
, cx
);
1005 x
= infoPtr
->nIndent
;
1006 btnPtr
[j
].fsState
|= TBSTATE_WRAP
;
1007 bButtonWrap
= FALSE
;
1012 /* If no separator available for wrapping, wrap one of */
1013 /* non-hidden previous button. */
1017 j
>= 0 && !(btnPtr
[j
].fsState
& TBSTATE_WRAP
); j
--)
1019 if (btnPtr
[j
].fsState
& TBSTATE_HIDDEN
)
1024 TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n",
1025 i
, btnPtr
[i
].fsStyle
, x
, cx
);
1026 x
= infoPtr
->nIndent
;
1027 btnPtr
[j
].fsState
|= TBSTATE_WRAP
;
1033 /* If all above failed, wrap the current button. */
1036 TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n",
1037 i
, btnPtr
[i
].fsStyle
, x
, cx
);
1038 btnPtr
[i
].fsState
|= TBSTATE_WRAP
;
1040 x
= infoPtr
->nIndent
;
1041 if (btnPtr
[i
].fsStyle
& TBSTYLE_SEP
)
1042 bButtonWrap
= FALSE
;
1048 TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n",
1049 i
, btnPtr
[i
].fsStyle
, x
, cx
);
1056 /***********************************************************************
1057 * TOOLBAR_CalcToolbar
1059 * This function calculates button and separator placement. It first
1060 * calculates the button sizes, gets the toolbar window width and then
1061 * calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
1062 * on. It assigns a new location to each item and sends this location to
1063 * the tooltip window if appropriate. Finally, it updates the rcBound
1064 * rect and calculates the new required toolbar window height.
1068 TOOLBAR_CalcToolbar (HWND hwnd
)
1070 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
1071 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1072 TBUTTON_INFO
*btnPtr
;
1073 INT i
, nRows
, nSepRows
;
1077 BOOL usesBitmaps
= FALSE
;
1078 BOOL hasDropDownArrows
= TOOLBAR_HasDropDownArrows(infoPtr
->dwExStyle
);
1080 TOOLBAR_CalcStrings (hwnd
, &sizeString
);
1082 if (dwStyle
& TBSTYLE_LIST
)
1084 for (i
= 0; i
< infoPtr
->nNumButtons
&& !usesBitmaps
; i
++)
1086 if (infoPtr
->buttons
[i
].iBitmap
>= 0)
1089 infoPtr
->nButtonHeight
= max((usesBitmaps
) ? infoPtr
->nBitmapHeight
:
1090 0, sizeString
.cy
) + 6;
1091 infoPtr
->nButtonWidth
= ((usesBitmaps
) ? infoPtr
->nBitmapWidth
:
1092 0) + sizeString
.cx
+ 6;
1093 TRACE("LIST style, But w=%d h=%d, useBitmaps=%d, Bit w=%d h=%d\n",
1094 infoPtr
->nButtonWidth
, infoPtr
->nButtonHeight
, usesBitmaps
,
1095 infoPtr
->nBitmapWidth
, infoPtr
->nBitmapHeight
);
1096 TOOLBAR_DumpToolbar (infoPtr
, __LINE__
);
1099 for (i
= 0; i
< infoPtr
->nNumButtons
&& !usesBitmaps
; i
++)
1101 if (TOOLBAR_IsValidBitmapIndex(infoPtr
,infoPtr
->buttons
[i
].iBitmap
))
1105 if (sizeString
.cy
> 0)
1108 infoPtr
->nButtonHeight
= sizeString
.cy
+
1109 2 + /* this is the space to separate text from bitmap */
1110 infoPtr
->nBitmapHeight
+ 6;
1112 infoPtr
->nButtonHeight
= sizeString
.cy
+ 6;
1114 else if (infoPtr
->nButtonHeight
< infoPtr
->nBitmapHeight
+ 6)
1115 infoPtr
->nButtonHeight
= infoPtr
->nBitmapHeight
+ 6;
1117 if (sizeString
.cx
> infoPtr
->nBitmapWidth
)
1118 infoPtr
->nButtonWidth
= sizeString
.cx
+ 6;
1119 else if (infoPtr
->nButtonWidth
< infoPtr
->nBitmapWidth
+ 6)
1120 infoPtr
->nButtonWidth
= infoPtr
->nBitmapWidth
+ 6;
1123 if ( infoPtr
->cxMin
>= 0 && infoPtr
->nButtonWidth
< infoPtr
->cxMin
)
1124 infoPtr
->nButtonWidth
= infoPtr
->cxMin
;
1125 if ( infoPtr
->cxMax
> 0 && infoPtr
->nButtonWidth
> infoPtr
->cxMax
)
1126 infoPtr
->nButtonWidth
= infoPtr
->cxMax
;
1128 TOOLBAR_WrapToolbar( hwnd
, dwStyle
);
1130 x
= infoPtr
->nIndent
;
1134 * We will set the height below, and we set the width on entry
1135 * so we do not reset them here..
1138 GetClientRect( hwnd
, &rc
);
1139 /* get initial values for toolbar */
1140 infoPtr
->nWidth
= rc
.right
- rc
.left
;
1141 infoPtr
->nHeight
= rc
.bottom
- rc
.top
;
1144 /* from above, minimum is a button, and possible text */
1145 cx
= infoPtr
->nButtonWidth
;
1147 /* cannot use just ButtonHeight, we may have no buttons! */
1148 if (infoPtr
->nNumButtons
> 0)
1149 infoPtr
->nHeight
= infoPtr
->nButtonHeight
;
1151 cy
= infoPtr
->nHeight
;
1153 nRows
= nSepRows
= 0;
1155 infoPtr
->rcBound
.top
= y
;
1156 infoPtr
->rcBound
.left
= x
;
1157 infoPtr
->rcBound
.bottom
= y
+ cy
;
1158 infoPtr
->rcBound
.right
= x
;
1160 btnPtr
= infoPtr
->buttons
;
1162 /* do not base height/width on parent, if the parent is a */
1163 /* rebar control it could have multiple rows of toolbars */
1164 /* GetClientRect( GetParent(hwnd), &rc ); */
1165 /* cx = rc.right - rc.left; */
1166 /* cy = rc.bottom - rc.top; */
1168 TRACE("cy=%d\n", cy
);
1170 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++ )
1173 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
1175 SetRectEmpty (&btnPtr
->rect
);
1179 cy
= infoPtr
->nHeight
;
1181 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
1182 /* it is the actual width of the separator. This is used for */
1183 /* custom controls in toolbars. */
1184 if (btnPtr
->fsStyle
& TBSTYLE_SEP
) {
1185 if (btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
) {
1186 cy
= (btnPtr
->iBitmap
> 0) ?
1187 btnPtr
->iBitmap
: SEPARATOR_WIDTH
;
1188 cx
= infoPtr
->nButtonWidth
;
1191 cx
= (btnPtr
->iBitmap
> 0) ?
1192 btnPtr
->iBitmap
: SEPARATOR_WIDTH
;
1196 if (btnPtr
->fsStyle
& TBSTYLE_AUTOSIZE
)
1203 hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
1205 TOOLBAR_MeasureString(infoPtr
, btnPtr
, hdc
, &sz
);
1207 SelectObject (hdc
, hOldFont
);
1208 ReleaseDC (hwnd
, hdc
);
1210 /* Fudge amount measured against IE4 "menu" and "Links" */
1211 /* toolbars with native control (v4.71). - GA 8/01 */
1212 cx
= sz
.cx
+ 6 + 5 + 5;
1213 if ((dwStyle
& TBSTYLE_LIST
) &&
1214 (TOOLBAR_TestImageExist (infoPtr
, btnPtr
, infoPtr
->himlDef
)))
1215 cx
+= infoPtr
->nBitmapWidth
;
1218 cx
= infoPtr
->nButtonWidth
;
1220 if (hasDropDownArrows
&& (btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
))
1221 cx
+= DDARROW_WIDTH
;
1223 if (btnPtr
->fsState
& TBSTATE_WRAP
)
1226 SetRect (&btnPtr
->rect
, x
, y
, x
+ cx
, y
+ cy
);
1228 if (infoPtr
->rcBound
.left
> x
)
1229 infoPtr
->rcBound
.left
= x
;
1230 if (infoPtr
->rcBound
.right
< x
+ cx
)
1231 infoPtr
->rcBound
.right
= x
+ cx
;
1232 if (infoPtr
->rcBound
.bottom
< y
+ cy
)
1233 infoPtr
->rcBound
.bottom
= y
+ cy
;
1235 /* Set the toolTip only for non-hidden, non-separator button */
1236 if (infoPtr
->hwndToolTip
&& !(btnPtr
->fsStyle
& TBSTYLE_SEP
))
1240 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
1241 ti
.cbSize
= sizeof(TTTOOLINFOA
);
1243 ti
.uId
= btnPtr
->idCommand
;
1244 ti
.rect
= btnPtr
->rect
;
1245 SendMessageA (infoPtr
->hwndToolTip
, TTM_NEWTOOLRECTA
,
1249 /* btnPtr->nRow is zero based. The space between the rows is */
1250 /* also considered as a row. */
1251 btnPtr
->nRow
= nRows
+ nSepRows
;
1253 TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d\n",
1254 i
, btnPtr
->fsStyle
, bWrap
, nRows
, nSepRows
, btnPtr
->nRow
);
1258 if ( !(btnPtr
->fsStyle
& TBSTYLE_SEP
) )
1262 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
1263 /* it is the actual width of the separator. This is used for */
1264 /* custom controls in toolbars. */
1265 if ( !(btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
))
1266 y
+= cy
+ ( (btnPtr
->iBitmap
> 0 ) ?
1267 btnPtr
->iBitmap
: SEPARATOR_WIDTH
) * 2 /3;
1271 /* nSepRows is used to calculate the extra height follwoing */
1275 x
= infoPtr
->nIndent
;
1282 /* infoPtr->nRows is the number of rows on the toolbar */
1283 infoPtr
->nRows
= nRows
+ nSepRows
+ 1;
1285 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
1287 infoPtr
->nHeight
= TOP_BORDER
+ (nRows
+ 1) * infoPtr
->nButtonHeight
+
1288 nSepRows
* (SEPARATOR_WIDTH
* 2 / 3) +
1289 nSepRows
* (infoPtr
->nBitmapHeight
+ 1) +
1291 TRACE("toolbar height %d, button width %d\n", infoPtr
->nHeight
, infoPtr
->nButtonWidth
);
1296 TOOLBAR_InternalHitTest (HWND hwnd
, LPPOINT lpPt
)
1298 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1299 TBUTTON_INFO
*btnPtr
;
1302 btnPtr
= infoPtr
->buttons
;
1303 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
1304 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
1307 if (btnPtr
->fsStyle
& TBSTYLE_SEP
) {
1308 if (PtInRect (&btnPtr
->rect
, *lpPt
)) {
1309 TRACE(" ON SEPARATOR %d!\n", i
);
1314 if (PtInRect (&btnPtr
->rect
, *lpPt
)) {
1315 TRACE(" ON BUTTON %d!\n", i
);
1321 TRACE(" NOWHERE!\n");
1327 TOOLBAR_GetButtonIndex (TOOLBAR_INFO
*infoPtr
, INT idCommand
, BOOL CommandIsIndex
)
1329 TBUTTON_INFO
*btnPtr
;
1332 if (CommandIsIndex
) {
1333 TRACE("command is really index command=%d\n", idCommand
);
1336 btnPtr
= infoPtr
->buttons
;
1337 for (i
= 0; i
< infoPtr
->nNumButtons
; i
++, btnPtr
++) {
1338 if (btnPtr
->idCommand
== idCommand
) {
1339 TRACE("command=%d index=%d\n", idCommand
, i
);
1343 TRACE("no index found for command=%d\n", idCommand
);
1349 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO
*infoPtr
, INT nIndex
)
1351 TBUTTON_INFO
*btnPtr
;
1354 if ((nIndex
< 0) || (nIndex
> infoPtr
->nNumButtons
))
1357 /* check index button */
1358 btnPtr
= &infoPtr
->buttons
[nIndex
];
1359 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
1360 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
1364 /* check previous buttons */
1365 nRunIndex
= nIndex
- 1;
1366 while (nRunIndex
>= 0) {
1367 btnPtr
= &infoPtr
->buttons
[nRunIndex
];
1368 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
1369 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
1377 /* check next buttons */
1378 nRunIndex
= nIndex
+ 1;
1379 while (nRunIndex
< infoPtr
->nNumButtons
) {
1380 btnPtr
= &infoPtr
->buttons
[nRunIndex
];
1381 if ((btnPtr
->fsStyle
& TBSTYLE_CHECKGROUP
) == TBSTYLE_CHECKGROUP
) {
1382 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
1395 TOOLBAR_RelayEvent (HWND hwndTip
, HWND hwndMsg
, UINT uMsg
,
1396 WPARAM wParam
, LPARAM lParam
)
1402 msg
.wParam
= wParam
;
1403 msg
.lParam
= lParam
;
1404 msg
.time
= GetMessageTime ();
1405 msg
.pt
.x
= LOWORD(GetMessagePos ());
1406 msg
.pt
.y
= HIWORD(GetMessagePos ());
1408 SendMessageA (hwndTip
, TTM_RELAYEVENT
, 0, (LPARAM
)&msg
);
1412 /***********************************************************************
1413 * TOOLBAR_CustomizeDialogProc
1414 * This function implements the toolbar customization dialog.
1417 TOOLBAR_CustomizeDialogProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1419 PCUSTDLG_INFO custInfo
= (PCUSTDLG_INFO
)GetWindowLongA (hwnd
, DWL_USER
);
1420 PCUSTOMBUTTON btnInfo
;
1422 TOOLBAR_INFO
*infoPtr
= custInfo
? custInfo
->tbInfo
: NULL
;
1427 custInfo
= (PCUSTDLG_INFO
)lParam
;
1428 SetWindowLongA (hwnd
, DWL_USER
, (DWORD
)custInfo
);
1436 infoPtr
= custInfo
->tbInfo
;
1438 /* send TBN_QUERYINSERT notification */
1439 nmtb
.iItem
= custInfo
->tbInfo
->nNumButtons
;
1441 if (!TOOLBAR_SendNotify ((NMHDR
*) &nmtb
, infoPtr
, TBN_QUERYINSERT
))
1444 /* add items to 'toolbar buttons' list and check if removable */
1445 for (i
= 0; i
< custInfo
->tbInfo
->nNumButtons
; i
++)
1447 btnInfo
= (PCUSTOMBUTTON
)COMCTL32_Alloc(sizeof(CUSTOMBUTTON
));
1448 memset (&btnInfo
->btn
, 0, sizeof(TBBUTTON
));
1449 btnInfo
->btn
.fsStyle
= TBSTYLE_SEP
;
1450 btnInfo
->bVirtual
= FALSE
;
1451 LoadStringA (COMCTL32_hModule
, IDS_SEPARATOR
, btnInfo
->text
, 64);
1453 /* send TBN_QUERYDELETE notification */
1455 btnInfo
->bRemovable
= TOOLBAR_SendNotify ((NMHDR
*) &nmtb
,
1459 index
= (int)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_ADDSTRING
, 0, 0);
1460 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1463 /* insert separator button into 'available buttons' list */
1464 btnInfo
= (PCUSTOMBUTTON
)COMCTL32_Alloc(sizeof(CUSTOMBUTTON
));
1465 memset (&btnInfo
->btn
, 0, sizeof(TBBUTTON
));
1466 btnInfo
->btn
.fsStyle
= TBSTYLE_SEP
;
1467 btnInfo
->bVirtual
= FALSE
;
1468 btnInfo
->bRemovable
= TRUE
;
1469 LoadStringA (COMCTL32_hModule
, IDS_SEPARATOR
, btnInfo
->text
, 64);
1470 index
= (int)SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_ADDSTRING
, 0, (LPARAM
)btnInfo
);
1471 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1473 /* insert all buttons into dsa */
1476 /* send TBN_GETBUTTONINFO notification */
1478 nmtb
.pszText
= Buffer
;
1481 if (!TOOLBAR_SendNotify ((NMHDR
*) &nmtb
, infoPtr
, TBN_GETBUTTONINFOA
))
1484 TRACE("style: %x\n", nmtb
.tbButton
.fsStyle
);
1486 /* insert button into the apropriate list */
1487 index
= TOOLBAR_GetButtonIndex (custInfo
->tbInfo
, nmtb
.tbButton
.idCommand
, FALSE
);
1490 btnInfo
= (PCUSTOMBUTTON
)COMCTL32_Alloc(sizeof(CUSTOMBUTTON
));
1491 memcpy (&btnInfo
->btn
, &nmtb
.tbButton
, sizeof(TBBUTTON
));
1492 btnInfo
->bVirtual
= FALSE
;
1493 btnInfo
->bRemovable
= TRUE
;
1494 if (!(nmtb
.tbButton
.fsStyle
& TBSTYLE_SEP
))
1495 strcpy (btnInfo
->text
, nmtb
.pszText
);
1497 index
= SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_ADDSTRING
, 0, 0);
1498 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1502 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1503 memcpy (&btnInfo
->btn
, &nmtb
.tbButton
, sizeof(TBBUTTON
));
1504 if (!(nmtb
.tbButton
.fsStyle
& TBSTYLE_SEP
))
1505 strcpy (btnInfo
->text
, nmtb
.pszText
);
1507 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1511 /* select first item in the 'available' list */
1512 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETCURSEL
, 0, 0);
1514 /* append 'virtual' separator button to the 'toolbar buttons' list */
1515 btnInfo
= (PCUSTOMBUTTON
)COMCTL32_Alloc(sizeof(CUSTOMBUTTON
));
1516 memset (&btnInfo
->btn
, 0, sizeof(TBBUTTON
));
1517 btnInfo
->btn
.fsStyle
= TBSTYLE_SEP
;
1518 btnInfo
->bVirtual
= TRUE
;
1519 btnInfo
->bRemovable
= FALSE
;
1520 LoadStringA (COMCTL32_hModule
, IDS_SEPARATOR
, btnInfo
->text
, 64);
1521 index
= (int)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_ADDSTRING
, 0, (LPARAM
)btnInfo
);
1522 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1524 /* select last item in the 'toolbar' list */
1525 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETCURSEL
, index
, 0);
1526 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETTOPINDEX
, index
, 0);
1528 /* set focus and disable buttons */
1529 PostMessageA (hwnd
, WM_USER
, 0, 0);
1534 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), FALSE
);
1535 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), FALSE
);
1536 EnableWindow (GetDlgItem (hwnd
,IDC_REMOVE_BTN
), FALSE
);
1537 SetFocus (GetDlgItem (hwnd
, IDC_TOOLBARBTN_LBOX
));
1541 EndDialog(hwnd
, FALSE
);
1545 switch (LOWORD(wParam
))
1547 case IDC_TOOLBARBTN_LBOX
:
1548 if (HIWORD(wParam
) == LBN_SELCHANGE
)
1550 PCUSTOMBUTTON btnInfo
;
1555 count
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1556 index
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1558 /* send TBN_QUERYINSERT notification */
1560 TOOLBAR_SendNotify ((NMHDR
*) &nmtb
, infoPtr
,
1563 /* get list box item */
1564 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1566 if (index
== (count
- 1))
1568 /* last item (virtual separator) */
1569 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), FALSE
);
1570 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), FALSE
);
1572 else if (index
== (count
- 2))
1574 /* second last item (last non-virtual item) */
1575 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), TRUE
);
1576 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), FALSE
);
1578 else if (index
== 0)
1581 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), FALSE
);
1582 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), TRUE
);
1586 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), TRUE
);
1587 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), TRUE
);
1590 EnableWindow (GetDlgItem (hwnd
,IDC_REMOVE_BTN
), btnInfo
->bRemovable
);
1594 case IDC_MOVEUP_BTN
:
1596 PCUSTOMBUTTON btnInfo
;
1600 count
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1601 index
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1602 TRACE("Move up: index %d\n", index
);
1604 /* send TBN_QUERYINSERT notification */
1607 if (TOOLBAR_SendNotify ((NMHDR
*) &nmtb
, infoPtr
,
1610 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1612 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_DELETESTRING
, index
, 0);
1613 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_INSERTSTRING
, index
-1, 0);
1614 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
-1, (LPARAM
)btnInfo
);
1615 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETCURSEL
, index
-1 , 0);
1618 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), FALSE
);
1619 else if (index
>= (count
- 3))
1620 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), TRUE
);
1622 SendMessageA (custInfo
->tbHwnd
, TB_DELETEBUTTON
, index
, 0);
1623 SendMessageA (custInfo
->tbHwnd
, TB_INSERTBUTTONA
, index
-1, (LPARAM
)&(btnInfo
->btn
));
1628 case IDC_MOVEDN_BTN
: /* move down */
1630 PCUSTOMBUTTON btnInfo
;
1634 count
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1635 index
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1636 TRACE("Move up: index %d\n", index
);
1638 /* send TBN_QUERYINSERT notification */
1640 if (TOOLBAR_SendNotify ((NMHDR
*) &nmtb
, infoPtr
,
1643 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1645 /* move button down */
1646 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_DELETESTRING
, index
, 0);
1647 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_INSERTSTRING
, index
+1, 0);
1648 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
+1, (LPARAM
)btnInfo
);
1649 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETCURSEL
, index
+1 , 0);
1652 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEUP_BTN
), TRUE
);
1653 else if (index
>= (count
- 3))
1654 EnableWindow (GetDlgItem (hwnd
,IDC_MOVEDN_BTN
), FALSE
);
1656 SendMessageA (custInfo
->tbHwnd
, TB_DELETEBUTTON
, index
, 0);
1657 SendMessageA (custInfo
->tbHwnd
, TB_INSERTBUTTONA
, index
+1, (LPARAM
)&(btnInfo
->btn
));
1662 case IDC_REMOVE_BTN
: /* remove button */
1664 PCUSTOMBUTTON btnInfo
;
1667 index
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1668 TRACE("Remove: index %d\n", index
);
1670 /* send TBN_QUERYDELETE notification */
1672 if (TOOLBAR_SendNotify ((NMHDR
*) &nmtb
, infoPtr
,
1675 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1676 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_DELETESTRING
, index
, 0);
1677 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETCURSEL
, index
, 0);
1679 SendMessageA (custInfo
->tbHwnd
, TB_DELETEBUTTON
, index
, 0);
1681 /* insert into 'available button' list */
1682 if (!(btnInfo
->btn
.fsStyle
& TBSTYLE_SEP
))
1684 index
= (int)SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_ADDSTRING
, 0, 0);
1685 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1688 COMCTL32_Free (btnInfo
);
1693 case IDOK
: /* Add button */
1698 count
= SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1699 index
= SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1700 TRACE("Add: index %d\n", index
);
1702 /* send TBN_QUERYINSERT notification */
1704 if (TOOLBAR_SendNotify ((NMHDR
*) &nmtb
, infoPtr
,
1707 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_GETITEMDATA
, index
, 0);
1711 /* remove from 'available buttons' list */
1712 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_DELETESTRING
, index
, 0);
1713 if (index
== count
-1)
1714 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETCURSEL
, index
-1 , 0);
1716 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETCURSEL
, index
, 0);
1720 PCUSTOMBUTTON btnNew
;
1722 /* duplicate 'separator' button */
1723 btnNew
= (PCUSTOMBUTTON
)COMCTL32_Alloc (sizeof(CUSTOMBUTTON
));
1724 memcpy (btnNew
, btnInfo
, sizeof(CUSTOMBUTTON
));
1728 /* insert into 'toolbar button' list */
1729 index
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCURSEL
, 0, 0);
1730 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_INSERTSTRING
, index
, 0);
1731 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, index
, (LPARAM
)btnInfo
);
1733 SendMessageA (custInfo
->tbHwnd
, TB_INSERTBUTTONA
, index
, (LPARAM
)&(btnInfo
->btn
));
1739 EndDialog(hwnd
, FALSE
);
1749 /* delete items from 'toolbar buttons' listbox*/
1750 count
= SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1751 for (i
= 0; i
< count
; i
++)
1753 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_GETITEMDATA
, i
, 0);
1754 COMCTL32_Free(btnInfo
);
1755 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_SETITEMDATA
, 0, 0);
1757 SendDlgItemMessageA (hwnd
, IDC_TOOLBARBTN_LBOX
, LB_RESETCONTENT
, 0, 0);
1760 /* delete items from 'available buttons' listbox*/
1761 count
= SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_GETCOUNT
, 0, 0);
1762 for (i
= 0; i
< count
; i
++)
1764 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_GETITEMDATA
, i
, 0);
1765 COMCTL32_Free(btnInfo
);
1766 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_SETITEMDATA
, i
, 0);
1768 SendDlgItemMessageA (hwnd
, IDC_AVAILBTN_LBOX
, LB_RESETCONTENT
, 0, 0);
1773 if (wParam
== IDC_AVAILBTN_LBOX
|| wParam
== IDC_TOOLBARBTN_LBOX
)
1775 LPDRAWITEMSTRUCT lpdis
= (LPDRAWITEMSTRUCT
)lParam
;
1780 COLORREF oldText
= 0;
1784 btnInfo
= (PCUSTOMBUTTON
)SendDlgItemMessageA (hwnd
, wParam
, LB_GETITEMDATA
, (WPARAM
)lpdis
->itemID
, 0);
1785 if (btnInfo
== NULL
)
1787 FIXME("btnInfo invalid!\n");
1791 /* set colors and select objects */
1792 oldBk
= SetBkColor (lpdis
->hDC
, GetSysColor((lpdis
->itemState
& ODS_FOCUS
)?COLOR_HIGHLIGHT
:COLOR_WINDOW
));
1793 if (btnInfo
->bVirtual
)
1794 oldText
= SetTextColor (lpdis
->hDC
, GetSysColor(COLOR_GRAYTEXT
));
1796 oldText
= SetTextColor (lpdis
->hDC
, GetSysColor((lpdis
->itemState
& ODS_FOCUS
)?COLOR_HIGHLIGHTTEXT
:COLOR_WINDOWTEXT
));
1797 hOldPen
= SelectObject (lpdis
->hDC
, GetSysColorPen ((lpdis
->itemState
& ODS_SELECTED
)?COLOR_HIGHLIGHT
:COLOR_WINDOW
));
1798 hOldBrush
= SelectObject (lpdis
->hDC
, GetSysColorBrush ((lpdis
->itemState
& ODS_FOCUS
)?COLOR_HIGHLIGHT
:COLOR_WINDOW
));
1800 /* fill background rectangle */
1801 Rectangle (lpdis
->hDC
, lpdis
->rcItem
.left
, lpdis
->rcItem
.top
,
1802 lpdis
->rcItem
.right
, lpdis
->rcItem
.bottom
);
1804 /* calculate button and text rectangles */
1805 CopyRect (&rcButton
, &lpdis
->rcItem
);
1806 InflateRect (&rcButton
, -1, -1);
1807 CopyRect (&rcText
, &rcButton
);
1808 rcButton
.right
= rcButton
.left
+ custInfo
->tbInfo
->nBitmapWidth
+ 6;
1809 rcText
.left
= rcButton
.right
+ 2;
1811 /* draw focus rectangle */
1812 if (lpdis
->itemState
& ODS_FOCUS
)
1813 DrawFocusRect (lpdis
->hDC
, &lpdis
->rcItem
);
1816 DrawEdge (lpdis
->hDC
, &rcButton
, EDGE_RAISED
, BF_RECT
|BF_MIDDLE
|BF_SOFT
);
1818 /* draw image and text */
1819 if ((btnInfo
->btn
.fsStyle
& TBSTYLE_SEP
) == 0)
1820 ImageList_Draw (custInfo
->tbInfo
->himlDef
, btnInfo
->btn
.iBitmap
, lpdis
->hDC
,
1821 rcButton
.left
+3, rcButton
.top
+3, ILD_NORMAL
);
1822 DrawTextA (lpdis
->hDC
, btnInfo
->text
, -1, &rcText
,
1823 DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
);
1825 /* delete objects and reset colors */
1826 SelectObject (lpdis
->hDC
, hOldBrush
);
1827 SelectObject (lpdis
->hDC
, hOldPen
);
1828 SetBkColor (lpdis
->hDC
, oldBk
);
1829 SetTextColor (lpdis
->hDC
, oldText
);
1835 case WM_MEASUREITEM
:
1836 if (wParam
== IDC_AVAILBTN_LBOX
|| wParam
== IDC_TOOLBARBTN_LBOX
)
1838 MEASUREITEMSTRUCT
*lpmis
= (MEASUREITEMSTRUCT
*)lParam
;
1840 if (custInfo
&& custInfo
->tbInfo
)
1841 lpmis
->itemHeight
= custInfo
->tbInfo
->nBitmapHeight
+ 8;
1843 lpmis
->itemHeight
= 15 + 8; /* default height */
1855 /***********************************************************************
1856 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1860 TOOLBAR_AddBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1862 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
1863 LPTBADDBITMAP lpAddBmp
= (LPTBADDBITMAP
)lParam
;
1864 INT nIndex
= 0, nButtons
, nCount
;
1867 TRACE("hwnd=%x wParam=%x lParam=%lx\n", hwnd
, wParam
, lParam
);
1871 if (lpAddBmp
->hInst
== HINST_COMMCTRL
)
1873 if ((lpAddBmp
->nID
& ~1) == IDB_STD_SMALL_COLOR
)
1875 else if ((lpAddBmp
->nID
& ~1) == IDB_VIEW_SMALL_COLOR
)
1877 else if ((lpAddBmp
->nID
& ~1) == IDB_HIST_SMALL_COLOR
)
1882 TRACE ("adding %d internal bitmaps!\n", nButtons
);
1884 /* Windows resize all the buttons to the size of a newly added standard image */
1885 if (lpAddBmp
->nID
& 1)
1888 /* FIXME: on windows the size of the images is 25x24 but the size of the bitmap
1889 * in rsrc is only 24x24. Fix the bitmap (how?) and then fix this
1891 SendMessageA (hwnd
, TB_SETBITMAPSIZE
, 0,
1892 MAKELPARAM((WORD
)24, (WORD
)24));
1893 SendMessageA (hwnd
, TB_SETBUTTONSIZE
, 0,
1894 MAKELPARAM((WORD
)31, (WORD
)30));
1899 SendMessageA (hwnd
, TB_SETBITMAPSIZE
, 0,
1900 MAKELPARAM((WORD
)16, (WORD
)16));
1901 SendMessageA (hwnd
, TB_SETBUTTONSIZE
, 0,
1902 MAKELPARAM((WORD
)22, (WORD
)22));
1905 TOOLBAR_CalcToolbar (hwnd
);
1909 nButtons
= (INT
)wParam
;
1913 TRACE ("adding %d bitmaps!\n", nButtons
);
1916 if (!(infoPtr
->himlDef
)) {
1917 /* create new default image list */
1918 TRACE ("creating default image list!\n");
1921 ImageList_Create (infoPtr
->nBitmapWidth
, infoPtr
->nBitmapHeight
,
1922 ILC_COLOR
| ILC_MASK
, nButtons
, 2);
1923 infoPtr
->himlInt
= infoPtr
->himlDef
;
1926 nCount
= ImageList_GetImageCount(infoPtr
->himlDef
);
1928 /* Add bitmaps to the default image list */
1929 if (lpAddBmp
->hInst
== (HINSTANCE
)0)
1932 ImageList_AddMasked (infoPtr
->himlDef
, (HBITMAP
)lpAddBmp
->nID
,
1935 else if (lpAddBmp
->hInst
== HINST_COMMCTRL
)
1937 /* Add system bitmaps */
1938 switch (lpAddBmp
->nID
)
1940 case IDB_STD_SMALL_COLOR
:
1941 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1942 MAKEINTRESOURCEA(IDB_STD_SMALL
));
1943 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1944 hbmLoad
, CLR_DEFAULT
);
1945 DeleteObject (hbmLoad
);
1948 case IDB_STD_LARGE_COLOR
:
1949 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1950 MAKEINTRESOURCEA(IDB_STD_LARGE
));
1951 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1952 hbmLoad
, CLR_DEFAULT
);
1953 DeleteObject (hbmLoad
);
1956 case IDB_VIEW_SMALL_COLOR
:
1957 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1958 MAKEINTRESOURCEA(IDB_VIEW_SMALL
));
1959 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1960 hbmLoad
, CLR_DEFAULT
);
1961 DeleteObject (hbmLoad
);
1964 case IDB_VIEW_LARGE_COLOR
:
1965 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1966 MAKEINTRESOURCEA(IDB_VIEW_LARGE
));
1967 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1968 hbmLoad
, CLR_DEFAULT
);
1969 DeleteObject (hbmLoad
);
1972 case IDB_HIST_SMALL_COLOR
:
1973 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1974 MAKEINTRESOURCEA(IDB_HIST_SMALL
));
1975 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1976 hbmLoad
, CLR_DEFAULT
);
1977 DeleteObject (hbmLoad
);
1980 case IDB_HIST_LARGE_COLOR
:
1981 hbmLoad
= LoadBitmapA (COMCTL32_hModule
,
1982 MAKEINTRESOURCEA(IDB_HIST_LARGE
));
1983 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
,
1984 hbmLoad
, CLR_DEFAULT
);
1985 DeleteObject (hbmLoad
);
1989 nIndex
= ImageList_GetImageCount (infoPtr
->himlDef
);
1990 ERR ("invalid imagelist!\n");
1996 hbmLoad
= LoadBitmapA (lpAddBmp
->hInst
, (LPSTR
)lpAddBmp
->nID
);
1997 nIndex
= ImageList_AddMasked (infoPtr
->himlDef
, hbmLoad
, CLR_DEFAULT
);
1998 DeleteObject (hbmLoad
);
2003 INT imagecount
= ImageList_GetImageCount(infoPtr
->himlDef
);
2005 if (infoPtr
->nNumBitmaps
+ nButtons
!= imagecount
)
2007 WARN("Desired images do not match received images : Previous image number %i Previous images in list %i added %i expecting total %i, Images in list %i\n",
2008 infoPtr
->nNumBitmaps
, nCount
, imagecount
- nCount
,
2009 infoPtr
->nNumBitmaps
+nButtons
,imagecount
);
2011 infoPtr
->nNumBitmaps
= imagecount
;
2014 infoPtr
->nNumBitmaps
+= nButtons
;
2017 InvalidateRect(hwnd
, NULL
, FALSE
);
2024 TOOLBAR_AddButtonsA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2026 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2027 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
2028 INT nOldButtons
, nNewButtons
, nAddButtons
, nCount
;
2030 TRACE("adding %d buttons!\n", wParam
);
2032 nAddButtons
= (UINT
)wParam
;
2033 nOldButtons
= infoPtr
->nNumButtons
;
2034 nNewButtons
= nOldButtons
+ nAddButtons
;
2036 if (infoPtr
->nNumButtons
== 0) {
2038 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
2041 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
2043 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
2044 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
2045 nOldButtons
* sizeof(TBUTTON_INFO
));
2046 COMCTL32_Free (oldButtons
);
2049 infoPtr
->nNumButtons
= nNewButtons
;
2051 /* insert new button data */
2052 for (nCount
= 0; nCount
< nAddButtons
; nCount
++) {
2053 TBUTTON_INFO
*btnPtr
= &infoPtr
->buttons
[nOldButtons
+nCount
];
2054 btnPtr
->iBitmap
= lpTbb
[nCount
].iBitmap
;
2055 btnPtr
->idCommand
= lpTbb
[nCount
].idCommand
;
2056 btnPtr
->fsState
= lpTbb
[nCount
].fsState
;
2057 btnPtr
->fsStyle
= lpTbb
[nCount
].fsStyle
;
2058 btnPtr
->dwData
= lpTbb
[nCount
].dwData
;
2059 btnPtr
->iString
= lpTbb
[nCount
].iString
;
2060 btnPtr
->bHot
= FALSE
;
2062 if ((infoPtr
->hwndToolTip
) && !(btnPtr
->fsStyle
& TBSTYLE_SEP
)) {
2065 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
2066 ti
.cbSize
= sizeof (TTTOOLINFOA
);
2068 ti
.uId
= btnPtr
->idCommand
;
2070 ti
.lpszText
= LPSTR_TEXTCALLBACKA
;
2072 SendMessageA (infoPtr
->hwndToolTip
, TTM_ADDTOOLA
,
2077 TOOLBAR_CalcToolbar (hwnd
);
2079 InvalidateRect(hwnd
, NULL
, FALSE
);
2086 TOOLBAR_AddButtonsW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2088 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2089 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
2090 INT nOldButtons
, nNewButtons
, nAddButtons
, nCount
;
2092 TRACE("adding %d buttons!\n", wParam
);
2094 nAddButtons
= (UINT
)wParam
;
2095 nOldButtons
= infoPtr
->nNumButtons
;
2096 nNewButtons
= nOldButtons
+ nAddButtons
;
2098 if (infoPtr
->nNumButtons
== 0) {
2100 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
2103 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
2105 COMCTL32_Alloc (sizeof(TBUTTON_INFO
) * nNewButtons
);
2106 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
2107 nOldButtons
* sizeof(TBUTTON_INFO
));
2108 COMCTL32_Free (oldButtons
);
2111 infoPtr
->nNumButtons
= nNewButtons
;
2113 /* insert new button data */
2114 for (nCount
= 0; nCount
< nAddButtons
; nCount
++) {
2115 TBUTTON_INFO
*btnPtr
= &infoPtr
->buttons
[nOldButtons
+nCount
];
2116 btnPtr
->iBitmap
= lpTbb
[nCount
].iBitmap
;
2117 btnPtr
->idCommand
= lpTbb
[nCount
].idCommand
;
2118 btnPtr
->fsState
= lpTbb
[nCount
].fsState
;
2119 btnPtr
->fsStyle
= lpTbb
[nCount
].fsStyle
;
2120 btnPtr
->dwData
= lpTbb
[nCount
].dwData
;
2121 btnPtr
->iString
= lpTbb
[nCount
].iString
;
2122 btnPtr
->bHot
= FALSE
;
2124 if ((infoPtr
->hwndToolTip
) && !(btnPtr
->fsStyle
& TBSTYLE_SEP
)) {
2127 ZeroMemory (&ti
, sizeof(TTTOOLINFOW
));
2128 ti
.cbSize
= sizeof (TTTOOLINFOW
);
2130 ti
.uId
= btnPtr
->idCommand
;
2132 ti
.lpszText
= LPSTR_TEXTCALLBACKW
;
2134 SendMessageW (infoPtr
->hwndToolTip
, TTM_ADDTOOLW
,
2139 TOOLBAR_CalcToolbar (hwnd
);
2141 InvalidateRect(hwnd
, NULL
, FALSE
);
2148 TOOLBAR_AddStringA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2150 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2153 if ((wParam
) && (HIWORD(lParam
) == 0)) {
2156 TRACE("adding string from resource!\n");
2158 len
= LoadStringA ((HINSTANCE
)wParam
, (UINT
)lParam
,
2161 TRACE("len=%d \"%s\"\n", len
, szString
);
2162 nIndex
= infoPtr
->nNumStrings
;
2163 if (infoPtr
->nNumStrings
== 0) {
2165 COMCTL32_Alloc (sizeof(LPWSTR
));
2168 LPWSTR
*oldStrings
= infoPtr
->strings
;
2170 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
2171 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
2172 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
2173 COMCTL32_Free (oldStrings
);
2176 lenW
= MultiByteToWideChar( CP_ACP
, 0, szString
, -1, NULL
, 0 );
2177 infoPtr
->strings
[infoPtr
->nNumStrings
] = COMCTL32_Alloc (sizeof(WCHAR
)*lenW
);
2178 MultiByteToWideChar( CP_ACP
, 0, szString
, -1,
2179 infoPtr
->strings
[infoPtr
->nNumStrings
], lenW
);
2180 infoPtr
->nNumStrings
++;
2183 LPSTR p
= (LPSTR
)lParam
;
2188 TRACE("adding string(s) from array!\n");
2190 nIndex
= infoPtr
->nNumStrings
;
2193 TRACE("len=%d \"%s\"\n", len
, p
);
2195 if (infoPtr
->nNumStrings
== 0) {
2197 COMCTL32_Alloc (sizeof(LPWSTR
));
2200 LPWSTR
*oldStrings
= infoPtr
->strings
;
2202 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
2203 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
2204 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
2205 COMCTL32_Free (oldStrings
);
2208 lenW
= MultiByteToWideChar( CP_ACP
, 0, p
, -1, NULL
, 0 );
2209 infoPtr
->strings
[infoPtr
->nNumStrings
] = COMCTL32_Alloc (sizeof(WCHAR
)*lenW
);
2210 MultiByteToWideChar( CP_ACP
, 0, p
, -1,
2211 infoPtr
->strings
[infoPtr
->nNumStrings
], lenW
);
2212 infoPtr
->nNumStrings
++;
2223 TOOLBAR_AddStringW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2225 #define MAX_RESOURCE_STRING_LENGTH 512
2226 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2229 if ((wParam
) && (HIWORD(lParam
) == 0)) {
2230 WCHAR szString
[MAX_RESOURCE_STRING_LENGTH
];
2232 TRACE("adding string from resource!\n");
2234 len
= LoadStringW ((HINSTANCE
)wParam
, (UINT
)lParam
,
2235 szString
, MAX_RESOURCE_STRING_LENGTH
);
2237 TRACE("len=%d %s\n", len
, debugstr_w(szString
));
2238 TRACE("First char: 0x%x\n", *szString
);
2239 if (szString
[0] == L
'|')
2241 PWSTR p
= szString
+ 1;
2243 nIndex
= infoPtr
->nNumStrings
;
2244 while (*p
!= L
'|') {
2246 if (infoPtr
->nNumStrings
== 0) {
2248 COMCTL32_Alloc (sizeof(LPWSTR
));
2251 LPWSTR
*oldStrings
= infoPtr
->strings
;
2253 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
2254 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
2255 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
2256 COMCTL32_Free (oldStrings
);
2259 len
= COMCTL32_StrChrW (p
, L
'|') - p
;
2260 TRACE("len=%d %s\n", len
, debugstr_w(p
));
2261 infoPtr
->strings
[infoPtr
->nNumStrings
] =
2262 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
2263 lstrcpynW (infoPtr
->strings
[infoPtr
->nNumStrings
], p
, len
+1);
2264 infoPtr
->nNumStrings
++;
2271 nIndex
= infoPtr
->nNumStrings
;
2272 if (infoPtr
->nNumStrings
== 0) {
2274 COMCTL32_Alloc (sizeof(LPWSTR
));
2277 LPWSTR
*oldStrings
= infoPtr
->strings
;
2279 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
2280 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
2281 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
2282 COMCTL32_Free (oldStrings
);
2285 infoPtr
->strings
[infoPtr
->nNumStrings
] =
2286 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
2287 strcpyW (infoPtr
->strings
[infoPtr
->nNumStrings
], szString
);
2288 infoPtr
->nNumStrings
++;
2292 LPWSTR p
= (LPWSTR
)lParam
;
2297 TRACE("adding string(s) from array!\n");
2298 nIndex
= infoPtr
->nNumStrings
;
2302 TRACE("len=%d %s\n", len
, debugstr_w(p
));
2303 if (infoPtr
->nNumStrings
== 0) {
2305 COMCTL32_Alloc (sizeof(LPWSTR
));
2308 LPWSTR
*oldStrings
= infoPtr
->strings
;
2310 COMCTL32_Alloc (sizeof(LPWSTR
) * (infoPtr
->nNumStrings
+ 1));
2311 memcpy (&infoPtr
->strings
[0], &oldStrings
[0],
2312 sizeof(LPWSTR
) * infoPtr
->nNumStrings
);
2313 COMCTL32_Free (oldStrings
);
2316 infoPtr
->strings
[infoPtr
->nNumStrings
] =
2317 COMCTL32_Alloc (sizeof(WCHAR
)*(len
+1));
2318 strcpyW (infoPtr
->strings
[infoPtr
->nNumStrings
], p
);
2319 infoPtr
->nNumStrings
++;
2330 TOOLBAR_AutoSize (HWND hwnd
)
2332 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2333 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
2339 UINT uPosFlags
= SWP_NOZORDER
;
2341 TRACE("resize forced, style=%lx!\n", dwStyle
);
2343 parent
= GetParent (hwnd
);
2344 GetClientRect(parent
, &parent_rect
);
2346 x
= parent_rect
.left
;
2347 y
= parent_rect
.top
;
2349 /* FIXME: we should be able to early out if nothing */
2350 /* has changed with nWidth != parent_rect width */
2352 if (dwStyle
& CCS_NORESIZE
) {
2353 uPosFlags
|= (SWP_NOSIZE
| SWP_NOMOVE
);
2358 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
2359 TOOLBAR_CalcToolbar (hwnd
);
2360 InvalidateRect( hwnd
, NULL
, TRUE
);
2361 cy
= infoPtr
->nHeight
;
2362 cx
= infoPtr
->nWidth
;
2364 if (dwStyle
& CCS_NOMOVEY
) {
2365 GetWindowRect(hwnd
, &window_rect
);
2366 ScreenToClient(parent
, (LPPOINT
)&window_rect
.left
);
2367 y
= window_rect
.top
;
2371 if (dwStyle
& CCS_NOPARENTALIGN
)
2372 uPosFlags
|= SWP_NOMOVE
;
2374 if (!(dwStyle
& CCS_NODIVIDER
))
2375 cy
+= GetSystemMetrics(SM_CYEDGE
);
2377 if (dwStyle
& WS_BORDER
)
2380 cy
+= GetSystemMetrics(SM_CYEDGE
);
2381 cx
+= GetSystemMetrics(SM_CYEDGE
);
2384 infoPtr
->bAutoSize
= TRUE
;
2385 SetWindowPos (hwnd
, HWND_TOP
, parent_rect
.left
- x
, parent_rect
.top
- y
,
2387 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
2388 * the setwindowpos calls */
2389 infoPtr
->bAutoSize
= FALSE
;
2396 TOOLBAR_ButtonCount (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2398 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2400 return infoPtr
->nNumButtons
;
2405 TOOLBAR_ButtonStructSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2407 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2409 if (infoPtr
== NULL
) {
2410 ERR("(0x%x, 0x%x, 0x%lx)\n", hwnd
, wParam
, lParam
);
2411 ERR("infoPtr == NULL!\n");
2415 infoPtr
->dwStructSize
= (DWORD
)wParam
;
2422 TOOLBAR_ChangeBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2424 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2425 TBUTTON_INFO
*btnPtr
;
2428 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
2432 btnPtr
= &infoPtr
->buttons
[nIndex
];
2433 btnPtr
->iBitmap
= LOWORD(lParam
);
2435 /* we HAVE to erase the background, the new bitmap could be */
2437 InvalidateRect(hwnd
, &btnPtr
->rect
, TRUE
);
2444 TOOLBAR_CheckButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2446 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2447 TBUTTON_INFO
*btnPtr
;
2450 BOOL bChecked
= FALSE
;
2452 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
2456 btnPtr
= &infoPtr
->buttons
[nIndex
];
2458 if (!(btnPtr
->fsStyle
& TBSTYLE_CHECK
))
2461 bChecked
= (btnPtr
->fsState
& TBSTATE_CHECKED
) ? TRUE
: FALSE
;
2463 if (LOWORD(lParam
) == FALSE
)
2464 btnPtr
->fsState
&= ~TBSTATE_CHECKED
;
2466 if (btnPtr
->fsStyle
& TBSTYLE_GROUP
) {
2468 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr
, nIndex
);
2469 if (nOldIndex
== nIndex
)
2471 if (nOldIndex
!= -1)
2472 infoPtr
->buttons
[nOldIndex
].fsState
&= ~TBSTATE_CHECKED
;
2474 btnPtr
->fsState
|= TBSTATE_CHECKED
;
2477 if( bChecked
!= LOWORD(lParam
) )
2479 if (nOldIndex
!= -1)
2481 InvalidateRect(hwnd
, &infoPtr
->buttons
[nOldIndex
].rect
,
2482 TOOLBAR_HasText(infoPtr
, &infoPtr
->buttons
[nOldIndex
]));
2484 InvalidateRect(hwnd
, &btnPtr
->rect
, TRUE
);
2487 /* FIXME: Send a WM_NOTIFY?? */
2494 TOOLBAR_CommandToIndex (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2496 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2498 return TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
2503 TOOLBAR_Customize (HWND hwnd
)
2505 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2506 CUSTDLG_INFO custInfo
;
2512 custInfo
.tbInfo
= infoPtr
;
2513 custInfo
.tbHwnd
= hwnd
;
2515 /* send TBN_BEGINADJUST notification */
2516 TOOLBAR_SendNotify ((NMHDR
*) &nmhdr
, infoPtr
,
2519 if (!(hRes
= FindResourceA (COMCTL32_hModule
,
2520 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE
),
2524 if(!(template = (LPVOID
)LoadResource (COMCTL32_hModule
, hRes
)))
2527 ret
= DialogBoxIndirectParamA (GetWindowLongA (hwnd
, GWL_HINSTANCE
),
2528 (LPDLGTEMPLATEA
)template,
2530 (DLGPROC
)TOOLBAR_CustomizeDialogProc
,
2533 /* send TBN_ENDADJUST notification */
2534 TOOLBAR_SendNotify ((NMHDR
*) &nmhdr
, infoPtr
,
2542 TOOLBAR_DeleteButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2544 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2545 INT nIndex
= (INT
)wParam
;
2547 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
2550 if ((infoPtr
->hwndToolTip
) &&
2551 !(infoPtr
->buttons
[nIndex
].fsStyle
& TBSTYLE_SEP
)) {
2554 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
2555 ti
.cbSize
= sizeof (TTTOOLINFOA
);
2557 ti
.uId
= infoPtr
->buttons
[nIndex
].idCommand
;
2559 SendMessageA (infoPtr
->hwndToolTip
, TTM_DELTOOLA
, 0, (LPARAM
)&ti
);
2562 if (infoPtr
->nNumButtons
== 1) {
2563 TRACE(" simple delete!\n");
2564 COMCTL32_Free (infoPtr
->buttons
);
2565 infoPtr
->buttons
= NULL
;
2566 infoPtr
->nNumButtons
= 0;
2569 TBUTTON_INFO
*oldButtons
= infoPtr
->buttons
;
2570 TRACE("complex delete! [nIndex=%d]\n", nIndex
);
2572 infoPtr
->nNumButtons
--;
2573 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
2575 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
2576 nIndex
* sizeof(TBUTTON_INFO
));
2579 if (nIndex
< infoPtr
->nNumButtons
) {
2580 memcpy (&infoPtr
->buttons
[nIndex
], &oldButtons
[nIndex
+1],
2581 (infoPtr
->nNumButtons
- nIndex
) * sizeof(TBUTTON_INFO
));
2584 COMCTL32_Free (oldButtons
);
2587 TOOLBAR_CalcToolbar (hwnd
);
2589 InvalidateRect (hwnd
, NULL
, TRUE
);
2596 TOOLBAR_EnableButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2598 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2599 TBUTTON_INFO
*btnPtr
;
2603 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
2607 btnPtr
= &infoPtr
->buttons
[nIndex
];
2609 bState
= btnPtr
->fsState
& TBSTATE_ENABLED
;
2611 /* update the toolbar button state */
2612 if(LOWORD(lParam
) == FALSE
) {
2613 btnPtr
->fsState
&= ~(TBSTATE_ENABLED
| TBSTATE_PRESSED
);
2615 btnPtr
->fsState
|= TBSTATE_ENABLED
;
2618 /* redraw the button only if the state of the button changed */
2619 if(bState
!= (btnPtr
->fsState
& TBSTATE_ENABLED
))
2621 InvalidateRect(hwnd
, &btnPtr
->rect
,
2622 TOOLBAR_HasText(infoPtr
, btnPtr
));
2629 static inline LRESULT
2630 TOOLBAR_GetAnchorHighlight (HWND hwnd
)
2632 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2634 return infoPtr
->bAnchor
;
2639 TOOLBAR_GetBitmap (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2641 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2644 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
2648 return infoPtr
->buttons
[nIndex
].iBitmap
;
2652 static inline LRESULT
2653 TOOLBAR_GetBitmapFlags (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2655 return (GetDeviceCaps (0, LOGPIXELSX
) >= 120) ? TBBF_LARGE
: 0;
2660 TOOLBAR_GetButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2662 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2663 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
2664 INT nIndex
= (INT
)wParam
;
2665 TBUTTON_INFO
*btnPtr
;
2667 if (infoPtr
== NULL
)
2673 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
2676 btnPtr
= &infoPtr
->buttons
[nIndex
];
2677 lpTbb
->iBitmap
= btnPtr
->iBitmap
;
2678 lpTbb
->idCommand
= btnPtr
->idCommand
;
2679 lpTbb
->fsState
= btnPtr
->fsState
;
2680 lpTbb
->fsStyle
= btnPtr
->fsStyle
;
2681 lpTbb
->dwData
= btnPtr
->dwData
;
2682 lpTbb
->iString
= btnPtr
->iString
;
2689 TOOLBAR_GetButtonInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2691 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2692 LPTBBUTTONINFOA lpTbInfo
= (LPTBBUTTONINFOA
)lParam
;
2693 TBUTTON_INFO
*btnPtr
;
2696 if (infoPtr
== NULL
)
2698 if (lpTbInfo
== NULL
)
2700 if (lpTbInfo
->cbSize
< sizeof(TBBUTTONINFOA
))
2703 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
,
2704 lpTbInfo
->dwMask
& 0x80000000);
2708 btnPtr
= &infoPtr
->buttons
[nIndex
];
2710 if (lpTbInfo
->dwMask
& TBIF_COMMAND
)
2711 lpTbInfo
->idCommand
= btnPtr
->idCommand
;
2712 if (lpTbInfo
->dwMask
& TBIF_IMAGE
)
2713 lpTbInfo
->iImage
= btnPtr
->iBitmap
;
2714 if (lpTbInfo
->dwMask
& TBIF_LPARAM
)
2715 lpTbInfo
->lParam
= btnPtr
->dwData
;
2716 if (lpTbInfo
->dwMask
& TBIF_SIZE
)
2717 lpTbInfo
->cx
= (WORD
)(btnPtr
->rect
.right
- btnPtr
->rect
.left
);
2718 if (lpTbInfo
->dwMask
& TBIF_STATE
)
2719 lpTbInfo
->fsState
= btnPtr
->fsState
;
2720 if (lpTbInfo
->dwMask
& TBIF_STYLE
)
2721 lpTbInfo
->fsStyle
= btnPtr
->fsStyle
;
2722 if (lpTbInfo
->dwMask
& TBIF_TEXT
) {
2723 if ((btnPtr
->iString
>= 0) && (btnPtr
->iString
< infoPtr
->nNumStrings
))
2725 if (!WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)infoPtr
->strings
[btnPtr
->iString
], -1,
2726 lpTbInfo
->pszText
, lpTbInfo
->cchText
, NULL
, NULL
))
2727 lpTbInfo
->pszText
[lpTbInfo
->cchText
-1] = 0;
2729 else lpTbInfo
->pszText
[0]=0;
2736 TOOLBAR_GetButtonInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2738 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2739 LPTBBUTTONINFOW lpTbInfo
= (LPTBBUTTONINFOW
)lParam
;
2740 TBUTTON_INFO
*btnPtr
;
2743 if (infoPtr
== NULL
)
2745 if (lpTbInfo
== NULL
)
2747 if (lpTbInfo
->cbSize
< sizeof(TBBUTTONINFOW
))
2750 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
,
2751 lpTbInfo
->dwMask
& 0x80000000);
2755 btnPtr
= &infoPtr
->buttons
[nIndex
];
2757 if (lpTbInfo
->dwMask
& TBIF_COMMAND
)
2758 lpTbInfo
->idCommand
= btnPtr
->idCommand
;
2759 if (lpTbInfo
->dwMask
& TBIF_IMAGE
)
2760 lpTbInfo
->iImage
= btnPtr
->iBitmap
;
2761 if (lpTbInfo
->dwMask
& TBIF_LPARAM
)
2762 lpTbInfo
->lParam
= btnPtr
->dwData
;
2763 if (lpTbInfo
->dwMask
& TBIF_SIZE
)
2764 lpTbInfo
->cx
= (WORD
)(btnPtr
->rect
.right
- btnPtr
->rect
.left
);
2765 if (lpTbInfo
->dwMask
& TBIF_STATE
)
2766 lpTbInfo
->fsState
= btnPtr
->fsState
;
2767 if (lpTbInfo
->dwMask
& TBIF_STYLE
)
2768 lpTbInfo
->fsStyle
= btnPtr
->fsStyle
;
2769 if (lpTbInfo
->dwMask
& TBIF_TEXT
) {
2770 if ((btnPtr
->iString
>= 0) || (btnPtr
->iString
< infoPtr
->nNumStrings
))
2771 lstrcpynW (lpTbInfo
->pszText
,
2772 (LPWSTR
)infoPtr
->strings
[btnPtr
->iString
],
2781 TOOLBAR_GetButtonSize (HWND hwnd
)
2783 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2785 if (infoPtr
->nNumButtons
> 0)
2786 return MAKELONG((WORD
)infoPtr
->nButtonWidth
,
2787 (WORD
)infoPtr
->nButtonHeight
);
2789 return MAKELONG(8,7);
2794 TOOLBAR_GetButtonTextA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2796 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2797 INT nIndex
, nStringIndex
;
2799 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
2803 nStringIndex
= infoPtr
->buttons
[nIndex
].iString
;
2805 TRACE("index=%d stringIndex=%d\n", nIndex
, nStringIndex
);
2807 if ((nStringIndex
< 0) || (nStringIndex
>= infoPtr
->nNumStrings
))
2813 return WideCharToMultiByte( CP_ACP
, 0, (LPWSTR
)infoPtr
->strings
[nStringIndex
], -1,
2814 (LPSTR
)lParam
, 0x7fffffff, NULL
, NULL
) - 1;
2819 TOOLBAR_GetButtonTextW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2821 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2822 INT nIndex
, nStringIndex
;
2824 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
2828 nStringIndex
= infoPtr
->buttons
[nIndex
].iString
;
2830 TRACE("index=%d stringIndex=%d\n", nIndex
, nStringIndex
);
2832 if ((nStringIndex
< 0) || (nStringIndex
>= infoPtr
->nNumStrings
))
2838 strcpyW ((LPWSTR
)lParam
, (LPWSTR
)infoPtr
->strings
[nStringIndex
]);
2840 return strlenW ((LPWSTR
)infoPtr
->strings
[nStringIndex
]);
2844 /* << TOOLBAR_GetColorScheme >> */
2848 TOOLBAR_GetDisabledImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2850 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2852 return (LRESULT
)infoPtr
->himlDis
;
2856 inline static LRESULT
2857 TOOLBAR_GetExtendedStyle (HWND hwnd
)
2859 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2861 return infoPtr
->dwExStyle
;
2866 TOOLBAR_GetHotImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2868 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2870 return (LRESULT
)infoPtr
->himlHot
;
2875 TOOLBAR_GetHotItem (HWND hwnd
)
2877 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2879 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_FLAT
))
2882 if (infoPtr
->nHotItem
< 0)
2885 return (LRESULT
)infoPtr
->nHotItem
;
2890 TOOLBAR_GetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2892 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2894 return (LRESULT
)infoPtr
->himlDef
;
2898 /* << TOOLBAR_GetInsertMark >> */
2899 /* << TOOLBAR_GetInsertMarkColor >> */
2903 TOOLBAR_GetItemRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2905 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2906 TBUTTON_INFO
*btnPtr
;
2910 if (infoPtr
== NULL
)
2912 nIndex
= (INT
)wParam
;
2913 btnPtr
= &infoPtr
->buttons
[nIndex
];
2914 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
2916 lpRect
= (LPRECT
)lParam
;
2919 if (btnPtr
->fsState
& TBSTATE_HIDDEN
)
2922 lpRect
->left
= btnPtr
->rect
.left
;
2923 lpRect
->right
= btnPtr
->rect
.right
;
2924 lpRect
->bottom
= btnPtr
->rect
.bottom
;
2925 lpRect
->top
= btnPtr
->rect
.top
;
2932 TOOLBAR_GetMaxSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2934 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2935 LPSIZE lpSize
= (LPSIZE
)lParam
;
2940 lpSize
->cx
= infoPtr
->rcBound
.right
- infoPtr
->rcBound
.left
;
2941 lpSize
->cy
= infoPtr
->rcBound
.bottom
- infoPtr
->rcBound
.top
;
2943 TRACE("maximum size %d x %d\n",
2944 infoPtr
->rcBound
.right
- infoPtr
->rcBound
.left
,
2945 infoPtr
->rcBound
.bottom
- infoPtr
->rcBound
.top
);
2951 /* << TOOLBAR_GetObject >> */
2952 /* << TOOLBAR_GetPadding >> */
2956 TOOLBAR_GetRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2958 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2959 TBUTTON_INFO
*btnPtr
;
2963 if (infoPtr
== NULL
)
2965 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
2966 btnPtr
= &infoPtr
->buttons
[nIndex
];
2967 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
2969 lpRect
= (LPRECT
)lParam
;
2973 lpRect
->left
= btnPtr
->rect
.left
;
2974 lpRect
->right
= btnPtr
->rect
.right
;
2975 lpRect
->bottom
= btnPtr
->rect
.bottom
;
2976 lpRect
->top
= btnPtr
->rect
.top
;
2983 TOOLBAR_GetRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2985 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
2987 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_WRAPABLE
)
2988 return infoPtr
->nRows
;
2995 TOOLBAR_GetState (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2997 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3000 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3004 return infoPtr
->buttons
[nIndex
].fsState
;
3009 TOOLBAR_GetStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3011 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3014 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3018 return infoPtr
->buttons
[nIndex
].fsStyle
;
3023 TOOLBAR_GetTextRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3025 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3027 if (infoPtr
== NULL
)
3030 return infoPtr
->nMaxTextRows
;
3035 TOOLBAR_GetToolTips (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3037 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3039 if (infoPtr
== NULL
)
3041 return infoPtr
->hwndToolTip
;
3046 TOOLBAR_GetUnicodeFormat (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3048 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3050 TRACE("%s hwnd=0x%x stub!\n",
3051 infoPtr
->bUnicode
? "TRUE" : "FALSE", hwnd
);
3053 return infoPtr
->bUnicode
;
3057 inline static LRESULT
3058 TOOLBAR_GetVersion (HWND hwnd
)
3060 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3061 return infoPtr
->iVersion
;
3066 TOOLBAR_HideButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3068 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3069 TBUTTON_INFO
*btnPtr
;
3074 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3078 btnPtr
= &infoPtr
->buttons
[nIndex
];
3079 if (LOWORD(lParam
) == FALSE
)
3080 btnPtr
->fsState
&= ~TBSTATE_HIDDEN
;
3082 btnPtr
->fsState
|= TBSTATE_HIDDEN
;
3084 TOOLBAR_CalcToolbar (hwnd
);
3086 InvalidateRect (hwnd
, NULL
, TRUE
);
3092 inline static LRESULT
3093 TOOLBAR_HitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3095 return TOOLBAR_InternalHitTest (hwnd
, (LPPOINT
)lParam
);
3100 TOOLBAR_Indeterminate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3102 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3103 TBUTTON_INFO
*btnPtr
;
3106 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3110 btnPtr
= &infoPtr
->buttons
[nIndex
];
3111 if (LOWORD(lParam
) == FALSE
)
3112 btnPtr
->fsState
&= ~TBSTATE_INDETERMINATE
;
3114 btnPtr
->fsState
|= TBSTATE_INDETERMINATE
;
3116 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
, btnPtr
));
3123 TOOLBAR_InsertButtonA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3125 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3126 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
3127 INT nIndex
= (INT
)wParam
;
3128 TBUTTON_INFO
*oldButtons
;
3133 TOOLBAR_DumpButton(infoPtr
, (TBUTTON_INFO
*)lpTbb
, nIndex
, FALSE
);
3136 /* EPP: this seems to be an undocumented call (from my IE4)
3137 * I assume in that case that:
3138 * - lpTbb->iString is a string pointer (not a string index in strings[] table
3139 * - index of insertion is at the end of existing buttons
3140 * I only see this happen with nIndex == -1, but it could have a special
3141 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
3146 /* FIXME: iString == -1 is undocumented */
3147 if(lpTbb
->iString
&& lpTbb
->iString
!=-1) {
3148 len
= strlen((char*)lpTbb
->iString
) + 2;
3149 ptr
= COMCTL32_Alloc(len
);
3150 nIndex
= infoPtr
->nNumButtons
;
3151 strcpy(ptr
, (char*)lpTbb
->iString
);
3152 ptr
[len
- 1] = 0; /* ended by two '\0' */
3153 lpTbb
->iString
= TOOLBAR_AddStringA(hwnd
, 0, (LPARAM
)ptr
);
3157 ERR("lpTbb->iString is NULL\n");
3161 } else if (nIndex
< 0)
3164 TRACE("inserting button index=%d\n", nIndex
);
3165 if (nIndex
> infoPtr
->nNumButtons
) {
3166 nIndex
= infoPtr
->nNumButtons
;
3167 TRACE("adjust index=%d\n", nIndex
);
3170 oldButtons
= infoPtr
->buttons
;
3171 infoPtr
->nNumButtons
++;
3172 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
3173 /* pre insert copy */
3175 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
3176 nIndex
* sizeof(TBUTTON_INFO
));
3179 /* insert new button */
3180 infoPtr
->buttons
[nIndex
].iBitmap
= lpTbb
->iBitmap
;
3181 infoPtr
->buttons
[nIndex
].idCommand
= lpTbb
->idCommand
;
3182 infoPtr
->buttons
[nIndex
].fsState
= lpTbb
->fsState
;
3183 infoPtr
->buttons
[nIndex
].fsStyle
= lpTbb
->fsStyle
;
3184 infoPtr
->buttons
[nIndex
].dwData
= lpTbb
->dwData
;
3185 infoPtr
->buttons
[nIndex
].iString
= lpTbb
->iString
;
3187 if ((infoPtr
->hwndToolTip
) && !(lpTbb
->fsStyle
& TBSTYLE_SEP
)) {
3190 ZeroMemory (&ti
, sizeof(TTTOOLINFOA
));
3191 ti
.cbSize
= sizeof (TTTOOLINFOA
);
3193 ti
.uId
= lpTbb
->idCommand
;
3195 ti
.lpszText
= LPSTR_TEXTCALLBACKA
;
3197 SendMessageA (infoPtr
->hwndToolTip
, TTM_ADDTOOLA
,
3201 /* post insert copy */
3202 if (nIndex
< infoPtr
->nNumButtons
- 1) {
3203 memcpy (&infoPtr
->buttons
[nIndex
+1], &oldButtons
[nIndex
],
3204 (infoPtr
->nNumButtons
- nIndex
- 1) * sizeof(TBUTTON_INFO
));
3207 COMCTL32_Free (oldButtons
);
3209 TOOLBAR_CalcToolbar (hwnd
);
3211 InvalidateRect (hwnd
, NULL
, FALSE
);
3218 TOOLBAR_InsertButtonW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3220 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3221 LPTBBUTTON lpTbb
= (LPTBBUTTON
)lParam
;
3222 INT nIndex
= (INT
)wParam
;
3223 TBUTTON_INFO
*oldButtons
;
3230 TRACE("inserting button index=%d\n", nIndex
);
3231 if (nIndex
> infoPtr
->nNumButtons
) {
3232 nIndex
= infoPtr
->nNumButtons
;
3233 TRACE("adjust index=%d\n", nIndex
);
3236 oldButtons
= infoPtr
->buttons
;
3237 infoPtr
->nNumButtons
++;
3238 infoPtr
->buttons
= COMCTL32_Alloc (sizeof (TBUTTON_INFO
) * infoPtr
->nNumButtons
);
3239 /* pre insert copy */
3241 memcpy (&infoPtr
->buttons
[0], &oldButtons
[0],
3242 nIndex
* sizeof(TBUTTON_INFO
));
3245 /* insert new button */
3246 infoPtr
->buttons
[nIndex
].iBitmap
= lpTbb
->iBitmap
;
3247 infoPtr
->buttons
[nIndex
].idCommand
= lpTbb
->idCommand
;
3248 infoPtr
->buttons
[nIndex
].fsState
= lpTbb
->fsState
;
3249 infoPtr
->buttons
[nIndex
].fsStyle
= lpTbb
->fsStyle
;
3250 infoPtr
->buttons
[nIndex
].dwData
= lpTbb
->dwData
;
3251 infoPtr
->buttons
[nIndex
].iString
= lpTbb
->iString
;
3253 if ((infoPtr
->hwndToolTip
) && !(lpTbb
->fsStyle
& TBSTYLE_SEP
)) {
3256 ZeroMemory (&ti
, sizeof(TTTOOLINFOW
));
3257 ti
.cbSize
= sizeof (TTTOOLINFOW
);
3259 ti
.uId
= lpTbb
->idCommand
;
3261 ti
.lpszText
= LPSTR_TEXTCALLBACKW
;
3263 SendMessageW (infoPtr
->hwndToolTip
, TTM_ADDTOOLW
,
3267 /* post insert copy */
3268 if (nIndex
< infoPtr
->nNumButtons
- 1) {
3269 memcpy (&infoPtr
->buttons
[nIndex
+1], &oldButtons
[nIndex
],
3270 (infoPtr
->nNumButtons
- nIndex
- 1) * sizeof(TBUTTON_INFO
));
3273 COMCTL32_Free (oldButtons
);
3275 InvalidateRect (hwnd
, NULL
, FALSE
);
3281 /* << TOOLBAR_InsertMarkHitTest >> */
3285 TOOLBAR_IsButtonChecked (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3287 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3290 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3294 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_CHECKED
);
3299 TOOLBAR_IsButtonEnabled (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3301 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3304 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3308 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_ENABLED
);
3313 TOOLBAR_IsButtonHidden (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3315 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3318 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3322 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_HIDDEN
);
3327 TOOLBAR_IsButtonHighlighted (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3329 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3332 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3336 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_MARKED
);
3341 TOOLBAR_IsButtonIndeterminate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3343 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3346 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3350 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_INDETERMINATE
);
3355 TOOLBAR_IsButtonPressed (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3357 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3360 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3364 return (infoPtr
->buttons
[nIndex
].fsState
& TBSTATE_PRESSED
);
3368 /* << TOOLBAR_LoadImages >> */
3369 /* << TOOLBAR_MapAccelerator >> */
3370 /* << TOOLBAR_MarkButton >> */
3371 /* << TOOLBAR_MoveButton >> */
3375 TOOLBAR_PressButton (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3377 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3378 TBUTTON_INFO
*btnPtr
;
3381 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3385 btnPtr
= &infoPtr
->buttons
[nIndex
];
3386 if (LOWORD(lParam
) == FALSE
)
3387 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
3389 btnPtr
->fsState
|= TBSTATE_PRESSED
;
3391 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
, btnPtr
));
3397 /* << TOOLBAR_ReplaceBitmap >> */
3401 TOOLBAR_SaveRestoreA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3404 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3405 LPTBSAVEPARAMSA lpSave
= (LPTBSAVEPARAMSA
)lParam
;
3407 if (lpSave
== NULL
) return 0;
3410 /* save toolbar information */
3411 FIXME("save to \"%s\" \"%s\"\n",
3412 lpSave
->pszSubKey
, lpSave
->pszValueName
);
3417 /* restore toolbar information */
3419 FIXME("restore from \"%s\" \"%s\"\n",
3420 lpSave
->pszSubKey
, lpSave
->pszValueName
);
3431 TOOLBAR_SaveRestoreW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3434 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3435 LPTBSAVEPARAMSW lpSave
= (LPTBSAVEPARAMSW
)lParam
;
3441 /* save toolbar information */
3442 FIXME("save to \"%s\" \"%s\"\n",
3443 lpSave
->pszSubKey
, lpSave
->pszValueName
);
3448 /* restore toolbar information */
3450 FIXME("restore from \"%s\" \"%s\"\n",
3451 lpSave
->pszSubKey
, lpSave
->pszValueName
);
3462 TOOLBAR_SetAnchorHighlight (HWND hwnd
, WPARAM wParam
)
3464 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3465 BOOL bOldAnchor
= infoPtr
->bAnchor
;
3467 infoPtr
->bAnchor
= (BOOL
)wParam
;
3469 return (LRESULT
)bOldAnchor
;
3474 TOOLBAR_SetBitmapSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3476 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3478 if ((LOWORD(lParam
) <= 0) || (HIWORD(lParam
)<=0))
3481 if (infoPtr
->nNumButtons
> 0)
3482 WARN("%d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n",
3483 infoPtr
->nNumButtons
,
3484 infoPtr
->nBitmapWidth
, infoPtr
->nBitmapHeight
,
3485 LOWORD(lParam
), HIWORD(lParam
));
3487 infoPtr
->nBitmapWidth
= (INT
)LOWORD(lParam
);
3488 infoPtr
->nBitmapHeight
= (INT
)HIWORD(lParam
);
3490 /* uses image list internals directly */
3491 if (infoPtr
->himlDef
) {
3492 infoPtr
->himlDef
->cx
= infoPtr
->nBitmapWidth
;
3493 infoPtr
->himlDef
->cy
= infoPtr
->nBitmapHeight
;
3501 TOOLBAR_SetButtonInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3503 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3504 LPTBBUTTONINFOA lptbbi
= (LPTBBUTTONINFOA
)lParam
;
3505 TBUTTON_INFO
*btnPtr
;
3510 if (lptbbi
->cbSize
< sizeof(TBBUTTONINFOA
))
3513 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
,
3514 lptbbi
->dwMask
& 0x80000000);
3518 btnPtr
= &infoPtr
->buttons
[nIndex
];
3519 if (lptbbi
->dwMask
& TBIF_COMMAND
)
3520 btnPtr
->idCommand
= lptbbi
->idCommand
;
3521 if (lptbbi
->dwMask
& TBIF_IMAGE
)
3522 btnPtr
->iBitmap
= lptbbi
->iImage
;
3523 if (lptbbi
->dwMask
& TBIF_LPARAM
)
3524 btnPtr
->dwData
= lptbbi
->lParam
;
3525 /* if (lptbbi->dwMask & TBIF_SIZE) */
3526 /* btnPtr->cx = lptbbi->cx; */
3527 if (lptbbi
->dwMask
& TBIF_STATE
)
3528 btnPtr
->fsState
= lptbbi
->fsState
;
3529 if (lptbbi
->dwMask
& TBIF_STYLE
)
3530 btnPtr
->fsStyle
= lptbbi
->fsStyle
;
3532 if (lptbbi
->dwMask
& TBIF_TEXT
) {
3533 if ((btnPtr
->iString
>= 0) ||
3534 (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
3535 TRACE("Ooooooch\n");
3537 WCHAR
**lpString
= &infoPtr
->strings
[btnPtr
->iString
];
3538 INT len
= lstrlenA (lptbbi
->pszText
);
3539 *lpString
= COMCTL32_ReAlloc (lpString
, sizeof(WCHAR
)*(len
+1));
3542 /* this is the ultimate sollution */
3543 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3552 TOOLBAR_SetButtonInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3554 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3555 LPTBBUTTONINFOW lptbbi
= (LPTBBUTTONINFOW
)lParam
;
3556 TBUTTON_INFO
*btnPtr
;
3561 if (lptbbi
->cbSize
< sizeof(TBBUTTONINFOW
))
3564 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
,
3565 lptbbi
->dwMask
& 0x80000000);
3569 btnPtr
= &infoPtr
->buttons
[nIndex
];
3570 if (lptbbi
->dwMask
& TBIF_COMMAND
)
3571 btnPtr
->idCommand
= lptbbi
->idCommand
;
3572 if (lptbbi
->dwMask
& TBIF_IMAGE
)
3573 btnPtr
->iBitmap
= lptbbi
->iImage
;
3574 if (lptbbi
->dwMask
& TBIF_LPARAM
)
3575 btnPtr
->dwData
= lptbbi
->lParam
;
3576 /* if (lptbbi->dwMask & TBIF_SIZE) */
3577 /* btnPtr->cx = lptbbi->cx; */
3578 if (lptbbi
->dwMask
& TBIF_STATE
)
3579 btnPtr
->fsState
= lptbbi
->fsState
;
3580 if (lptbbi
->dwMask
& TBIF_STYLE
)
3581 btnPtr
->fsStyle
= lptbbi
->fsStyle
;
3583 if (lptbbi
->dwMask
& TBIF_TEXT
) {
3584 if ((btnPtr
->iString
>= 0) ||
3585 (btnPtr
->iString
< infoPtr
->nNumStrings
)) {
3587 WCHAR
**lpString
= &infoPtr
->strings
[btnPtr
->iString
];
3588 INT len
= lstrlenW (lptbbi
->pszText
);
3589 *lpString
= COMCTL32_ReAlloc (lpString
, sizeof(WCHAR
)*(len
+1));
3592 /* this is the ultimate solution */
3593 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3602 TOOLBAR_SetButtonSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3604 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3606 if ((LOWORD(lParam
) <= 0) || (HIWORD(lParam
)<=0))
3608 ERR("invalid parameter\n");
3612 /* The documentation claims you can only change the button size before
3613 * any button has been added. But this is wrong.
3614 * WINZIP32.EXE (ver 8) calls this on one of its buttons after adding
3615 * it to the toolbar, and it checks that the return value is nonzero - mjm
3616 * Further testing shows that we must actually perform the change too.
3618 infoPtr
->nButtonWidth
= (INT
)LOWORD(lParam
);
3619 infoPtr
->nButtonHeight
= (INT
)HIWORD(lParam
);
3625 TOOLBAR_SetButtonWidth (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3627 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3629 if (infoPtr
== NULL
) {
3630 TRACE("Toolbar not initialized yet?????\n");
3634 /* if setting to current values, ignore */
3635 if ((infoPtr
->cxMin
== (INT
)LOWORD(lParam
)) &&
3636 (infoPtr
->cxMax
== (INT
)HIWORD(lParam
))) {
3637 TRACE("matches current width, min=%d, max=%d, no recalc\n",
3638 infoPtr
->cxMin
, infoPtr
->cxMax
);
3642 /* save new values */
3643 infoPtr
->cxMin
= (INT
)LOWORD(lParam
);
3644 infoPtr
->cxMax
= (INT
)HIWORD(lParam
);
3646 /* if both values are 0 then we are done */
3648 TRACE("setting both min and max to 0, norecalc\n");
3652 /* otherwise we need to recalc the toolbar and in some cases
3653 recalc the bounding rectangle (does DrawText w/ DT_CALCRECT
3654 which doesn't actually draw - GA). */
3655 TRACE("number of buttons %d, cx=%d, cy=%d, recalcing\n",
3656 infoPtr
->nNumButtons
, infoPtr
->cxMin
, infoPtr
->cxMax
);
3658 TOOLBAR_CalcToolbar (hwnd
);
3660 InvalidateRect (hwnd
, NULL
, TRUE
);
3667 TOOLBAR_SetCmdId (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3669 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3670 INT nIndex
= (INT
)wParam
;
3672 if ((nIndex
< 0) || (nIndex
>= infoPtr
->nNumButtons
))
3675 infoPtr
->buttons
[nIndex
].idCommand
= (INT
)lParam
;
3677 if (infoPtr
->hwndToolTip
) {
3679 FIXME("change tool tip!\n");
3687 /* << TOOLBAR_SetColorScheme >> */
3691 TOOLBAR_SetDisabledImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3693 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3694 HIMAGELIST himlTemp
;
3697 himlTemp
= infoPtr
->himlDis
;
3698 infoPtr
->himlDis
= (HIMAGELIST
)lParam
;
3700 /* FIXME: redraw ? */
3702 return (LRESULT
)himlTemp
;
3707 TOOLBAR_SetDrawTextFlags (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3709 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3712 dwTemp
= infoPtr
->dwDTFlags
;
3713 infoPtr
->dwDTFlags
=
3714 (infoPtr
->dwDTFlags
& (DWORD
)wParam
) | (DWORD
)lParam
;
3716 return (LRESULT
)dwTemp
;
3721 TOOLBAR_SetExtendedStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3723 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3726 dwTemp
= infoPtr
->dwExStyle
;
3727 infoPtr
->dwExStyle
= (DWORD
)lParam
;
3729 return (LRESULT
)dwTemp
;
3734 TOOLBAR_SetHotImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3736 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
3737 HIMAGELIST himlTemp
;
3739 himlTemp
= infoPtr
->himlHot
;
3740 infoPtr
->himlHot
= (HIMAGELIST
)lParam
;
3742 /* FIXME: redraw ? */
3744 return (LRESULT
)himlTemp
;
3749 TOOLBAR_SetHotItem (HWND hwnd
, WPARAM wParam
)
3751 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
3752 INT nOldHotItem
= infoPtr
->nHotItem
;
3753 TBUTTON_INFO
*btnPtr
;
3755 if ((INT
) wParam
< 0 || (INT
)wParam
> infoPtr
->nNumButtons
)
3758 if (GetWindowLongA (hwnd
, GWL_STYLE
) & TBSTYLE_FLAT
)
3761 infoPtr
->nHotItem
= (INT
)wParam
;
3762 if ((INT
)wParam
>=0)
3764 btnPtr
= &infoPtr
->buttons
[(INT
)wParam
];
3765 btnPtr
->bHot
= TRUE
;
3766 InvalidateRect (hwnd
, &btnPtr
->rect
,
3767 TOOLBAR_HasText(infoPtr
, btnPtr
));
3771 btnPtr
= &infoPtr
->buttons
[nOldHotItem
];
3772 btnPtr
->bHot
= FALSE
;
3773 InvalidateRect (hwnd
, &btnPtr
->rect
,
3774 TOOLBAR_HasText(infoPtr
, btnPtr
));
3778 if (nOldHotItem
< 0)
3781 return (LRESULT
)nOldHotItem
;
3786 TOOLBAR_SetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3788 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3789 HIMAGELIST himlTemp
;
3791 himlTemp
= infoPtr
->himlDef
;
3792 infoPtr
->himlDef
= (HIMAGELIST
)lParam
;
3794 infoPtr
->nNumBitmaps
= ImageList_GetImageCount(infoPtr
->himlDef
);
3796 ImageList_GetIconSize(infoPtr
->himlDef
, &infoPtr
->nBitmapWidth
,
3797 &infoPtr
->nBitmapHeight
);
3798 TRACE("hwnd %08x, new himl=%08x, count=%d, bitmap w=%d, h=%d\n",
3799 hwnd
, (INT
)infoPtr
->himlDef
, infoPtr
->nNumBitmaps
,
3800 infoPtr
->nBitmapWidth
, infoPtr
->nBitmapHeight
);
3802 /* FIXME: redraw ? */
3804 return (LRESULT
)himlTemp
;
3809 TOOLBAR_SetIndent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3811 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3813 infoPtr
->nIndent
= (INT
)wParam
;
3817 /* process only on indent changing */
3818 if(infoPtr
->nIndent
!= (INT
)wParam
)
3820 infoPtr
->nIndent
= (INT
)wParam
;
3821 TOOLBAR_CalcToolbar (hwnd
);
3822 InvalidateRect(hwnd
, NULL
, FALSE
);
3829 /* << TOOLBAR_SetInsertMark >> */
3833 TOOLBAR_SetInsertMarkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3835 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3837 infoPtr
->clrInsertMark
= (COLORREF
)lParam
;
3839 /* FIXME : redraw ??*/
3846 TOOLBAR_SetMaxTextRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3848 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3850 if (infoPtr
== NULL
)
3853 infoPtr
->nMaxTextRows
= (INT
)wParam
;
3859 /* << TOOLBAR_SetPadding >> */
3863 TOOLBAR_SetParent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3865 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3870 if (infoPtr
== NULL
)
3872 hwndOldNotify
= infoPtr
->hwndNotify
;
3873 infoPtr
->hwndNotify
= (HWND
)wParam
;
3875 return hwndOldNotify
;
3880 TOOLBAR_SetRows (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3882 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3883 LPRECT lprc
= (LPRECT
)lParam
;
3887 if (LOWORD(wParam
) > 1) {
3888 FIXME("multiple rows not supported!\n");
3891 if(infoPtr
->nRows
!= LOWORD(wParam
))
3893 infoPtr
->nRows
= LOWORD(wParam
);
3895 /* recalculate toolbar */
3896 TOOLBAR_CalcToolbar (hwnd
);
3898 /* repaint toolbar */
3899 InvalidateRect(hwnd
, NULL
, FALSE
);
3902 /* return bounding rectangle */
3904 lprc
->left
= infoPtr
->rcBound
.left
;
3905 lprc
->right
= infoPtr
->rcBound
.right
;
3906 lprc
->top
= infoPtr
->rcBound
.top
;
3907 lprc
->bottom
= infoPtr
->rcBound
.bottom
;
3915 TOOLBAR_SetState (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3917 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3918 TBUTTON_INFO
*btnPtr
;
3921 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3925 btnPtr
= &infoPtr
->buttons
[nIndex
];
3927 /* if hidden state has changed the invalidate entire window and recalc */
3928 if ((btnPtr
->fsState
& TBSTATE_HIDDEN
) != (LOWORD(lParam
) & TBSTATE_HIDDEN
)) {
3929 btnPtr
->fsState
= LOWORD(lParam
);
3930 TOOLBAR_CalcToolbar (hwnd
);
3931 InvalidateRect(hwnd
, 0, TOOLBAR_HasText(infoPtr
, btnPtr
));
3935 /* process state changing if current state doesn't match new state */
3936 if(btnPtr
->fsState
!= LOWORD(lParam
))
3938 btnPtr
->fsState
= LOWORD(lParam
);
3939 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
,
3948 TOOLBAR_SetStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3950 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3951 TBUTTON_INFO
*btnPtr
;
3954 nIndex
= TOOLBAR_GetButtonIndex (infoPtr
, (INT
)wParam
, FALSE
);
3958 btnPtr
= &infoPtr
->buttons
[nIndex
];
3960 /* process style change if current style doesn't match new style */
3961 if(btnPtr
->fsStyle
!= LOWORD(lParam
))
3963 btnPtr
->fsStyle
= LOWORD(lParam
);
3964 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
,
3967 if (infoPtr
->hwndToolTip
) {
3968 FIXME("change tool tip!\n");
3976 inline static LRESULT
3977 TOOLBAR_SetToolTips (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3979 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3981 if (infoPtr
== NULL
)
3983 infoPtr
->hwndToolTip
= (HWND
)wParam
;
3989 TOOLBAR_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
3991 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
3994 TRACE("%s hwnd=0x%04x stub!\n",
3995 ((BOOL
)wParam
) ? "TRUE" : "FALSE", hwnd
);
3997 bTemp
= infoPtr
->bUnicode
;
3998 infoPtr
->bUnicode
= (BOOL
)wParam
;
4005 TOOLBAR_SetVersion (HWND hwnd
, INT iVersion
)
4007 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4008 INT iOldVersion
= infoPtr
->iVersion
;
4010 infoPtr
->iVersion
= iVersion
;
4017 TOOLBAR_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4019 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4020 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
4023 /* initialize info structure */
4024 infoPtr
->nButtonHeight
= 22;
4025 infoPtr
->nButtonWidth
= 24;
4026 infoPtr
->nBitmapHeight
= 15;
4027 infoPtr
->nBitmapWidth
= 16;
4029 infoPtr
->nHeight
= infoPtr
->nButtonHeight
+ TOP_BORDER
+ BOTTOM_BORDER
;
4031 infoPtr
->nMaxTextRows
= 1;
4032 infoPtr
->cxMin
= -1;
4033 infoPtr
->cxMax
= -1;
4034 infoPtr
->nNumBitmaps
= 0;
4035 infoPtr
->nNumStrings
= 0;
4037 infoPtr
->bCaptured
= FALSE
;
4038 infoPtr
->bUnicode
= IsWindowUnicode (hwnd
);
4039 infoPtr
->nButtonDown
= -1;
4040 infoPtr
->nOldHit
= -1;
4041 infoPtr
->nHotItem
= -2; /* It has to be initially different from nOldHit */
4042 infoPtr
->hwndNotify
= GetParent (hwnd
);
4043 infoPtr
->bTransparent
= (dwStyle
& TBSTYLE_TRANSPARENT
);
4044 infoPtr
->bBtnTranspnt
= (dwStyle
& (TBSTYLE_FLAT
| TBSTYLE_LIST
));
4045 infoPtr
->dwDTFlags
= (dwStyle
& TBSTYLE_LIST
) ? DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
: DT_CENTER
;
4046 infoPtr
->bAnchor
= FALSE
; /* no anchor highlighting */
4047 infoPtr
->iVersion
= 0;
4048 infoPtr
->bNtfUnicode
= FALSE
;
4049 infoPtr
->hwndSelf
= hwnd
;
4051 SystemParametersInfoA (SPI_GETICONTITLELOGFONT
, 0, &logFont
, 0);
4052 infoPtr
->hFont
= infoPtr
->hDefaultFont
= CreateFontIndirectA (&logFont
);
4054 if (dwStyle
& TBSTYLE_TOOLTIPS
) {
4055 /* Create tooltip control */
4056 infoPtr
->hwndToolTip
=
4057 CreateWindowExA (0, TOOLTIPS_CLASSA
, NULL
, 0,
4058 CW_USEDEFAULT
, CW_USEDEFAULT
,
4059 CW_USEDEFAULT
, CW_USEDEFAULT
,
4062 /* Send NM_TOOLTIPSCREATED notification */
4063 if (infoPtr
->hwndToolTip
) {
4064 NMTOOLTIPSCREATED nmttc
;
4066 nmttc
.hwndToolTips
= infoPtr
->hwndToolTip
;
4068 TOOLBAR_SendNotify ((NMHDR
*) &nmttc
, infoPtr
,
4069 NM_TOOLTIPSCREATED
);
4073 TOOLBAR_CheckStyle (hwnd
, dwStyle
);
4075 TOOLBAR_CalcToolbar(hwnd
);
4082 TOOLBAR_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4084 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4086 /* delete tooltip control */
4087 if (infoPtr
->hwndToolTip
)
4088 DestroyWindow (infoPtr
->hwndToolTip
);
4090 /* delete button data */
4091 if (infoPtr
->buttons
)
4092 COMCTL32_Free (infoPtr
->buttons
);
4094 /* delete strings */
4095 if (infoPtr
->strings
) {
4097 for (i
= 0; i
< infoPtr
->nNumStrings
; i
++)
4098 if (infoPtr
->strings
[i
])
4099 COMCTL32_Free (infoPtr
->strings
[i
]);
4101 COMCTL32_Free (infoPtr
->strings
);
4104 /* destroy internal image list */
4105 if (infoPtr
->himlInt
)
4106 ImageList_Destroy (infoPtr
->himlInt
);
4108 /* delete default font */
4110 DeleteObject (infoPtr
->hDefaultFont
);
4112 /* free toolbar info data */
4113 COMCTL32_Free (infoPtr
);
4114 SetWindowLongA (hwnd
, 0, 0);
4121 TOOLBAR_EraseBackground (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4123 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4124 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
4125 NMTBCUSTOMDRAW tbcd
;
4128 if (dwStyle
& TBSTYLE_CUSTOMERASE
) {
4129 ZeroMemory (&tbcd
, sizeof(NMTBCUSTOMDRAW
));
4130 tbcd
.nmcd
.dwDrawStage
= CDDS_PREERASE
;
4131 tbcd
.nmcd
.hdc
= (HDC
)wParam
;
4132 ntfret
= TOOLBAR_SendNotify ((NMHDR
*)&tbcd
, infoPtr
, NM_CUSTOMDRAW
);
4133 /* FIXME: in general the return flags *can* be or'ed together */
4136 case CDRF_DODEFAULT
:
4138 case CDRF_SKIPDEFAULT
:
4141 FIXME("[%04x] response %d not handled to NM_CUSTOMDRAW (CDDS_PREERASE)\n",
4146 /* If the toolbar is "transparent" then pass the WM_ERASEBKGND up
4147 * to my parent for processing.
4149 if (infoPtr
->bTransparent
) {
4151 HDC hdc
= (HDC
)wParam
;
4156 parent
= GetParent(hwnd
);
4157 MapWindowPoints(hwnd
, parent
, &pt
, 1);
4158 OffsetWindowOrgEx (hdc
, pt
.x
, pt
.y
, &ptorig
);
4159 SendMessageA (parent
, WM_ERASEBKGND
, wParam
, lParam
);
4160 SetWindowOrgEx (hdc
, ptorig
.x
, ptorig
.y
, 0);
4163 ret
= DefWindowProcA (hwnd
, WM_ERASEBKGND
, wParam
, lParam
);
4165 if (dwStyle
& TBSTYLE_CUSTOMERASE
) {
4166 ZeroMemory (&tbcd
, sizeof(NMTBCUSTOMDRAW
));
4167 tbcd
.nmcd
.dwDrawStage
= CDDS_POSTERASE
;
4168 tbcd
.nmcd
.hdc
= (HDC
)wParam
;
4169 ntfret
= TOOLBAR_SendNotify ((NMHDR
*)&tbcd
, infoPtr
, NM_CUSTOMDRAW
);
4172 case CDRF_DODEFAULT
:
4174 case CDRF_SKIPDEFAULT
:
4177 FIXME("[%04x] response %d not handled to NM_CUSTOMDRAW (CDDS_PREERASE)\n",
4186 TOOLBAR_GetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4188 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4190 return infoPtr
->hFont
;
4195 TOOLBAR_LButtonDblClk (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4197 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4198 TBUTTON_INFO
*btnPtr
;
4202 pt
.x
= (INT
)LOWORD(lParam
);
4203 pt
.y
= (INT
)HIWORD(lParam
);
4204 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
4207 btnPtr
= &infoPtr
->buttons
[nHit
];
4208 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
))
4211 infoPtr
->bCaptured
= TRUE
;
4212 infoPtr
->nButtonDown
= nHit
;
4214 btnPtr
->fsState
|= TBSTATE_PRESSED
;
4216 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
,
4219 else if (GetWindowLongA (hwnd
, GWL_STYLE
) & CCS_ADJUSTABLE
)
4220 TOOLBAR_Customize (hwnd
);
4227 TOOLBAR_LButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4229 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4230 TBUTTON_INFO
*btnPtr
;
4235 if (infoPtr
->hwndToolTip
)
4236 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
4237 WM_LBUTTONDOWN
, wParam
, lParam
);
4239 pt
.x
= (INT
)LOWORD(lParam
);
4240 pt
.y
= (INT
)HIWORD(lParam
);
4241 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
4245 btnPtr
= &infoPtr
->buttons
[nHit
];
4246 if (!(btnPtr
->fsState
& TBSTATE_ENABLED
))
4249 infoPtr
->nOldHit
= nHit
;
4251 CopyRect(&arrowRect
, &btnPtr
->rect
);
4252 arrowRect
.left
= max(btnPtr
->rect
.left
, btnPtr
->rect
.right
- DDARROW_WIDTH
);
4254 /* for EX_DRAWDDARROWS style, click must be in the drop-down arrow rect */
4255 if ((btnPtr
->fsStyle
& TBSTYLE_DROPDOWN
) &&
4256 ((TOOLBAR_HasDropDownArrows(infoPtr
->dwExStyle
) && PtInRect(&arrowRect
, pt
)) ||
4257 (!TOOLBAR_HasDropDownArrows(infoPtr
->dwExStyle
))))
4261 * this time we must force a Redraw, so the btn is
4262 * painted down before CaptureChanged repaints it up
4264 RedrawWindow(hwnd
,&btnPtr
->rect
,0,
4265 RDW_ERASE
|RDW_INVALIDATE
|RDW_UPDATENOW
);
4267 nmtb
.iItem
= btnPtr
->idCommand
;
4268 memset(&nmtb
.tbButton
, 0, sizeof(TBBUTTON
));
4271 memset(&nmtb
.rcButton
, 0, sizeof(RECT
));
4272 res
= TOOLBAR_SendNotify ((NMHDR
*) &nmtb
, infoPtr
,
4274 if (res
!= TBDDRET_TREATPRESSED
)
4275 /* ??? guess (GA) */
4277 /* otherwise drop through and process as pushed */
4279 /* SetCapture (hwnd); */
4280 infoPtr
->bCaptured
= TRUE
;
4281 infoPtr
->nButtonDown
= nHit
;
4283 btnPtr
->fsState
|= TBSTATE_PRESSED
;
4284 btnPtr
->bHot
= FALSE
;
4286 InvalidateRect(hwnd
, &btnPtr
->rect
,
4287 TOOLBAR_HasText(infoPtr
, btnPtr
));
4291 /* native issues the TBN_BEGINDRAG here */
4292 nmtb
.iItem
= btnPtr
->idCommand
;
4293 nmtb
.tbButton
.iBitmap
= btnPtr
->iBitmap
;
4294 nmtb
.tbButton
.idCommand
= btnPtr
->idCommand
;
4295 nmtb
.tbButton
.fsState
= btnPtr
->fsState
;
4296 nmtb
.tbButton
.fsStyle
= btnPtr
->fsStyle
;
4297 nmtb
.tbButton
.dwData
= btnPtr
->dwData
;
4298 nmtb
.tbButton
.iString
= btnPtr
->iString
;
4299 nmtb
.cchText
= 0; /* !!! not correct */
4300 nmtb
.pszText
= 0; /* !!! not correct */
4301 TOOLBAR_SendNotify ((NMHDR
*) &nmtb
, infoPtr
,
4309 TOOLBAR_LButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4311 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4312 TBUTTON_INFO
*btnPtr
;
4316 BOOL bSendMessage
= TRUE
;
4321 if (infoPtr
->hwndToolTip
)
4322 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
4323 WM_LBUTTONUP
, wParam
, lParam
);
4325 pt
.x
= (INT
)LOWORD(lParam
);
4326 pt
.y
= (INT
)HIWORD(lParam
);
4327 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
4329 /* restore hot effect to hot button disabled by TOOLBAR_LButtonDown() */
4330 /* if the cursor is still inside of the toolbar */
4331 if((infoPtr
->nHotItem
>= 0) && (nHit
!= -1))
4332 infoPtr
->buttons
[infoPtr
->nHotItem
].bHot
= TRUE
;
4334 if ((infoPtr
->bCaptured
) && (infoPtr
->nButtonDown
>= 0)) {
4335 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
4336 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
4338 if (nHit
== infoPtr
->nButtonDown
) {
4339 if (btnPtr
->fsStyle
& TBSTYLE_CHECK
) {
4340 if (btnPtr
->fsStyle
& TBSTYLE_GROUP
) {
4341 nOldIndex
= TOOLBAR_GetCheckedGroupButtonIndex (infoPtr
,
4342 infoPtr
->nButtonDown
);
4343 if (nOldIndex
== infoPtr
->nButtonDown
)
4344 bSendMessage
= FALSE
;
4345 if ((nOldIndex
!= infoPtr
->nButtonDown
) &&
4347 infoPtr
->buttons
[nOldIndex
].fsState
&= ~TBSTATE_CHECKED
;
4348 btnPtr
->fsState
|= TBSTATE_CHECKED
;
4351 if (btnPtr
->fsState
& TBSTATE_CHECKED
)
4352 btnPtr
->fsState
&= ~TBSTATE_CHECKED
;
4354 btnPtr
->fsState
|= TBSTATE_CHECKED
;
4359 bSendMessage
= FALSE
;
4361 if (nOldIndex
!= -1)
4363 InvalidateRect(hwnd
, &infoPtr
->buttons
[nOldIndex
].rect
,
4364 TOOLBAR_HasText(infoPtr
, &infoPtr
->buttons
[nOldIndex
]));
4368 * now we can ReleaseCapture, which triggers CAPTURECHANGED msg,
4369 * that resets bCaptured and btn TBSTATE_PRESSED flags,
4370 * and obliterates nButtonDown and nOldHit (see TOOLBAR_CaptureChanged)
4374 /* Issue NM_RELEASEDCAPTURE to parent to let him know it is released */
4375 TOOLBAR_SendNotify ((NMHDR
*) &hdr
, infoPtr
,
4376 NM_RELEASEDCAPTURE
);
4378 /* native issues TBN_ENDDRAG here, if _LBUTTONDOWN issued the
4381 nmtb
.iItem
= btnPtr
->idCommand
;
4382 nmtb
.tbButton
.iBitmap
= btnPtr
->iBitmap
;
4383 nmtb
.tbButton
.idCommand
= btnPtr
->idCommand
;
4384 nmtb
.tbButton
.fsState
= btnPtr
->fsState
;
4385 nmtb
.tbButton
.fsStyle
= btnPtr
->fsStyle
;
4386 nmtb
.tbButton
.dwData
= btnPtr
->dwData
;
4387 nmtb
.tbButton
.iString
= btnPtr
->iString
;
4388 nmtb
.cchText
= 0; /* !!! not correct */
4389 nmtb
.pszText
= 0; /* !!! not correct */
4390 TOOLBAR_SendNotify ((NMHDR
*) &nmtb
, infoPtr
,
4394 SendMessageA (infoPtr
->hwndNotify
, WM_COMMAND
,
4395 MAKEWPARAM(btnPtr
->idCommand
, 0), (LPARAM
)hwnd
);
4397 /* !!! Undocumented - toolbar at 4.71 level and above sends
4398 * either NMRCLICK or NM_CLICK with the NMMOUSE structure.
4399 * Only NM_RCLICK is documented.
4401 nmmouse
.dwItemSpec
= btnPtr
->idCommand
;
4402 nmmouse
.dwItemData
= btnPtr
->dwData
;
4403 TOOLBAR_SendNotify ((NMHDR
*) &nmmouse
, infoPtr
,
4411 TOOLBAR_CaptureChanged(HWND hwnd
)
4413 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4414 TBUTTON_INFO
*btnPtr
;
4416 infoPtr
->bCaptured
= FALSE
;
4418 if (infoPtr
->nButtonDown
>= 0)
4420 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
4421 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
4423 infoPtr
->nButtonDown
= -1;
4424 infoPtr
->nOldHit
= -1;
4426 InvalidateRect(hwnd
, &btnPtr
->rect
, TOOLBAR_HasText(infoPtr
,
4433 TOOLBAR_MouseLeave (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4435 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4436 TBUTTON_INFO
*hotBtnPtr
, *btnPtr
;
4439 if (infoPtr
->nOldHit
< 0)
4442 hotBtnPtr
= &infoPtr
->buttons
[infoPtr
->nOldHit
];
4444 /* Redraw the button if the last button we were over is the hot button and it
4446 if((infoPtr
->nOldHit
== infoPtr
->nHotItem
) && (hotBtnPtr
->fsState
& TBSTATE_ENABLED
))
4448 hotBtnPtr
->bHot
= FALSE
;
4449 rc1
= hotBtnPtr
->rect
;
4450 InflateRect (&rc1
, 1, 1);
4451 InvalidateRect (hwnd
, &rc1
, TOOLBAR_HasText(infoPtr
,
4455 /* If the last button we were over is depressed then make it not */
4456 /* depressed and redraw it */
4457 if(infoPtr
->nOldHit
== infoPtr
->nButtonDown
)
4459 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
4461 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
4463 rc1
= hotBtnPtr
->rect
;
4464 InflateRect (&rc1
, 1, 1);
4465 InvalidateRect (hwnd
, &rc1
, TRUE
);
4468 infoPtr
->nOldHit
= -1; /* reset the old hit index as we've left the toolbar */
4469 infoPtr
->nHotItem
= -2; /* It has to be initially different from nOldHit */
4475 TOOLBAR_MouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4477 TBUTTON_INFO
*btnPtr
, *oldBtnPtr
;
4478 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4481 TRACKMOUSEEVENT trackinfo
;
4483 /* fill in the TRACKMOUSEEVENT struct */
4484 trackinfo
.cbSize
= sizeof(TRACKMOUSEEVENT
);
4485 trackinfo
.dwFlags
= TME_QUERY
;
4486 trackinfo
.hwndTrack
= hwnd
;
4487 trackinfo
.dwHoverTime
= HOVER_DEFAULT
;
4489 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
4490 _TrackMouseEvent(&trackinfo
);
4492 /* Make sure tracking is enabled so we receive a WM_MOUSELEAVE message */
4493 if(!(trackinfo
.dwFlags
& TME_LEAVE
)) {
4494 trackinfo
.dwFlags
= TME_LEAVE
; /* notify upon leaving */
4496 /* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
4497 /* and can properly deactivate the hot toolbar button */
4498 _TrackMouseEvent(&trackinfo
);
4501 if (infoPtr
->hwndToolTip
)
4502 TOOLBAR_RelayEvent (infoPtr
->hwndToolTip
, hwnd
,
4503 WM_MOUSEMOVE
, wParam
, lParam
);
4505 pt
.x
= (INT
)LOWORD(lParam
);
4506 pt
.y
= (INT
)HIWORD(lParam
);
4508 nHit
= TOOLBAR_InternalHitTest (hwnd
, &pt
);
4510 if (infoPtr
->nOldHit
!= nHit
)
4512 /* Remove the effect of an old hot button if the button was enabled and was
4513 drawn with the hot button effect */
4514 if(infoPtr
->nOldHit
>= 0 && infoPtr
->nOldHit
== infoPtr
->nHotItem
&&
4515 (infoPtr
->buttons
[infoPtr
->nOldHit
].fsState
& TBSTATE_ENABLED
))
4517 oldBtnPtr
= &infoPtr
->buttons
[infoPtr
->nOldHit
];
4518 oldBtnPtr
->bHot
= FALSE
;
4520 InvalidateRect (hwnd
, &oldBtnPtr
->rect
,
4521 TOOLBAR_HasText(infoPtr
, oldBtnPtr
));
4524 /* It's not a separator or in nowhere. It's a hot button. */
4527 btnPtr
= &infoPtr
->buttons
[nHit
];
4529 infoPtr
->nHotItem
= nHit
;
4531 /* only enabled buttons show hot effect */
4532 if(infoPtr
->buttons
[nHit
].fsState
& TBSTATE_ENABLED
)
4534 btnPtr
->bHot
= TRUE
;
4535 InvalidateRect(hwnd
, &btnPtr
->rect
,
4536 TOOLBAR_HasText(infoPtr
, btnPtr
));
4541 if (infoPtr
->bCaptured
) {
4542 btnPtr
= &infoPtr
->buttons
[infoPtr
->nButtonDown
];
4543 if (infoPtr
->nOldHit
== infoPtr
->nButtonDown
) {
4544 btnPtr
->fsState
&= ~TBSTATE_PRESSED
;
4545 InvalidateRect(hwnd
, &btnPtr
->rect
, TRUE
);
4547 else if (nHit
== infoPtr
->nButtonDown
) {
4548 btnPtr
->fsState
|= TBSTATE_PRESSED
;
4549 InvalidateRect(hwnd
, &btnPtr
->rect
, TRUE
);
4552 infoPtr
->nOldHit
= nHit
;
4558 inline static LRESULT
4559 TOOLBAR_NCActivate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4561 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
4562 return DefWindowProcA (hwnd
, WM_NCACTIVATE
, wParam
, lParam
);
4564 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
4568 inline static LRESULT
4569 TOOLBAR_NCCalcSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4571 if (!(GetWindowLongA (hwnd
, GWL_STYLE
) & CCS_NODIVIDER
))
4572 ((LPRECT
)lParam
)->top
+= GetSystemMetrics(SM_CYEDGE
);
4574 return DefWindowProcA (hwnd
, WM_NCCALCSIZE
, wParam
, lParam
);
4579 TOOLBAR_NCCreate (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4581 TOOLBAR_INFO
*infoPtr
;
4582 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
)lParam
;
4585 /* allocate memory for info structure */
4586 infoPtr
= (TOOLBAR_INFO
*)COMCTL32_Alloc (sizeof(TOOLBAR_INFO
));
4587 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
4590 infoPtr
->dwStructSize
= sizeof(TBBUTTON
);
4592 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
4593 if (!GetWindowLongA (hwnd
, GWL_HINSTANCE
)) {
4594 HINSTANCE hInst
= (HINSTANCE
)GetWindowLongA (GetParent (hwnd
), GWL_HINSTANCE
);
4595 SetWindowLongA (hwnd
, GWL_HINSTANCE
, (DWORD
)hInst
);
4598 /* native control does:
4599 * Get a lot of colors and brushes
4601 * SystemParametersInfoA(0x1f, 0x3c, adr1, 0)
4602 * CreateFontIndirectA(adr1)
4603 * CreateBitmap(0x27, 0x24, 1, 1, 0)
4604 * hdc = GetDC(toolbar)
4605 * GetSystemMetrics(0x48)
4606 * fnt2=CreateFontA(0xe, 0, 0, 0, 0x190, 0, 0, 0, 0, 2,
4607 * 0, 0, 0, 0, "MARLETT")
4608 * oldfnt = SelectObject(hdc, fnt2)
4609 * GetCharWidthA(hdc, 0x36, 0x36, adr2)
4610 * GetTextMetricsA(hdc, adr3)
4611 * SelectObject(hdc, oldfnt)
4612 * DeleteObject(fnt2)
4614 * InvalidateRect(toolbar, 0, 1)
4615 * SetWindowLongA(toolbar, 0, addr)
4616 * SetWindowLongA(toolbar, -16, xxx) **sometimes**
4619 * ie 1 0x56000a4c 0x46000a4c 0x56008a4d
4620 * ie 2 0x4600094c 0x4600094c 0x4600894d
4621 * ie 3 0x56000b4c 0x46000b4c 0x56008b4d
4622 * rebar 0x50008844 0x40008844 0x50008845
4623 * pager 0x50000844 0x40000844 0x50008845
4624 * IC35mgr 0x5400084e **nochange**
4625 * on entry to _NCCREATE 0x5400084e
4626 * rowlist 0x5400004e **nochange**
4627 * on entry to _NCCREATE 0x5400004e
4631 /* I think the code below is a bug, but it is the way that the native
4632 * controls seem to work. The effect is that if the user of TBSTYLE_FLAT
4633 * forgets to specify TBSTYLE_TRANSPARENT but does specify either
4634 * CCS_TOP or CCS_BOTTOM (_NOMOVEY and _TOP), then the control
4635 * does *not* set TBSTYLE_TRANSPARENT even though it should!!!!
4636 * Some how, the only cases of this seem to be MFC programs.
4638 * Note also that the addition of _TRANSPARENT occurs *only* here. It
4639 * does not occur in the WM_STYLECHANGING routine.
4640 * (Guy Albertelli 9/2001)
4643 if ((cs
->style
& TBSTYLE_FLAT
) && !(cs
->style
& TBSTYLE_TRANSPARENT
))
4644 styleadd
|= TBSTYLE_TRANSPARENT
;
4645 if (!(cs
->style
& (CCS_TOP
| CCS_NOMOVEY
))) {
4646 styleadd
|= CCS_TOP
; /* default to top */
4647 SetWindowLongA (hwnd
, GWL_STYLE
, cs
->style
| styleadd
);
4650 return DefWindowProcA (hwnd
, WM_NCCREATE
, wParam
, lParam
);
4655 TOOLBAR_NCPaint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4657 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
4661 if (dwStyle
& WS_MINIMIZE
)
4662 return 0; /* Nothing to do */
4664 DefWindowProcA (hwnd
, WM_NCPAINT
, wParam
, lParam
);
4666 if (!(hdc
= GetDCEx (hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
)))
4669 if (!(dwStyle
& CCS_NODIVIDER
))
4671 GetWindowRect (hwnd
, &rcWindow
);
4672 OffsetRect (&rcWindow
, -rcWindow
.left
, -rcWindow
.top
);
4673 if( dwStyle
& WS_BORDER
)
4674 OffsetRect (&rcWindow
, 1, 1);
4675 DrawEdge (hdc
, &rcWindow
, EDGE_ETCHED
, BF_TOP
);
4678 ReleaseDC( hwnd
, hdc
);
4684 inline static LRESULT
4685 TOOLBAR_Notify (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4687 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4688 LPNMHDR lpnmh
= (LPNMHDR
)lParam
;
4690 if (lpnmh
->code
== PGN_CALCSIZE
) {
4691 LPNMPGCALCSIZE lppgc
= (LPNMPGCALCSIZE
)lParam
;
4693 if (lppgc
->dwFlag
== PGF_CALCWIDTH
) {
4694 lppgc
->iWidth
= infoPtr
->nWidth
;
4695 TRACE("processed PGN_CALCSIZE, returning horz size = %d\n",
4699 lppgc
->iHeight
= infoPtr
->nHeight
;
4700 TRACE("processed PGN_CALCSIZE, returning vert size = %d\n",
4707 TRACE("passing WM_NOTIFY!\n");
4709 if ((infoPtr
->hwndToolTip
) && (lpnmh
->hwndFrom
== infoPtr
->hwndToolTip
)) {
4710 SendMessageA (infoPtr
->hwndNotify
, WM_NOTIFY
, wParam
, lParam
);
4713 if (lpnmh
->code
== TTN_GETDISPINFOA
) {
4714 LPNMTTDISPINFOA lpdi
= (LPNMTTDISPINFOA
)lParam
;
4716 FIXME("retrieving ASCII string\n");
4719 else if (lpnmh
->code
== TTN_GETDISPINFOW
) {
4720 LPNMTTDISPINFOW lpdi
= (LPNMTTDISPINFOW
)lParam
;
4722 FIXME("retrieving UNICODE string\n");
4733 TOOLBAR_Paint (HWND hwnd
, WPARAM wParam
)
4735 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr(hwnd
);
4739 /* fill ps.rcPaint with a default rect */
4740 memcpy(&(ps
.rcPaint
), &(infoPtr
->rcBound
), sizeof(infoPtr
->rcBound
));
4742 hdc
= wParam
==0 ? BeginPaint(hwnd
, &ps
) : (HDC
)wParam
;
4744 TRACE("psrect=(%d,%d)-(%d,%d)\n",
4745 ps
.rcPaint
.left
, ps
.rcPaint
.top
,
4746 ps
.rcPaint
.right
, ps
.rcPaint
.bottom
);
4748 TOOLBAR_Refresh (hwnd
, hdc
, &ps
);
4749 if (!wParam
) EndPaint (hwnd
, &ps
);
4756 TOOLBAR_Size (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
4758 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4759 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
4768 /* Resize deadlock check */
4769 if (infoPtr
->bAutoSize
) {
4770 infoPtr
->bAutoSize
= FALSE
;
4774 /* FIXME: optimize to only update size if the new size doesn't */
4775 /* match the current size */
4777 flags
= (INT
) wParam
;
4779 /* FIXME for flags =
4780 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
4783 TRACE("sizing toolbar!\n");
4785 if (flags
== SIZE_RESTORED
) {
4786 /* width and height don't apply */
4787 parent
= GetParent (hwnd
);
4788 GetClientRect(parent
, &parent_rect
);
4789 x
= parent_rect
.left
;
4790 y
= parent_rect
.top
;
4792 if (dwStyle
& CCS_NORESIZE
) {
4793 uPosFlags
|= (SWP_NOSIZE
| SWP_NOMOVE
);
4796 * this sets the working width of the toolbar, and
4797 * Calc Toolbar will not adjust it, only the height
4799 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
4800 cy
= infoPtr
->nHeight
;
4801 cx
= infoPtr
->nWidth
;
4802 TOOLBAR_CalcToolbar (hwnd
);
4803 infoPtr
->nWidth
= cx
;
4804 infoPtr
->nHeight
= cy
;
4807 infoPtr
->nWidth
= parent_rect
.right
- parent_rect
.left
;
4808 TOOLBAR_CalcToolbar (hwnd
);
4809 cy
= infoPtr
->nHeight
;
4810 cx
= infoPtr
->nWidth
;
4812 if (dwStyle
& CCS_NOMOVEY
) {
4813 GetWindowRect(hwnd
, &window_rect
);
4814 ScreenToClient(parent
, (LPPOINT
)&window_rect
.left
);
4815 y
= window_rect
.top
;
4819 if (dwStyle
& CCS_NOPARENTALIGN
) {
4820 uPosFlags
|= SWP_NOMOVE
;
4821 cy
= infoPtr
->nHeight
;
4822 cx
= infoPtr
->nWidth
;
4825 if (!(dwStyle
& CCS_NODIVIDER
))
4826 cy
+= GetSystemMetrics(SM_CYEDGE
);
4828 if (dwStyle
& WS_BORDER
)
4831 cy
+= GetSystemMetrics(SM_CYEDGE
);
4832 cx
+= GetSystemMetrics(SM_CYEDGE
);
4835 SetWindowPos (hwnd
, 0, parent_rect
.left
- x
, parent_rect
.top
- y
,
4836 cx
, cy
, uPosFlags
| SWP_NOZORDER
);
4843 TOOLBAR_StyleChanged (HWND hwnd
, INT nType
, LPSTYLESTRUCT lpStyle
)
4845 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
4847 if (nType
== GWL_STYLE
) {
4848 if (lpStyle
->styleNew
& TBSTYLE_LIST
) {
4849 infoPtr
->dwDTFlags
= DT_LEFT
| DT_VCENTER
| DT_SINGLELINE
;
4852 infoPtr
->dwDTFlags
= DT_CENTER
;
4854 infoPtr
->bTransparent
= (lpStyle
->styleNew
& TBSTYLE_TRANSPARENT
);
4855 infoPtr
->bBtnTranspnt
= (lpStyle
->styleNew
&
4856 (TBSTYLE_FLAT
| TBSTYLE_LIST
));
4857 TOOLBAR_CheckStyle (hwnd
, lpStyle
->styleNew
);
4860 TOOLBAR_AutoSize (hwnd
);
4862 InvalidateRect(hwnd
, NULL
, FALSE
);
4869 static LRESULT WINAPI
4870 ToolbarWindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
4872 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n",
4873 hwnd
, uMsg
, /* SPY_GetMsgName(uMsg), */ wParam
, lParam
);
4875 if (!TOOLBAR_GetInfoPtr(hwnd
) && (uMsg
!= WM_NCCREATE
))
4876 return DefWindowProcA( hwnd
, uMsg
, wParam
, lParam
);
4881 return TOOLBAR_AddBitmap (hwnd
, wParam
, lParam
);
4883 case TB_ADDBUTTONSA
:
4884 return TOOLBAR_AddButtonsA (hwnd
, wParam
, lParam
);
4886 case TB_ADDBUTTONSW
:
4887 return TOOLBAR_AddButtonsW (hwnd
, wParam
, lParam
);
4890 return TOOLBAR_AddStringA (hwnd
, wParam
, lParam
);
4893 return TOOLBAR_AddStringW (hwnd
, wParam
, lParam
);
4896 return TOOLBAR_AutoSize (hwnd
);
4898 case TB_BUTTONCOUNT
:
4899 return TOOLBAR_ButtonCount (hwnd
, wParam
, lParam
);
4901 case TB_BUTTONSTRUCTSIZE
:
4902 return TOOLBAR_ButtonStructSize (hwnd
, wParam
, lParam
);
4904 case TB_CHANGEBITMAP
:
4905 return TOOLBAR_ChangeBitmap (hwnd
, wParam
, lParam
);
4907 case TB_CHECKBUTTON
:
4908 return TOOLBAR_CheckButton (hwnd
, wParam
, lParam
);
4910 case TB_COMMANDTOINDEX
:
4911 return TOOLBAR_CommandToIndex (hwnd
, wParam
, lParam
);
4914 return TOOLBAR_Customize (hwnd
);
4916 case TB_DELETEBUTTON
:
4917 return TOOLBAR_DeleteButton (hwnd
, wParam
, lParam
);
4919 case TB_ENABLEBUTTON
:
4920 return TOOLBAR_EnableButton (hwnd
, wParam
, lParam
);
4922 case TB_GETANCHORHIGHLIGHT
:
4923 return TOOLBAR_GetAnchorHighlight (hwnd
);
4926 return TOOLBAR_GetBitmap (hwnd
, wParam
, lParam
);
4928 case TB_GETBITMAPFLAGS
:
4929 return TOOLBAR_GetBitmapFlags (hwnd
, wParam
, lParam
);
4932 return TOOLBAR_GetButton (hwnd
, wParam
, lParam
);
4934 case TB_GETBUTTONINFOA
:
4935 return TOOLBAR_GetButtonInfoA (hwnd
, wParam
, lParam
);
4937 case TB_GETBUTTONINFOW
:
4938 return TOOLBAR_GetButtonInfoW (hwnd
, wParam
, lParam
);
4940 case TB_GETBUTTONSIZE
:
4941 return TOOLBAR_GetButtonSize (hwnd
);
4943 case TB_GETBUTTONTEXTA
:
4944 return TOOLBAR_GetButtonTextA (hwnd
, wParam
, lParam
);
4946 case TB_GETBUTTONTEXTW
:
4947 return TOOLBAR_GetButtonTextW (hwnd
, wParam
, lParam
);
4949 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
4951 case TB_GETDISABLEDIMAGELIST
:
4952 return TOOLBAR_GetDisabledImageList (hwnd
, wParam
, lParam
);
4954 case TB_GETEXTENDEDSTYLE
:
4955 return TOOLBAR_GetExtendedStyle (hwnd
);
4957 case TB_GETHOTIMAGELIST
:
4958 return TOOLBAR_GetHotImageList (hwnd
, wParam
, lParam
);
4961 return TOOLBAR_GetHotItem (hwnd
);
4963 case TB_GETIMAGELIST
:
4964 return TOOLBAR_GetImageList (hwnd
, wParam
, lParam
);
4966 /* case TB_GETINSERTMARK: */ /* 4.71 */
4967 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
4969 case TB_GETITEMRECT
:
4970 return TOOLBAR_GetItemRect (hwnd
, wParam
, lParam
);
4973 return TOOLBAR_GetMaxSize (hwnd
, wParam
, lParam
);
4975 /* case TB_GETOBJECT: */ /* 4.71 */
4976 /* case TB_GETPADDING: */ /* 4.71 */
4979 return TOOLBAR_GetRect (hwnd
, wParam
, lParam
);
4982 return TOOLBAR_GetRows (hwnd
, wParam
, lParam
);
4985 return TOOLBAR_GetState (hwnd
, wParam
, lParam
);
4988 return TOOLBAR_GetStyle (hwnd
, wParam
, lParam
);
4990 case TB_GETTEXTROWS
:
4991 return TOOLBAR_GetTextRows (hwnd
, wParam
, lParam
);
4993 case TB_GETTOOLTIPS
:
4994 return TOOLBAR_GetToolTips (hwnd
, wParam
, lParam
);
4996 case TB_GETUNICODEFORMAT
:
4997 return TOOLBAR_GetUnicodeFormat (hwnd
, wParam
, lParam
);
4999 case CCM_GETVERSION
:
5000 return TOOLBAR_GetVersion (hwnd
);
5003 return TOOLBAR_HideButton (hwnd
, wParam
, lParam
);
5006 return TOOLBAR_HitTest (hwnd
, wParam
, lParam
);
5008 case TB_INDETERMINATE
:
5009 return TOOLBAR_Indeterminate (hwnd
, wParam
, lParam
);
5011 case TB_INSERTBUTTONA
:
5012 return TOOLBAR_InsertButtonA (hwnd
, wParam
, lParam
);
5014 case TB_INSERTBUTTONW
:
5015 return TOOLBAR_InsertButtonW (hwnd
, wParam
, lParam
);
5017 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
5019 case TB_ISBUTTONCHECKED
:
5020 return TOOLBAR_IsButtonChecked (hwnd
, wParam
, lParam
);
5022 case TB_ISBUTTONENABLED
:
5023 return TOOLBAR_IsButtonEnabled (hwnd
, wParam
, lParam
);
5025 case TB_ISBUTTONHIDDEN
:
5026 return TOOLBAR_IsButtonHidden (hwnd
, wParam
, lParam
);
5028 case TB_ISBUTTONHIGHLIGHTED
:
5029 return TOOLBAR_IsButtonHighlighted (hwnd
, wParam
, lParam
);
5031 case TB_ISBUTTONINDETERMINATE
:
5032 return TOOLBAR_IsButtonIndeterminate (hwnd
, wParam
, lParam
);
5034 case TB_ISBUTTONPRESSED
:
5035 return TOOLBAR_IsButtonPressed (hwnd
, wParam
, lParam
);
5037 case TB_LOADIMAGES
: /* 4.70 */
5038 FIXME("missing standard imagelists\n");
5041 /* case TB_MAPACCELERATORA: */ /* 4.71 */
5042 /* case TB_MAPACCELERATORW: */ /* 4.71 */
5043 /* case TB_MARKBUTTON: */ /* 4.71 */
5044 /* case TB_MOVEBUTTON: */ /* 4.71 */
5046 case TB_PRESSBUTTON
:
5047 return TOOLBAR_PressButton (hwnd
, wParam
, lParam
);
5049 /* case TB_REPLACEBITMAP: */
5051 case TB_SAVERESTOREA
:
5052 return TOOLBAR_SaveRestoreA (hwnd
, wParam
, lParam
);
5054 case TB_SAVERESTOREW
:
5055 return TOOLBAR_SaveRestoreW (hwnd
, wParam
, lParam
);
5057 case TB_SETANCHORHIGHLIGHT
:
5058 return TOOLBAR_SetAnchorHighlight (hwnd
, wParam
);
5060 case TB_SETBITMAPSIZE
:
5061 return TOOLBAR_SetBitmapSize (hwnd
, wParam
, lParam
);
5063 case TB_SETBUTTONINFOA
:
5064 return TOOLBAR_SetButtonInfoA (hwnd
, wParam
, lParam
);
5066 case TB_SETBUTTONINFOW
:
5067 return TOOLBAR_SetButtonInfoW (hwnd
, wParam
, lParam
);
5069 case TB_SETBUTTONSIZE
:
5070 return TOOLBAR_SetButtonSize (hwnd
, wParam
, lParam
);
5072 case TB_SETBUTTONWIDTH
:
5073 return TOOLBAR_SetButtonWidth (hwnd
, wParam
, lParam
);
5076 return TOOLBAR_SetCmdId (hwnd
, wParam
, lParam
);
5078 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
5080 case TB_SETDISABLEDIMAGELIST
:
5081 return TOOLBAR_SetDisabledImageList (hwnd
, wParam
, lParam
);
5083 case TB_SETDRAWTEXTFLAGS
:
5084 return TOOLBAR_SetDrawTextFlags (hwnd
, wParam
, lParam
);
5086 case TB_SETEXTENDEDSTYLE
:
5087 return TOOLBAR_SetExtendedStyle (hwnd
, wParam
, lParam
);
5089 case TB_SETHOTIMAGELIST
:
5090 return TOOLBAR_SetHotImageList (hwnd
, wParam
, lParam
);
5093 return TOOLBAR_SetHotItem (hwnd
, wParam
);
5095 case TB_SETIMAGELIST
:
5096 return TOOLBAR_SetImageList (hwnd
, wParam
, lParam
);
5099 return TOOLBAR_SetIndent (hwnd
, wParam
, lParam
);
5101 /* case TB_SETINSERTMARK: */ /* 4.71 */
5103 case TB_SETINSERTMARKCOLOR
:
5104 return TOOLBAR_SetInsertMarkColor (hwnd
, wParam
, lParam
);
5106 case TB_SETMAXTEXTROWS
:
5107 return TOOLBAR_SetMaxTextRows (hwnd
, wParam
, lParam
);
5109 /* case TB_SETPADDING: */ /* 4.71 */
5112 return TOOLBAR_SetParent (hwnd
, wParam
, lParam
);
5115 return TOOLBAR_SetRows (hwnd
, wParam
, lParam
);
5118 return TOOLBAR_SetState (hwnd
, wParam
, lParam
);
5121 return TOOLBAR_SetStyle (hwnd
, wParam
, lParam
);
5123 case TB_SETTOOLTIPS
:
5124 return TOOLBAR_SetToolTips (hwnd
, wParam
, lParam
);
5126 case TB_SETUNICODEFORMAT
:
5127 return TOOLBAR_SetUnicodeFormat (hwnd
, wParam
, lParam
);
5129 case CCM_SETVERSION
:
5130 return TOOLBAR_SetVersion (hwnd
, (INT
)wParam
);
5136 return TOOLBAR_Create (hwnd
, wParam
, lParam
);
5139 return TOOLBAR_Destroy (hwnd
, wParam
, lParam
);
5142 return TOOLBAR_EraseBackground (hwnd
, wParam
, lParam
);
5145 return TOOLBAR_GetFont (hwnd
, wParam
, lParam
);
5147 /* case WM_KEYDOWN: */
5148 /* case WM_KILLFOCUS: */
5150 case WM_LBUTTONDBLCLK
:
5151 return TOOLBAR_LButtonDblClk (hwnd
, wParam
, lParam
);
5153 case WM_LBUTTONDOWN
:
5154 return TOOLBAR_LButtonDown (hwnd
, wParam
, lParam
);
5157 return TOOLBAR_LButtonUp (hwnd
, wParam
, lParam
);
5160 return TOOLBAR_MouseMove (hwnd
, wParam
, lParam
);
5163 return TOOLBAR_MouseLeave (hwnd
, wParam
, lParam
);
5165 case WM_CAPTURECHANGED
:
5166 return TOOLBAR_CaptureChanged(hwnd
);
5169 return TOOLBAR_NCActivate (hwnd
, wParam
, lParam
);
5172 return TOOLBAR_NCCalcSize (hwnd
, wParam
, lParam
);
5175 return TOOLBAR_NCCreate (hwnd
, wParam
, lParam
);
5178 return TOOLBAR_NCPaint (hwnd
, wParam
, lParam
);
5181 return TOOLBAR_Notify (hwnd
, wParam
, lParam
);
5183 /* case WM_NOTIFYFORMAT: */
5186 return TOOLBAR_Paint (hwnd
, wParam
);
5189 return TOOLBAR_Size (hwnd
, wParam
, lParam
);
5191 case WM_STYLECHANGED
:
5192 return TOOLBAR_StyleChanged (hwnd
, (INT
)wParam
, (LPSTYLESTRUCT
)lParam
);
5194 /* case WM_SYSCOLORCHANGE: */
5196 /* case WM_WININICHANGE: */
5201 case WM_MEASUREITEM
:
5204 TOOLBAR_INFO
*infoPtr
= TOOLBAR_GetInfoPtr (hwnd
);
5206 return SendMessageA (infoPtr
->hwndNotify
, uMsg
, wParam
, lParam
);
5208 return SendMessageA (GetParent (hwnd
), uMsg
, wParam
, lParam
);
5212 if (uMsg
>= WM_USER
)
5213 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
5214 uMsg
, wParam
, lParam
);
5215 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
5222 TOOLBAR_Register (void)
5226 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
5227 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
;
5228 wndClass
.lpfnWndProc
= (WNDPROC
)ToolbarWindowProc
;
5229 wndClass
.cbClsExtra
= 0;
5230 wndClass
.cbWndExtra
= sizeof(TOOLBAR_INFO
*);
5231 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
5232 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_3DFACE
+ 1);
5233 wndClass
.lpszClassName
= TOOLBARCLASSNAMEA
;
5235 RegisterClassA (&wndClass
);
5240 TOOLBAR_Unregister (void)
5242 UnregisterClassA (TOOLBARCLASSNAMEA
, (HINSTANCE
)NULL
);