source: trunk/src/comctl32/toolbar.cpp@ 5120

Last change on this file since 5120 was 4204, checked in by sandervl, 25 years ago

toolbar fixes (MFC assertions failed)

File size: 121.9 KB
Line 
1/* $Id: toolbar.cpp,v 1.11 2000-09-07 18:16:52 sandervl Exp $ */
2/*
3 * Toolbar control
4 *
5 * Copyright 1998,1999 Eric Kohl
6 * Copyright 1999 Achim Hasenmueller
7 * Copyright 1999 Christoph Bratschi
8 *
9 * TODO:
10 * - A little bug in TOOLBAR_DrawMasked()
11 * - Button wrapping (under construction).
12 * - Messages (under construction).
13 * - Notifications.
14 * - Fix TB_SETROWS.
15 * - Tooltip support (almost complete).
16 * - Unicode support (under construction).
17 * - Fix TOOLBAR_SetButtonInfo32A/W.
18 * - Drag & drop of buttons
19 *
20 * Testing:
21 * - Run tests using Waite Group Windows95 API Bible Volume 2.
22 * The second cdrom contains executables addstr.exe, btncount.exe,
23 * btnstate.exe, butstrsz.exe, chkbtn.exe, chngbmp.exe, customiz.exe,
24 * enablebtn.exe, getbmp.exe, getbtn.exe, getflags.exe, hidebtn.exe,
25 * indetbtn.exe, insbtn.exe, pressbtn.exe, setbtnsz.exe, setcmdid.exe,
26 * setparnt.exe, setrows.exe, toolwnd.exe.
27 * - Microsofts controlspy examples.
28 */
29
30/*
31 - Corel 20000807 level
32 - (WINE 991212 level)
33*/
34
35#include <string.h>
36
37#include "winbase.h"
38#include "commctrl.h"
39#include "cache.h"
40#include "comctl32.h"
41#include "ccbase.h"
42#include "toolbar.h"
43
44#define SEPARATOR_WIDTH 8 //CB: Corel says 5 but this breaks the layout!
45#define TOP_BORDER 2
46#define BOTTOM_BORDER 2
47
48#define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO*)getInfoPtr(hwnd))
49
50
51static void
52TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
53{
54 INT x = (lpRect->left + lpRect->right) / 2 - 1;
55 INT yBottom = lpRect->bottom - 3;
56 INT yTop = lpRect->top + 1;
57
58 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
59 MoveToEx (hdc, x, yBottom, NULL);
60 LineTo (hdc, x, yTop);
61 x++;
62 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
63 MoveToEx (hdc, x, yBottom, NULL);
64 LineTo (hdc, x, yTop);
65}
66
67
68static void
69TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
70 HDC hdc, INT nState, DWORD dwStyle)
71{
72 RECT rcText = btnPtr->rect;
73 HFONT hOldFont;
74 INT nOldBkMode;
75 COLORREF clrOld;
76
77 /* draw text */
78 if ((btnPtr->iString > -1) && (btnPtr->iString < infoPtr->nNumStrings)) {
79 InflateRect (&rcText, -3, -3);
80 if (dwStyle & TBSTYLE_LIST) {
81 rcText.left += infoPtr->nBitmapWidth;
82 }
83 else {
84 rcText.top += infoPtr->nBitmapHeight;
85 }
86 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
87 OffsetRect (&rcText, 1, 1);
88
89 hOldFont = SelectObject (hdc, infoPtr->hFont);
90 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
91 if (!(nState & TBSTATE_ENABLED)) {
92 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
93 OffsetRect (&rcText, 1, 1);
94 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
95 &rcText, infoPtr->dwDTFlags);
96 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
97 OffsetRect (&rcText, -1, -1);
98 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
99 &rcText, infoPtr->dwDTFlags);
100 }
101 else if (nState & TBSTATE_INDETERMINATE) {
102 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
103 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
104 &rcText, infoPtr->dwDTFlags);
105 }
106 else {
107 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
108 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
109 &rcText, infoPtr->dwDTFlags);
110 }
111
112 SetTextColor (hdc, clrOld);
113 SelectObject (hdc, hOldFont);
114 if (nOldBkMode != TRANSPARENT)
115 SetBkMode (hdc, nOldBkMode);
116 }
117}
118
119
120static void
121TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
122{
123 HBRUSH hbr = SelectObject (hdc, GetPattern55AABrush ());
124 INT cx = lpRect->right - lpRect->left;
125 INT cy = lpRect->bottom - lpRect->top;
126 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
127 SelectObject (hdc, hbr);
128}
129
130
131static void
132TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
133 HDC hdc, INT x, INT y)
134{
135 /* FIXME: this function is a hack since it uses image list
136 internals directly */
137
138 HIMAGELIST himl = infoPtr->himlDef;
139 HBITMAP hbmMask;
140 HDC hdcImageList;
141 HDC hdcMask;
142
143 if (!himl)
144 return;
145
146 /* create new dc's */
147 hdcImageList = CreateCompatibleDC (0);
148 hdcMask = CreateCompatibleDC (0);
149
150 /* create new bitmap */
151 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
152 SelectObject (hdcMask, hbmMask);
153
154 /* copy the mask bitmap */
155 SelectObject (hdcImageList, himl->hbmMask);
156 SetBkColor (hdcImageList, RGB(255, 255, 255));
157 SetTextColor (hdcImageList, RGB(0, 0, 0));
158 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
159 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
160
161#if 0
162 /* add white mask from image */
163 SelectObject (hdcImageList, himl->hbmImage);
164 SetBkColor (hdcImageList, RGB(0, 0, 0));
165 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
166 hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
167#endif
168
169 /* draw the new mask */
170 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
171 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
172 hdcMask, 0, 0, 0xB8074A);
173
174 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
175 BitBlt (hdc, x, y, himl->cx, himl->cy,
176 hdcMask, 0, 0, 0xB8074A);
177
178 DeleteObject (hbmMask);
179 DeleteDC (hdcMask);
180 DeleteDC (hdcImageList);
181}
182
183
184static void
185TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
186{
187 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
188 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
189 RECT rc;
190
191 if (btnPtr->fsState & TBSTATE_HIDDEN) return;
192
193 rc = btnPtr->rect;
194
195 /* separator */
196 if (btnPtr->fsStyle & TBSTYLE_SEP)
197 {
198 if ((dwStyle & TBSTYLE_FLAT) && (btnPtr->iBitmap == 0))
199 TOOLBAR_DrawFlatSeparator (&rc, hdc);
200 return;
201 }
202
203 /* disabled */
204 if (!(btnPtr->fsState & TBSTATE_ENABLED))
205 {
206 if (!(dwStyle & TBSTYLE_FLAT))
207 DrawEdge (hdc, &rc, EDGE_RAISED,
208 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
209
210 if (infoPtr->himlDis)
211 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
212 rc.left+1, rc.top+1, ILD_NORMAL);
213 else
214 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
215
216 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
217 return;
218 }
219
220 /* pressed TBSTYLE_BUTTON */
221 if (btnPtr->fsState & TBSTATE_PRESSED)
222 {
223 if (dwStyle & TBSTYLE_FLAT)
224 DrawEdge(hdc, &rc, BDR_SUNKENOUTER, BF_RECT | BF_MIDDLE | BF_ADJUST);
225 else
226 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
227 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
228 rc.left+2, rc.top+2, ILD_NORMAL);
229 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
230 return;
231 }
232
233 /* checked TBSTYLE_CHECK*/
234 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
235 (btnPtr->fsState & TBSTATE_CHECKED)) {
236 if (dwStyle & TBSTYLE_FLAT)
237 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
238 BF_RECT | BF_MIDDLE | BF_ADJUST);
239 else
240 DrawEdge (hdc, &rc, EDGE_SUNKEN,
241 BF_RECT | BF_MIDDLE | BF_ADJUST);
242
243 TOOLBAR_DrawPattern (hdc, &rc);
244
245 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
246 rc.left+2, rc.top+2, ILD_NORMAL);
247
248 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
249 return;
250 }
251
252 /* indeterminate */
253 if (btnPtr->fsState & TBSTATE_INDETERMINATE)
254 {
255 DrawEdge (hdc, &rc, EDGE_RAISED,
256 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
257
258 TOOLBAR_DrawPattern (hdc, &rc);
259 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
260 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
261 return;
262 }
263
264 /* normal state */
265 if (dwStyle & TBSTYLE_FLAT)
266 {
267 if(btnPtr->bHot)
268 DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
269
270 if(btnPtr->bHot && infoPtr->himlHot)
271 ImageList_Draw (infoPtr->himlHot, btnPtr->iBitmap, hdc,
272 rc.left +2, rc.top +2, ILD_NORMAL);
273 else
274 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
275 rc.left +2, rc.top +2, ILD_NORMAL);
276 } else
277 {
278 DrawEdge (hdc, &rc, EDGE_RAISED,
279 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
280
281 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
282 rc.left+1, rc.top+1, ILD_NORMAL);
283 }
284
285 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle);
286}
287
288
289static void
290TOOLBAR_Refresh (HWND hwnd, HDC hdc)
291{
292 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
293 TBUTTON_INFO *btnPtr;
294 INT i;
295
296 /* draw buttons */
297 btnPtr = infoPtr->buttons;
298 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
299 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
300}
301
302
303static void
304TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
305{
306 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
307 TBUTTON_INFO *btnPtr;
308 INT i;
309 HDC hdc;
310 HFONT hOldFont;
311 SIZE sz;
312
313 lpSize->cx = 0;
314 lpSize->cy = 0;
315 hdc = GetDC (0);
316 hOldFont = SelectObject (hdc, infoPtr->hFont);
317
318 btnPtr = infoPtr->buttons;
319 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
320 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
321 (btnPtr->iString > -1) &&
322 (btnPtr->iString < infoPtr->nNumStrings)) {
323 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
324 GetTextExtentPoint32W (hdc, lpText, lstrlenW (lpText), &sz);
325 if (sz.cx > lpSize->cx)
326 lpSize->cx = sz.cx;
327 if (sz.cy > lpSize->cy)
328 lpSize->cy = sz.cy;
329 }
330 }
331
332 SelectObject (hdc, hOldFont);
333 ReleaseDC (0, hdc);
334
335// TRACE (toolbar, "string size %d x %d!\n", lpSize->cx, lpSize->cy);
336}
337
338/***********************************************************************
339* TOOLBAR_WrapToolbar
340*
341* This function walks through the buttons and seperators in the
342* toolbar, and sets the TBSTATE_WRAP flag only on those items where
343* wrapping should occur based on the width of the toolbar window.
344* It does *not* calculate button placement itself. That task
345* takes place in TOOLBAR_CalcToolbar. If the program wants to manage
346* the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
347* flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
348*/
349
350static void
351TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
352{
353 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
354 TBUTTON_INFO *btnPtr;
355 INT x, cx, i, j;
356 RECT rc;
357 BOOL bWrap, bButtonWrap;
358
359 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
360 /* no layout is necessary. Applications may use this style */
361 /* to perform their own layout on the toolbar. */
362 if( !(dwStyle & TBSTYLE_WRAPABLE) )
363 return;
364
365 btnPtr = infoPtr->buttons;
366 x = infoPtr->nIndent;
367
368 GetClientRect( GetParent(hwnd), &rc );
369 infoPtr->nWidth = rc.right - rc.left;
370 bButtonWrap = FALSE;
371
372 for (i = 0; i < infoPtr->nNumButtons; i++ )
373 {
374 bWrap = FALSE;
375 btnPtr[i].fsState &= ~TBSTATE_WRAP;
376
377 if (btnPtr[i].fsState & TBSTATE_HIDDEN)
378 continue;
379
380 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
381 /* it is the actual width of the separator. This is used for */
382 /* custom controls in toolbars. */
383 if (btnPtr[i].fsStyle & TBSTYLE_SEP)
384 cx = (btnPtr[i].iBitmap > 0) ?
385 btnPtr[i].iBitmap : SEPARATOR_WIDTH;
386 else
387 cx = infoPtr->nButtonWidth;
388
389 /* Two or more adjacent separators form a separator group. */
390 /* The first separator in a group should be wrapped to the */
391 /* next row if the previous wrapping is on a button. */
392 if( bButtonWrap &&
393 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
394 (i + 1 < infoPtr->nNumButtons ) &&
395 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
396 {
397 btnPtr[i].fsState |= TBSTATE_WRAP;
398 x = infoPtr->nIndent;
399 i++;
400 bButtonWrap = FALSE;
401 continue;
402 }
403
404 /* The layout makes sure the bitmap is visible, but not the button. */
405 if ( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
406 > infoPtr->nWidth )
407 {
408 BOOL bFound = FALSE;
409
410 /* If the current button is a separator and not hidden, */
411 /* go to the next until it reaches a non separator. */
412 /* Wrap the last separator if it is before a button. */
413 while( ( (btnPtr[i].fsStyle & TBSTYLE_SEP) ||
414 (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
415 i < infoPtr->nNumButtons )
416 {
417 i++;
418 bFound = TRUE;
419 }
420
421 if( bFound && i < infoPtr->nNumButtons )
422 {
423 i--;
424 btnPtr[i].fsState |= TBSTATE_WRAP;
425 x = infoPtr->nIndent;
426 bButtonWrap = FALSE;
427 continue;
428 }
429 else if ( i >= infoPtr->nNumButtons)
430 break;
431
432 /* If the current button is not a separator, find the last */
433 /* separator and wrap it. */
434 for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
435 {
436 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
437 !(btnPtr[j].fsState & TBSTATE_HIDDEN))
438 {
439 bFound = TRUE;
440 i = j;
441 x = infoPtr->nIndent;
442 btnPtr[j].fsState |= TBSTATE_WRAP;
443 bButtonWrap = FALSE;
444 break;
445 }
446 }
447
448 /* If no separator available for wrapping, wrap one of */
449 /* non-hidden previous button. */
450 if (!bFound)
451 {
452 for ( j = i - 1;
453 j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
454 {
455 if (btnPtr[j].fsState & TBSTATE_HIDDEN)
456 continue;
457
458 bFound = TRUE;
459 i = j;
460 x = infoPtr->nIndent;
461 btnPtr[j].fsState |= TBSTATE_WRAP;
462 bButtonWrap = TRUE;
463 break;
464 }
465 }
466
467 /* If all above failed, wrap the current button. */
468 if (!bFound)
469 {
470 btnPtr[i].fsState |= TBSTATE_WRAP;
471 bFound = TRUE;
472 x = infoPtr->nIndent;
473 if (btnPtr[i].fsState & TBSTYLE_SEP )
474 bButtonWrap = FALSE;
475 else
476 bButtonWrap = TRUE;
477 }
478 }
479 else
480 x += cx;
481 }
482}
483
484/***********************************************************************
485* TOOLBAR_CalcToolbar
486*
487* This function calculates button and separator placement. It first
488* calculates the button sizes, gets the toolbar window width and then
489* calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
490* on. It assigns a new location to each item and sends this location to
491* the tooltip window if appropriate. Finally, it updates the rcBound
492* rect and calculates the new required toolbar window height.
493*/
494
495static void
496TOOLBAR_CalcToolbar (HWND hwnd)
497{
498 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
499 DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
500 TBUTTON_INFO *btnPtr;
501 INT i, nRows, nSepRows;
502 INT x, y, cx, cy;
503 SIZE sizeString;
504 RECT rc;
505 BOOL bWrap;
506
507 TOOLBAR_CalcStrings (hwnd, &sizeString);
508
509 if (dwStyle & TBSTYLE_LIST) {
510 infoPtr->nButtonHeight = max(infoPtr->nBitmapHeight, sizeString.cy) + 6;
511 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + sizeString.cx + 6;
512 }
513 else {
514 if (sizeString.cy > 0)
515 infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
516 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
517 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
518
519 if (sizeString.cx > infoPtr->nBitmapWidth)
520 infoPtr->nButtonWidth = sizeString.cx + 6;
521 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
522 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
523 }
524
525 TOOLBAR_WrapToolbar( hwnd, dwStyle );
526
527 x = infoPtr->nIndent;
528 y = (dwStyle & TBSTYLE_FLAT) ? 0: TOP_BORDER;
529 cx = infoPtr->nButtonWidth;
530 cy = infoPtr->nButtonHeight;
531 nRows = nSepRows = 0;
532
533 infoPtr->rcBound.top = y;
534 infoPtr->rcBound.left = x;
535 infoPtr->rcBound.bottom = y + cy;
536 infoPtr->rcBound.right = x;
537
538 btnPtr = infoPtr->buttons;
539 GetClientRect( GetParent(hwnd), &rc );
540 infoPtr->nWidth = rc.right - rc.left;
541
542 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
543 {
544 bWrap = FALSE;
545 if (btnPtr->fsState & TBSTATE_HIDDEN)
546 {
547 SetRectEmpty (&btnPtr->rect);
548 continue;
549 }
550
551 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
552 /* it is the actual width of the separator. This is used for */
553 /* custom controls in toolbars. */
554 if (btnPtr->fsStyle & TBSTYLE_SEP)
555 cx = (btnPtr->iBitmap > 0) ?
556 btnPtr->iBitmap : SEPARATOR_WIDTH;
557 else
558 cx = infoPtr->nButtonWidth;
559
560 if (btnPtr->fsState & TBSTATE_WRAP )
561 bWrap = TRUE;
562
563 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
564
565 if (infoPtr->rcBound.left > x)
566 infoPtr->rcBound.left = x;
567 if (infoPtr->rcBound.right < x + cx)
568 infoPtr->rcBound.right = x + cx;
569 if (infoPtr->rcBound.bottom < y + cy)
570 infoPtr->rcBound.bottom = y + cy;
571
572 /* Set the toolTip only for non-hidden, non-separator button */
573 if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP))
574 {
575 TTTOOLINFOA ti;
576
577 ZeroMemory (&ti,sizeof(TTTOOLINFOA));
578 ti.cbSize = sizeof(TTTOOLINFOA);
579 ti.hwnd = hwnd;
580 ti.uId = btnPtr->idCommand;
581 ti.rect = btnPtr->rect;
582 SendMessageA(infoPtr->hwndToolTip,TTM_NEWTOOLRECTA,0,(LPARAM)&ti);
583 }
584
585 /* btnPtr->nRow is zero based. The space between the rows is */
586 /* also considered as a row. */
587 btnPtr->nRow = nRows + nSepRows;
588 if( bWrap )
589 {
590 if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
591 y += cy;
592 else
593 {
594 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
595 /* it is the actual width of the separator. This is used for */
596 /* custom controls in toolbars. */
597 y += cy + ( (btnPtr->iBitmap > 0 ) ?
598 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
599
600 /* nSepRows is used to calculate the extra height follwoing */
601 /* the last row. */
602 nSepRows++;
603 }
604 x = infoPtr->nIndent;
605 nRows++;
606 }
607 else
608 x += cx;
609 }
610
611 /* infoPtr->nRows is the number of rows on the toolbar */
612 infoPtr->nRows = nRows + nSepRows + 1;
613
614 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
615 /* the last row. */
616 infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
617 nSepRows * (SEPARATOR_WIDTH * 2 / 3) +
618 nSepRows * (infoPtr->nBitmapHeight + 1) +
619 BOTTOM_BORDER;
620// TRACE (toolbar, "toolbar height %d\n", infoPtr->nHeight);
621}
622
623
624static INT
625TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
626{
627 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
628 TBUTTON_INFO *btnPtr;
629 INT i;
630
631 btnPtr = infoPtr->buttons;
632 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
633 if (btnPtr->fsState & TBSTATE_HIDDEN)
634 continue;
635
636 if (btnPtr->fsStyle & TBSTYLE_SEP) {
637 if (PtInRect (&btnPtr->rect, *lpPt)) {
638// TRACE (toolbar, " ON SEPARATOR %d!\n", i);
639 return -i;
640 }
641 }
642 else {
643 if (PtInRect (&btnPtr->rect, *lpPt)) {
644// TRACE (toolbar, " ON BUTTON %d!\n", i);
645 return i;
646 }
647 }
648 }
649
650// TRACE (toolbar, " NOWHERE!\n");
651 return -1;
652}
653
654
655static INT
656TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
657{
658 TBUTTON_INFO *btnPtr;
659 INT i;
660
661 btnPtr = infoPtr->buttons;
662 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
663 if (btnPtr->idCommand == idCommand) {
664// TRACE (toolbar, "command=%d index=%d\n", idCommand, i);
665 return i;
666 }
667 }
668// TRACE (toolbar, "no index found for command=%d\n", idCommand);
669 return -1;
670}
671
672
673static INT
674TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
675{
676 TBUTTON_INFO *btnPtr;
677 INT nRunIndex;
678
679 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
680 return -1;
681
682 /* check index button */
683 btnPtr = &infoPtr->buttons[nIndex];
684 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
685 if (btnPtr->fsState & TBSTATE_CHECKED)
686 return nIndex;
687 }
688
689 /* check previous buttons */
690 nRunIndex = nIndex - 1;
691 while (nRunIndex >= 0) {
692 btnPtr = &infoPtr->buttons[nRunIndex];
693 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
694 if (btnPtr->fsState & TBSTATE_CHECKED)
695 return nRunIndex;
696 }
697 else
698 break;
699 nRunIndex--;
700 }
701
702 /* check next buttons */
703 nRunIndex = nIndex + 1;
704 while (nRunIndex < infoPtr->nNumButtons) {
705 btnPtr = &infoPtr->buttons[nRunIndex];
706 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
707 if (btnPtr->fsState & TBSTATE_CHECKED)
708 return nRunIndex;
709 }
710 else
711 break;
712 nRunIndex++;
713 }
714
715 return -1;
716}
717
718
719static VOID
720TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
721 WPARAM wParam, LPARAM lParam)
722{
723 MSG msg;
724
725 msg.hwnd = hwndMsg;
726 msg.message = uMsg;
727 msg.wParam = wParam;
728 msg.lParam = lParam;
729 msg.time = GetMessageTime();
730 msg.pt.x = LOWORD(GetMessagePos());
731 msg.pt.y = HIWORD(GetMessagePos());
732
733 SendMessageA(hwndTip,TTM_RELAYEVENT,0,(LPARAM)&msg);
734}
735
736static void TBCUSTOMIZE_GetToolName(TOOLBAR_INFO* infoPtr,TBUTTON_INFO* btnPtr,INT pos)
737{
738 if (btnPtr->iString > -1 && btnPtr->iString < infoPtr->nNumStrings)
739 {
740 if (!btnPtr->pszName) btnPtr->pszName = (WCHAR*)COMCTL32_Alloc(MAXTOOLNAME*sizeof(WCHAR));
741 lstrcpynW(btnPtr->pszName,infoPtr->strings[btnPtr->iString],MAXTOOLNAME*sizeof(WCHAR));
742
743 return;
744 }
745
746 if (btnPtr->fsStyle & TBSTYLE_SEP)
747 {
748 if (!btnPtr->pszName) btnPtr->pszName = (WCHAR*)COMCTL32_Alloc(MAXTOOLNAME*sizeof(WCHAR));
749 lstrcpyW(btnPtr->pszName,(WCHAR*)L"Separator");
750 } else
751 {
752 TBNOTIFYW tbNotify;
753 BOOL unicode = isUnicodeNotify(&infoPtr->header);
754
755 tbNotify.iItem = pos;
756 tbNotify.tbButton.iBitmap = btnPtr->iBitmap;
757 tbNotify.tbButton.idCommand = btnPtr->idCommand;
758 tbNotify.tbButton.fsState = btnPtr->fsState;
759 tbNotify.tbButton.fsStyle = btnPtr->fsStyle;
760 tbNotify.tbButton.dwData = btnPtr->dwData;
761 tbNotify.tbButton.iString = btnPtr->iString;
762
763 tbNotify.cchText = MAXTOOLNAME;
764 if (unicode)
765 {
766 tbNotify.pszText = (WCHAR*)COMCTL32_Alloc(MAXTOOLNAME*sizeof(WCHAR));
767 tbNotify.pszText[0] = 0;
768 } else
769 {
770 tbNotify.pszText = (WCHAR*)COMCTL32_Alloc(MAXTOOLNAME*sizeof(CHAR));
771 ((CHAR*)tbNotify.pszText)[0] = 0;
772 }
773
774 if (!sendNotify(infoPtr->hwndToolbar,unicode ? TBN_GETBUTTONINFOW:TBN_GETBUTTONINFOA,&tbNotify.hdr))
775 { //CB: failed, try other methods
776 if (infoPtr->hwndToolTip)
777 { //try to get tool tip text
778 TTTOOLINFOW ti;
779
780 ZeroMemory (&ti,sizeof(ti));
781 ti.cbSize = sizeof(ti);
782 ti.hwnd = infoPtr->hwndToolbar;
783 ti.uId = btnPtr->idCommand;
784 ti.hinst = 0;
785 ti.lpszText = (WCHAR*)COMCTL32_Alloc(INFOTIPSIZE*sizeof(WCHAR));
786 ti.lpszText[0] = 0;
787
788 SendMessageW(infoPtr->hwndToolTip,TTM_GETTEXTW,0,(LPARAM)&ti);
789 if (unicode)
790 {
791 if (ti.lpszText[0] != 0) lstrcpynW(tbNotify.pszText,ti.lpszText,MAXTOOLNAME);
792 else lstrcpyW(tbNotify.pszText,(WCHAR*)L"Button");
793 } else
794 {
795 if (ti.lpszText[0] != 0) lstrcpynWtoA((CHAR*)tbNotify.pszText,ti.lpszText,MAXTOOLNAME);
796 else lstrcpyWtoA((CHAR*)tbNotify.pszText,(WCHAR*)L"Button");
797 }
798
799 COMCTL32_Free(ti.lpszText);
800
801 } else
802 {
803 if (unicode)
804 lstrcpyW(tbNotify.pszText,(WCHAR*)L"Button");
805 else
806 lstrcpyA((CHAR*)tbNotify.pszText,"Button");
807 }
808 }
809
810 if (!btnPtr->pszName) btnPtr->pszName = (WCHAR*)COMCTL32_Alloc(MAXTOOLNAME*sizeof(WCHAR));
811 if (unicode)
812 lstrcpyW(btnPtr->pszName,tbNotify.pszText);
813 else
814 lstrcpyAtoW(btnPtr->pszName,(CHAR*)tbNotify.pszText);
815 COMCTL32_Free(tbNotify.pszText);
816 }
817}
818
819static VOID TBCUSTOMIZE_AvailSelChange(HWND hwnd);
820static VOID TBCUSTOMIZE_VisSelChange(HWND hwnd);
821
822static BOOL TBCUSTOMIZE_FillData(HWND hwnd,TOOLBAR_INFO* infoPtr)
823{
824 TBUTTON_INFO* btnPtr;
825 INT i;
826 INT leftCount = 0;
827 INT rightCount = 0;
828 INT nItem;
829
830 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,WM_SETREDRAW,FALSE,0);
831 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,WM_SETREDRAW,FALSE,0);
832 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_RESETCONTENT,0,0);
833 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_RESETCONTENT,0,0);
834
835 /* insert 'virtual' separator button into 'available buttons' list */
836 nItem = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_ADDSTRING,0,(LPARAM)"Separator");
837 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_SETITEMDATA,nItem,0);
838
839 /* copy all buttons and append them to the listboxes */
840 btnPtr = infoPtr->buttons;
841 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
842 {
843 TBNOTIFYW tbNotify;
844
845 tbNotify.iItem = i;
846 tbNotify.tbButton.iBitmap = btnPtr->iBitmap;
847 tbNotify.tbButton.idCommand = btnPtr->idCommand;
848 tbNotify.tbButton.fsState = btnPtr->fsState;
849 tbNotify.tbButton.fsStyle = btnPtr->fsStyle;
850 tbNotify.tbButton.dwData = btnPtr->dwData;
851 tbNotify.tbButton.iString = btnPtr->iString;
852 tbNotify.cchText = 0;
853 tbNotify.pszText = NULL;
854
855 // send TBN_QUERYINSERT notification
856 if (!sendNotify(infoPtr->hwndToolbar,TBN_QUERYINSERT,&tbNotify.hdr)) continue;
857
858 // send TBN_QUERYDELETE notification
859 btnPtr->bDelete = (BOOL)sendNotify(infoPtr->hwndToolbar,TBN_QUERYDELETE,&tbNotify.hdr);
860
861 //get tool name
862
863 TBCUSTOMIZE_GetToolName(infoPtr,btnPtr,i);
864
865 if (btnPtr->fsState & TBSTATE_HIDDEN)
866 {
867 nItem = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_ADDSTRING,0,(LPARAM)"");
868 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_SETITEMDATA,nItem,btnPtr->nCustomID);
869 leftCount++;
870 } else
871 {
872 nItem = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_ADDSTRING,0,(LPARAM)"");
873 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETITEMDATA,nItem,btnPtr->nCustomID);
874 rightCount++;
875 }
876 }
877
878 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_SETCURSEL,0,0);
879 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETCURSEL,(rightCount > 0) ? 0:(WPARAM)-1,0);
880
881 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,WM_SETREDRAW,TRUE,0);
882 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,WM_SETREDRAW,TRUE,0);
883 InvalidateRect(GetDlgItem(hwnd,IDC_AVAILBTN_LBOX),NULL,TRUE);
884 InvalidateRect(GetDlgItem(hwnd,IDC_TOOLBARBTN_LBOX),NULL,TRUE);
885
886 if (leftCount == 0 && rightCount == 0) return FALSE;
887
888 TBCUSTOMIZE_AvailSelChange(hwnd);
889 TBCUSTOMIZE_VisSelChange(hwnd);
890
891 return TRUE;
892}
893
894static BOOL TBCUSTOMIZE_InitDialog(HWND hwnd,WPARAM wParam,LPARAM lParam)
895{
896 TOOLBAR_INFO* infoPtr;
897 DWORD dwStyle;
898
899 infoPtr = (TOOLBAR_INFO*)lParam;
900 SetWindowLongA(hwnd,DWL_USER,(DWORD)infoPtr);
901 dwStyle = GetWindowLongA(infoPtr->hwndToolbar,GWL_STYLE);
902
903 if (infoPtr)
904 {
905 INT x,itemHeight;
906
907 //custom ID: 1-nNumButtons, 0 == new separator
908 for (x = 0;x < infoPtr->nNumButtons;x++)
909 {
910 infoPtr->buttons[x].nCustomID = x+1;
911 infoPtr->buttons[x].pszName = NULL;
912 }
913 infoPtr->nMaxCustomID = infoPtr->nNumButtons;
914
915 //save tools
916 infoPtr->nNumOldButtons = infoPtr->nNumButtons;
917 infoPtr->oldButtons = (TBUTTON_INFO*)COMCTL32_Alloc(infoPtr->nNumOldButtons*sizeof(TBUTTON_INFO));
918 memcpy(&infoPtr->oldButtons[0],&infoPtr->buttons[0],infoPtr->nNumOldButtons*sizeof(TBUTTON_INFO));
919
920 //set height
921 if (dwStyle & TBSTYLE_FLAT)
922 itemHeight = infoPtr->nBitmapHeight+4;
923 else
924 itemHeight = infoPtr->nBitmapHeight+8;
925
926 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_SETITEMHEIGHT,0,itemHeight);
927 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETITEMHEIGHT,0,itemHeight);
928
929 infoPtr->changed = FALSE;
930
931 if (!TBCUSTOMIZE_FillData(hwnd,infoPtr)) EndDialog(hwnd,FALSE);
932 } else EndDialog(hwnd,FALSE);
933
934 return TRUE;
935}
936
937static BOOL TBCUSTOMIZE_Close(HWND hwnd,WPARAM wParam,LPARAM lParam)
938{
939 EndDialog(hwnd,FALSE);
940
941 return TRUE;
942}
943
944static VOID TBCUSTOMIZE_Reset(HWND hwnd)
945{
946 TOOLBAR_INFO* infoPtr = (TOOLBAR_INFO*)GetWindowLongA(hwnd,DWL_USER);
947 INT x;
948
949 if (!infoPtr->changed) return;
950
951 //Send TBN_RESET
952 sendNotify(infoPtr->hwndToolbar,TBN_RESET);
953
954 for (x = 0;x < infoPtr->nNumOldButtons;x++) COMCTL32_Free(infoPtr->oldButtons[x].pszName);
955
956 //restore data
957 if (infoPtr->nNumButtons != infoPtr->nNumOldButtons)
958 {
959 COMCTL32_Free(infoPtr->buttons);
960 infoPtr->nNumButtons = infoPtr->nNumOldButtons;
961 infoPtr->buttons = (TBUTTON_INFO*)COMCTL32_Alloc(infoPtr->nNumButtons*sizeof(TBUTTON_INFO));
962 }
963 memcpy(&infoPtr->buttons[0],&infoPtr->oldButtons[0],infoPtr->nNumButtons*sizeof(TBUTTON_INFO));
964
965 if (!TBCUSTOMIZE_FillData(hwnd,infoPtr)) EndDialog(hwnd,FALSE);
966
967 TOOLBAR_CalcToolbar(infoPtr->hwndToolbar);
968 InvalidateRect(infoPtr->hwndToolbar,NULL,TRUE);
969
970 infoPtr->changed = FALSE;
971}
972
973static TBUTTON_INFO* TBCUSTOMIZE_GetBtnPtr(TOOLBAR_INFO* infoPtr,INT customID)
974{
975 INT x;
976 TBUTTON_INFO* btnPtr = infoPtr->buttons;
977
978 if (customID == 0) return NULL;
979
980 for (x = 0;x < infoPtr->nNumButtons;btnPtr++)
981 if (btnPtr->nCustomID == customID) return btnPtr;
982
983 return NULL;
984}
985
986static VOID TBCUSTOMIZE_AddTool(HWND hwnd)
987{
988 TOOLBAR_INFO* infoPtr = (TOOLBAR_INFO*)GetWindowLongA(hwnd,DWL_USER);
989 LRESULT pos,count;
990 INT customID;
991 TBUTTON_INFO* btnPtr;
992 LRESULT rightSel,rightCount,rightPos;
993
994 pos = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_GETCURSEL,0,0);
995 if (pos == (LRESULT)-1) return;
996
997 count = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_GETCOUNT,0,0);
998
999 customID = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_GETITEMDATA,pos,0);
1000 if (customID == 0) btnPtr = NULL; else
1001 {
1002 btnPtr = TBCUSTOMIZE_GetBtnPtr(infoPtr,customID);
1003 if (btnPtr == NULL) return;
1004
1005 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_DELETESTRING,pos,0);
1006 }
1007
1008 rightSel = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETCURSEL,0,0);
1009 rightCount = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETCOUNT,0,0);
1010
1011 if (rightSel != (LRESULT)-1)
1012 rightPos = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_INSERTSTRING,rightSel,(LPARAM)"");
1013 else
1014 rightPos = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_ADDSTRING,0,(LPARAM)"");
1015 if (!btnPtr)
1016 { //new separator
1017 TBUTTON_INFO* newButtons;
1018
1019 newButtons = (TBUTTON_INFO*)COMCTL32_Alloc((infoPtr->nNumButtons+1)*sizeof(TBUTTON_INFO));
1020 memcpy(&newButtons[0],&infoPtr->buttons[0],infoPtr->nNumButtons*sizeof(TBUTTON_INFO));
1021 COMCTL32_Free(infoPtr->buttons);
1022
1023 infoPtr->buttons = newButtons;
1024 infoPtr->nNumButtons++;
1025
1026 btnPtr = &infoPtr->buttons[infoPtr->nNumButtons-1];
1027 ZeroMemory(btnPtr,sizeof(TBUTTON_INFO));
1028 btnPtr->fsStyle = TBSTYLE_SEP;
1029 btnPtr->bDelete = TRUE;
1030
1031 customID = ++infoPtr->nMaxCustomID;
1032 btnPtr->nCustomID = customID;
1033 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETITEMDATA,rightPos,customID);
1034 } else
1035 {
1036 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETITEMDATA,rightPos,customID);
1037 btnPtr->fsState &= ~TBSTATE_HIDDEN;
1038 }
1039 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETCURSEL,rightPos,0);
1040 TBCUSTOMIZE_VisSelChange(hwnd);
1041
1042 if (rightCount > 0)
1043 { //change order
1044 TBUTTON_INFO* btnPtr2;
1045 INT customID2,pos1,pos2;
1046
1047 pos1 = 0;
1048 while (infoPtr->buttons[pos1].nCustomID != customID) pos1++;
1049 if (rightPos < rightCount)
1050 { //insert before
1051 customID2 = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETITEMDATA,rightPos+1,0);
1052 pos2 = 0;
1053 while (infoPtr->buttons[pos2].nCustomID != customID2) pos2++;
1054 } else
1055 { //insert behind
1056 INT x;
1057
1058 customID2 = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETITEMDATA,rightPos-1,0);
1059 pos2 = 0;
1060 while (infoPtr->buttons[pos2].nCustomID != customID2) pos2++;
1061 //exchange to use first alogrithm
1062 x = pos1;
1063 pos1 = pos2;
1064 pos2 = x;
1065 }
1066
1067 if (pos1+1 != pos2)
1068 {
1069 TBUTTON_INFO temp;
1070 INT x;
1071
1072 memcpy(&temp,&infoPtr->buttons[pos1],sizeof(TBUTTON_INFO));
1073 if (pos1 < pos2)
1074 {
1075 for (x = pos1;x < pos2;x++)
1076 memcpy(&infoPtr->buttons[x],&infoPtr->buttons[x+1],sizeof(TBUTTON_INFO));
1077 memcpy(&infoPtr->buttons[pos2-1],&temp,sizeof(TBUTTON_INFO));
1078 } else
1079 {
1080 for (x = pos1-1;x >= pos2;x--)
1081 memcpy(&infoPtr->buttons[x+1],&infoPtr->buttons[x],sizeof(TBUTTON_INFO));
1082 memcpy(&infoPtr->buttons[pos2],&temp,sizeof(TBUTTON_INFO));
1083 }
1084 }
1085 }
1086
1087 if (pos == count-1 && pos > 0) pos--;
1088 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_SETCURSEL,pos,0);
1089 TBCUSTOMIZE_AvailSelChange(hwnd);
1090
1091 TOOLBAR_CalcToolbar(infoPtr->hwndToolbar);
1092 InvalidateRect(infoPtr->hwndToolbar,NULL,TRUE);
1093
1094 infoPtr->changed = TRUE;
1095}
1096
1097static VOID TBCUSTOMIZE_RemoveTool(HWND hwnd)
1098{
1099 TOOLBAR_INFO* infoPtr = (TOOLBAR_INFO*)GetWindowLongA(hwnd,DWL_USER);
1100 LRESULT pos,count;
1101 INT customID;
1102 TBUTTON_INFO* btnPtr;
1103
1104 pos = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETCURSEL,0,0);
1105 if (pos == (LRESULT)-1) return;
1106
1107 count = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETCOUNT,0,0);
1108
1109 customID = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETITEMDATA,pos,0);
1110 if (customID == 0) return; //no allowed
1111
1112 btnPtr = TBCUSTOMIZE_GetBtnPtr(infoPtr,customID);
1113 if (btnPtr == NULL || !btnPtr->bDelete) return;
1114
1115 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_DELETESTRING,pos,0);
1116
1117 if (btnPtr->fsStyle & TBSTYLE_SEP)
1118 { //remove separator
1119 TBUTTON_INFO* newButtons;
1120 INT nIndex,x;
1121
1122 //find pos
1123 for (x = 0;x < infoPtr->nNumButtons;x++) if (&infoPtr->buttons[x] == btnPtr)
1124 {
1125 nIndex = x;
1126 break;
1127 }
1128
1129 infoPtr->nNumButtons--;
1130 newButtons = (TBUTTON_INFO*)COMCTL32_Alloc(infoPtr->nNumButtons*sizeof(TBUTTON_INFO));
1131
1132 if (nIndex > 0)
1133 memcpy(&newButtons[0],&infoPtr->buttons[0],nIndex*sizeof(TBUTTON_INFO));
1134
1135 if (nIndex < infoPtr->nNumButtons)
1136 memcpy (&newButtons[nIndex],&infoPtr->buttons[nIndex+1],(infoPtr->nNumButtons-nIndex)*sizeof(TBUTTON_INFO));
1137
1138 COMCTL32_Free(infoPtr->buttons);
1139 infoPtr->buttons = newButtons;
1140 } else
1141 {
1142 LRESULT leftSel,leftCount,leftPos;
1143
1144 leftSel = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_GETCURSEL,0,0);
1145 leftCount = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_GETCOUNT,0,0);
1146
1147 if (leftSel == 0)
1148 if (leftCount > 1) leftSel++; else leftSel = -1;
1149
1150 if (leftSel != (LRESULT)-1)
1151 leftPos = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_INSERTSTRING,leftSel,(LPARAM)"");
1152 else
1153 leftPos = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_ADDSTRING,0,(LPARAM)"");
1154 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_SETITEMDATA,leftPos,customID);
1155
1156 SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_SETCURSEL,leftPos,0);
1157 TBCUSTOMIZE_AvailSelChange(hwnd);
1158
1159 btnPtr->fsState |= TBSTATE_HIDDEN;
1160
1161 if (leftCount > 1)
1162 { //change order
1163 TBUTTON_INFO* btnPtr2;
1164 INT customID2,pos1,pos2;
1165
1166 pos1 = 0;
1167 while (infoPtr->buttons[pos1].nCustomID != customID) pos1++;
1168 if (leftPos < leftCount)
1169 { //insert before
1170 customID2 = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_GETITEMDATA,leftPos+1,0);
1171 pos2 = 0;
1172 while (infoPtr->buttons[pos2].nCustomID != customID2) pos2++;
1173 } else
1174 { //insert behind
1175 INT x;
1176
1177 customID2 = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_GETITEMDATA,leftPos-1,0);
1178 pos2 = 0;
1179 while (infoPtr->buttons[pos2].nCustomID != customID2) pos2++;
1180 //exchange to use first alogrithm
1181 x = pos1;
1182 pos1 = pos2;
1183 pos2 = x;
1184 }
1185
1186 if (pos1+1 != pos2)
1187 {
1188 TBUTTON_INFO temp;
1189 INT x;
1190
1191 memcpy(&temp,&infoPtr->buttons[pos1],sizeof(TBUTTON_INFO));
1192 if (pos1 < pos2)
1193 {
1194 for (x = pos1;x < pos2;x++)
1195 memcpy(&infoPtr->buttons[x],&infoPtr->buttons[x+1],sizeof(TBUTTON_INFO));
1196 memcpy(&infoPtr->buttons[pos2-1],&temp,sizeof(TBUTTON_INFO));
1197 } else
1198 {
1199 for (x = pos1-1;x >= pos2;x--)
1200 memcpy(&infoPtr->buttons[x+1],&infoPtr->buttons[x],sizeof(TBUTTON_INFO));
1201 memcpy(&infoPtr->buttons[pos2],&temp,sizeof(TBUTTON_INFO));
1202 }
1203 }
1204 }
1205 }
1206
1207 if (pos == count-1) pos--;
1208 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETCURSEL,pos,0);
1209 TBCUSTOMIZE_VisSelChange(hwnd);
1210
1211 TOOLBAR_CalcToolbar(infoPtr->hwndToolbar);
1212 InvalidateRect(infoPtr->hwndToolbar,NULL,TRUE);
1213
1214 infoPtr->changed = TRUE;
1215}
1216
1217static VOID TBCUSTOMIZE_Help(HWND hwnd)
1218{
1219 TOOLBAR_INFO* infoPtr = (TOOLBAR_INFO*)GetWindowLongA(hwnd,DWL_USER);
1220
1221 //Send TBN_CUSTHELP
1222 sendNotify(infoPtr->hwndToolbar,TBN_CUSTHELP);
1223}
1224
1225static VOID TBCUSTOMIZE_MoveToolUp(HWND hwnd)
1226{
1227 TOOLBAR_INFO* infoPtr = (TOOLBAR_INFO*)GetWindowLongA(hwnd,DWL_USER);
1228 LRESULT pos;
1229 TBUTTON_INFO button;
1230 INT customID;
1231 TBUTTON_INFO* btnPtr1,* btnPtr2;
1232
1233 pos = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETCURSEL,0,0);
1234 if (pos == (LRESULT)-1 || pos == 0) return;
1235
1236 //update listbox
1237
1238 customID = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETITEMDATA,pos,0);
1239 btnPtr1 = TBCUSTOMIZE_GetBtnPtr(infoPtr,customID);
1240 if (btnPtr1 == NULL) return;
1241
1242 customID = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETITEMDATA,pos-1,0);
1243 btnPtr2 = TBCUSTOMIZE_GetBtnPtr(infoPtr,customID);
1244 if (btnPtr2 == NULL) return;
1245
1246 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETITEMDATA,pos,btnPtr2->nCustomID);
1247 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETITEMDATA,pos-1,btnPtr1->nCustomID);
1248
1249 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETCURSEL,pos-1,0);
1250 TBCUSTOMIZE_VisSelChange(hwnd);
1251
1252 //update buttons
1253 memcpy(&button,btnPtr1,sizeof(TBUTTON_INFO));
1254 memcpy(btnPtr1,btnPtr2,sizeof(TBUTTON_INFO));
1255 memcpy(btnPtr2,&button,sizeof(TBUTTON_INFO));
1256
1257 TOOLBAR_CalcToolbar(infoPtr->hwndToolbar);
1258 InvalidateRect(infoPtr->hwndToolbar,NULL,TRUE);
1259
1260 infoPtr->changed = TRUE;
1261}
1262
1263static VOID TBCUSTOMIZE_MoveToolDown(HWND hwnd)
1264{
1265 TOOLBAR_INFO* infoPtr = (TOOLBAR_INFO*)GetWindowLongA(hwnd,DWL_USER);
1266 LRESULT pos,count;
1267 TBUTTON_INFO button;
1268 INT customID;
1269 TBUTTON_INFO* btnPtr1,* btnPtr2;
1270
1271 pos = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETCURSEL,0,0);
1272 if (pos == (LRESULT)-1) return;
1273
1274 count = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETCOUNT,0,0);
1275 if (pos == count-1) return;
1276
1277 //update listbox
1278
1279 customID = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETITEMDATA,pos,0);
1280 btnPtr1 = TBCUSTOMIZE_GetBtnPtr(infoPtr,customID);
1281 if (btnPtr1 == NULL) return;
1282
1283 customID = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETITEMDATA,pos+1,0);
1284 btnPtr2 = TBCUSTOMIZE_GetBtnPtr(infoPtr,customID);
1285 if (btnPtr2 == NULL) return;
1286
1287 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETITEMDATA,pos,btnPtr2->nCustomID);
1288 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETITEMDATA,pos+1,btnPtr1->nCustomID);
1289
1290 SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_SETCURSEL,pos+1,0);
1291 TBCUSTOMIZE_VisSelChange(hwnd);
1292
1293 //update buttons
1294 memcpy(&button,btnPtr1,sizeof(TBUTTON_INFO));
1295 memcpy(btnPtr1,btnPtr2,sizeof(TBUTTON_INFO));
1296 memcpy(btnPtr2,&button,sizeof(TBUTTON_INFO));
1297
1298 TOOLBAR_CalcToolbar(infoPtr->hwndToolbar);
1299 InvalidateRect(infoPtr->hwndToolbar,NULL,TRUE);
1300
1301 infoPtr->changed = TRUE;
1302}
1303
1304static VOID TBCUSTOMIZE_AvailSelChange(HWND hwnd)
1305{
1306 LRESULT pos;
1307 HWND hwndBtn;
1308
1309 pos = SendDlgItemMessageA(hwnd,IDC_AVAILBTN_LBOX,LB_GETCURSEL,0,0);
1310
1311 hwndBtn = GetDlgItem(hwnd,IDOK);
1312 EnableWindow(hwndBtn,(pos == (LRESULT)-1) ? FALSE:TRUE);
1313}
1314
1315static VOID TBCUSTOMIZE_VisSelChange(HWND hwnd)
1316{
1317 TOOLBAR_INFO* infoPtr = (TOOLBAR_INFO*)GetWindowLongA(hwnd,DWL_USER);
1318 LRESULT pos;
1319
1320 pos = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETCURSEL,0,0);
1321
1322 if (pos == (LRESULT)-1)
1323 {
1324 EnableWindow(GetDlgItem(hwnd,IDC_REMOVE_BTN),FALSE);
1325 EnableWindow(GetDlgItem(hwnd,IDC_MOVEUP_BTN),FALSE);
1326 EnableWindow(GetDlgItem(hwnd,IDC_MOVEDN_BTN),FALSE);
1327 } else
1328 {
1329 INT customID;
1330 TBUTTON_INFO* btnPtr;
1331 LRESULT count;
1332
1333 customID = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETITEMDATA,pos,0);
1334 btnPtr = TBCUSTOMIZE_GetBtnPtr(infoPtr,customID);
1335 count = SendDlgItemMessageA(hwnd,IDC_TOOLBARBTN_LBOX,LB_GETCOUNT,0,0);
1336
1337 if (btnPtr)
1338 EnableWindow(GetDlgItem(hwnd,IDC_REMOVE_BTN),btnPtr->bDelete);
1339 else
1340 EnableWindow(GetDlgItem(hwnd,IDC_REMOVE_BTN),TRUE);
1341 EnableWindow(GetDlgItem(hwnd,IDC_MOVEUP_BTN),!(pos == 0));
1342 EnableWindow(GetDlgItem(hwnd,IDC_MOVEDN_BTN),!(pos == count-1));
1343 }
1344}
1345
1346static BOOL TBCUSTOMIZE_Command(HWND hwnd,WPARAM wParam,LPARAM lParam)
1347{
1348 switch(LOWORD(wParam))
1349 {
1350 case IDCANCEL:
1351 EndDialog(hwnd,FALSE);
1352 break;
1353
1354 case IDC_RESET_BTN:
1355 TBCUSTOMIZE_Reset(hwnd);
1356 break;
1357
1358 case IDOK: //== add tool
1359 TBCUSTOMIZE_AddTool(hwnd);
1360 break;
1361
1362 case IDC_REMOVE_BTN:
1363 TBCUSTOMIZE_RemoveTool(hwnd);
1364 break;
1365
1366 case IDC_HELP_BTN:
1367 TBCUSTOMIZE_Help(hwnd);
1368 break;
1369
1370 case IDC_MOVEUP_BTN:
1371 TBCUSTOMIZE_MoveToolUp(hwnd);
1372 break;
1373
1374 case IDC_MOVEDN_BTN:
1375 TBCUSTOMIZE_MoveToolDown(hwnd);
1376 break;
1377
1378 case IDC_AVAILBTN_LBOX:
1379 switch(HIWORD(wParam))
1380 {
1381 case LBN_SELCHANGE:
1382 TBCUSTOMIZE_AvailSelChange(hwnd);
1383 break;
1384 case LBN_DBLCLK:
1385 TBCUSTOMIZE_AddTool(hwnd);
1386 break;
1387 }
1388 break;
1389
1390 case IDC_TOOLBARBTN_LBOX:
1391 switch(HIWORD(wParam))
1392 {
1393 case LBN_SELCHANGE:
1394 TBCUSTOMIZE_VisSelChange(hwnd);
1395 break;
1396 case LBN_DBLCLK:
1397 TBCUSTOMIZE_RemoveTool(hwnd);
1398 break;
1399 }
1400 break;
1401 }
1402
1403 return TRUE;
1404}
1405
1406static BOOL TBCUSTOMIZE_Destroy(HWND hwnd,WPARAM wParam,LPARAM lParam)
1407{
1408 TOOLBAR_INFO* infoPtr = (TOOLBAR_INFO*)GetWindowLongA(hwnd,DWL_USER);
1409 INT x;
1410
1411 for (x = 0;x < infoPtr->nNumOldButtons;x++)
1412 COMCTL32_Free(infoPtr->oldButtons[x].pszName);
1413 COMCTL32_Free(infoPtr->oldButtons);
1414 infoPtr->oldButtons = NULL;
1415 infoPtr->nNumOldButtons = 0;
1416
1417 return TRUE;
1418}
1419
1420static BOOL TBCUSTOMIZE_DrawItem(HWND hwnd,WPARAM wParam,LPARAM lParam)
1421{
1422 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
1423 {
1424 TOOLBAR_INFO* infoPtr = (TOOLBAR_INFO*)GetWindowLongA(hwnd,DWL_USER);
1425 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
1426 RECT rcButton;
1427 RECT rcText;
1428 HPEN hOldPen;
1429 HBRUSH hOldBrush;
1430 COLORREF oldText = 0;
1431 COLORREF oldBk = 0;
1432 INT customID;
1433 TBUTTON_INFO* btnPtr;
1434 DWORD dwStyle = GetWindowLongA(infoPtr->hwndToolbar,GWL_STYLE);
1435
1436 customID = SendDlgItemMessageA(hwnd,wParam,LB_GETITEMDATA,lpdis->itemID,0);
1437 btnPtr = TBCUSTOMIZE_GetBtnPtr(infoPtr,customID);
1438
1439 if (btnPtr != NULL && !btnPtr->bDelete)
1440 {
1441 if (lpdis->itemState & ODS_FOCUS) oldBk = SetBkColor(lpdis->hDC,GetSysColor(COLOR_HIGHLIGHT));
1442 oldText = SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT));
1443 } else if (lpdis->itemState & ODS_FOCUS)
1444 {
1445 oldBk = SetBkColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
1446 oldText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
1447 }
1448
1449
1450 hOldPen = SelectObject (lpdis->hDC, GetSysColorPen ((lpdis->itemState & ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1451 hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
1452
1453 /* fill background rectangle */
1454 Rectangle (lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,lpdis->rcItem.right,lpdis->rcItem.bottom);
1455
1456 /* calculate button and text rectangles */
1457 CopyRect (&rcButton, &lpdis->rcItem);
1458 InflateRect (&rcButton, -1, -1);
1459 CopyRect (&rcText, &rcButton);
1460 rcButton.right = rcButton.left + infoPtr->nBitmapWidth + 6;
1461 rcText.left = rcButton.right + 2;
1462
1463 /* draw focus rectangle */
1464 if (lpdis->itemState & ODS_FOCUS) DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
1465
1466 //draw tool
1467 if (btnPtr && !(btnPtr->fsStyle & TBSTYLE_SEP))
1468 {
1469 //draw button
1470 if (dwStyle & TBSTYLE_FLAT)
1471 {
1472 ImageList_Draw(infoPtr->himlDef,btnPtr->iBitmap,lpdis->hDC,rcButton.left+2,rcButton.top+2,ILD_NORMAL);
1473 } else
1474 {
1475 DrawEdge (lpdis->hDC,&rcButton,EDGE_RAISED,BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
1476
1477 ImageList_Draw(infoPtr->himlDef,btnPtr->iBitmap,lpdis->hDC,rcButton.left+1,rcButton.top+1,ILD_NORMAL);
1478 }
1479
1480 } else
1481 { //draw separator
1482 if (!(dwStyle & TBSTYLE_FLAT))
1483 DrawEdge (lpdis->hDC,&rcButton,EDGE_RAISED,BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
1484
1485 TOOLBAR_DrawFlatSeparator(&rcButton,lpdis->hDC);
1486 }
1487
1488 /* draw text */
1489 if (!btnPtr || btnPtr->fsStyle & TBSTYLE_SEP)
1490 { //new separator
1491 DrawTextA(lpdis->hDC,"Separator",-1,&rcText,DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1492 } else if (btnPtr->pszName != NULL)
1493 {
1494 DrawTextW(lpdis->hDC,btnPtr->pszName,-1,&rcText,DT_LEFT | DT_VCENTER | DT_SINGLELINE);
1495 }
1496
1497 if (lpdis->itemState & ODS_FOCUS)
1498 {
1499 SetBkColor (lpdis->hDC, oldBk);
1500 SetTextColor (lpdis->hDC, oldText);
1501 }
1502
1503 SelectObject (lpdis->hDC, hOldBrush);
1504 SelectObject (lpdis->hDC, hOldPen);
1505
1506 return TRUE;
1507 }
1508
1509 return FALSE;
1510}
1511
1512/***********************************************************************
1513 * TOOLBAR_CustomizeDialogProc
1514 * This function implements the toolbar customization dialog.
1515 */
1516static BOOL WINAPI
1517TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1518{
1519 TOOLBAR_INFO *infoPtr;
1520
1521 switch (uMsg)
1522 {
1523 case WM_INITDIALOG:
1524 return TBCUSTOMIZE_InitDialog(hwnd,wParam,lParam);
1525
1526 case WM_CLOSE:
1527 return TBCUSTOMIZE_Close(hwnd,wParam,lParam);
1528
1529 case WM_COMMAND:
1530 return TBCUSTOMIZE_Command(hwnd,wParam,lParam);
1531
1532 case WM_DESTROY:
1533 return TBCUSTOMIZE_Destroy(hwnd,wParam,lParam);
1534
1535 case WM_DRAWITEM:
1536 return TBCUSTOMIZE_DrawItem(hwnd,wParam,lParam);
1537
1538 default:
1539 return FALSE;
1540 }
1541}
1542
1543/***********************************************************************
1544 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
1545 *
1546 */
1547static LRESULT
1548TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1549{
1550 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1551 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
1552 INT nIndex = 0,nButtons;
1553 HBITMAP hbmLoad;
1554
1555 if (!lpAddBmp)
1556 return -1;
1557
1558 if (lpAddBmp->hInst == HINST_COMMCTRL)
1559 {
1560 if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR)
1561 nButtons = 15;
1562 else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR)
1563 nButtons = 13;
1564 else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR)
1565 nButtons = 5;
1566 else
1567 return -1;
1568
1569// TRACE ("adding %d internal bitmaps!\n", nButtons);
1570
1571 /* Windows resize all the buttons to the size of a newly added standard Image*/
1572 if (lpAddBmp->nID & 1)
1573 {
1574 /* large icons */
1575 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1576 MAKELPARAM((WORD)26, (WORD)26));
1577 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1578 MAKELPARAM((WORD)33, (WORD)33));
1579 }
1580 else
1581 {
1582 /* small icons */
1583 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
1584 MAKELPARAM((WORD)16, (WORD)16));
1585 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
1586 MAKELPARAM((WORD)22, (WORD)22));
1587 }
1588
1589 TOOLBAR_CalcToolbar (hwnd);
1590 }
1591 else
1592 {
1593 nButtons = (INT)wParam;
1594 if (nButtons <= 0)
1595 return -1;
1596
1597 //TRACE ("adding %d bitmaps!\n", nButtons);
1598 }
1599
1600 if (!(infoPtr->himlDef)) {
1601 /* create new default image list */
1602 //TRACE ("creating default image list!\n");
1603 /* It seems that the image list created is 1 pixel taller than the bitmap height */
1604//CB: nope, it's otherwise
1605 infoPtr->himlDef =
1606 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight-1,
1607 ILC_COLOR | ILC_MASK, nButtons, 2);
1608 infoPtr->himlInt = infoPtr->himlDef;
1609 }
1610
1611 /* Add bitmaps to the default image list */
1612 if (lpAddBmp->hInst == (HINSTANCE)0)
1613 {
1614 nIndex =
1615 ImageList_AddMasked (infoPtr->himlDef, (HBITMAP)lpAddBmp->nID,
1616 CLR_DEFAULT);
1617 }
1618 else if (lpAddBmp->hInst == HINST_COMMCTRL)
1619 {
1620 /* Add system bitmaps */
1621 switch (lpAddBmp->nID)
1622 {
1623 case IDB_STD_SMALL_COLOR:
1624 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1625 MAKEINTRESOURCEA(IDB_STD_SMALL));
1626 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1627 hbmLoad, CLR_DEFAULT);
1628 DeleteObject (hbmLoad);
1629 break;
1630
1631 case IDB_STD_LARGE_COLOR:
1632 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1633 MAKEINTRESOURCEA(IDB_STD_LARGE));
1634 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1635 hbmLoad, CLR_DEFAULT);
1636 DeleteObject (hbmLoad);
1637 break;
1638
1639 case IDB_VIEW_SMALL_COLOR:
1640 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1641 MAKEINTRESOURCEA(IDB_VIEW_SMALL));
1642 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1643 hbmLoad, CLR_DEFAULT);
1644 DeleteObject (hbmLoad);
1645 break;
1646
1647 case IDB_VIEW_LARGE_COLOR:
1648 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1649 MAKEINTRESOURCEA(IDB_VIEW_LARGE));
1650 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1651 hbmLoad, CLR_DEFAULT);
1652 DeleteObject (hbmLoad);
1653 break;
1654
1655 case IDB_HIST_SMALL_COLOR:
1656 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1657 MAKEINTRESOURCEA(IDB_HIST_SMALL));
1658 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1659 hbmLoad, CLR_DEFAULT);
1660 DeleteObject (hbmLoad);
1661 break;
1662
1663 case IDB_HIST_LARGE_COLOR:
1664 hbmLoad = LoadBitmapA (COMCTL32_hModule,
1665 MAKEINTRESOURCEA(IDB_HIST_LARGE));
1666 nIndex = ImageList_AddMasked (infoPtr->himlDef,
1667 hbmLoad, CLR_DEFAULT);
1668 DeleteObject (hbmLoad);
1669 break;
1670
1671 default:
1672 nIndex = ImageList_GetImageCount (infoPtr->himlDef);
1673 //ERR ("invalid imagelist!\n");
1674 break;
1675 }
1676 }
1677 else
1678 {
1679 hbmLoad = LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
1680 nIndex = ImageList_AddMasked (infoPtr->himlDef, hbmLoad, CLR_DEFAULT);
1681 DeleteObject (hbmLoad);
1682 }
1683
1684 infoPtr->nNumBitmaps += nButtons;
1685
1686 return nIndex;
1687}
1688
1689
1690static LRESULT
1691TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1692{
1693 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1694 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1695 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1696
1697// TRACE (toolbar, "adding %d buttons!\n", wParam);
1698
1699 nAddButtons = (UINT)wParam;
1700 nOldButtons = infoPtr->nNumButtons;
1701 nNewButtons = nOldButtons+nAddButtons;
1702
1703 if (infoPtr->nNumButtons == 0)
1704 {
1705 infoPtr->buttons = (TBUTTON_INFO*)COMCTL32_Alloc(sizeof(TBUTTON_INFO)*nNewButtons);
1706 } else
1707 {
1708 TBUTTON_INFO* oldButtons = infoPtr->buttons;
1709
1710 infoPtr->buttons = (TBUTTON_INFO*)COMCTL32_Alloc(sizeof(TBUTTON_INFO)*nNewButtons);
1711 memcpy(&infoPtr->buttons[0], &oldButtons[0],nOldButtons * sizeof(TBUTTON_INFO));
1712 COMCTL32_Free(oldButtons);
1713 }
1714
1715 infoPtr->nNumButtons = nNewButtons;
1716
1717 /* insert new button data */
1718 for (nCount = 0; nCount < nAddButtons; nCount++)
1719 {
1720 TBUTTON_INFO* btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1721
1722 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1723 btnPtr->idCommand = lpTbb[nCount].idCommand;
1724 btnPtr->fsState = lpTbb[nCount].fsState;
1725 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1726 btnPtr->dwData = lpTbb[nCount].dwData;
1727 btnPtr->iString = lpTbb[nCount].iString;
1728 btnPtr->bHot = FALSE;
1729 btnPtr->bDelete = FALSE; //only used in customize
1730 btnPtr->pszName = NULL;
1731
1732 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP))
1733 {
1734 TTTOOLINFOA ti;
1735
1736 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1737 ti.cbSize = sizeof (TTTOOLINFOA);
1738 ti.hwnd = hwnd;
1739 ti.uId = btnPtr->idCommand;
1740 ti.hinst = 0;
1741 ti.lpszText = LPSTR_TEXTCALLBACKA;
1742
1743 SendMessageA (infoPtr->hwndToolTip,TTM_ADDTOOLA,0,(LPARAM)&ti);
1744 }
1745 }
1746
1747 TOOLBAR_CalcToolbar(hwnd);
1748
1749 InvalidateRect(hwnd,NULL,FALSE);
1750
1751 return TRUE;
1752}
1753
1754static LRESULT
1755TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1756{
1757 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1758 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1759 INT nOldButtons, nNewButtons, nAddButtons, nCount;
1760
1761// TRACE("adding %d buttons!\n", wParam);
1762
1763 nAddButtons = (UINT)wParam;
1764 nOldButtons = infoPtr->nNumButtons;
1765 nNewButtons = nOldButtons + nAddButtons;
1766
1767 if (infoPtr->nNumButtons == 0) {
1768 infoPtr->buttons =
1769 (TBUTTON_INFO*)COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1770 }
1771 else {
1772 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1773 infoPtr->buttons =
1774 (TBUTTON_INFO*)COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
1775 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1776 nOldButtons * sizeof(TBUTTON_INFO));
1777 COMCTL32_Free (oldButtons);
1778 }
1779
1780 infoPtr->nNumButtons = nNewButtons;
1781
1782 /* insert new button data */
1783 for (nCount = 0; nCount < nAddButtons; nCount++) {
1784 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
1785 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
1786 btnPtr->idCommand = lpTbb[nCount].idCommand;
1787 btnPtr->fsState = lpTbb[nCount].fsState;
1788 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
1789 btnPtr->dwData = lpTbb[nCount].dwData;
1790 btnPtr->iString = lpTbb[nCount].iString;
1791 btnPtr->bHot = FALSE;
1792
1793 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP)) {
1794 TTTOOLINFOW ti;
1795
1796 ZeroMemory (&ti, sizeof(TTTOOLINFOW));
1797 ti.cbSize = sizeof (TTTOOLINFOW);
1798 ti.hwnd = hwnd;
1799 ti.uId = btnPtr->idCommand;
1800 ti.hinst = 0;
1801 ti.lpszText = LPSTR_TEXTCALLBACKW;
1802
1803 SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
1804 0, (LPARAM)&ti);
1805 }
1806 }
1807
1808 TOOLBAR_CalcToolbar (hwnd);
1809
1810 InvalidateRect(hwnd, NULL, FALSE);
1811
1812 return TRUE;
1813}
1814
1815
1816static LRESULT
1817TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1818{
1819 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1820 INT nIndex;
1821
1822 if ((wParam) && (HIWORD(lParam) == 0)) {
1823 char szString[256];
1824 INT len;
1825// TRACE (toolbar, "adding string from resource!\n");
1826
1827 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
1828 szString, 256);
1829
1830// TRACE (toolbar, "len=%d \"%s\"\n", len, szString);
1831 nIndex = infoPtr->nNumStrings;
1832 if (infoPtr->nNumStrings == 0) {
1833 infoPtr->strings =
1834 (LPWSTR*)COMCTL32_Alloc (sizeof(LPWSTR));
1835 }
1836 else {
1837 LPWSTR *oldStrings = infoPtr->strings;
1838 infoPtr->strings =
1839 (LPWSTR*)COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1840 memcpy (&infoPtr->strings[0], &oldStrings[0],
1841 sizeof(LPWSTR) * infoPtr->nNumStrings);
1842 COMCTL32_Free (oldStrings);
1843 }
1844
1845 infoPtr->strings[infoPtr->nNumStrings] =
1846 (WCHAR*)COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1847 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
1848 infoPtr->nNumStrings++;
1849 }
1850 else {
1851 LPSTR p = (LPSTR)lParam;
1852 INT len;
1853
1854 if (p == NULL)
1855 return -1;
1856// TRACE (toolbar, "adding string(s) from array!\n");
1857 nIndex = infoPtr->nNumStrings;
1858 while (*p) {
1859 len = lstrlenA (p);
1860// TRACE (toolbar, "len=%d \"%s\"\n", len, p);
1861
1862 if (infoPtr->nNumStrings == 0) {
1863 infoPtr->strings =
1864 (LPWSTR*)COMCTL32_Alloc (sizeof(LPWSTR));
1865 }
1866 else {
1867 LPWSTR *oldStrings = infoPtr->strings;
1868 infoPtr->strings =
1869 (LPWSTR*)COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1870 memcpy (&infoPtr->strings[0], &oldStrings[0],
1871 sizeof(LPWSTR) * infoPtr->nNumStrings);
1872 COMCTL32_Free (oldStrings);
1873 }
1874
1875 infoPtr->strings[infoPtr->nNumStrings] =
1876 (WCHAR*)COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1877 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
1878 infoPtr->nNumStrings++;
1879
1880 p += (len+1);
1881 }
1882 }
1883
1884 return nIndex;
1885}
1886
1887
1888static LRESULT
1889TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1890{
1891 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1892 INT nIndex;
1893
1894 if ((wParam) && (HIWORD(lParam) == 0)) {
1895 WCHAR szString[256];
1896 INT len;
1897// TRACE (toolbar, "adding string from resource!\n");
1898
1899 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
1900 szString, 256);
1901
1902// TRACE (toolbar, "len=%d \"%s\"\n", len, debugstr_w(szString));
1903 nIndex = infoPtr->nNumStrings;
1904 if (infoPtr->nNumStrings == 0) {
1905 infoPtr->strings =
1906 (LPWSTR*)COMCTL32_Alloc (sizeof(LPWSTR));
1907 }
1908 else {
1909 LPWSTR *oldStrings = infoPtr->strings;
1910 infoPtr->strings =
1911 (LPWSTR*)COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1912 memcpy (&infoPtr->strings[0], &oldStrings[0],
1913 sizeof(LPWSTR) * infoPtr->nNumStrings);
1914 COMCTL32_Free (oldStrings);
1915 }
1916
1917 infoPtr->strings[infoPtr->nNumStrings] =
1918 (WCHAR*)COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1919 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
1920 infoPtr->nNumStrings++;
1921 }
1922 else {
1923 LPWSTR p = (LPWSTR)lParam;
1924 INT len;
1925
1926 if (p == NULL)
1927 return -1;
1928// TRACE (toolbar, "adding string(s) from array!\n");
1929 nIndex = infoPtr->nNumStrings;
1930 while (*p) {
1931 len = lstrlenW (p);
1932// TRACE (toolbar, "len=%d \"%s\"\n", len, debugstr_w(p));
1933
1934 if (infoPtr->nNumStrings == 0) {
1935 infoPtr->strings =
1936 (LPWSTR*)COMCTL32_Alloc (sizeof(LPWSTR));
1937 }
1938 else {
1939 LPWSTR *oldStrings = infoPtr->strings;
1940 infoPtr->strings =
1941 (LPWSTR*)COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1942 memcpy (&infoPtr->strings[0], &oldStrings[0],
1943 sizeof(LPWSTR) * infoPtr->nNumStrings);
1944 COMCTL32_Free (oldStrings);
1945 }
1946
1947 infoPtr->strings[infoPtr->nNumStrings] =
1948 (WCHAR*)COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1949 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1950 infoPtr->nNumStrings++;
1951
1952 p += (len+1);
1953 }
1954 }
1955
1956 return nIndex;
1957}
1958
1959
1960static LRESULT
1961TOOLBAR_AutoSize (HWND hwnd)
1962{
1963 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1964 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1965 RECT parent_rect;
1966 HWND parent;
1967 INT x, y;
1968 INT cx, cy;
1969 UINT uPosFlags = 0;
1970
1971 //TRACE (toolbar, "resize forced!\n");
1972
1973 x = y = 0;
1974 parent = GetParent (hwnd);
1975 GetClientRect(parent, &parent_rect);
1976
1977 if (dwStyle & CCS_NORESIZE) {
1978 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
1979 cx = 0;
1980 cy = 0;
1981 }
1982 else {
1983 infoPtr->nWidth = parent_rect.right - parent_rect.left;
1984 TOOLBAR_CalcToolbar (hwnd);
1985 InvalidateRect( hwnd, NULL, TRUE );
1986 cy = infoPtr->nHeight;
1987 cx = infoPtr->nWidth;
1988 }
1989
1990 if (dwStyle & CCS_NOPARENTALIGN)
1991 uPosFlags |= SWP_NOMOVE;
1992
1993 if (!(dwStyle & CCS_NODIVIDER))
1994 cy += GetSystemMetrics(SM_CYEDGE);
1995
1996 if (dwStyle & WS_BORDER)
1997 {
1998 x = y = 1;
1999 cy += GetSystemMetrics(SM_CYEDGE);
2000 cx += GetSystemMetrics(SM_CYEDGE);
2001 }
2002
2003 infoPtr->bAutoSize = TRUE;
2004 SetWindowPos (hwnd, HWND_TOP, parent_rect.left - x, parent_rect.top - y,
2005 cx, cy, uPosFlags);
2006
2007 /* The following line makes sure that the infoPtr->bAutoSize is turned off after
2008 * the setwindowpos calls */
2009 infoPtr->bAutoSize = FALSE;
2010
2011 return 0;
2012}
2013
2014
2015static LRESULT
2016TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
2017{
2018 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2019
2020 return infoPtr->nNumButtons;
2021}
2022
2023
2024static LRESULT
2025TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2026{
2027 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2028
2029 if (infoPtr == NULL) {
2030// ERR (toolbar, "(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
2031// ERR (toolbar, "infoPtr == NULL!\n");
2032 return 0;
2033 }
2034
2035 infoPtr->dwStructSize = (DWORD)wParam;
2036
2037 return 0;
2038}
2039
2040
2041static LRESULT
2042TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
2043{
2044 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2045 TBUTTON_INFO *btnPtr;
2046 HDC hdc;
2047 INT nIndex;
2048
2049 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2050 if (nIndex == -1)
2051 return FALSE;
2052
2053 btnPtr = &infoPtr->buttons[nIndex];
2054 btnPtr->iBitmap = LOWORD(lParam);
2055
2056 hdc = GetDC (hwnd);
2057 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2058 ReleaseDC (hwnd, hdc);
2059
2060 return TRUE;
2061}
2062
2063
2064static LRESULT
2065TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2066{
2067 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2068 TBUTTON_INFO *btnPtr;
2069 HDC hdc;
2070 INT nIndex;
2071 INT nOldIndex = -1;
2072 BOOL bChecked = FALSE;
2073
2074 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2075 if (nIndex == -1)
2076 return FALSE;
2077
2078 btnPtr = &infoPtr->buttons[nIndex];
2079
2080 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
2081 return FALSE;
2082
2083 bChecked = (btnPtr->fsState & TBSTATE_CHECKED) ? TRUE : FALSE;
2084
2085 if (LOWORD(lParam) == FALSE)
2086 btnPtr->fsState &= ~TBSTATE_CHECKED;
2087 else {
2088 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
2089 nOldIndex =
2090 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
2091 if (nOldIndex == nIndex)
2092 return 0;
2093 if (nOldIndex != -1)
2094 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
2095 }
2096 btnPtr->fsState |= TBSTATE_CHECKED;
2097 }
2098
2099 if( bChecked != LOWORD(lParam) )
2100 {
2101 hdc = GetDC (hwnd);
2102 if (nOldIndex != -1)
2103 TOOLBAR_DrawButton (hwnd, &infoPtr->buttons[nOldIndex], hdc);
2104 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2105 ReleaseDC (hwnd, hdc);
2106 }
2107
2108 /* FIXME: Send a WM_NOTIFY?? */
2109
2110 return TRUE;
2111}
2112
2113
2114static LRESULT
2115TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
2116{
2117 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2118
2119 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2120}
2121
2122static LRESULT
2123TOOLBAR_Customize (HWND hwnd)
2124{
2125 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2126 LRESULT ret;
2127 LPCVOID temp;
2128 HRSRC hRes;
2129
2130 if (infoPtr->nNumButtons == 0) return 0;
2131
2132 /* send TBN_BEGINADJUST notification */
2133 sendNotify(hwnd,TBN_BEGINADJUST);
2134
2135 if (!(hRes = FindResourceA (COMCTL32_hModule,
2136 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
2137 RT_DIALOGA)))
2138 return FALSE;
2139
2140 if(!(temp = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
2141 return FALSE;
2142
2143 ret = DialogBoxIndirectParamA (GetWindowLongA (hwnd, GWL_HINSTANCE),
2144 (LPDLGTEMPLATEA)temp,
2145 hwnd,
2146 (DLGPROC)TOOLBAR_CustomizeDialogProc,
2147 (LPARAM)infoPtr);
2148
2149 /* send TBN_ENDADJUST notification */
2150 sendNotify(hwnd,TBN_ENDADJUST);
2151
2152 return ret;
2153}
2154
2155
2156static LRESULT
2157TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2158{
2159 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2160 INT nIndex = (INT)wParam;
2161
2162 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2163 return FALSE;
2164
2165 if ((infoPtr->hwndToolTip) &&
2166 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
2167 TTTOOLINFOA ti;
2168
2169 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2170 ti.cbSize = sizeof (TTTOOLINFOA);
2171 ti.hwnd = hwnd;
2172 ti.uId = infoPtr->buttons[nIndex].idCommand;
2173
2174 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
2175 }
2176
2177 COMCTL32_Free(infoPtr->buttons[nIndex].pszName);
2178
2179 if (infoPtr->nNumButtons == 1)
2180 {
2181// TRACE (toolbar, " simple delete!\n");
2182 COMCTL32_Free (infoPtr->buttons);
2183 infoPtr->buttons = NULL;
2184 infoPtr->nNumButtons = 0;
2185 } else
2186 {
2187 TBUTTON_INFO *oldButtons = infoPtr->buttons;
2188// TRACE(toolbar, "complex delete! [nIndex=%d]\n", nIndex);
2189
2190 infoPtr->nNumButtons--;
2191 infoPtr->buttons = (TBUTTON_INFO*)COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2192 if (nIndex > 0) {
2193 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2194 nIndex * sizeof(TBUTTON_INFO));
2195 }
2196
2197 if (nIndex < infoPtr->nNumButtons) {
2198 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
2199 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
2200 }
2201
2202 COMCTL32_Free (oldButtons);
2203 }
2204
2205 TOOLBAR_CalcToolbar (hwnd);
2206
2207 InvalidateRect (hwnd, NULL, TRUE);
2208
2209 return TRUE;
2210}
2211
2212
2213static LRESULT
2214TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2215{
2216 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2217 TBUTTON_INFO *btnPtr;
2218 HDC hdc;
2219 INT nIndex;
2220 BOOL bEnabled = FALSE;
2221
2222 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2223 if (nIndex == -1)
2224 return FALSE;
2225
2226 btnPtr = &infoPtr->buttons[nIndex];
2227 bEnabled = (btnPtr->fsState & TBSTATE_ENABLED )? TRUE : FALSE ;
2228
2229 if (LOWORD(lParam) == FALSE)
2230 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
2231 else
2232 btnPtr->fsState |= TBSTATE_ENABLED;
2233
2234 if( bEnabled != LOWORD(lParam) )
2235 {
2236 hdc = GetDC (hwnd);
2237 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2238 ReleaseDC (hwnd, hdc);
2239 }
2240
2241 return TRUE;
2242}
2243
2244
2245static LRESULT
2246TOOLBAR_GetAnchorHighlight (HWND hwnd)
2247{
2248 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2249
2250 return infoPtr->bAnchor;
2251}
2252
2253
2254static LRESULT
2255TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
2256{
2257 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2258 INT nIndex;
2259
2260 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2261 if (nIndex == -1)
2262 return -1;
2263
2264 return infoPtr->buttons[nIndex].iBitmap;
2265}
2266
2267
2268static LRESULT
2269TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
2270{
2271 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
2272}
2273
2274
2275static LRESULT
2276TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2277{
2278 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2279 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2280 INT nIndex = (INT)wParam;
2281 TBUTTON_INFO *btnPtr;
2282
2283 if (infoPtr == NULL)
2284 return FALSE;
2285
2286 if (lpTbb == NULL)
2287 return FALSE;
2288
2289 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2290 return FALSE;
2291
2292 btnPtr = &infoPtr->buttons[nIndex];
2293 lpTbb->iBitmap = btnPtr->iBitmap;
2294 lpTbb->idCommand = btnPtr->idCommand;
2295 lpTbb->fsState = btnPtr->fsState;
2296 lpTbb->fsStyle = btnPtr->fsStyle;
2297 lpTbb->dwData = btnPtr->dwData;
2298 lpTbb->iString = btnPtr->iString;
2299
2300 return TRUE;
2301}
2302
2303
2304static LRESULT
2305TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2306{
2307 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2308 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
2309 TBUTTON_INFO *btnPtr;
2310 INT nIndex;
2311
2312 if (infoPtr == NULL)
2313 return -1;
2314 if (lpTbInfo == NULL)
2315 return -1;
2316 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOA))
2317 return -1;
2318
2319 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2320 if (nIndex == -1)
2321 return -1;
2322
2323 btnPtr = &infoPtr->buttons[nIndex];
2324
2325 if (lpTbInfo->dwMask & TBIF_COMMAND)
2326 lpTbInfo->idCommand = btnPtr->idCommand;
2327 if (lpTbInfo->dwMask & TBIF_IMAGE)
2328 lpTbInfo->iImage = btnPtr->iBitmap;
2329 if (lpTbInfo->dwMask & TBIF_LPARAM)
2330 lpTbInfo->lParam = btnPtr->dwData;
2331 if (lpTbInfo->dwMask & TBIF_SIZE)
2332 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
2333 if (lpTbInfo->dwMask & TBIF_STATE)
2334 lpTbInfo->fsState = btnPtr->fsState;
2335 if (lpTbInfo->dwMask & TBIF_STYLE)
2336 lpTbInfo->fsStyle = btnPtr->fsStyle;
2337 if (lpTbInfo->dwMask & TBIF_TEXT) {
2338 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
2339 lstrcpynWtoA (lpTbInfo->pszText,
2340 infoPtr->strings[btnPtr->iString],
2341 lpTbInfo->cchText);
2342 }
2343
2344 return nIndex;
2345}
2346
2347static LRESULT TOOLBAR_GetButtonInfoW(HWND hwnd,WPARAM wParam,LPARAM lParam)
2348{
2349 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2350 LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
2351 TBUTTON_INFO *btnPtr;
2352 INT nIndex;
2353
2354 if (infoPtr == NULL)
2355 return -1;
2356 if (lpTbInfo == NULL)
2357 return -1;
2358 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
2359 return -1;
2360
2361 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2362 if (nIndex == -1)
2363 return -1;
2364
2365 btnPtr = &infoPtr->buttons[nIndex];
2366
2367 if (lpTbInfo->dwMask & TBIF_COMMAND)
2368 lpTbInfo->idCommand = btnPtr->idCommand;
2369 if (lpTbInfo->dwMask & TBIF_IMAGE)
2370 lpTbInfo->iImage = btnPtr->iBitmap;
2371 if (lpTbInfo->dwMask & TBIF_LPARAM)
2372 lpTbInfo->lParam = btnPtr->dwData;
2373 if (lpTbInfo->dwMask & TBIF_SIZE)
2374 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
2375 if (lpTbInfo->dwMask & TBIF_STATE)
2376 lpTbInfo->fsState = btnPtr->fsState;
2377 if (lpTbInfo->dwMask & TBIF_STYLE)
2378 lpTbInfo->fsStyle = btnPtr->fsStyle;
2379 if (lpTbInfo->dwMask & TBIF_TEXT) {
2380 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
2381 lstrcpynW (lpTbInfo->pszText,
2382 infoPtr->strings[btnPtr->iString],
2383 lpTbInfo->cchText);
2384 }
2385
2386 return nIndex;
2387}
2388
2389
2390static LRESULT
2391TOOLBAR_GetButtonSize (HWND hwnd)
2392{
2393 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2394
2395 return MAKELONG((WORD)infoPtr->nButtonWidth,
2396 (WORD)infoPtr->nButtonHeight);
2397}
2398
2399
2400static LRESULT
2401TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2402{
2403 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2404 INT nIndex, nStringIndex;
2405
2406 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2407 if (nIndex == -1)
2408 return -1;
2409
2410 nStringIndex = infoPtr->buttons[nIndex].iString;
2411
2412// TRACE (toolbar, "index=%d stringIndex=%d\n", nIndex, nStringIndex);
2413
2414 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2415 return -1;
2416
2417 if (lParam == 0) return -1;
2418
2419 lstrcpyWtoA ((LPSTR)lParam, infoPtr->strings[nStringIndex]);
2420
2421 return lstrlenW (infoPtr->strings[nStringIndex]);
2422}
2423
2424static LRESULT TOOLBAR_GetButtonTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2425{
2426 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2427 INT nIndex, nStringIndex;
2428
2429 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2430 if (nIndex == -1)
2431 return -1;
2432
2433 nStringIndex = infoPtr->buttons[nIndex].iString;
2434
2435// TRACE (toolbar, "index=%d stringIndex=%d\n", nIndex, nStringIndex);
2436
2437 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
2438 return -1;
2439
2440 if (lParam == 0) return -1;
2441
2442 lstrcpyW ((LPWSTR)lParam, infoPtr->strings[nStringIndex]);
2443
2444 return lstrlenW (infoPtr->strings[nStringIndex]);
2445}
2446
2447/* << TOOLBAR_GetButtonText32W >> */
2448/* << TOOLBAR_GetColorScheme >> */
2449
2450
2451static LRESULT
2452TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2453{
2454 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2455
2456 return (LRESULT)infoPtr->himlDis;
2457}
2458
2459
2460static LRESULT
2461TOOLBAR_GetExtendedStyle (HWND hwnd)
2462{
2463 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2464
2465 return infoPtr->dwExStyle;
2466}
2467
2468
2469static LRESULT
2470TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2471{
2472 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2473
2474 return (LRESULT)infoPtr->himlHot;
2475}
2476
2477
2478static LRESULT
2479TOOLBAR_GetHotItem (HWND hwnd)
2480{
2481 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2482
2483 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2484 return -1;
2485
2486 if (infoPtr->nHotItem < 0)
2487 return -1;
2488
2489 return (LRESULT)infoPtr->nHotItem;
2490}
2491
2492
2493static LRESULT
2494TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2495{
2496 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2497
2498 return (LRESULT)infoPtr->himlDef;
2499}
2500
2501
2502/* << TOOLBAR_GetInsertMark >> */
2503/* << TOOLBAR_GetInsertMarkColor >> */
2504
2505
2506static LRESULT
2507TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2508{
2509 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2510 TBUTTON_INFO *btnPtr;
2511 LPRECT lpRect;
2512 INT nIndex;
2513
2514 if (infoPtr == NULL)
2515 return FALSE;
2516 nIndex = (INT)wParam;
2517 btnPtr = &infoPtr->buttons[nIndex];
2518 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2519 return FALSE;
2520 lpRect = (LPRECT)lParam;
2521 if (lpRect == NULL)
2522 return FALSE;
2523 if (btnPtr->fsState & TBSTATE_HIDDEN)
2524 return FALSE;
2525
2526 TOOLBAR_CalcToolbar( hwnd );
2527
2528 lpRect->left = btnPtr->rect.left;
2529 lpRect->right = btnPtr->rect.right;
2530 lpRect->bottom = btnPtr->rect.bottom;
2531 lpRect->top = btnPtr->rect.top;
2532
2533 return TRUE;
2534}
2535
2536
2537static LRESULT
2538TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2539{
2540 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2541 LPSIZE lpSize = (LPSIZE)lParam;
2542
2543 if (lpSize == NULL)
2544 return FALSE;
2545
2546 lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
2547 lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
2548
2549// TRACE (toolbar, "maximum size %d x %d\n",
2550// infoPtr->rcBound.right - infoPtr->rcBound.left,
2551// infoPtr->rcBound.bottom - infoPtr->rcBound.top);
2552
2553 return TRUE;
2554}
2555
2556
2557/* << TOOLBAR_GetObject >> */
2558/* << TOOLBAR_GetPadding >> */
2559
2560
2561static LRESULT
2562TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2563{
2564 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2565 TBUTTON_INFO *btnPtr;
2566 LPRECT lpRect;
2567 INT nIndex;
2568
2569 if (infoPtr == NULL)
2570 return FALSE;
2571 nIndex = (INT)wParam;
2572 btnPtr = &infoPtr->buttons[nIndex];
2573 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2574 return FALSE;
2575 lpRect = (LPRECT)lParam;
2576 if (lpRect == NULL)
2577 return FALSE;
2578
2579 lpRect->left = btnPtr->rect.left;
2580 lpRect->right = btnPtr->rect.right;
2581 lpRect->bottom = btnPtr->rect.bottom;
2582 lpRect->top = btnPtr->rect.top;
2583
2584 return TRUE;
2585}
2586
2587
2588static LRESULT
2589TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2590{
2591 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2592
2593 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
2594 return infoPtr->nRows;
2595 else
2596 return 1;
2597}
2598
2599
2600static LRESULT
2601TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2602{
2603 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2604 INT nIndex;
2605
2606 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2607 if (nIndex == -1)
2608 return -1;
2609
2610 return infoPtr->buttons[nIndex].fsState;
2611}
2612
2613
2614static LRESULT
2615TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2616{
2617 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2618 INT nIndex;
2619
2620 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2621 if (nIndex == -1)
2622 return -1;
2623
2624 return infoPtr->buttons[nIndex].fsStyle;
2625}
2626
2627
2628static LRESULT
2629TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2630{
2631 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2632
2633 if (infoPtr == NULL)
2634 return 0;
2635
2636 return infoPtr->nMaxTextRows;
2637}
2638
2639
2640static LRESULT
2641TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
2642{
2643 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2644
2645 if (infoPtr == NULL) return 0;
2646 return infoPtr->hwndToolTip;
2647}
2648
2649
2650static LRESULT
2651TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2652{
2653 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2654 TBUTTON_INFO *btnPtr;
2655 INT nIndex;
2656
2657 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2658 if (nIndex == -1)
2659 return FALSE;
2660
2661 btnPtr = &infoPtr->buttons[nIndex];
2662 if (LOWORD(lParam) == FALSE)
2663 btnPtr->fsState &= ~TBSTATE_HIDDEN;
2664 else
2665 btnPtr->fsState |= TBSTATE_HIDDEN;
2666
2667 TOOLBAR_CalcToolbar (hwnd);
2668
2669 InvalidateRect (hwnd, NULL, TRUE);
2670
2671 return TRUE;
2672}
2673
2674
2675static LRESULT
2676TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2677{
2678 return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
2679}
2680
2681
2682static LRESULT
2683TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2684{
2685 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2686 TBUTTON_INFO *btnPtr;
2687 HDC hdc;
2688 INT nIndex;
2689
2690 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2691 if (nIndex == -1)
2692 return FALSE;
2693
2694 btnPtr = &infoPtr->buttons[nIndex];
2695 if (LOWORD(lParam) == FALSE)
2696 btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
2697 else
2698 btnPtr->fsState |= TBSTATE_INDETERMINATE;
2699
2700 hdc = GetDC (hwnd);
2701 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2702 ReleaseDC (hwnd, hdc);
2703
2704 return TRUE;
2705}
2706
2707
2708static LRESULT
2709TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2710{
2711 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2712 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
2713 INT nIndex = (INT)wParam;
2714 TBUTTON_INFO *oldButtons;
2715
2716 if (lpTbb == NULL)
2717 return FALSE;
2718
2719 if (nIndex == -1) {
2720 /* EPP: this seems to be an undocumented call (from my IE4)
2721 * I assume in that case that:
2722 * - lpTbb->iString is a string pointer (not a string index in strings[] table
2723 * - index of insertion is at the end of existing buttons
2724 * I only see this happen with nIndex == -1, but it could have a special
2725 * meaning (like -nIndex (or ~nIndex) to get the real position of insertion).
2726 */
2727 int len = lstrlenA((char*)lpTbb->iString) + 2;
2728 LPSTR ptr = (LPSTR)COMCTL32_Alloc(len);
2729
2730 nIndex = infoPtr->nNumButtons;
2731 strcpy(ptr, (char*)lpTbb->iString);
2732 ptr[len - 1] = 0; /* ended by two '\0' */
2733 lpTbb->iString = TOOLBAR_AddStringA(hwnd, 0, (LPARAM)ptr);
2734 COMCTL32_Free(ptr);
2735
2736 } else if (nIndex < 0)
2737 return FALSE;
2738
2739
2740// TRACE (toolbar, "inserting button index=%d\n", nIndex);
2741 if (nIndex > infoPtr->nNumButtons) {
2742 nIndex = infoPtr->nNumButtons;
2743// TRACE (toolbar, "adjust index=%d\n", nIndex);
2744 }
2745
2746 oldButtons = infoPtr->buttons;
2747 infoPtr->nNumButtons++;
2748 infoPtr->buttons = (TBUTTON_INFO*)COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
2749 /* pre insert copy */
2750 if (nIndex > 0) {
2751 memcpy (&infoPtr->buttons[0], &oldButtons[0],
2752 nIndex * sizeof(TBUTTON_INFO));
2753 }
2754
2755 /* insert new button */
2756 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
2757 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
2758 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
2759 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
2760 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
2761 infoPtr->buttons[nIndex].iString = lpTbb->iString;
2762
2763 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
2764 TTTOOLINFOA ti;
2765
2766 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
2767 ti.cbSize = sizeof (TTTOOLINFOA);
2768 ti.hwnd = hwnd;
2769 ti.uId = lpTbb->idCommand;
2770 ti.hinst = 0;
2771 ti.lpszText = LPSTR_TEXTCALLBACKA;
2772
2773 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
2774 0, (LPARAM)&ti);
2775 }
2776
2777 /* post insert copy */
2778 if (nIndex < infoPtr->nNumButtons - 1) {
2779 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
2780 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
2781 }
2782
2783 COMCTL32_Free (oldButtons);
2784
2785 TOOLBAR_CalcToolbar (hwnd);
2786
2787 InvalidateRect (hwnd, NULL, FALSE);
2788
2789 return TRUE;
2790}
2791
2792static LRESULT TOOLBAR_InsertButtonW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2793{
2794 //CB: just call InsertButtonA, no Unicode used?!?
2795
2796 return TOOLBAR_InsertButtonA(hwnd,wParam,lParam);
2797}
2798
2799/* << TOOLBAR_InsertMarkHitTest >> */
2800
2801
2802static LRESULT
2803TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
2804{
2805 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2806 INT nIndex;
2807
2808 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2809 if (nIndex == -1)
2810 return FALSE;
2811
2812 return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
2813}
2814
2815
2816static LRESULT
2817TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
2818{
2819 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2820 INT nIndex;
2821
2822 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2823 if (nIndex == -1)
2824 return FALSE;
2825
2826 return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
2827}
2828
2829
2830static LRESULT
2831TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
2832{
2833 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2834 INT nIndex;
2835
2836 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2837 if (nIndex == -1)
2838 return FALSE;
2839
2840 return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
2841}
2842
2843
2844static LRESULT
2845TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
2846{
2847 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2848 INT nIndex;
2849
2850 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2851 if (nIndex == -1)
2852 return FALSE;
2853
2854 return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
2855}
2856
2857
2858static LRESULT
2859TOOLBAR_IsButtonIndeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2860{
2861 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2862 INT nIndex;
2863
2864 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2865 if (nIndex == -1)
2866 return FALSE;
2867
2868 return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
2869}
2870
2871
2872static LRESULT
2873TOOLBAR_IsButtonPressed (HWND hwnd, WPARAM wParam, LPARAM lParam)
2874{
2875 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2876 INT nIndex;
2877
2878 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2879 if (nIndex == -1)
2880 return FALSE;
2881
2882 return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
2883}
2884
2885
2886/* << TOOLBAR_LoadImages >> */
2887/* << TOOLBAR_MapAccelerator >> */
2888/* << TOOLBAR_MarkButton >> */
2889/* << TOOLBAR_MoveButton >> */
2890
2891
2892static LRESULT
2893TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2894{
2895 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2896 TBUTTON_INFO *btnPtr;
2897 HDC hdc;
2898 INT nIndex;
2899
2900 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2901 if (nIndex == -1)
2902 return FALSE;
2903
2904 btnPtr = &infoPtr->buttons[nIndex];
2905 if (LOWORD(lParam) == FALSE)
2906 btnPtr->fsState &= ~TBSTATE_PRESSED;
2907 else
2908 btnPtr->fsState |= TBSTATE_PRESSED;
2909
2910 hdc = GetDC (hwnd);
2911 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2912 ReleaseDC (hwnd, hdc);
2913
2914 return TRUE;
2915}
2916
2917
2918/* << TOOLBAR_ReplaceBitmap >> */
2919
2920
2921static LRESULT
2922TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2923{
2924#if 0
2925 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2926 LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
2927
2928 if (lpSave == NULL) return 0;
2929
2930 if ((BOOL)wParam) {
2931 /* save toolbar information */
2932// FIXME (toolbar, "save to \"%s\" \"%s\"\n",
2933// lpSave->pszSubKey, lpSave->pszValueName);
2934
2935
2936 }
2937 else {
2938 /* restore toolbar information */
2939
2940// FIXME (toolbar, "restore from \"%s\" \"%s\"\n",
2941// lpSave->pszSubKey, lpSave->pszValueName);
2942
2943
2944 }
2945#endif
2946
2947 return 0;
2948}
2949
2950static LRESULT TOOLBAR_SaveRestoreW(HWND hwnd,WPARAM wParam,LPARAM lParam)
2951{
2952#if 0
2953 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2954 LPTBSAVEPARAMSW lpSave = (LPTBSAVEPARAMSW)lParam;
2955
2956 if (lpSave == NULL) return 0;
2957
2958 if ((BOOL)wParam) {
2959 /* save toolbar information */
2960// FIXME (toolbar, "save to \"%s\" \"%s\"\n",
2961// lpSave->pszSubKey, lpSave->pszValueName);
2962
2963
2964 }
2965 else {
2966 /* restore toolbar information */
2967
2968// FIXME (toolbar, "restore from \"%s\" \"%s\"\n",
2969// lpSave->pszSubKey, lpSave->pszValueName);
2970
2971
2972 }
2973#endif
2974
2975 return 0;
2976}
2977
2978/* << TOOLBAR_SaveRestore32W >> */
2979
2980static LRESULT
2981TOOLBAR_SetAnchorHighlight (HWND hwnd, WPARAM wParam)
2982{
2983 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2984 BOOL bOldAnchor = infoPtr->bAnchor;
2985
2986 infoPtr->bAnchor = (BOOL)wParam;
2987
2988 return (LRESULT)bOldAnchor;
2989}
2990
2991
2992static LRESULT
2993TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2994{
2995 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2996
2997 if (((INT)LOWORD(lParam) <= 0) || ((INT)HIWORD(lParam) <= 0)) return FALSE;
2998
2999//SvL: Old code causes assertion failures in MFC apps; this is from the latest
3000// Wine sources
3001#if 1
3002 if (infoPtr->nNumButtons > 0)
3003 dprintf(("TOOLBAR_SetBitmapSize: %d buttons, undoc increase to bitmap size : %d-%d -> %d-%d\n",
3004 infoPtr->nNumButtons,
3005 infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
3006 LOWORD(lParam), HIWORD(lParam)));
3007#else
3008 /* Bitmap size can only be set before adding any button to the toolbar
3009 according to the documentation. */
3010 if( infoPtr->nNumButtons != 0 )
3011 return FALSE;
3012#endif
3013
3014 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
3015 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
3016
3017 return TRUE;
3018}
3019
3020
3021static LRESULT
3022TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
3023{
3024 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3025 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
3026 TBUTTON_INFO *btnPtr;
3027 INT nIndex;
3028
3029 if (lptbbi == NULL)
3030 return FALSE;
3031 if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
3032 return FALSE;
3033
3034 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3035 if (nIndex == -1)
3036 return FALSE;
3037
3038 btnPtr = &infoPtr->buttons[nIndex];
3039 if (lptbbi->dwMask & TBIF_COMMAND)
3040 btnPtr->idCommand = lptbbi->idCommand;
3041 if (lptbbi->dwMask & TBIF_IMAGE)
3042 btnPtr->iBitmap = lptbbi->iImage;
3043 if (lptbbi->dwMask & TBIF_LPARAM)
3044 btnPtr->dwData = lptbbi->lParam;
3045/* if (lptbbi->dwMask & TBIF_SIZE) */
3046/* btnPtr->cx = lptbbi->cx; */
3047 if (lptbbi->dwMask & TBIF_STATE)
3048 btnPtr->fsState = lptbbi->fsState;
3049 if (lptbbi->dwMask & TBIF_STYLE)
3050 btnPtr->fsStyle = lptbbi->fsStyle;
3051
3052 if (lptbbi->dwMask & TBIF_TEXT) {
3053 if ((btnPtr->iString >= 0) ||
3054 (btnPtr->iString < infoPtr->nNumStrings)) {
3055#if 0
3056 CHAR **lpString = &infoPtr->strings[btnPtr->iString]; //wrong, it's Unicode!!!
3057 INT len = lstrlenA (lptbbi->pszText);
3058 *lpString = COMCTL32_ReAlloc (lpString, sizeof(char)*(len+1));
3059#endif
3060
3061 /* this is the ultimate sollution */
3062/* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3063 }
3064 }
3065
3066 return TRUE;
3067}
3068
3069static LRESULT TOOLBAR_SetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
3070{
3071 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3072 LPTBBUTTONINFOW lptbbi = (LPTBBUTTONINFOW)lParam;
3073 TBUTTON_INFO *btnPtr;
3074 INT nIndex;
3075
3076 if (lptbbi == NULL)
3077 return FALSE;
3078 if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
3079 return FALSE;
3080
3081 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3082 if (nIndex == -1)
3083 return FALSE;
3084
3085 btnPtr = &infoPtr->buttons[nIndex];
3086 if (lptbbi->dwMask & TBIF_COMMAND)
3087 btnPtr->idCommand = lptbbi->idCommand;
3088 if (lptbbi->dwMask & TBIF_IMAGE)
3089 btnPtr->iBitmap = lptbbi->iImage;
3090 if (lptbbi->dwMask & TBIF_LPARAM)
3091 btnPtr->dwData = lptbbi->lParam;
3092/* if (lptbbi->dwMask & TBIF_SIZE) */
3093/* btnPtr->cx = lptbbi->cx; */
3094 if (lptbbi->dwMask & TBIF_STATE)
3095 btnPtr->fsState = lptbbi->fsState;
3096 if (lptbbi->dwMask & TBIF_STYLE)
3097 btnPtr->fsStyle = lptbbi->fsStyle;
3098
3099 if (lptbbi->dwMask & TBIF_TEXT) {
3100 if ((btnPtr->iString >= 0) ||
3101 (btnPtr->iString < infoPtr->nNumStrings)) {
3102#if 0
3103 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
3104 INT len = lstrlenW (lptbbi->pszText);
3105 *lpString = COMCTL32_ReAlloc (lpString, sizeof(wchar)*(len+1));
3106#endif
3107
3108 /* this is the ultimate sollution */
3109/* Str_SetPtrW (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3110 }
3111 }
3112
3113 return TRUE;
3114}
3115
3116static LRESULT
3117TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3118{
3119 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3120
3121 if (((INT)LOWORD(lParam) <= 0) || ((INT)HIWORD(lParam) <= 0)) return FALSE;
3122
3123#if 1
3124 //SvL: Same for MFC apps (assertion failed when returning FALSE
3125 /* Button size can only be set before adding any button to the toolbar
3126 according to the documentation. */
3127 /* this appears to be wrong. WINZIP32.EXE (ver 8) calls this on
3128 one of its buttons after adding it to the toolbar, and it
3129 checks that the return value is nonzero - mjm */
3130 if( infoPtr->nNumButtons != 0 )
3131 {
3132 dprintf(("TOOLBAR_SetButtonSize: Button size set after button in toolbar\n"));
3133 return TRUE;
3134 }
3135#else
3136 /* Button size can only be set before adding any button to the toolbar
3137 according to the documentation. */
3138 if( infoPtr->nNumButtons != 0 )
3139 return FALSE;
3140#endif
3141
3142 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
3143 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
3144
3145 return TRUE;
3146}
3147
3148
3149static LRESULT
3150TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
3151{
3152 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3153
3154 if (infoPtr == NULL)
3155 return FALSE;
3156
3157 infoPtr->cxMin = (INT)LOWORD(lParam);
3158 infoPtr->cxMax = (INT)HIWORD(lParam);
3159
3160 return TRUE;
3161}
3162
3163
3164static LRESULT
3165TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
3166{
3167 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3168 INT nIndex = (INT)wParam;
3169
3170 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
3171 return FALSE;
3172
3173 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
3174
3175 if (infoPtr->hwndToolTip) {
3176
3177// FIXME (toolbar, "change tool tip!\n");
3178
3179 }
3180
3181 return TRUE;
3182}
3183
3184
3185/* << TOOLBAR_SetColorScheme >> */
3186
3187
3188static LRESULT
3189TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3190{
3191 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3192 HIMAGELIST himlTemp;
3193
3194 himlTemp = infoPtr->himlDis;
3195 infoPtr->himlDis = (HIMAGELIST)lParam;
3196
3197 /* FIXME: redraw ? */
3198
3199 return (LRESULT)himlTemp;
3200}
3201
3202
3203static LRESULT
3204TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
3205{
3206 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3207 DWORD dwTemp;
3208
3209 dwTemp = infoPtr->dwDTFlags;
3210 infoPtr->dwDTFlags =
3211 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
3212
3213 return (LRESULT)dwTemp;
3214}
3215
3216
3217static LRESULT
3218TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3219{
3220 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3221 DWORD dwTemp;
3222
3223 dwTemp = infoPtr->dwExStyle;
3224 infoPtr->dwExStyle = (DWORD)lParam;
3225
3226 return (LRESULT)dwTemp;
3227}
3228
3229
3230static LRESULT
3231TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3232{
3233 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3234 HIMAGELIST himlTemp;
3235
3236 himlTemp = infoPtr->himlHot;
3237 infoPtr->himlHot = (HIMAGELIST)lParam;
3238
3239 /* FIXME: redraw ? */
3240
3241 return (LRESULT)himlTemp;
3242}
3243
3244
3245static LRESULT
3246TOOLBAR_SetHotItem (HWND hwnd, WPARAM wParam)
3247{
3248 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3249 INT nOldHotItem = infoPtr->nHotItem;
3250
3251 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
3252 {
3253 infoPtr->nHotItem = (INT)wParam;
3254
3255 /* FIXME: What else must be done ??? */
3256
3257 }
3258
3259 if (nOldHotItem < 0)
3260 return -1;
3261
3262 return (LRESULT)nOldHotItem;
3263}
3264
3265
3266static LRESULT
3267TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3268{
3269 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3270 HIMAGELIST himlTemp;
3271
3272 himlTemp = infoPtr->himlDef;
3273 infoPtr->himlDef = (HIMAGELIST)lParam;
3274
3275 /* FIXME: redraw ? */
3276
3277 return (LRESULT)himlTemp;
3278}
3279
3280
3281static LRESULT
3282TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3283{
3284 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3285
3286 infoPtr->nIndent = (INT)wParam;
3287
3288 TOOLBAR_CalcToolbar (hwnd);
3289
3290 InvalidateRect(hwnd, NULL, FALSE);
3291
3292 return TRUE;
3293}
3294
3295
3296/* << TOOLBAR_SetInsertMark >> */
3297
3298
3299static LRESULT
3300TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
3301{
3302 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3303
3304 infoPtr->clrInsertMark = (COLORREF)lParam;
3305
3306 /* FIXME : redraw ??*/
3307
3308 return 0;
3309}
3310
3311
3312static LRESULT
3313TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3314{
3315 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3316
3317 if (infoPtr == NULL)
3318 return FALSE;
3319
3320 infoPtr->nMaxTextRows = (INT)wParam;
3321
3322 return TRUE;
3323}
3324
3325
3326/* << TOOLBAR_SetPadding >> */
3327
3328
3329static LRESULT
3330TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3331{
3332 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3333 HWND hwndOldNotify;
3334
3335 if (infoPtr == NULL)
3336 return 0;
3337 hwndOldNotify = infoPtr->header.hwndNotify;
3338 infoPtr->header.hwndNotify = (HWND)wParam;
3339
3340 return hwndOldNotify;
3341}
3342
3343
3344static LRESULT
3345TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3346{
3347 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3348 LPRECT lprc = (LPRECT)lParam;
3349
3350 if (LOWORD(wParam) > 1) {
3351
3352// FIXME (toolbar, "multiple rows not supported!\n");
3353
3354 }
3355
3356 /* recalculate toolbar */
3357 TOOLBAR_CalcToolbar (hwnd);
3358
3359 /* return bounding rectangle */
3360 if (lprc) {
3361 lprc->left = infoPtr->rcBound.left;
3362 lprc->right = infoPtr->rcBound.right;
3363 lprc->top = infoPtr->rcBound.top;
3364 lprc->bottom = infoPtr->rcBound.bottom;
3365 }
3366
3367 /* repaint toolbar */
3368 InvalidateRect(hwnd, NULL, FALSE);
3369
3370 return 0;
3371}
3372
3373
3374static LRESULT
3375TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
3376{
3377 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3378 TBUTTON_INFO *btnPtr;
3379 HDC hdc;
3380 INT nIndex;
3381
3382 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3383 if (nIndex == -1)
3384 return FALSE;
3385
3386 btnPtr = &infoPtr->buttons[nIndex];
3387 btnPtr->fsState = LOWORD(lParam);
3388
3389 hdc = GetDC (hwnd);
3390 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3391 ReleaseDC (hwnd, hdc);
3392
3393 return TRUE;
3394}
3395
3396
3397static LRESULT
3398TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3399{
3400 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3401 TBUTTON_INFO *btnPtr;
3402 HDC hdc;
3403 INT nIndex;
3404
3405 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3406 if (nIndex == -1)
3407 return FALSE;
3408
3409 btnPtr = &infoPtr->buttons[nIndex];
3410 btnPtr->fsStyle = LOWORD(lParam);
3411
3412 hdc = GetDC (hwnd);
3413 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3414 ReleaseDC (hwnd, hdc);
3415
3416 if (infoPtr->hwndToolTip) {
3417
3418// FIXME (toolbar, "change tool tip!\n");
3419
3420 }
3421
3422 return TRUE;
3423}
3424
3425
3426static LRESULT
3427TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
3428{
3429 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3430
3431 if (infoPtr == NULL)
3432 return 0;
3433 infoPtr->hwndToolTip = (HWND)wParam;
3434 return 0;
3435}
3436
3437static LRESULT
3438TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
3439{
3440 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3441 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3442 LOGFONTA logFont;
3443
3444 /* initialize info structure */
3445 infoPtr->nButtonHeight = 22;
3446 infoPtr->nButtonWidth = 24;
3447 infoPtr->nBitmapHeight = 15;
3448 infoPtr->nBitmapWidth = 16;
3449
3450 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
3451 infoPtr->nRows = 1;
3452 infoPtr->nMaxTextRows = 1;
3453 infoPtr->cxMin = -1;
3454 infoPtr->cxMax = -1;
3455
3456 infoPtr->bCaptured = FALSE;
3457 infoPtr->nButtonDown = -1;
3458 infoPtr->nOldHit = -1;
3459 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3460 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
3461 infoPtr->dwDTFlags = (dwStyle & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE : DT_CENTER;
3462 infoPtr->bAnchor = FALSE; /* no anchor highlighting */
3463
3464 infoPtr->hwndToolbar = hwnd;
3465 infoPtr->oldButtons = NULL;
3466 infoPtr->nNumOldButtons = 0;
3467
3468 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
3469 infoPtr->hFont = CreateFontIndirectA (&logFont);
3470
3471 /* Create tooltip control */
3472 if (dwStyle & TBSTYLE_TOOLTIPS)
3473 infoPtr->hwndToolTip = createToolTip(hwnd,0,FALSE);
3474
3475 return 0;
3476}
3477
3478
3479static LRESULT
3480TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
3481{
3482 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3483
3484 /* delete button data */
3485 if (infoPtr->buttons)
3486 {
3487 INT x;
3488
3489 //SvL: Check pointers
3490 for (x = 0;x < infoPtr->nNumButtons;x++)
3491 if(infoPtr->buttons[x].pszName)
3492 COMCTL32_Free(infoPtr->buttons[x].pszName);
3493
3494 COMCTL32_Free(infoPtr->buttons);
3495 }
3496
3497 /* delete strings */
3498 if (infoPtr->strings) {
3499 INT i;
3500 for (i = 0; i < infoPtr->nNumStrings; i++)
3501 if (infoPtr->strings[i])
3502 COMCTL32_Free (infoPtr->strings[i]);
3503
3504 COMCTL32_Free (infoPtr->strings);
3505 }
3506
3507 /* destroy internal image list */
3508 if (infoPtr->himlInt)
3509 ImageList_Destroy (infoPtr->himlInt);
3510
3511 /* delete default font */
3512 if (infoPtr->hFont)
3513 DeleteObject (infoPtr->hFont);
3514
3515 /* free toolbar info data */
3516 doneControl(hwnd);
3517
3518 return 0;
3519}
3520
3521
3522static LRESULT
3523TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
3524{
3525 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3526
3527 //SvL: Check ptr
3528 if (infoPtr && infoPtr->bTransparent)
3529 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
3530
3531 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
3532}
3533
3534static LRESULT
3535TOOLBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
3536{
3537 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3538
3539 return infoPtr->hFont;
3540}
3541
3542static LRESULT
3543TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
3544{
3545 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3546 TBUTTON_INFO *btnPtr;
3547 POINT pt;
3548 INT nHit;
3549 HDC hdc;
3550
3551 pt.x = (INT)LOWORD(lParam);
3552 pt.y = (INT)HIWORD(lParam);
3553 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3554
3555 if (nHit >= 0) {
3556 btnPtr = &infoPtr->buttons[nHit];
3557 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3558 return 0;
3559 SetCapture (hwnd);
3560 infoPtr->bCaptured = TRUE;
3561 infoPtr->nButtonDown = nHit;
3562
3563 btnPtr->fsState |= TBSTATE_PRESSED;
3564
3565 hdc = GetDC (hwnd);
3566 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3567 ReleaseDC (hwnd, hdc);
3568 }
3569 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
3570 TOOLBAR_Customize (hwnd);
3571
3572 return 0;
3573}
3574
3575
3576static LRESULT
3577TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
3578{
3579 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3580 TBUTTON_INFO *btnPtr;
3581 POINT pt;
3582 INT nHit;
3583 HDC hdc;
3584
3585 if (infoPtr->hwndToolTip)
3586 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3587 WM_LBUTTONDOWN, wParam, lParam);
3588
3589 pt.x = (INT)LOWORD(lParam);
3590 pt.y = (INT)HIWORD(lParam);
3591 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3592
3593 if (nHit >= 0) {
3594 btnPtr = &infoPtr->buttons[nHit];
3595 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3596 return 0;
3597
3598 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN)
3599 {
3600 NMTOOLBARA nmtb;
3601
3602 nmtb.iItem = btnPtr->idCommand;
3603
3604 sendNotify(hwnd,TBN_DROPDOWN,&nmtb.hdr);
3605 }
3606
3607 SetCapture (hwnd);
3608 infoPtr->bCaptured = TRUE;
3609 infoPtr->nButtonDown = nHit;
3610 infoPtr->nOldHit = nHit;
3611
3612 btnPtr->fsState |= TBSTATE_PRESSED;
3613
3614 hdc = GetDC (hwnd);
3615 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3616 ReleaseDC (hwnd, hdc);
3617 }
3618
3619 return 0;
3620}
3621
3622
3623static LRESULT
3624TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
3625{
3626 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3627 TBUTTON_INFO *btnPtr;
3628 POINT pt;
3629 INT nHit;
3630 INT nOldIndex = -1;
3631 HDC hdc;
3632 BOOL bSendMessage = TRUE;
3633
3634 if (infoPtr->hwndToolTip)
3635 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3636 WM_LBUTTONUP, wParam, lParam);
3637
3638 pt.x = (INT)LOWORD(lParam);
3639 pt.y = (INT)HIWORD(lParam);
3640 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3641
3642 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
3643 infoPtr->bCaptured = FALSE;
3644 ReleaseCapture ();
3645 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3646 btnPtr->fsState &= ~TBSTATE_PRESSED;
3647
3648 if (nHit == infoPtr->nButtonDown) {
3649 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
3650 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
3651 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
3652 infoPtr->nButtonDown);
3653 if (nOldIndex == infoPtr->nButtonDown)
3654 bSendMessage = FALSE;
3655 if ((nOldIndex != infoPtr->nButtonDown) &&
3656 (nOldIndex != -1))
3657 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
3658 btnPtr->fsState |= TBSTATE_CHECKED;
3659 }
3660 else {
3661 if (btnPtr->fsState & TBSTATE_CHECKED)
3662 btnPtr->fsState &= ~TBSTATE_CHECKED;
3663 else
3664 btnPtr->fsState |= TBSTATE_CHECKED;
3665 }
3666 }
3667 }
3668 else
3669 bSendMessage = FALSE;
3670
3671 hdc = GetDC (hwnd);
3672 if (nOldIndex != -1)
3673 TOOLBAR_DrawButton (hwnd, &infoPtr->buttons[nOldIndex], hdc);
3674 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3675 ReleaseDC (hwnd, hdc);
3676
3677 if (bSendMessage) {
3678 SendMessageA (GetParent(hwnd), WM_COMMAND,
3679 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
3680
3681 if ((GetWindowLongA(hwnd, GWL_STYLE) & TBSTYLE_DROPDOWN) ||
3682 (btnPtr->fsStyle & 0x08/* BTNS_DROPDOWN */)) {
3683 NMTOOLBARW nmtb;
3684
3685 nmtb.iItem = nHit;
3686 /* nmtb.tbButton not used with TBN_DROPDOWN */
3687 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings)) {
3688 nmtb.pszText = infoPtr->strings[btnPtr->iString];
3689 nmtb.cchText = lstrlenW(nmtb.pszText);
3690 } else {
3691 nmtb.pszText = NULL;
3692 nmtb.cchText = 0;
3693 }
3694 nmtb.rcButton = btnPtr->rect;
3695
3696 sendNotify(hwnd,TBN_DROPDOWN,&nmtb.hdr);
3697 }
3698 }
3699
3700 infoPtr->nButtonDown = -1;
3701 infoPtr->nOldHit = -1;
3702 }
3703
3704 return 0;
3705}
3706
3707
3708static LRESULT
3709TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
3710{
3711 TBUTTON_INFO *btnPtr, *oldBtnPtr;
3712 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3713 POINT pt;
3714 INT nHit;
3715 HDC hdc;
3716 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
3717
3718 if (infoPtr->hwndToolTip)
3719 TOOLBAR_RelayEvent (infoPtr->hwndToolTip,hwnd,
3720 WM_MOUSEMOVE,wParam,lParam);
3721
3722 pt.x = (INT)LOWORD(lParam);
3723 pt.y = (INT)HIWORD(lParam);
3724
3725 nHit = TOOLBAR_InternalHitTest(hwnd,&pt);
3726
3727 if (infoPtr->nOldHit != nHit)
3728 {
3729 /* Remove the effect of an old hot button */
3730 if(infoPtr->nOldHit == infoPtr->nHotItem)
3731 {
3732 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3733 if (oldBtnPtr->bHot) //CB: dynamic buttons
3734 {
3735 oldBtnPtr->bHot = FALSE;
3736
3737 if (dwStyle & TBSTYLE_FLAT) InvalidateRect(hwnd,&oldBtnPtr->rect,TRUE);
3738 }
3739 }
3740
3741 /* It's not a separator or in nowhere. It's a hot button. */
3742 if (nHit >= 0)
3743 {
3744 btnPtr = &infoPtr->buttons[nHit];
3745 if (!btnPtr->bHot)
3746 {
3747 btnPtr->bHot = TRUE;
3748
3749 if (dwStyle & TBSTYLE_FLAT)
3750 {
3751 hdc = GetDC (hwnd);
3752 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3753 ReleaseDC (hwnd, hdc);
3754 }
3755
3756 infoPtr->nHotItem = nHit;
3757 }
3758 }
3759
3760 if (infoPtr->bCaptured)
3761 {
3762 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3763 if (infoPtr->nOldHit == infoPtr->nButtonDown)
3764 {
3765 btnPtr->fsState &= ~TBSTATE_PRESSED;
3766
3767 hdc = GetDC (hwnd);
3768 TOOLBAR_DrawButton(hwnd,btnPtr,hdc);
3769 ReleaseDC(hwnd,hdc);
3770 } else if (nHit == infoPtr->nButtonDown)
3771 {
3772 btnPtr->fsState |= TBSTATE_PRESSED;
3773
3774 hdc = GetDC(hwnd);
3775 TOOLBAR_DrawButton(hwnd,btnPtr,hdc);
3776 ReleaseDC(hwnd,hdc);
3777 }
3778 }
3779 infoPtr->nOldHit = nHit;
3780 }
3781 return 0;
3782}
3783
3784
3785static LRESULT
3786TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3787{
3788/* if (wndPtr->dwStyle & CCS_NODIVIDER) */
3789 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
3790/* else */
3791/* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
3792}
3793
3794
3795static LRESULT
3796TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3797{
3798 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
3799 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
3800
3801 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
3802}
3803
3804
3805static LRESULT
3806TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3807{
3808 TOOLBAR_INFO *infoPtr;
3809
3810 /* allocate memory for info structure */
3811 infoPtr = (TOOLBAR_INFO*)initControl(hwnd,sizeof(TOOLBAR_INFO));
3812
3813 /* paranoid!! */
3814 infoPtr->dwStructSize = sizeof(TBBUTTON);
3815
3816 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
3817 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
3818 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
3819 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
3820 }
3821
3822 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
3823}
3824
3825
3826static LRESULT
3827TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3828{
3829 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3830 RECT rcWindow;
3831 HDC hdc;
3832
3833 if (dwStyle & WS_MINIMIZE)
3834 return 0; /* Nothing to do */
3835
3836 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
3837
3838 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
3839 return 0;
3840
3841 if (!(dwStyle & CCS_NODIVIDER))
3842 {
3843 GetWindowRect (hwnd, &rcWindow);
3844 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3845 if( dwStyle & WS_BORDER )
3846 OffsetRect (&rcWindow, 1, 1);
3847 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
3848 }
3849
3850 ReleaseDC( hwnd, hdc );
3851
3852 return 0;
3853}
3854
3855
3856static LRESULT
3857TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
3858{
3859 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3860 LPNMHDR lpnmh = (LPNMHDR)lParam;
3861
3862// TRACE (toolbar, "passing WM_NOTIFY!\n");
3863
3864 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
3865 SendMessageA (infoPtr->header.hwndNotify, WM_NOTIFY, wParam, lParam);
3866
3867#if 0
3868 if (lpnmh->code == TTN_GETDISPINFOA) {
3869 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
3870
3871// FIXME (toolbar, "retrieving ASCII string\n");
3872
3873 }
3874 else if (lpnmh->code == TTN_GETDISPINFOW) {
3875 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
3876
3877// FIXME (toolbar, "retrieving UNICODE string\n");
3878
3879 }
3880#endif
3881 }
3882
3883 return 0;
3884}
3885
3886
3887static LRESULT
3888TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
3889{
3890 HDC hdc;
3891 PAINTSTRUCT ps;
3892
3893 TOOLBAR_CalcToolbar(hwnd);
3894 hdc = wParam == 0 ? BeginPaint(hwnd,&ps) : (HDC)wParam;
3895 TOOLBAR_Refresh(hwnd,hdc);
3896 if (!wParam) EndPaint (hwnd, &ps);
3897 return 0;
3898}
3899
3900
3901static LRESULT
3902TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
3903{
3904 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3905 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3906 RECT parent_rect;
3907 HWND parent;
3908 INT x = 0,y = 0,cx,cy;
3909 INT flags;
3910 UINT uPosFlags = 0;
3911
3912 /* Resize deadlock check */
3913 if (infoPtr->bAutoSize) {
3914 infoPtr->bAutoSize = FALSE;
3915 return 0;
3916 }
3917
3918 flags = (INT) wParam;
3919
3920 /* FIXME for flags =
3921 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
3922 */
3923
3924 //TRACE (toolbar, "sizing toolbar!\n");
3925
3926 if (flags == SIZE_RESTORED) {
3927 /* width and height don't apply */
3928 parent = GetParent (hwnd);
3929 GetClientRect(parent, &parent_rect);
3930 x = parent_rect.left;
3931 y = parent_rect.top;
3932
3933//SvL: Latest Wine
3934#if 1
3935 RECT window_rect;
3936 if (dwStyle & CCS_NORESIZE) {
3937 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
3938
3939 /*
3940 * this sets the working width of the toolbar, and
3941 * Calc Toolbar will not adjust it, only the height
3942 */
3943 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3944 cy = infoPtr->nHeight;
3945 cx = infoPtr->nWidth;
3946 TOOLBAR_CalcToolbar (hwnd);
3947 infoPtr->nWidth = cx;
3948 infoPtr->nHeight = cy;
3949 }
3950 else {
3951 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3952 TOOLBAR_CalcToolbar (hwnd);
3953 cy = infoPtr->nHeight;
3954 cx = infoPtr->nWidth;
3955
3956 if (dwStyle & CCS_NOMOVEY) {
3957 GetWindowRect(hwnd, &window_rect);
3958 ScreenToClient(parent, (LPPOINT)&window_rect.left);
3959 y = window_rect.top;
3960 }
3961 }
3962#else
3963 if (dwStyle & CCS_NORESIZE) {
3964 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
3965 /* FIXME */
3966/* infoPtr->nWidth = parent_rect.right - parent_rect.left; */
3967 cy = infoPtr->nHeight;
3968 cx = infoPtr->nWidth;
3969 TOOLBAR_CalcToolbar (hwnd);
3970 infoPtr->nWidth = cx;
3971 infoPtr->nHeight = cy;
3972 }
3973 else {
3974 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3975 TOOLBAR_CalcToolbar (hwnd);
3976 cy = infoPtr->nHeight;
3977 cx = infoPtr->nWidth;
3978 }
3979#endif
3980 if (dwStyle & CCS_NOPARENTALIGN) {
3981 uPosFlags |= SWP_NOMOVE;
3982 cy = infoPtr->nHeight;
3983 cx = infoPtr->nWidth;
3984 }
3985
3986 if (!(dwStyle & CCS_NODIVIDER))
3987 cy += GetSystemMetrics(SM_CYEDGE);
3988
3989 if (dwStyle & WS_BORDER)
3990 {
3991 x = y = 1;
3992 cy += GetSystemMetrics(SM_CYEDGE);
3993 cx += GetSystemMetrics(SM_CYEDGE);
3994 }
3995
3996 SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
3997 cx, cy, uPosFlags | SWP_NOZORDER);
3998 }
3999 return 0;
4000}
4001
4002
4003static LRESULT
4004TOOLBAR_StyleChanged (HWND hwnd, INT nType, LPSTYLESTRUCT lpStyle)
4005{
4006 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
4007
4008 if (nType == GWL_STYLE) {
4009 if (lpStyle->styleNew & TBSTYLE_LIST) {
4010 infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
4011 }
4012 else {
4013 infoPtr->dwDTFlags = DT_CENTER;
4014 }
4015 }
4016
4017 TOOLBAR_AutoSize (hwnd);
4018
4019 InvalidateRect(hwnd, NULL, FALSE);
4020
4021 return 0;
4022}
4023
4024
4025
4026static LRESULT WINAPI
4027ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
4028{
4029 switch (uMsg)
4030 {
4031 case WM_DESTROY:
4032 return TOOLBAR_Destroy (hwnd, wParam, lParam);
4033
4034 case WM_NCCREATE:
4035 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
4036 }
4037
4038 if (!TOOLBAR_GetInfoPtr (hwnd))
4039 {
4040 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
4041 }
4042
4043 switch (uMsg)
4044 {
4045 case TB_ADDBITMAP:
4046 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
4047
4048 case TB_ADDBUTTONSA:
4049 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
4050
4051 case TB_ADDBUTTONSW:
4052 return TOOLBAR_AddButtonsW(hwnd,wParam,lParam);
4053
4054 case TB_ADDSTRINGA:
4055 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
4056
4057 case TB_ADDSTRINGW:
4058 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
4059
4060 case TB_AUTOSIZE:
4061 return TOOLBAR_AutoSize (hwnd);
4062
4063 case TB_BUTTONCOUNT:
4064 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
4065
4066 case TB_BUTTONSTRUCTSIZE:
4067 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
4068
4069 case TB_CHANGEBITMAP:
4070 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
4071
4072 case TB_CHECKBUTTON:
4073 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
4074
4075 case TB_COMMANDTOINDEX:
4076 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
4077
4078 case TB_CUSTOMIZE:
4079 return TOOLBAR_Customize (hwnd);
4080
4081 case TB_DELETEBUTTON:
4082 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
4083
4084 case TB_ENABLEBUTTON:
4085 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
4086
4087 case TB_GETANCHORHIGHLIGHT:
4088 return TOOLBAR_GetAnchorHighlight (hwnd);
4089
4090 case TB_GETBITMAP:
4091 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
4092
4093 case TB_GETBITMAPFLAGS:
4094 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
4095
4096 case TB_GETBUTTON:
4097 return TOOLBAR_GetButton (hwnd, wParam, lParam);
4098
4099 case TB_GETBUTTONINFOA:
4100 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
4101
4102 case TB_GETBUTTONINFOW: /* 4.71 */
4103 return TOOLBAR_GetButtonInfoW(hwnd,wParam,lParam);
4104
4105 case TB_GETBUTTONSIZE:
4106 return TOOLBAR_GetButtonSize (hwnd);
4107
4108 case TB_GETBUTTONTEXTA:
4109 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
4110
4111 case TB_GETBUTTONTEXTW:
4112 return TOOLBAR_GetButtonTextW(hwnd,wParam,lParam);
4113
4114/* case TB_GETCOLORSCHEME: */ /* 4.71 */
4115
4116 case TB_GETDISABLEDIMAGELIST:
4117 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
4118
4119 case TB_GETEXTENDEDSTYLE:
4120 return TOOLBAR_GetExtendedStyle (hwnd);
4121
4122 case TB_GETHOTIMAGELIST:
4123 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
4124
4125 case TB_GETHOTITEM:
4126 return TOOLBAR_GetHotItem (hwnd);
4127
4128 case TB_GETIMAGELIST:
4129 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
4130
4131/* case TB_GETINSERTMARK: */ /* 4.71 */
4132/* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
4133
4134 case TB_GETITEMRECT:
4135 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
4136
4137 case TB_GETMAXSIZE:
4138 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
4139
4140/* case TB_GETOBJECT: */ /* 4.71 */
4141/* case TB_GETPADDING: */ /* 4.71 */
4142
4143 case TB_GETRECT:
4144 return TOOLBAR_GetRect (hwnd, wParam, lParam);
4145
4146 case TB_GETROWS:
4147 return TOOLBAR_GetRows (hwnd, wParam, lParam);
4148
4149 case TB_GETSTATE:
4150 return TOOLBAR_GetState (hwnd, wParam, lParam);
4151
4152 case TB_GETSTYLE:
4153 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
4154
4155 case TB_GETTEXTROWS:
4156 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
4157
4158 case TB_GETTOOLTIPS:
4159 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
4160
4161 case TB_HIDEBUTTON:
4162 return TOOLBAR_HideButton (hwnd, wParam, lParam);
4163
4164 case TB_HITTEST:
4165 return TOOLBAR_HitTest (hwnd, wParam, lParam);
4166
4167 case TB_INDETERMINATE:
4168 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
4169
4170 case TB_INSERTBUTTONA:
4171 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
4172
4173 case TB_INSERTBUTTONW:
4174 return TOOLBAR_InsertButtonW(hwnd,wParam,lParam);
4175
4176/* case TB_INSERTMARKHITTEST: */ /* 4.71 */
4177
4178 case TB_ISBUTTONCHECKED:
4179 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
4180
4181 case TB_ISBUTTONENABLED:
4182 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
4183
4184 case TB_ISBUTTONHIDDEN:
4185 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
4186
4187 case TB_ISBUTTONHIGHLIGHTED:
4188 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
4189
4190 case TB_ISBUTTONINDETERMINATE:
4191 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
4192
4193 case TB_ISBUTTONPRESSED:
4194 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
4195
4196 case TB_LOADIMAGES: /* 4.70 */
4197// FIXME("missing standard imagelists\n");
4198 return 0;
4199/* case TB_MAPACCELERATORA: */ /* 4.71 */
4200/* case TB_MAPACCELERATORW: */ /* 4.71 */
4201/* case TB_MARKBUTTON: */ /* 4.71 */
4202/* case TB_MOVEBUTTON: */ /* 4.71 */
4203
4204 case TB_PRESSBUTTON:
4205 return TOOLBAR_PressButton (hwnd, wParam, lParam);
4206
4207/* case TB_REPLACEBITMAP: */
4208
4209 case TB_SAVERESTOREA:
4210 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
4211
4212 case TB_SAVERESTOREW:
4213 return TOOLBAR_SaveRestoreW(hwnd,wParam,lParam);
4214
4215 case TB_SETANCHORHIGHLIGHT:
4216 return TOOLBAR_SetAnchorHighlight (hwnd, wParam);
4217
4218 case TB_SETBITMAPSIZE:
4219 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
4220
4221 case TB_SETBUTTONINFOA:
4222 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
4223
4224 case TB_SETBUTTONINFOW: /* 4.71 */
4225 return TOOLBAR_SetButtonInfoW(hwnd,wParam,lParam);
4226
4227 case TB_SETBUTTONSIZE:
4228 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
4229
4230 case TB_SETBUTTONWIDTH:
4231 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
4232
4233 case TB_SETCMDID:
4234 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
4235
4236/* case TB_SETCOLORSCHEME: */ /* 4.71 */
4237
4238 case TB_SETDISABLEDIMAGELIST:
4239 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
4240
4241 case TB_SETDRAWTEXTFLAGS:
4242 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
4243
4244 case TB_SETEXTENDEDSTYLE:
4245 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
4246
4247 case TB_SETHOTIMAGELIST:
4248 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
4249
4250 case TB_SETHOTITEM:
4251 return TOOLBAR_SetHotItem (hwnd, wParam);
4252
4253 case TB_SETIMAGELIST:
4254 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
4255
4256 case TB_SETINDENT:
4257 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
4258
4259/* case TB_SETINSERTMARK: */ /* 4.71 */
4260
4261 case TB_SETINSERTMARKCOLOR:
4262 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
4263
4264 case TB_SETMAXTEXTROWS:
4265 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
4266
4267/* case TB_SETPADDING: */ /* 4.71 */
4268
4269 case TB_SETPARENT:
4270 return TOOLBAR_SetParent (hwnd, wParam, lParam);
4271
4272 case TB_SETROWS:
4273 return TOOLBAR_SetRows (hwnd, wParam, lParam);
4274
4275 case TB_SETSTATE:
4276 return TOOLBAR_SetState (hwnd, wParam, lParam);
4277
4278 case TB_SETSTYLE:
4279 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
4280
4281 case TB_SETTOOLTIPS:
4282 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
4283
4284/* case WM_CHAR: */
4285
4286 case WM_CREATE:
4287 return TOOLBAR_Create (hwnd, wParam, lParam);
4288
4289 case WM_ERASEBKGND:
4290 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
4291
4292 case WM_GETFONT:
4293 return TOOLBAR_GetFont (hwnd, wParam, lParam);
4294
4295/* case WM_KEYDOWN: */
4296/* case WM_KILLFOCUS: */
4297
4298 case WM_LBUTTONDBLCLK:
4299 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
4300
4301 case WM_LBUTTONDOWN:
4302 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
4303
4304 case WM_LBUTTONUP:
4305 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
4306
4307 case WM_MOUSEMOVE:
4308 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
4309
4310 case WM_NCACTIVATE:
4311 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
4312
4313 case WM_NCCALCSIZE:
4314 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
4315
4316 case WM_NCPAINT:
4317 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
4318
4319 case WM_NOTIFY:
4320 return TOOLBAR_Notify (hwnd, wParam, lParam);
4321
4322 case WM_PAINT:
4323 return TOOLBAR_Paint (hwnd, wParam);
4324
4325 case WM_SIZE:
4326 return TOOLBAR_Size (hwnd, wParam, lParam);
4327
4328 case WM_STYLECHANGED:
4329 return TOOLBAR_StyleChanged (hwnd, (INT)wParam, (LPSTYLESTRUCT)lParam);
4330
4331/* case WM_SYSCOLORCHANGE: */
4332
4333/* case WM_WININICHANGE: */
4334
4335 case WM_CHARTOITEM:
4336 case WM_COMMAND:
4337 case WM_DRAWITEM:
4338 case WM_MEASUREITEM:
4339 case WM_VKEYTOITEM:
4340 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
4341
4342 default:
4343// if (uMsg >= WM_USER)
4344// ERR (toolbar, "unknown msg %04x wp=%08x lp=%08lx\n",
4345// uMsg, wParam, lParam);
4346 return defComCtl32ProcA (hwnd, uMsg, wParam, lParam);
4347 }
4348 return 0;
4349}
4350
4351
4352VOID
4353TOOLBAR_Register (VOID)
4354{
4355 WNDCLASSA wndClass;
4356
4357 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
4358 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
4359 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
4360 wndClass.cbClsExtra = 0;
4361 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
4362 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
4363 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
4364 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
4365
4366 RegisterClassA (&wndClass);
4367}
4368
4369
4370VOID
4371TOOLBAR_Unregister (VOID)
4372{
4373 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);
4374}
4375
Note: See TracBrowser for help on using the repository browser.