New debug scheme with explicit debug channels declaration.
[wine.git] / dlls / comctl32 / toolbar.c
blob5e772b5b397dd3bc25ced878337835056baeb8af
2 /*
3 * Toolbar control
5 * Copyright 1998 Eric Kohl
7 * TODO:
8 * - A little bug in TOOLBAR_DrawMasked()
9 * - Button wrapping (under construction).
10 * - Messages.
11 * - Notifications.
12 * - Fix TB_SETROWS.
13 * - Tooltip support (almost complete).
14 * - Unicode suppport.
15 * - Internal COMMCTL32 bitmaps.
16 * - Fix TOOLBAR_SetButtonInfo32A.
17 * - Fix TOOLBAR_Customize. (Customize dialog.)
19 * Testing:
20 * - Run tests using Waite Group Windows95 API Bible Volume 2.
21 * The second cdrom contains executables addstr.exe, btncount.exe,
22 * btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
23 * enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
24 * indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
25 * setparnt.exe, setrows.exe, toolwnd.exe.
26 * - Microsofts controlspy examples.
29 #include <string.h>
31 #include "winbase.h"
32 #include "commctrl.h"
33 #include "sysmetrics.h"
34 #include "cache.h"
35 #include "toolbar.h"
36 #include "debug.h"
38 DEFAULT_DEBUG_CHANNEL(toolbar)
40 /* #define __NEW_WRAP_CODE__ */
42 #define SEPARATOR_WIDTH 8
43 #define SEPARATOR_HEIGHT 5
44 #define TOP_BORDER 2
45 #define BOTTOM_BORDER 2
49 #define TOOLBAR_GetInfoPtr(wndPtr) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
52 static void
53 TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
55 INT x = (lpRect->left + lpRect->right) / 2 - 1;
56 INT yBottom = lpRect->bottom - 3;
57 INT yTop = lpRect->top + 1;
59 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
60 MoveToEx (hdc, x, yBottom, NULL);
61 LineTo (hdc, x, yTop);
62 x++;
63 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
64 MoveToEx (hdc, x, yBottom, NULL);
65 LineTo (hdc, x, yTop);
69 static void
70 TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
71 HDC hdc, INT nState)
73 RECT rcText = btnPtr->rect;
74 HFONT hOldFont;
75 INT nOldBkMode;
76 COLORREF clrOld;
78 /* draw text */
79 if ((btnPtr->iString > -1) && (btnPtr->iString < infoPtr->nNumStrings)) {
80 InflateRect (&rcText, -3, -3);
81 rcText.top += infoPtr->nBitmapHeight;
82 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
83 OffsetRect (&rcText, 1, 1);
85 hOldFont = SelectObject (hdc, infoPtr->hFont);
86 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
87 if (!(nState & TBSTATE_ENABLED)) {
88 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
89 OffsetRect (&rcText, 1, 1);
90 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
91 &rcText, infoPtr->dwDTFlags);
92 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
93 OffsetRect (&rcText, -1, -1);
94 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
95 &rcText, infoPtr->dwDTFlags);
97 else if (nState & TBSTATE_INDETERMINATE) {
98 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
99 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
100 &rcText, infoPtr->dwDTFlags);
102 else {
103 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
104 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
105 &rcText, infoPtr->dwDTFlags);
108 SetTextColor (hdc, clrOld);
109 SelectObject (hdc, hOldFont);
110 if (nOldBkMode != TRANSPARENT)
111 SetBkMode (hdc, nOldBkMode);
116 static void
117 TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
119 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
120 INT cx = lpRect->right - lpRect->left;
121 INT cy = lpRect->bottom - lpRect->top;
122 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
123 SelectObject (hdc, hbr);
127 static void
128 TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
129 HDC hdc, INT x, INT y)
131 /* FIXME: this function is a hack since it uses image list
132 internals directly */
134 HDC hdcImageList = CreateCompatibleDC (0);
135 HDC hdcMask = CreateCompatibleDC (0);
136 HIMAGELIST himl = infoPtr->himlStd;
137 HBITMAP hbmMask;
139 /* create new bitmap */
140 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
141 SelectObject (hdcMask, hbmMask);
143 /* copy the mask bitmap */
144 SelectObject (hdcImageList, himl->hbmMask);
145 SetBkColor (hdcImageList, RGB(255, 255, 255));
146 SetTextColor (hdcImageList, RGB(0, 0, 0));
147 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
148 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
150 #if 0
151 /* add white mask from image */
152 SelectObject (hdcImageList, himl->hbmImage);
153 SetBkColor (hdcImageList, RGB(0, 0, 0));
154 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
155 hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
156 #endif
158 /* draw the new mask */
159 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
160 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
161 hdcMask, 0, 0, 0xB8074A);
163 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
164 BitBlt (hdc, x, y, himl->cx, himl->cy,
165 hdcMask, 0, 0, 0xB8074A);
167 DeleteObject (hbmMask);
168 DeleteDC (hdcMask);
169 DeleteDC (hdcImageList);
173 static void
174 TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
176 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
177 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
178 RECT rc;
180 if (btnPtr->fsState & TBSTATE_HIDDEN)
181 return;
183 rc = btnPtr->rect;
184 if (btnPtr->fsStyle & TBSTYLE_SEP) {
185 if ((dwStyle & TBSTYLE_FLAT) && (btnPtr->idCommand == 0))
186 TOOLBAR_DrawFlatSeparator (&btnPtr->rect, hdc);
187 return;
190 /* disabled */
191 if (!(btnPtr->fsState & TBSTATE_ENABLED)) {
192 DrawEdge (hdc, &rc, EDGE_RAISED,
193 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
195 if (dwStyle & TBSTYLE_FLAT) {
196 /* if (infoPtr->himlDis) */
197 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
198 rc.left+1, rc.top+1, ILD_NORMAL);
199 /* else */
200 /* TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1); */
202 else
203 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
205 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
206 return;
209 /* pressed TBSTYLE_BUTTON */
210 if (btnPtr->fsState & TBSTATE_PRESSED) {
211 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
212 ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
213 rc.left+2, rc.top+2, ILD_NORMAL);
214 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
215 return;
218 /* checked TBSTYLE_CHECK*/
219 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
220 (btnPtr->fsState & TBSTATE_CHECKED)) {
221 if (dwStyle & TBSTYLE_FLAT)
222 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
223 BF_RECT | BF_MIDDLE | BF_ADJUST);
224 else
225 DrawEdge (hdc, &rc, EDGE_SUNKEN,
226 BF_RECT | BF_MIDDLE | BF_ADJUST);
228 TOOLBAR_DrawPattern (hdc, &rc);
229 if (dwStyle & TBSTYLE_FLAT)
231 if (infoPtr->himlDef != NULL)
232 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
233 rc.left+2, rc.top+2, ILD_NORMAL);
234 else
235 ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
236 rc.left+2, rc.top+2, ILD_NORMAL);
238 else
239 ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
240 rc.left+2, rc.top+2, ILD_NORMAL);
241 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
242 return;
245 /* indeterminate */
246 if (btnPtr->fsState & TBSTATE_INDETERMINATE) {
247 DrawEdge (hdc, &rc, EDGE_RAISED,
248 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
250 TOOLBAR_DrawPattern (hdc, &rc);
251 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
252 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
253 return;
256 if (dwStyle & TBSTYLE_FLAT)
258 if(btnPtr->bHot)
259 DrawEdge (hdc, &rc, BDR_RAISEDINNER,
260 BF_RECT | BF_MIDDLE | BF_SOFT);
262 if(infoPtr->himlDef != NULL)
263 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
264 rc.left +2, rc.top +2, ILD_NORMAL);
265 else
266 ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
267 rc.left +2, rc.top +2, ILD_NORMAL);
269 else{
270 /* normal state */
271 DrawEdge (hdc, &rc, EDGE_RAISED,
272 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
274 ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
275 rc.left+1, rc.top+1, ILD_NORMAL);
278 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
282 static void
283 TOOLBAR_Refresh (HWND hwnd, HDC hdc)
285 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
286 TBUTTON_INFO *btnPtr;
287 INT i;
289 /* draw buttons */
290 btnPtr = infoPtr->buttons;
291 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
292 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
296 static void
297 TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
299 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
300 TBUTTON_INFO *btnPtr;
301 INT i;
302 HDC hdc;
303 HFONT hOldFont;
304 SIZE sz;
306 lpSize->cx = 0;
307 lpSize->cy = 0;
308 hdc = GetDC (0);
309 hOldFont = SelectObject (hdc, infoPtr->hFont);
311 btnPtr = infoPtr->buttons;
312 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
313 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
314 (btnPtr->iString > -1) &&
315 (btnPtr->iString < infoPtr->nNumStrings)) {
316 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
317 GetTextExtentPoint32W (hdc, lpText, lstrlenW (lpText), &sz);
318 if (sz.cx > lpSize->cx)
319 lpSize->cx = sz.cx;
320 if (sz.cy > lpSize->cy)
321 lpSize->cy = sz.cy;
325 SelectObject (hdc, hOldFont);
326 ReleaseDC (0, hdc);
328 TRACE (toolbar, "string size %d x %d!\n", lpSize->cx, lpSize->cy);
332 static void
333 TOOLBAR_CalcToolbar (HWND hwnd)
335 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
336 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
337 TBUTTON_INFO *btnPtr;
338 INT i, nRows;
339 INT x, y, cx, cy;
340 BOOL bWrap;
341 SIZE sizeString;
342 /* --- new --- */
343 #ifdef __NEW_WRAP_CODE__
344 INT nGrpCount = 0;
345 INT grpX,j;
346 TBUTTON_INFO *grpPtr;
347 #endif
348 /* --- end new --- */
350 TOOLBAR_CalcStrings (hwnd, &sizeString);
352 if (sizeString.cy > 0)
353 infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
354 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
355 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
357 if (sizeString.cx > infoPtr->nBitmapWidth)
358 infoPtr->nButtonWidth = sizeString.cx + 6;
359 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
360 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
362 x = infoPtr->nIndent;
363 y = TOP_BORDER;
364 cx = infoPtr->nButtonWidth;
365 cy = infoPtr->nButtonHeight;
366 nRows = 0;
368 /* calculate the size of each button according to it's style */
369 /* TOOLBAR_CalcButtons (hwnd); */
371 infoPtr->rcBound.top = y;
372 infoPtr->rcBound.left = x;
373 infoPtr->rcBound.bottom = y + cy;
374 infoPtr->rcBound.right = x;
376 btnPtr = infoPtr->buttons;
377 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
378 bWrap = FALSE;
380 if (btnPtr->fsState & TBSTATE_HIDDEN) {
381 SetRectEmpty (&btnPtr->rect);
382 continue;
385 #ifdef __NEW_WRAP_CODE__
386 /*#if 0 */
387 if (btnPtr->fsStyle & TBSTYLE_SEP) {
388 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
389 /* it is the actual width of the separator. This is used for */
390 /* custom controls in toolbars. */
391 if ((dwStyle & TBSTYLE_WRAPABLE) &&
392 (btnPtr->fsState & TBSTATE_WRAP)) {
393 x = 0;
394 y += cy;
395 cx = infoPtr->nWidth;
396 cy = ((btnPtr->iBitmap > 0) ?
397 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3;
398 /* nRows++; */
399 /* bWrap = TRUE; */
401 else
402 cx = (btnPtr->iBitmap > 0) ?
403 btnPtr->iBitmap : SEPARATOR_WIDTH;
405 else {
406 /* this must be a button */
407 cx = infoPtr->nButtonWidth;
409 /*#endif */
411 /* --- begin test --- */
412 if ((i >= nGrpCount) && (btnPtr->fsStyle & TBSTYLE_GROUP)) {
413 for (j = i, grpX = x, nGrpCount = 0; j < infoPtr->nNumButtons; j++) {
414 grpPtr = &infoPtr->buttons[j];
415 if (grpPtr->fsState & TBSTATE_HIDDEN)
416 continue;
418 grpX += cx;
420 if ((grpPtr->fsStyle & TBSTYLE_SEP) ||
421 !(grpPtr->fsStyle & TBSTYLE_GROUP) ||
422 (grpX > infoPtr->nWidth)) {
423 nGrpCount = j;
424 break;
426 else if (grpX + x > infoPtr->nWidth) {
427 bWrap = TRUE;
428 nGrpCount = j;
429 break;
434 bWrap = ((bWrap || (x + cx > infoPtr->nWidth)) &&
435 (dwStyle & TBSTYLE_WRAPABLE));
436 if (bWrap) {
437 nRows++;
438 y += cy;
439 x = infoPtr->nIndent;
440 bWrap = FALSE;
443 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
445 btnPtr->nRow = nRows;
446 x += cx;
448 if (btnPtr->fsState & TBSTATE_WRAP) {
449 nRows++;
450 y += (cy + SEPARATOR_HEIGHT);
451 x = infoPtr->nIndent;
454 infoPtr->nRows = nRows + 1;
456 /* --- end test --- */
457 #else
458 if (btnPtr->fsStyle & TBSTYLE_SEP) {
459 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
460 /* it is the actual width of the separator. This is used for */
461 /* custom controls in toolbars. */
462 if ((dwStyle & TBSTYLE_WRAPABLE) &&
463 (btnPtr->fsState & TBSTATE_WRAP)) {
464 x = 0;
465 y += cy;
466 cx = infoPtr->nWidth;
467 cy = ((btnPtr->iBitmap > 0) ?
468 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 / 3;
469 nRows++;
470 bWrap = TRUE;
472 else
473 cx = (btnPtr->iBitmap > 0) ?
474 btnPtr->iBitmap : SEPARATOR_WIDTH;
476 else {
477 /* this must be a button */
478 cx = infoPtr->nButtonWidth;
481 btnPtr->rect.left = x;
482 btnPtr->rect.top = y;
483 btnPtr->rect.right = x + cx;
484 btnPtr->rect.bottom = y + cy;
486 if (infoPtr->rcBound.left > x)
487 infoPtr->rcBound.left = x;
488 if (infoPtr->rcBound.right < x + cx)
489 infoPtr->rcBound.right = x + cx;
490 if (infoPtr->rcBound.bottom < y + cy)
491 infoPtr->rcBound.bottom = y + cy;
493 if (infoPtr->hwndToolTip) {
494 TTTOOLINFOA ti;
496 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
497 ti.cbSize = sizeof(TTTOOLINFOA);
498 ti.hwnd = hwnd;
499 ti.uId = btnPtr->idCommand;
500 ti.rect = btnPtr->rect;
501 SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
502 0, (LPARAM)&ti);
505 if (bWrap) {
506 x = 0;
507 y += cy;
508 if (i < infoPtr->nNumButtons)
509 nRows++;
511 else
512 x += cx;
513 #endif
516 infoPtr->nHeight = y + cy + BOTTOM_BORDER;
517 TRACE (toolbar, "toolbar height %d\n", infoPtr->nHeight);
521 static INT
522 TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
524 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
525 TBUTTON_INFO *btnPtr;
526 INT i;
528 btnPtr = infoPtr->buttons;
529 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
530 if (btnPtr->fsState & TBSTATE_HIDDEN)
531 continue;
533 if (btnPtr->fsStyle & TBSTYLE_SEP) {
534 if (PtInRect (&btnPtr->rect, *lpPt)) {
535 TRACE (toolbar, " ON SEPARATOR %d!\n", i);
536 return -i;
539 else {
540 if (PtInRect (&btnPtr->rect, *lpPt)) {
541 TRACE (toolbar, " ON BUTTON %d!\n", i);
542 return i;
547 TRACE (toolbar, " NOWHERE!\n");
548 return -1;
552 static INT
553 TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
555 TBUTTON_INFO *btnPtr;
556 INT i;
558 btnPtr = infoPtr->buttons;
559 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
560 if (btnPtr->idCommand == idCommand) {
561 TRACE (toolbar, "command=%d index=%d\n", idCommand, i);
562 return i;
565 TRACE (toolbar, "no index found for command=%d\n", idCommand);
566 return -1;
570 static INT
571 TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
573 TBUTTON_INFO *btnPtr;
574 INT nRunIndex;
576 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
577 return -1;
579 /* check index button */
580 btnPtr = &infoPtr->buttons[nIndex];
581 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
582 if (btnPtr->fsState & TBSTATE_CHECKED)
583 return nIndex;
586 /* check previous buttons */
587 nRunIndex = nIndex - 1;
588 while (nRunIndex >= 0) {
589 btnPtr = &infoPtr->buttons[nRunIndex];
590 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
591 if (btnPtr->fsState & TBSTATE_CHECKED)
592 return nRunIndex;
594 else
595 break;
596 nRunIndex--;
599 /* check next buttons */
600 nRunIndex = nIndex + 1;
601 while (nRunIndex < infoPtr->nNumButtons) {
602 btnPtr = &infoPtr->buttons[nRunIndex];
603 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
604 if (btnPtr->fsState & TBSTATE_CHECKED)
605 return nRunIndex;
607 else
608 break;
609 nRunIndex++;
612 return -1;
616 static VOID
617 TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
618 WPARAM wParam, LPARAM lParam)
620 MSG msg;
622 msg.hwnd = hwndMsg;
623 msg.message = uMsg;
624 msg.wParam = wParam;
625 msg.lParam = lParam;
626 msg.time = GetMessageTime ();
627 msg.pt.x = LOWORD(GetMessagePos ());
628 msg.pt.y = HIWORD(GetMessagePos ());
630 SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
633 /***********************************************************************
634 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
637 static LRESULT
638 TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
640 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
641 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
642 INT nIndex = 0;
644 if ((!lpAddBmp) || ((INT)wParam <= 0))
645 return -1;
647 TRACE (toolbar, "adding %d bitmaps!\n", wParam);
649 if (!(infoPtr->himlStd)) {
650 /* create new standard image list */
652 TRACE (toolbar, "creating standard image list!\n");
655 /* Windows resize all the buttons to the size of a newly added STandard Image*/
656 /* TODO: The resizing should be done each time a standard image is added*/
657 if (lpAddBmp->hInst == HINST_COMMCTRL)
660 if (lpAddBmp->nID & 1)
662 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
663 MAKELPARAM((WORD)26, (WORD)26));
664 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
665 MAKELPARAM((WORD)33, (WORD)33));
667 else
669 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
670 MAKELPARAM((WORD)16, (WORD)16));
672 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
673 MAKELPARAM((WORD)22, (WORD)22));
676 TOOLBAR_CalcToolbar (hwnd);
679 infoPtr->himlStd =
680 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
681 ILC_COLOR | ILC_MASK, (INT)wParam, 2);
684 /* Add bitmaps to the standard image list */
685 if (lpAddBmp->hInst == (HINSTANCE)0) {
686 nIndex =
687 ImageList_AddMasked (infoPtr->himlStd, (HBITMAP)lpAddBmp->nID,
688 CLR_DEFAULT);
690 else if (lpAddBmp->hInst == HINST_COMMCTRL) {
691 /* add internal bitmaps */
693 FIXME (toolbar, "internal bitmaps not supported!\n");
694 /* TODO: Resize all the buttons when a new standard image is added */
696 /* Hack to "add" some reserved images within the image list
697 to get the right image indices */
698 nIndex = ImageList_GetImageCount (infoPtr->himlStd);
699 ImageList_SetImageCount (infoPtr->himlStd, nIndex + (INT)wParam);
702 else {
703 HBITMAP hBmp =
704 LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
705 nIndex = ImageList_AddMasked (infoPtr->himlStd, hBmp, CLR_DEFAULT);
707 DeleteObject (hBmp);
710 infoPtr->nNumBitmaps += (INT)wParam;
712 return nIndex;
716 static LRESULT
717 TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
719 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
720 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
721 INT nOldButtons, nNewButtons, nAddButtons, nCount;
722 HDC hdc;
724 TRACE (toolbar, "adding %d buttons!\n", wParam);
726 nAddButtons = (UINT)wParam;
727 nOldButtons = infoPtr->nNumButtons;
728 nNewButtons = nOldButtons + nAddButtons;
730 if (infoPtr->nNumButtons == 0) {
731 infoPtr->buttons =
732 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
734 else {
735 TBUTTON_INFO *oldButtons = infoPtr->buttons;
736 infoPtr->buttons =
737 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
738 memcpy (&infoPtr->buttons[0], &oldButtons[0],
739 nOldButtons * sizeof(TBUTTON_INFO));
740 COMCTL32_Free (oldButtons);
743 infoPtr->nNumButtons = nNewButtons;
745 /* insert new button data */
746 for (nCount = 0; nCount < nAddButtons; nCount++) {
747 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
748 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
749 btnPtr->idCommand = lpTbb[nCount].idCommand;
750 btnPtr->fsState = lpTbb[nCount].fsState;
751 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
752 btnPtr->dwData = lpTbb[nCount].dwData;
753 btnPtr->iString = lpTbb[nCount].iString;
754 btnPtr->bHot = FALSE;
756 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
757 TTTOOLINFOA ti;
759 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
760 ti.cbSize = sizeof (TTTOOLINFOA);
761 ti.hwnd = hwnd;
762 ti.uId = btnPtr->idCommand;
763 ti.hinst = 0;
764 ti.lpszText = LPSTR_TEXTCALLBACKA;
766 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
767 0, (LPARAM)&ti);
771 TOOLBAR_CalcToolbar (hwnd);
773 hdc = GetDC (hwnd);
774 TOOLBAR_Refresh (hwnd, hdc);
775 ReleaseDC (hwnd, hdc);
777 return TRUE;
781 /* << TOOLBAR_AddButtons32W >> */
784 static LRESULT
785 TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
787 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
788 INT nIndex;
790 if ((wParam) && (HIWORD(lParam) == 0)) {
791 char szString[256];
792 INT len;
793 TRACE (toolbar, "adding string from resource!\n");
795 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
796 szString, 256);
798 TRACE (toolbar, "len=%d \"%s\"\n", len, szString);
799 nIndex = infoPtr->nNumStrings;
800 if (infoPtr->nNumStrings == 0) {
801 infoPtr->strings =
802 COMCTL32_Alloc (sizeof(LPWSTR));
804 else {
805 LPWSTR *oldStrings = infoPtr->strings;
806 infoPtr->strings =
807 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
808 memcpy (&infoPtr->strings[0], &oldStrings[0],
809 sizeof(LPWSTR) * infoPtr->nNumStrings);
810 COMCTL32_Free (oldStrings);
813 infoPtr->strings[infoPtr->nNumStrings] =
814 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
815 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
816 infoPtr->nNumStrings++;
818 else {
819 LPSTR p = (LPSTR)lParam;
820 INT len;
822 if (p == NULL)
823 return -1;
824 TRACE (toolbar, "adding string(s) from array!\n");
825 nIndex = infoPtr->nNumStrings;
826 while (*p) {
827 len = lstrlenA (p);
828 TRACE (toolbar, "len=%d \"%s\"\n", len, p);
830 if (infoPtr->nNumStrings == 0) {
831 infoPtr->strings =
832 COMCTL32_Alloc (sizeof(LPWSTR));
834 else {
835 LPWSTR *oldStrings = infoPtr->strings;
836 infoPtr->strings =
837 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
838 memcpy (&infoPtr->strings[0], &oldStrings[0],
839 sizeof(LPWSTR) * infoPtr->nNumStrings);
840 COMCTL32_Free (oldStrings);
843 infoPtr->strings[infoPtr->nNumStrings] =
844 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
845 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
846 infoPtr->nNumStrings++;
848 p += (len+1);
852 return nIndex;
856 static LRESULT
857 TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
859 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
860 INT nIndex;
862 if ((wParam) && (HIWORD(lParam) == 0)) {
863 WCHAR szString[256];
864 INT len;
865 TRACE (toolbar, "adding string from resource!\n");
867 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
868 szString, 256);
870 TRACE (toolbar, "len=%d \"%s\"\n", len, debugstr_w(szString));
871 nIndex = infoPtr->nNumStrings;
872 if (infoPtr->nNumStrings == 0) {
873 infoPtr->strings =
874 COMCTL32_Alloc (sizeof(LPWSTR));
876 else {
877 LPWSTR *oldStrings = infoPtr->strings;
878 infoPtr->strings =
879 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
880 memcpy (&infoPtr->strings[0], &oldStrings[0],
881 sizeof(LPWSTR) * infoPtr->nNumStrings);
882 COMCTL32_Free (oldStrings);
885 infoPtr->strings[infoPtr->nNumStrings] =
886 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
887 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
888 infoPtr->nNumStrings++;
890 else {
891 LPWSTR p = (LPWSTR)lParam;
892 INT len;
894 if (p == NULL)
895 return -1;
896 TRACE (toolbar, "adding string(s) from array!\n");
897 nIndex = infoPtr->nNumStrings;
898 while (*p) {
899 len = lstrlenW (p);
900 TRACE (toolbar, "len=%d \"%s\"\n", len, debugstr_w(p));
902 if (infoPtr->nNumStrings == 0) {
903 infoPtr->strings =
904 COMCTL32_Alloc (sizeof(LPWSTR));
906 else {
907 LPWSTR *oldStrings = infoPtr->strings;
908 infoPtr->strings =
909 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
910 memcpy (&infoPtr->strings[0], &oldStrings[0],
911 sizeof(LPWSTR) * infoPtr->nNumStrings);
912 COMCTL32_Free (oldStrings);
915 infoPtr->strings[infoPtr->nNumStrings] =
916 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
917 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
918 infoPtr->nNumStrings++;
920 p += (len+1);
924 return nIndex;
928 static LRESULT
929 TOOLBAR_AutoSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
931 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
932 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
933 RECT parent_rect;
934 HWND parent;
935 /* INT32 x, y; */
936 INT cx, cy;
937 UINT uPosFlags = 0;
939 TRACE (toolbar, "resize forced!\n");
941 parent = GetParent (hwnd);
942 GetClientRect(parent, &parent_rect);
944 if (dwStyle & CCS_NORESIZE) {
945 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
946 cx = 0;
947 cy = 0;
949 else {
950 infoPtr->nWidth = parent_rect.right - parent_rect.left;
951 TOOLBAR_CalcToolbar (hwnd);
952 cy = infoPtr->nHeight;
953 cx = infoPtr->nWidth;
956 if (dwStyle & CCS_NOPARENTALIGN)
957 uPosFlags |= SWP_NOMOVE;
959 if (!(dwStyle & CCS_NODIVIDER))
960 cy += sysMetrics[SM_CYEDGE];
962 infoPtr->bAutoSize = TRUE;
963 SetWindowPos (hwnd, HWND_TOP, parent_rect.left, parent_rect.top,
964 cx, cy, uPosFlags);
966 return 0;
970 static LRESULT
971 TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
973 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
975 return infoPtr->nNumButtons;
979 static LRESULT
980 TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
982 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
984 if (infoPtr == NULL) {
985 ERR (toolbar, "(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
986 ERR (toolbar, "infoPtr == NULL!\n");
987 return 0;
990 infoPtr->dwStructSize = (DWORD)wParam;
992 return 0;
996 static LRESULT
997 TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
999 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1000 TBUTTON_INFO *btnPtr;
1001 HDC hdc;
1002 INT nIndex;
1004 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1005 if (nIndex == -1)
1006 return FALSE;
1008 btnPtr = &infoPtr->buttons[nIndex];
1009 btnPtr->iBitmap = LOWORD(lParam);
1011 hdc = GetDC (hwnd);
1012 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
1013 ReleaseDC (hwnd, hdc);
1015 return TRUE;
1019 static LRESULT
1020 TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1022 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1023 TBUTTON_INFO *btnPtr;
1024 HDC hdc;
1025 INT nIndex;
1026 INT nOldIndex = -1;
1028 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1029 if (nIndex == -1)
1030 return FALSE;
1032 btnPtr = &infoPtr->buttons[nIndex];
1034 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
1035 return FALSE;
1037 if (LOWORD(lParam) == FALSE)
1038 btnPtr->fsState &= ~TBSTATE_CHECKED;
1039 else {
1040 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
1041 nOldIndex =
1042 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
1043 if (nOldIndex == nIndex)
1044 return 0;
1045 if (nOldIndex != -1)
1046 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
1048 btnPtr->fsState |= TBSTATE_CHECKED;
1051 hdc = GetDC (hwnd);
1052 if (nOldIndex != -1)
1053 TOOLBAR_DrawButton (hwnd, &infoPtr->buttons[nOldIndex], hdc);
1054 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
1055 ReleaseDC (hwnd, hdc);
1057 /* FIXME: Send a WM_NOTIFY?? */
1059 return TRUE;
1063 static LRESULT
1064 TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
1066 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1068 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1072 static LRESULT
1073 TOOLBAR_Customize (HWND hwnd)
1075 FIXME (toolbar, "customization not implemented!\n");
1077 return 0;
1081 static LRESULT
1082 TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1084 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1085 INT nIndex = (INT)wParam;
1087 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1088 return FALSE;
1090 if ((infoPtr->hwndToolTip) &&
1091 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
1092 TTTOOLINFOA ti;
1094 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1095 ti.cbSize = sizeof (TTTOOLINFOA);
1096 ti.hwnd = hwnd;
1097 ti.uId = infoPtr->buttons[nIndex].idCommand;
1099 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
1102 if (infoPtr->nNumButtons == 1) {
1103 TRACE (toolbar, " simple delete!\n");
1104 COMCTL32_Free (infoPtr->buttons);
1105 infoPtr->buttons = NULL;
1106 infoPtr->nNumButtons = 0;
1108 else {
1109 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1110 TRACE(toolbar, "complex delete! [nIndex=%d]\n", nIndex);
1112 infoPtr->nNumButtons--;
1113 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
1114 if (nIndex > 0) {
1115 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1116 nIndex * sizeof(TBUTTON_INFO));
1119 if (nIndex < infoPtr->nNumButtons) {
1120 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
1121 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
1124 COMCTL32_Free (oldButtons);
1127 TOOLBAR_CalcToolbar (hwnd);
1129 InvalidateRect (hwnd, NULL, TRUE);
1130 UpdateWindow (hwnd);
1132 return TRUE;
1136 static LRESULT
1137 TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1139 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1140 TBUTTON_INFO *btnPtr;
1141 HDC hdc;
1142 INT nIndex;
1144 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1145 if (nIndex == -1)
1146 return FALSE;
1148 btnPtr = &infoPtr->buttons[nIndex];
1149 if (LOWORD(lParam) == FALSE)
1150 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
1151 else
1152 btnPtr->fsState |= TBSTATE_ENABLED;
1154 hdc = GetDC (hwnd);
1155 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
1156 ReleaseDC (hwnd, hdc);
1158 return TRUE;
1162 /* << TOOLBAR_GetAnchorHighlight >> */
1165 static LRESULT
1166 TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1168 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1169 INT nIndex;
1171 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1172 if (nIndex == -1)
1173 return -1;
1175 return infoPtr->buttons[nIndex].iBitmap;
1179 static __inline__ LRESULT
1180 TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
1182 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
1186 static LRESULT
1187 TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1189 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1190 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1191 INT nIndex = (INT)wParam;
1192 TBUTTON_INFO *btnPtr;
1194 if (infoPtr == NULL)
1195 return FALSE;
1197 if (lpTbb == NULL)
1198 return FALSE;
1200 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1201 return FALSE;
1203 btnPtr = &infoPtr->buttons[nIndex];
1204 lpTbb->iBitmap = btnPtr->iBitmap;
1205 lpTbb->idCommand = btnPtr->idCommand;
1206 lpTbb->fsState = btnPtr->fsState;
1207 lpTbb->fsStyle = btnPtr->fsStyle;
1208 lpTbb->dwData = btnPtr->dwData;
1209 lpTbb->iString = btnPtr->iString;
1211 return TRUE;
1215 static LRESULT
1216 TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1218 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1219 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
1220 TBUTTON_INFO *btnPtr;
1221 INT nIndex;
1223 if (infoPtr == NULL)
1224 return -1;
1225 if (lpTbInfo == NULL)
1226 return -1;
1227 if (lpTbInfo->cbSize < sizeof(LPTBBUTTONINFOA))
1228 return -1;
1230 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1231 if (nIndex == -1)
1232 return -1;
1234 btnPtr = &infoPtr->buttons[nIndex];
1236 if (lpTbInfo->dwMask & TBIF_COMMAND)
1237 lpTbInfo->idCommand = btnPtr->idCommand;
1238 if (lpTbInfo->dwMask & TBIF_IMAGE)
1239 lpTbInfo->iImage = btnPtr->iBitmap;
1240 if (lpTbInfo->dwMask & TBIF_LPARAM)
1241 lpTbInfo->lParam = btnPtr->dwData;
1242 if (lpTbInfo->dwMask & TBIF_SIZE)
1243 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1244 if (lpTbInfo->dwMask & TBIF_STATE)
1245 lpTbInfo->fsState = btnPtr->fsState;
1246 if (lpTbInfo->dwMask & TBIF_STYLE)
1247 lpTbInfo->fsStyle = btnPtr->fsStyle;
1248 if (lpTbInfo->dwMask & TBIF_TEXT) {
1249 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
1250 lstrcpynA (lpTbInfo->pszText,
1251 (LPSTR)infoPtr->strings[btnPtr->iString],
1252 lpTbInfo->cchText);
1255 return nIndex;
1259 /* << TOOLBAR_GetButtonInfo32W >> */
1262 static LRESULT
1263 TOOLBAR_GetButtonSize (HWND hwnd)
1265 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1267 return MAKELONG((WORD)infoPtr->nButtonWidth,
1268 (WORD)infoPtr->nButtonHeight);
1272 static LRESULT
1273 TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1275 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1276 INT nIndex, nStringIndex;
1278 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1279 if (nIndex == -1)
1280 return -1;
1282 nStringIndex = infoPtr->buttons[nIndex].iString;
1284 TRACE (toolbar, "index=%d stringIndex=%d\n", nIndex, nStringIndex);
1286 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
1287 return -1;
1289 if (lParam == 0) return -1;
1291 lstrcpyA ((LPSTR)lParam, (LPSTR)infoPtr->strings[nStringIndex]);
1293 return lstrlenA ((LPSTR)infoPtr->strings[nStringIndex]);
1297 /* << TOOLBAR_GetButtonText32W >> */
1298 /* << TOOLBAR_GetColorScheme >> */
1301 static LRESULT
1302 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1304 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1306 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
1307 return (LRESULT)infoPtr->himlDis;
1308 else
1309 return 0;
1313 __inline__ static LRESULT
1314 TOOLBAR_GetExtendedStyle (HWND hwnd)
1316 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1318 return infoPtr->dwExStyle;
1322 static LRESULT
1323 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1325 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1327 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
1328 return (LRESULT)infoPtr->himlHot;
1329 else
1330 return 0;
1334 /* << TOOLBAR_GetHotItem >> */
1337 static LRESULT
1338 TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1340 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1342 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
1343 return (LRESULT)infoPtr->himlDef;
1344 else
1345 return 0;
1349 /* << TOOLBAR_GetInsertMark >> */
1350 /* << TOOLBAR_GetInsertMarkColor >> */
1353 static LRESULT
1354 TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
1356 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1357 TBUTTON_INFO *btnPtr;
1358 LPRECT lpRect;
1359 INT nIndex;
1361 if (infoPtr == NULL)
1362 return FALSE;
1363 nIndex = (INT)wParam;
1364 btnPtr = &infoPtr->buttons[nIndex];
1365 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1366 return FALSE;
1367 lpRect = (LPRECT)lParam;
1368 if (lpRect == NULL)
1369 return FALSE;
1370 if (btnPtr->fsState & TBSTATE_HIDDEN)
1371 return FALSE;
1373 lpRect->left = btnPtr->rect.left;
1374 lpRect->right = btnPtr->rect.right;
1375 lpRect->bottom = btnPtr->rect.bottom;
1376 lpRect->top = btnPtr->rect.top;
1378 return TRUE;
1382 static LRESULT
1383 TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1385 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1386 LPSIZE lpSize = (LPSIZE)lParam;
1388 if (lpSize == NULL)
1389 return FALSE;
1391 lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
1392 lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
1394 TRACE (toolbar, "maximum size %d x %d\n",
1395 infoPtr->rcBound.right - infoPtr->rcBound.left,
1396 infoPtr->rcBound.bottom - infoPtr->rcBound.top);
1398 return TRUE;
1402 /* << TOOLBAR_GetObject >> */
1403 /* << TOOLBAR_GetPadding >> */
1406 static LRESULT
1407 TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
1409 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1410 TBUTTON_INFO *btnPtr;
1411 LPRECT lpRect;
1412 INT nIndex;
1414 if (infoPtr == NULL)
1415 return FALSE;
1416 nIndex = (INT)wParam;
1417 btnPtr = &infoPtr->buttons[nIndex];
1418 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1419 return FALSE;
1420 lpRect = (LPRECT)lParam;
1421 if (lpRect == NULL)
1422 return FALSE;
1424 lpRect->left = btnPtr->rect.left;
1425 lpRect->right = btnPtr->rect.right;
1426 lpRect->bottom = btnPtr->rect.bottom;
1427 lpRect->top = btnPtr->rect.top;
1429 return TRUE;
1433 static LRESULT
1434 TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
1436 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1438 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
1439 return infoPtr->nRows;
1440 else
1441 return 1;
1445 static LRESULT
1446 TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
1448 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1449 INT nIndex;
1451 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1452 if (nIndex == -1)
1453 return -1;
1455 return infoPtr->buttons[nIndex].fsState;
1459 static LRESULT
1460 TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
1462 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1463 INT nIndex;
1465 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1466 if (nIndex == -1)
1467 return -1;
1469 return infoPtr->buttons[nIndex].fsStyle;
1473 static LRESULT
1474 TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
1476 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1478 if (infoPtr == NULL)
1479 return 0;
1481 return infoPtr->nMaxTextRows;
1485 static LRESULT
1486 TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
1488 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1490 if (infoPtr == NULL)
1491 return 0;
1492 return infoPtr->hwndToolTip;
1496 static LRESULT
1497 TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
1499 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1501 TRACE (toolbar, "%s hwnd=0x%x stub!\n",
1502 infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
1504 return infoPtr->bUnicode;
1508 static LRESULT
1509 TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1511 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1512 TBUTTON_INFO *btnPtr;
1513 INT nIndex;
1515 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1516 if (nIndex == -1)
1517 return FALSE;
1519 btnPtr = &infoPtr->buttons[nIndex];
1520 if (LOWORD(lParam) == FALSE)
1521 btnPtr->fsState &= ~TBSTATE_HIDDEN;
1522 else
1523 btnPtr->fsState |= TBSTATE_HIDDEN;
1525 TOOLBAR_CalcToolbar (hwnd);
1527 InvalidateRect (hwnd, NULL, TRUE);
1528 UpdateWindow (hwnd);
1530 return TRUE;
1534 __inline__ static LRESULT
1535 TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1537 return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
1541 static LRESULT
1542 TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
1544 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1545 TBUTTON_INFO *btnPtr;
1546 HDC hdc;
1547 INT nIndex;
1549 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1550 if (nIndex == -1)
1551 return FALSE;
1553 btnPtr = &infoPtr->buttons[nIndex];
1554 if (LOWORD(lParam) == FALSE)
1555 btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
1556 else
1557 btnPtr->fsState |= TBSTATE_INDETERMINATE;
1559 hdc = GetDC (hwnd);
1560 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
1561 ReleaseDC (hwnd, hdc);
1563 return TRUE;
1567 static LRESULT
1568 TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1570 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1571 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1572 INT nIndex = (INT)wParam;
1573 TBUTTON_INFO *oldButtons;
1574 HDC hdc;
1576 if (lpTbb == NULL)
1577 return FALSE;
1578 if (nIndex < 0)
1579 return FALSE;
1581 TRACE (toolbar, "inserting button index=%d\n", nIndex);
1582 if (nIndex > infoPtr->nNumButtons) {
1583 nIndex = infoPtr->nNumButtons;
1584 TRACE (toolbar, "adjust index=%d\n", nIndex);
1587 oldButtons = infoPtr->buttons;
1588 infoPtr->nNumButtons++;
1589 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
1590 /* pre insert copy */
1591 if (nIndex > 0) {
1592 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1593 nIndex * sizeof(TBUTTON_INFO));
1596 /* insert new button */
1597 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
1598 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
1599 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
1600 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
1601 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
1602 infoPtr->buttons[nIndex].iString = lpTbb->iString;
1604 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
1605 TTTOOLINFOA ti;
1607 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1608 ti.cbSize = sizeof (TTTOOLINFOA);
1609 ti.hwnd = hwnd;
1610 ti.uId = lpTbb->idCommand;
1611 ti.hinst = 0;
1612 ti.lpszText = LPSTR_TEXTCALLBACKA;
1614 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
1615 0, (LPARAM)&ti);
1618 /* post insert copy */
1619 if (nIndex < infoPtr->nNumButtons - 1) {
1620 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
1621 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
1624 COMCTL32_Free (oldButtons);
1626 TOOLBAR_CalcToolbar (hwnd);
1628 hdc = GetDC (hwnd);
1629 TOOLBAR_Refresh (hwnd, hdc);
1630 ReleaseDC (hwnd, hdc);
1632 return TRUE;
1636 /* << TOOLBAR_InsertButton32W >> */
1637 /* << TOOLBAR_InsertMarkHitTest >> */
1640 static LRESULT
1641 TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
1643 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1644 INT nIndex;
1646 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1647 if (nIndex == -1)
1648 return FALSE;
1650 return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
1654 static LRESULT
1655 TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
1657 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1658 INT nIndex;
1660 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1661 if (nIndex == -1)
1662 return FALSE;
1664 return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
1668 static LRESULT
1669 TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
1671 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1672 INT nIndex;
1674 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1675 if (nIndex == -1)
1676 return FALSE;
1678 return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
1682 static LRESULT
1683 TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
1685 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1686 INT nIndex;
1688 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1689 if (nIndex == -1)
1690 return FALSE;
1692 return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
1696 static LRESULT
1697 TOOLBAR_IsButtonIndeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
1699 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1700 INT nIndex;
1702 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1703 if (nIndex == -1)
1704 return FALSE;
1706 return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
1710 static LRESULT
1711 TOOLBAR_IsButtonPressed (HWND hwnd, WPARAM wParam, LPARAM lParam)
1713 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1714 INT nIndex;
1716 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1717 if (nIndex == -1)
1718 return FALSE;
1720 return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
1724 /* << TOOLBAR_LoadImages >> */
1725 /* << TOOLBAR_MapAccelerator >> */
1726 /* << TOOLBAR_MarkButton >> */
1727 /* << TOOLBAR_MoveButton >> */
1730 static LRESULT
1731 TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1733 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1734 TBUTTON_INFO *btnPtr;
1735 HDC hdc;
1736 INT nIndex;
1738 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1739 if (nIndex == -1)
1740 return FALSE;
1742 btnPtr = &infoPtr->buttons[nIndex];
1743 if (LOWORD(lParam) == FALSE)
1744 btnPtr->fsState &= ~TBSTATE_PRESSED;
1745 else
1746 btnPtr->fsState |= TBSTATE_PRESSED;
1748 hdc = GetDC (hwnd);
1749 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
1750 ReleaseDC (hwnd, hdc);
1752 return TRUE;
1756 /* << TOOLBAR_ReplaceBitmap >> */
1759 static LRESULT
1760 TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1762 #if 0
1763 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1764 LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
1766 if (lpSave == NULL) return 0;
1768 if ((BOOL)wParam) {
1769 /* save toolbar information */
1770 FIXME (toolbar, "save to \"%s\" \"%s\"\n",
1771 lpSave->pszSubKey, lpSave->pszValueName);
1775 else {
1776 /* restore toolbar information */
1778 FIXME (toolbar, "restore from \"%s\" \"%s\"\n",
1779 lpSave->pszSubKey, lpSave->pszValueName);
1783 #endif
1785 return 0;
1789 /* << TOOLBAR_SaveRestore32W >> */
1790 /* << TOOLBAR_SetAnchorHighlight >> */
1793 static LRESULT
1794 TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1796 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1798 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
1799 return FALSE;
1801 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
1802 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
1804 return TRUE;
1808 static LRESULT
1809 TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1811 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1812 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
1813 TBUTTON_INFO *btnPtr;
1814 INT nIndex;
1816 if (lptbbi == NULL)
1817 return FALSE;
1818 if (lptbbi->cbSize < sizeof(LPTBBUTTONINFOA))
1819 return FALSE;
1821 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1822 if (nIndex == -1)
1823 return FALSE;
1825 btnPtr = &infoPtr->buttons[nIndex];
1826 if (lptbbi->dwMask & TBIF_COMMAND)
1827 btnPtr->idCommand = lptbbi->idCommand;
1828 if (lptbbi->dwMask & TBIF_IMAGE)
1829 btnPtr->iBitmap = lptbbi->iImage;
1830 if (lptbbi->dwMask & TBIF_LPARAM)
1831 btnPtr->dwData = lptbbi->lParam;
1832 /* if (lptbbi->dwMask & TBIF_SIZE) */
1833 /* btnPtr->cx = lptbbi->cx; */
1834 if (lptbbi->dwMask & TBIF_STATE)
1835 btnPtr->fsState = lptbbi->fsState;
1836 if (lptbbi->dwMask & TBIF_STYLE)
1837 btnPtr->fsStyle = lptbbi->fsStyle;
1839 if (lptbbi->dwMask & TBIF_TEXT) {
1840 if ((btnPtr->iString >= 0) ||
1841 (btnPtr->iString < infoPtr->nNumStrings)) {
1842 #if 0
1843 CHAR **lpString = &infoPtr->strings[btnPtr->iString];
1844 INT len = lstrlenA (lptbbi->pszText);
1845 *lpString = COMCTL32_ReAlloc (lpString, sizeof(char)*(len+1));
1846 #endif
1848 /* this is the ultimate sollution */
1849 /* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
1853 return TRUE;
1857 /* << TOOLBAR_SetButtonInfo32W >> */
1860 static LRESULT
1861 TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1863 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1865 if ((LOWORD(lParam) <= 0) || (HIWORD(lParam)<=0))
1866 return FALSE;
1868 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
1869 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
1871 return TRUE;
1875 static LRESULT
1876 TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
1878 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1880 if (infoPtr == NULL)
1881 return FALSE;
1883 infoPtr->cxMin = (INT)LOWORD(lParam);
1884 infoPtr->cxMax = (INT)HIWORD(lParam);
1886 return TRUE;
1890 static LRESULT
1891 TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
1893 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1894 INT nIndex = (INT)wParam;
1896 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1897 return FALSE;
1899 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
1901 if (infoPtr->hwndToolTip) {
1903 FIXME (toolbar, "change tool tip!\n");
1907 return TRUE;
1911 /* << TOOLBAR_SetColorScheme >> */
1914 static LRESULT
1915 TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1917 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1918 HIMAGELIST himlTemp;
1920 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
1921 return 0;
1923 himlTemp = infoPtr->himlDis;
1924 infoPtr->himlDis = (HIMAGELIST)lParam;
1926 /* FIXME: redraw ? */
1928 return (LRESULT)himlTemp;
1932 static LRESULT
1933 TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
1935 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1936 DWORD dwTemp;
1938 dwTemp = infoPtr->dwDTFlags;
1939 infoPtr->dwDTFlags =
1940 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
1942 return (LRESULT)dwTemp;
1946 static LRESULT
1947 TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
1949 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1950 DWORD dwTemp;
1952 dwTemp = infoPtr->dwExStyle;
1953 infoPtr->dwExStyle = (DWORD)lParam;
1955 return (LRESULT)dwTemp;
1959 static LRESULT
1960 TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1962 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
1963 HIMAGELIST himlTemp;
1965 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
1966 return 0;
1968 himlTemp = infoPtr->himlHot;
1969 infoPtr->himlHot = (HIMAGELIST)lParam;
1971 /* FIXME: redraw ? */
1973 return (LRESULT)himlTemp;
1977 /* << TOOLBAR_SetHotItem >> */
1980 static LRESULT
1981 TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1983 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1984 HIMAGELIST himlTemp;
1986 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
1987 return 0;
1989 himlTemp = infoPtr->himlDef;
1990 infoPtr->himlDef = (HIMAGELIST)lParam;
1992 /* FIXME: redraw ? */
1994 return (LRESULT)himlTemp;
1998 static LRESULT
1999 TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2001 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2002 HDC hdc;
2004 infoPtr->nIndent = (INT)wParam;
2006 TOOLBAR_CalcToolbar (hwnd);
2008 hdc = GetDC (hwnd);
2009 TOOLBAR_Refresh (hwnd, hdc);
2010 ReleaseDC (hwnd, hdc);
2012 return TRUE;
2016 /* << TOOLBAR_SetInsertMark >> */
2019 static LRESULT
2020 TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2022 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2024 infoPtr->clrInsertMark = (COLORREF)lParam;
2026 /* FIXME : redraw ??*/
2028 return 0;
2032 static LRESULT
2033 TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2035 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2037 if (infoPtr == NULL)
2038 return FALSE;
2040 infoPtr->nMaxTextRows = (INT)wParam;
2042 return TRUE;
2046 /* << TOOLBAR_SetPadding >> */
2049 static LRESULT
2050 TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2052 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2053 HWND hwndOldNotify;
2055 if (infoPtr == NULL)
2056 return 0;
2057 hwndOldNotify = infoPtr->hwndNotify;
2058 infoPtr->hwndNotify = (HWND)wParam;
2060 return hwndOldNotify;
2064 static LRESULT
2065 TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2067 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2068 LPRECT lprc = (LPRECT)lParam;
2069 HDC hdc;
2071 if (LOWORD(wParam) > 1) {
2073 FIXME (toolbar, "multiple rows not supported!\n");
2077 /* recalculate toolbar */
2078 TOOLBAR_CalcToolbar (hwnd);
2080 /* return bounding rectangle */
2081 if (lprc) {
2082 lprc->left = infoPtr->rcBound.left;
2083 lprc->right = infoPtr->rcBound.right;
2084 lprc->top = infoPtr->rcBound.top;
2085 lprc->bottom = infoPtr->rcBound.bottom;
2088 /* repaint toolbar */
2089 hdc = GetDC (hwnd);
2090 TOOLBAR_Refresh (hwnd, hdc);
2091 ReleaseDC (hwnd, hdc);
2093 return 0;
2097 static LRESULT
2098 TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2100 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2101 TBUTTON_INFO *btnPtr;
2102 HDC hdc;
2103 INT nIndex;
2105 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2106 if (nIndex == -1)
2107 return FALSE;
2109 btnPtr = &infoPtr->buttons[nIndex];
2110 btnPtr->fsState = LOWORD(lParam);
2112 hdc = GetDC (hwnd);
2113 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2114 ReleaseDC (hwnd, hdc);
2116 return TRUE;
2120 static LRESULT
2121 TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2123 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2124 TBUTTON_INFO *btnPtr;
2125 HDC hdc;
2126 INT nIndex;
2128 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2129 if (nIndex == -1)
2130 return FALSE;
2132 btnPtr = &infoPtr->buttons[nIndex];
2133 btnPtr->fsStyle = LOWORD(lParam);
2135 hdc = GetDC (hwnd);
2136 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2137 ReleaseDC (hwnd, hdc);
2139 if (infoPtr->hwndToolTip) {
2141 FIXME (toolbar, "change tool tip!\n");
2145 return TRUE;
2149 __inline__ static LRESULT
2150 TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
2152 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2154 if (infoPtr == NULL)
2155 return 0;
2156 infoPtr->hwndToolTip = (HWND)wParam;
2157 return 0;
2161 static LRESULT
2162 TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2164 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2165 BOOL bTemp;
2167 TRACE (toolbar, "%s hwnd=0x%04x stub!\n",
2168 ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
2170 bTemp = infoPtr->bUnicode;
2171 infoPtr->bUnicode = (BOOL)wParam;
2173 return bTemp;
2177 static LRESULT
2178 TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
2180 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2181 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2182 LOGFONTA logFont;
2184 /* initialize info structure */
2185 infoPtr->nButtonHeight = 22;
2186 infoPtr->nButtonWidth = 23;
2187 infoPtr->nBitmapHeight = 15;
2188 infoPtr->nBitmapWidth = 16;
2190 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
2191 infoPtr->nRows = 1;
2192 infoPtr->nMaxTextRows = 1;
2193 infoPtr->cxMin = -1;
2194 infoPtr->cxMax = -1;
2196 infoPtr->bCaptured = FALSE;
2197 infoPtr->bUnicode = IsWindowUnicode (hwnd);
2198 infoPtr->nButtonDown = -1;
2199 infoPtr->nOldHit = -1;
2200 infoPtr->nHotItem = -2; // It has to be initially different from nOldHit
2201 infoPtr->hwndNotify = GetParent (hwnd);
2202 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
2203 infoPtr->dwDTFlags = DT_CENTER;
2205 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
2206 infoPtr->hFont = CreateFontIndirectA (&logFont);
2208 if (dwStyle & TBSTYLE_TOOLTIPS) {
2209 /* Create tooltip control */
2210 infoPtr->hwndToolTip =
2211 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
2212 CW_USEDEFAULT, CW_USEDEFAULT,
2213 CW_USEDEFAULT, CW_USEDEFAULT,
2214 hwnd, 0, 0, 0);
2216 /* Send NM_TOOLTIPSCREATED notification */
2217 if (infoPtr->hwndToolTip) {
2218 NMTOOLTIPSCREATED nmttc;
2220 nmttc.hdr.hwndFrom = hwnd;
2221 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
2222 nmttc.hdr.code = NM_TOOLTIPSCREATED;
2223 nmttc.hwndToolTips = infoPtr->hwndToolTip;
2225 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
2226 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
2230 return 0;
2234 static LRESULT
2235 TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
2237 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2239 /* delete tooltip control */
2240 if (infoPtr->hwndToolTip)
2241 DestroyWindow (infoPtr->hwndToolTip);
2243 /* delete button data */
2244 if (infoPtr->buttons)
2245 COMCTL32_Free (infoPtr->buttons);
2247 /* delete strings */
2248 if (infoPtr->strings) {
2249 INT i;
2250 for (i = 0; i < infoPtr->nNumStrings; i++)
2251 if (infoPtr->strings[i])
2252 COMCTL32_Free (infoPtr->strings[i]);
2254 COMCTL32_Free (infoPtr->strings);
2257 /* destroy default image list */
2258 if (infoPtr->himlDef)
2259 ImageList_Destroy (infoPtr->himlDef);
2261 /* destroy disabled image list */
2262 if (infoPtr->himlDis)
2263 ImageList_Destroy (infoPtr->himlDis);
2265 /* destroy hot image list */
2266 if (infoPtr->himlHot)
2267 ImageList_Destroy (infoPtr->himlHot);
2269 /* delete default font */
2270 if (infoPtr->hFont)
2271 DeleteObject (infoPtr->hFont);
2273 /* free toolbar info data */
2274 COMCTL32_Free (infoPtr);
2276 return 0;
2280 static LRESULT
2281 TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
2283 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2285 if (infoPtr->bTransparent)
2286 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
2288 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
2292 static LRESULT
2293 TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
2295 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2296 TBUTTON_INFO *btnPtr;
2297 POINT pt;
2298 INT nHit;
2299 HDC hdc;
2301 pt.x = (INT)LOWORD(lParam);
2302 pt.y = (INT)HIWORD(lParam);
2303 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
2305 if (nHit >= 0) {
2306 btnPtr = &infoPtr->buttons[nHit];
2307 if (!(btnPtr->fsState & TBSTATE_ENABLED))
2308 return 0;
2309 SetCapture (hwnd);
2310 infoPtr->bCaptured = TRUE;
2311 infoPtr->nButtonDown = nHit;
2313 btnPtr->fsState |= TBSTATE_PRESSED;
2315 hdc = GetDC (hwnd);
2316 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2317 ReleaseDC (hwnd, hdc);
2319 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
2320 TOOLBAR_Customize (hwnd);
2322 return 0;
2326 static LRESULT
2327 TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
2329 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2330 TBUTTON_INFO *btnPtr;
2331 POINT pt;
2332 INT nHit;
2333 HDC hdc;
2335 if (infoPtr->hwndToolTip)
2336 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
2337 WM_LBUTTONDOWN, wParam, lParam);
2339 pt.x = (INT)LOWORD(lParam);
2340 pt.y = (INT)HIWORD(lParam);
2341 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
2343 if (nHit >= 0) {
2344 btnPtr = &infoPtr->buttons[nHit];
2345 if (!(btnPtr->fsState & TBSTATE_ENABLED))
2346 return 0;
2348 SetCapture (hwnd);
2349 infoPtr->bCaptured = TRUE;
2350 infoPtr->nButtonDown = nHit;
2351 infoPtr->nOldHit = nHit;
2353 btnPtr->fsState |= TBSTATE_PRESSED;
2355 hdc = GetDC (hwnd);
2356 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2357 ReleaseDC (hwnd, hdc);
2360 return 0;
2364 static LRESULT
2365 TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
2367 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2368 TBUTTON_INFO *btnPtr;
2369 POINT pt;
2370 INT nHit;
2371 INT nOldIndex = -1;
2372 HDC hdc;
2373 BOOL bSendMessage = TRUE;
2375 if (infoPtr->hwndToolTip)
2376 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
2377 WM_LBUTTONUP, wParam, lParam);
2379 pt.x = (INT)LOWORD(lParam);
2380 pt.y = (INT)HIWORD(lParam);
2381 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
2383 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
2384 infoPtr->bCaptured = FALSE;
2385 ReleaseCapture ();
2386 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
2387 btnPtr->fsState &= ~TBSTATE_PRESSED;
2389 if (nHit == infoPtr->nButtonDown) {
2390 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
2391 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
2392 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
2393 infoPtr->nButtonDown);
2394 if (nOldIndex == infoPtr->nButtonDown)
2395 bSendMessage = FALSE;
2396 if ((nOldIndex != infoPtr->nButtonDown) &&
2397 (nOldIndex != -1))
2398 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
2399 btnPtr->fsState |= TBSTATE_CHECKED;
2401 else {
2402 if (btnPtr->fsState & TBSTATE_CHECKED)
2403 btnPtr->fsState &= ~TBSTATE_CHECKED;
2404 else
2405 btnPtr->fsState |= TBSTATE_CHECKED;
2409 else
2410 bSendMessage = FALSE;
2412 hdc = GetDC (hwnd);
2413 if (nOldIndex != -1)
2414 TOOLBAR_DrawButton (hwnd, &infoPtr->buttons[nOldIndex], hdc);
2415 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2416 ReleaseDC (hwnd, hdc);
2418 if (bSendMessage)
2419 SendMessageA (infoPtr->hwndNotify, WM_COMMAND,
2420 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
2422 infoPtr->nButtonDown = -1;
2423 infoPtr->nOldHit = -1;
2426 return 0;
2430 static LRESULT
2431 TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
2433 TBUTTON_INFO *btnPtr, *oldBtnPtr;
2434 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2435 POINT pt;
2436 INT nHit;
2437 HDC hdc;
2439 if (infoPtr->hwndToolTip)
2440 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
2441 WM_MOUSEMOVE, wParam, lParam);
2443 pt.x = (INT)LOWORD(lParam);
2444 pt.y = (INT)HIWORD(lParam);
2446 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
2448 if (infoPtr->nOldHit != nHit)
2450 //Remove the effect of an old hot button
2451 if(infoPtr->nOldHit == infoPtr->nHotItem)
2453 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
2454 oldBtnPtr->bHot = FALSE;
2456 InvalidateRect (hwnd, &oldBtnPtr->rect, TRUE);
2459 // It's not a separator or in nowhere. It's a hot button.
2460 if (nHit >= 0)
2462 btnPtr = &infoPtr->buttons[nHit];
2463 btnPtr->bHot = TRUE;
2465 hdc = GetDC (hwnd);
2466 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2467 ReleaseDC (hwnd, hdc);
2469 infoPtr->nHotItem = nHit;
2472 if (infoPtr->bCaptured) {
2473 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
2474 if (infoPtr->nOldHit == infoPtr->nButtonDown) {
2475 btnPtr->fsState &= ~TBSTATE_PRESSED;
2476 hdc = GetDC (hwnd);
2477 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2478 ReleaseDC (hwnd, hdc);
2480 else if (nHit == infoPtr->nButtonDown) {
2481 btnPtr->fsState |= TBSTATE_PRESSED;
2482 hdc = GetDC (hwnd);
2483 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2484 ReleaseDC (hwnd, hdc);
2487 infoPtr->nOldHit = nHit;
2489 return 0;
2493 __inline__ static LRESULT
2494 TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2496 /* if (wndPtr->dwStyle & CCS_NODIVIDER) */
2497 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
2498 /* else */
2499 /* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
2503 __inline__ static LRESULT
2504 TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2506 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
2507 ((LPRECT)lParam)->top += sysMetrics[SM_CYEDGE];
2509 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
2513 static LRESULT
2514 TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2516 TOOLBAR_INFO *infoPtr;
2518 /* allocate memory for info structure */
2519 infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
2520 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
2522 /* paranoid!! */
2523 infoPtr->dwStructSize = sizeof(TBBUTTON);
2525 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
2526 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
2527 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
2528 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
2531 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
2535 static LRESULT
2536 TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
2538 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2539 RECT rcWindow;
2540 HDC hdc;
2542 if (dwStyle & WS_MINIMIZE)
2543 return 0; /* Nothing to do */
2545 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
2547 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
2548 return 0;
2550 if (!(dwStyle & CCS_NODIVIDER))
2552 GetWindowRect (hwnd, &rcWindow);
2553 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
2554 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
2557 ReleaseDC( hwnd, hdc );
2559 return 0;
2563 __inline__ static LRESULT
2564 TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
2566 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2567 LPNMHDR lpnmh = (LPNMHDR)lParam;
2569 TRACE (toolbar, "passing WM_NOTIFY!\n");
2571 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
2572 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
2574 #if 0
2575 if (lpnmh->code == TTN_GETDISPINFOA) {
2576 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
2578 FIXME (toolbar, "retrieving ASCII string\n");
2581 else if (lpnmh->code == TTN_GETDISPINFOW) {
2582 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
2584 FIXME (toolbar, "retrieving UNICODE string\n");
2587 #endif
2590 return 0;
2594 static LRESULT
2595 TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
2597 HDC hdc;
2598 PAINTSTRUCT ps;
2600 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
2601 TOOLBAR_Refresh (hwnd, hdc);
2602 if (!wParam)
2603 EndPaint (hwnd, &ps);
2604 return 0;
2608 static LRESULT
2609 TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
2611 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2612 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2613 RECT parent_rect;
2614 HWND parent;
2615 /* INT32 x, y; */
2616 INT cx, cy;
2617 INT flags;
2618 UINT uPosFlags = 0;
2620 /* Resize deadlock check */
2621 if (infoPtr->bAutoSize) {
2622 infoPtr->bAutoSize = FALSE;
2623 return 0;
2626 flags = (INT) wParam;
2628 /* FIXME for flags =
2629 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
2632 TRACE (toolbar, "sizing toolbar!\n");
2634 if (flags == SIZE_RESTORED) {
2635 /* width and height don't apply */
2636 parent = GetParent (hwnd);
2637 GetClientRect(parent, &parent_rect);
2639 if (dwStyle & CCS_NORESIZE) {
2640 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
2642 /* FIXME */
2643 /* infoPtr->nWidth = parent_rect.right - parent_rect.left; */
2644 cy = infoPtr->nHeight;
2645 cx = infoPtr->nWidth;
2646 TOOLBAR_CalcToolbar (hwnd);
2647 infoPtr->nWidth = cx;
2648 infoPtr->nHeight = cy;
2650 else {
2651 infoPtr->nWidth = parent_rect.right - parent_rect.left;
2652 TOOLBAR_CalcToolbar (hwnd);
2653 cy = infoPtr->nHeight;
2654 cx = infoPtr->nWidth;
2657 if (dwStyle & CCS_NOPARENTALIGN) {
2658 uPosFlags |= SWP_NOMOVE;
2659 cy = infoPtr->nHeight;
2660 cx = infoPtr->nWidth;
2663 if (!(dwStyle & CCS_NODIVIDER))
2664 cy += sysMetrics[SM_CYEDGE];
2666 SetWindowPos (hwnd, 0, parent_rect.left, parent_rect.top,
2667 cx, cy, uPosFlags | SWP_NOZORDER);
2669 return 0;
2673 static LRESULT
2674 TOOLBAR_StyleChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
2676 HDC hdc;
2678 TOOLBAR_AutoSize (hwnd, wParam, lParam);
2680 hdc = GetDC (hwnd);
2681 TOOLBAR_Refresh (hwnd, hdc);
2682 ReleaseDC (hwnd, hdc);
2684 return 0;
2689 LRESULT WINAPI
2690 ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2692 switch (uMsg)
2694 case TB_ADDBITMAP:
2695 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
2697 case TB_ADDBUTTONSA:
2698 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
2700 /* case TB_ADDBUTTONS32W: */
2702 case TB_ADDSTRINGA:
2703 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
2705 case TB_ADDSTRINGW:
2706 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
2708 case TB_AUTOSIZE:
2709 return TOOLBAR_AutoSize (hwnd, wParam, lParam);
2711 case TB_BUTTONCOUNT:
2712 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
2714 case TB_BUTTONSTRUCTSIZE:
2715 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
2717 case TB_CHANGEBITMAP:
2718 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
2720 case TB_CHECKBUTTON:
2721 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
2723 case TB_COMMANDTOINDEX:
2724 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
2726 case TB_CUSTOMIZE:
2727 return TOOLBAR_Customize (hwnd);
2729 case TB_DELETEBUTTON:
2730 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
2732 case TB_ENABLEBUTTON:
2733 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
2735 /* case TB_GETANCHORHIGHLIGHT: */ /* 4.71 */
2737 case TB_GETBITMAP:
2738 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
2740 case TB_GETBITMAPFLAGS:
2741 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
2743 case TB_GETBUTTON:
2744 return TOOLBAR_GetButton (hwnd, wParam, lParam);
2746 case TB_GETBUTTONINFOA:
2747 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
2749 /* case TB_GETBUTTONINFO32W: */ /* 4.71 */
2751 case TB_GETBUTTONSIZE:
2752 return TOOLBAR_GetButtonSize (hwnd);
2754 case TB_GETBUTTONTEXTA:
2755 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
2757 /* case TB_GETBUTTONTEXT32W: */
2758 /* case TB_GETCOLORSCHEME: */ /* 4.71 */
2760 case TB_GETDISABLEDIMAGELIST:
2761 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
2763 case TB_GETEXTENDEDSTYLE:
2764 return TOOLBAR_GetExtendedStyle (hwnd);
2766 case TB_GETHOTIMAGELIST:
2767 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
2769 /* case TB_GETHOTITEM: */ /* 4.71 */
2771 case TB_GETIMAGELIST:
2772 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
2774 /* case TB_GETINSERTMARK: */ /* 4.71 */
2775 /* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
2777 case TB_GETITEMRECT:
2778 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
2780 case TB_GETMAXSIZE:
2781 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
2783 /* case TB_GETOBJECT: */ /* 4.71 */
2784 /* case TB_GETPADDING: */ /* 4.71 */
2786 case TB_GETRECT:
2787 return TOOLBAR_GetRect (hwnd, wParam, lParam);
2789 case TB_GETROWS:
2790 return TOOLBAR_GetRows (hwnd, wParam, lParam);
2792 case TB_GETSTATE:
2793 return TOOLBAR_GetState (hwnd, wParam, lParam);
2795 case TB_GETSTYLE:
2796 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
2798 case TB_GETTEXTROWS:
2799 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
2801 case TB_GETTOOLTIPS:
2802 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
2804 case TB_GETUNICODEFORMAT:
2805 return TOOLBAR_GetUnicodeFormat (hwnd, wParam, lParam);
2807 case TB_HIDEBUTTON:
2808 return TOOLBAR_HideButton (hwnd, wParam, lParam);
2810 case TB_HITTEST:
2811 return TOOLBAR_HitTest (hwnd, wParam, lParam);
2813 case TB_INDETERMINATE:
2814 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
2816 case TB_INSERTBUTTONA:
2817 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
2819 /* case TB_INSERTBUTTON32W: */
2820 /* case TB_INSERTMARKHITTEST: */ /* 4.71 */
2822 case TB_ISBUTTONCHECKED:
2823 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
2825 case TB_ISBUTTONENABLED:
2826 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
2828 case TB_ISBUTTONHIDDEN:
2829 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
2831 case TB_ISBUTTONHIGHLIGHTED:
2832 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
2834 case TB_ISBUTTONINDETERMINATE:
2835 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
2837 case TB_ISBUTTONPRESSED:
2838 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
2840 /* case TB_LOADIMAGES: */ /* 4.70 */
2841 /* case TB_MAPACCELERATOR32A: */ /* 4.71 */
2842 /* case TB_MAPACCELERATOR32W: */ /* 4.71 */
2843 /* case TB_MARKBUTTON: */ /* 4.71 */
2844 /* case TB_MOVEBUTTON: */ /* 4.71 */
2846 case TB_PRESSBUTTON:
2847 return TOOLBAR_PressButton (hwnd, wParam, lParam);
2849 /* case TB_REPLACEBITMAP: */
2851 case TB_SAVERESTOREA:
2852 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
2854 /* case TB_SAVERESTORE32W: */
2855 /* case TB_SETANCHORHIGHLIGHT: */ /* 4.71 */
2857 case TB_SETBITMAPSIZE:
2858 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
2860 case TB_SETBUTTONINFOA:
2861 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
2863 /* case TB_SETBUTTONINFO32W: */ /* 4.71 */
2865 case TB_SETBUTTONSIZE:
2866 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
2868 case TB_SETBUTTONWIDTH:
2869 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
2871 case TB_SETCMDID:
2872 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
2874 /* case TB_SETCOLORSCHEME: */ /* 4.71 */
2876 case TB_SETDISABLEDIMAGELIST:
2877 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
2879 case TB_SETDRAWTEXTFLAGS:
2880 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
2882 case TB_SETEXTENDEDSTYLE:
2883 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
2885 case TB_SETHOTIMAGELIST:
2886 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
2888 /* case TB_SETHOTITEM: */ /* 4.71 */
2890 case TB_SETIMAGELIST:
2891 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
2893 case TB_SETINDENT:
2894 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
2896 /* case TB_SETINSERTMARK: */ /* 4.71 */
2898 case TB_SETINSERTMARKCOLOR:
2899 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
2901 case TB_SETMAXTEXTROWS:
2902 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
2904 /* case TB_SETPADDING: */ /* 4.71 */
2906 case TB_SETPARENT:
2907 return TOOLBAR_SetParent (hwnd, wParam, lParam);
2909 case TB_SETROWS:
2910 return TOOLBAR_SetRows (hwnd, wParam, lParam);
2912 case TB_SETSTATE:
2913 return TOOLBAR_SetState (hwnd, wParam, lParam);
2915 case TB_SETSTYLE:
2916 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
2918 case TB_SETTOOLTIPS:
2919 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
2921 case TB_SETUNICODEFORMAT:
2922 return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
2925 /* case WM_CHAR: */
2927 case WM_CREATE:
2928 return TOOLBAR_Create (hwnd, wParam, lParam);
2930 case WM_DESTROY:
2931 return TOOLBAR_Destroy (hwnd, wParam, lParam);
2933 case WM_ERASEBKGND:
2934 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
2936 /* case WM_GETFONT: */
2937 /* case WM_KEYDOWN: */
2938 /* case WM_KILLFOCUS: */
2940 case WM_LBUTTONDBLCLK:
2941 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
2943 case WM_LBUTTONDOWN:
2944 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
2946 case WM_LBUTTONUP:
2947 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
2949 case WM_MOUSEMOVE:
2950 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
2952 case WM_NCACTIVATE:
2953 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
2955 case WM_NCCALCSIZE:
2956 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
2958 case WM_NCCREATE:
2959 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
2961 case WM_NCPAINT:
2962 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
2964 case WM_NOTIFY:
2965 return TOOLBAR_Notify (hwnd, wParam, lParam);
2967 /* case WM_NOTIFYFORMAT: */
2969 case WM_PAINT:
2970 return TOOLBAR_Paint (hwnd, wParam);
2972 case WM_SIZE:
2973 return TOOLBAR_Size (hwnd, wParam, lParam);
2975 case WM_STYLECHANGED:
2976 return TOOLBAR_StyleChanged (hwnd, wParam, lParam);
2978 /* case WM_SYSCOLORCHANGE: */
2980 /* case WM_WININICHANGE: */
2982 case WM_CHARTOITEM:
2983 case WM_COMMAND:
2984 case WM_DRAWITEM:
2985 case WM_MEASUREITEM:
2986 case WM_VKEYTOITEM:
2987 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
2989 default:
2990 if (uMsg >= WM_USER)
2991 ERR (toolbar, "unknown msg %04x wp=%08x lp=%08lx\n",
2992 uMsg, wParam, lParam);
2993 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
2995 return 0;
2999 VOID
3000 TOOLBAR_Register (VOID)
3002 WNDCLASSA wndClass;
3004 if (GlobalFindAtomA (TOOLBARCLASSNAMEA)) return;
3006 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
3007 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
3008 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
3009 wndClass.cbClsExtra = 0;
3010 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
3011 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
3012 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
3013 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
3015 RegisterClassA (&wndClass);
3019 VOID
3020 TOOLBAR_Unregister (VOID)
3022 if (GlobalFindAtomA (TOOLBARCLASSNAMEA))
3023 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);