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

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

put back old toolbar+tooltips code

File size: 120.1 KB
Line 
1/* $Id: toolbar.cpp,v 1.9 2000-08-06 20:28:28 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 20000513 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
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 /* Bitmap size can only be set before adding any button to the toolbar
3000 according to the documentation. */
3001 if( infoPtr->nNumButtons != 0 )
3002 return FALSE;
3003
3004 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
3005 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
3006
3007 return TRUE;
3008}
3009
3010
3011static LRESULT
3012TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
3013{
3014 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3015 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
3016 TBUTTON_INFO *btnPtr;
3017 INT nIndex;
3018
3019 if (lptbbi == NULL)
3020 return FALSE;
3021 if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
3022 return FALSE;
3023
3024 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3025 if (nIndex == -1)
3026 return FALSE;
3027
3028 btnPtr = &infoPtr->buttons[nIndex];
3029 if (lptbbi->dwMask & TBIF_COMMAND)
3030 btnPtr->idCommand = lptbbi->idCommand;
3031 if (lptbbi->dwMask & TBIF_IMAGE)
3032 btnPtr->iBitmap = lptbbi->iImage;
3033 if (lptbbi->dwMask & TBIF_LPARAM)
3034 btnPtr->dwData = lptbbi->lParam;
3035/* if (lptbbi->dwMask & TBIF_SIZE) */
3036/* btnPtr->cx = lptbbi->cx; */
3037 if (lptbbi->dwMask & TBIF_STATE)
3038 btnPtr->fsState = lptbbi->fsState;
3039 if (lptbbi->dwMask & TBIF_STYLE)
3040 btnPtr->fsStyle = lptbbi->fsStyle;
3041
3042 if (lptbbi->dwMask & TBIF_TEXT) {
3043 if ((btnPtr->iString >= 0) ||
3044 (btnPtr->iString < infoPtr->nNumStrings)) {
3045#if 0
3046 CHAR **lpString = &infoPtr->strings[btnPtr->iString]; //wrong, it's Unicode!!!
3047 INT len = lstrlenA (lptbbi->pszText);
3048 *lpString = COMCTL32_ReAlloc (lpString, sizeof(char)*(len+1));
3049#endif
3050
3051 /* this is the ultimate sollution */
3052/* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3053 }
3054 }
3055
3056 return TRUE;
3057}
3058
3059static LRESULT TOOLBAR_SetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
3060{
3061 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3062 LPTBBUTTONINFOW lptbbi = (LPTBBUTTONINFOW)lParam;
3063 TBUTTON_INFO *btnPtr;
3064 INT nIndex;
3065
3066 if (lptbbi == NULL)
3067 return FALSE;
3068 if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
3069 return FALSE;
3070
3071 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3072 if (nIndex == -1)
3073 return FALSE;
3074
3075 btnPtr = &infoPtr->buttons[nIndex];
3076 if (lptbbi->dwMask & TBIF_COMMAND)
3077 btnPtr->idCommand = lptbbi->idCommand;
3078 if (lptbbi->dwMask & TBIF_IMAGE)
3079 btnPtr->iBitmap = lptbbi->iImage;
3080 if (lptbbi->dwMask & TBIF_LPARAM)
3081 btnPtr->dwData = lptbbi->lParam;
3082/* if (lptbbi->dwMask & TBIF_SIZE) */
3083/* btnPtr->cx = lptbbi->cx; */
3084 if (lptbbi->dwMask & TBIF_STATE)
3085 btnPtr->fsState = lptbbi->fsState;
3086 if (lptbbi->dwMask & TBIF_STYLE)
3087 btnPtr->fsStyle = lptbbi->fsStyle;
3088
3089 if (lptbbi->dwMask & TBIF_TEXT) {
3090 if ((btnPtr->iString >= 0) ||
3091 (btnPtr->iString < infoPtr->nNumStrings)) {
3092#if 0
3093 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
3094 INT len = lstrlenW (lptbbi->pszText);
3095 *lpString = COMCTL32_ReAlloc (lpString, sizeof(wchar)*(len+1));
3096#endif
3097
3098 /* this is the ultimate sollution */
3099/* Str_SetPtrW (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
3100 }
3101 }
3102
3103 return TRUE;
3104}
3105
3106static LRESULT
3107TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3108{
3109 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3110
3111 if (((INT)LOWORD(lParam) <= 0) || ((INT)HIWORD(lParam) <= 0)) return FALSE;
3112
3113 /* Button size can only be set before adding any button to the toolbar
3114 according to the documentation. */
3115 if( infoPtr->nNumButtons != 0 )
3116 return FALSE;
3117
3118 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
3119 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
3120
3121 return TRUE;
3122}
3123
3124
3125static LRESULT
3126TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
3127{
3128 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3129
3130 if (infoPtr == NULL)
3131 return FALSE;
3132
3133 infoPtr->cxMin = (INT)LOWORD(lParam);
3134 infoPtr->cxMax = (INT)HIWORD(lParam);
3135
3136 return TRUE;
3137}
3138
3139
3140static LRESULT
3141TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
3142{
3143 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3144 INT nIndex = (INT)wParam;
3145
3146 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
3147 return FALSE;
3148
3149 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
3150
3151 if (infoPtr->hwndToolTip) {
3152
3153// FIXME (toolbar, "change tool tip!\n");
3154
3155 }
3156
3157 return TRUE;
3158}
3159
3160
3161/* << TOOLBAR_SetColorScheme >> */
3162
3163
3164static LRESULT
3165TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3166{
3167 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3168 HIMAGELIST himlTemp;
3169
3170 himlTemp = infoPtr->himlDis;
3171 infoPtr->himlDis = (HIMAGELIST)lParam;
3172
3173 /* FIXME: redraw ? */
3174
3175 return (LRESULT)himlTemp;
3176}
3177
3178
3179static LRESULT
3180TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
3181{
3182 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3183 DWORD dwTemp;
3184
3185 dwTemp = infoPtr->dwDTFlags;
3186 infoPtr->dwDTFlags =
3187 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
3188
3189 return (LRESULT)dwTemp;
3190}
3191
3192
3193static LRESULT
3194TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3195{
3196 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3197 DWORD dwTemp;
3198
3199 dwTemp = infoPtr->dwExStyle;
3200 infoPtr->dwExStyle = (DWORD)lParam;
3201
3202 return (LRESULT)dwTemp;
3203}
3204
3205
3206static LRESULT
3207TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3208{
3209 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3210 HIMAGELIST himlTemp;
3211
3212 himlTemp = infoPtr->himlHot;
3213 infoPtr->himlHot = (HIMAGELIST)lParam;
3214
3215 /* FIXME: redraw ? */
3216
3217 return (LRESULT)himlTemp;
3218}
3219
3220
3221static LRESULT
3222TOOLBAR_SetHotItem (HWND hwnd, WPARAM wParam)
3223{
3224 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
3225 INT nOldHotItem = infoPtr->nHotItem;
3226
3227 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
3228 {
3229 infoPtr->nHotItem = (INT)wParam;
3230
3231 /* FIXME: What else must be done ??? */
3232
3233 }
3234
3235 if (nOldHotItem < 0)
3236 return -1;
3237
3238 return (LRESULT)nOldHotItem;
3239}
3240
3241
3242static LRESULT
3243TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
3244{
3245 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3246 HIMAGELIST himlTemp;
3247
3248 himlTemp = infoPtr->himlDef;
3249 infoPtr->himlDef = (HIMAGELIST)lParam;
3250
3251 /* FIXME: redraw ? */
3252
3253 return (LRESULT)himlTemp;
3254}
3255
3256
3257static LRESULT
3258TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3259{
3260 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3261
3262 infoPtr->nIndent = (INT)wParam;
3263
3264 TOOLBAR_CalcToolbar (hwnd);
3265
3266 InvalidateRect(hwnd, NULL, FALSE);
3267
3268 return TRUE;
3269}
3270
3271
3272/* << TOOLBAR_SetInsertMark >> */
3273
3274
3275static LRESULT
3276TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
3277{
3278 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3279
3280 infoPtr->clrInsertMark = (COLORREF)lParam;
3281
3282 /* FIXME : redraw ??*/
3283
3284 return 0;
3285}
3286
3287
3288static LRESULT
3289TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3290{
3291 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3292
3293 if (infoPtr == NULL)
3294 return FALSE;
3295
3296 infoPtr->nMaxTextRows = (INT)wParam;
3297
3298 return TRUE;
3299}
3300
3301
3302/* << TOOLBAR_SetPadding >> */
3303
3304
3305static LRESULT
3306TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
3307{
3308 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3309 HWND hwndOldNotify;
3310
3311 if (infoPtr == NULL)
3312 return 0;
3313 hwndOldNotify = infoPtr->header.hwndNotify;
3314 infoPtr->header.hwndNotify = (HWND)wParam;
3315
3316 return hwndOldNotify;
3317}
3318
3319
3320static LRESULT
3321TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
3322{
3323 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3324 LPRECT lprc = (LPRECT)lParam;
3325
3326 if (LOWORD(wParam) > 1) {
3327
3328// FIXME (toolbar, "multiple rows not supported!\n");
3329
3330 }
3331
3332 /* recalculate toolbar */
3333 TOOLBAR_CalcToolbar (hwnd);
3334
3335 /* return bounding rectangle */
3336 if (lprc) {
3337 lprc->left = infoPtr->rcBound.left;
3338 lprc->right = infoPtr->rcBound.right;
3339 lprc->top = infoPtr->rcBound.top;
3340 lprc->bottom = infoPtr->rcBound.bottom;
3341 }
3342
3343 /* repaint toolbar */
3344 InvalidateRect(hwnd, NULL, FALSE);
3345
3346 return 0;
3347}
3348
3349
3350static LRESULT
3351TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
3352{
3353 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3354 TBUTTON_INFO *btnPtr;
3355 HDC hdc;
3356 INT nIndex;
3357
3358 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3359 if (nIndex == -1)
3360 return FALSE;
3361
3362 btnPtr = &infoPtr->buttons[nIndex];
3363 btnPtr->fsState = LOWORD(lParam);
3364
3365 hdc = GetDC (hwnd);
3366 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3367 ReleaseDC (hwnd, hdc);
3368
3369 return TRUE;
3370}
3371
3372
3373static LRESULT
3374TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
3375{
3376 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3377 TBUTTON_INFO *btnPtr;
3378 HDC hdc;
3379 INT nIndex;
3380
3381 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
3382 if (nIndex == -1)
3383 return FALSE;
3384
3385 btnPtr = &infoPtr->buttons[nIndex];
3386 btnPtr->fsStyle = LOWORD(lParam);
3387
3388 hdc = GetDC (hwnd);
3389 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3390 ReleaseDC (hwnd, hdc);
3391
3392 if (infoPtr->hwndToolTip) {
3393
3394// FIXME (toolbar, "change tool tip!\n");
3395
3396 }
3397
3398 return TRUE;
3399}
3400
3401
3402static LRESULT
3403TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
3404{
3405 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3406
3407 if (infoPtr == NULL)
3408 return 0;
3409 infoPtr->hwndToolTip = (HWND)wParam;
3410 return 0;
3411}
3412
3413static LRESULT
3414TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
3415{
3416 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3417 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3418 LOGFONTA logFont;
3419
3420 /* initialize info structure */
3421 infoPtr->nButtonHeight = 22;
3422 infoPtr->nButtonWidth = 24;
3423 infoPtr->nBitmapHeight = 15;
3424 infoPtr->nBitmapWidth = 16;
3425
3426 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
3427 infoPtr->nRows = 1;
3428 infoPtr->nMaxTextRows = 1;
3429 infoPtr->cxMin = -1;
3430 infoPtr->cxMax = -1;
3431
3432 infoPtr->bCaptured = FALSE;
3433 infoPtr->nButtonDown = -1;
3434 infoPtr->nOldHit = -1;
3435 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
3436 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
3437 infoPtr->dwDTFlags = (dwStyle & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE : DT_CENTER;
3438 infoPtr->bAnchor = FALSE; /* no anchor highlighting */
3439
3440 infoPtr->hwndToolbar = hwnd;
3441 infoPtr->oldButtons = NULL;
3442 infoPtr->nNumOldButtons = 0;
3443
3444 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
3445 infoPtr->hFont = CreateFontIndirectA (&logFont);
3446
3447 /* Create tooltip control */
3448 if (dwStyle & TBSTYLE_TOOLTIPS)
3449 infoPtr->hwndToolTip = createToolTip(hwnd,0,FALSE);
3450
3451 return 0;
3452}
3453
3454
3455static LRESULT
3456TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
3457{
3458 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3459
3460 /* delete button data */
3461 if (infoPtr->buttons)
3462 {
3463 INT x;
3464
3465 //SvL: Check pointers
3466 for (x = 0;x < infoPtr->nNumButtons;x++)
3467 if(infoPtr->buttons[x].pszName)
3468 COMCTL32_Free(infoPtr->buttons[x].pszName);
3469
3470 COMCTL32_Free(infoPtr->buttons);
3471 }
3472
3473 /* delete strings */
3474 if (infoPtr->strings) {
3475 INT i;
3476 for (i = 0; i < infoPtr->nNumStrings; i++)
3477 if (infoPtr->strings[i])
3478 COMCTL32_Free (infoPtr->strings[i]);
3479
3480 COMCTL32_Free (infoPtr->strings);
3481 }
3482
3483 /* destroy internal image list */
3484 if (infoPtr->himlInt)
3485 ImageList_Destroy (infoPtr->himlInt);
3486
3487 /* delete default font */
3488 if (infoPtr->hFont)
3489 DeleteObject (infoPtr->hFont);
3490
3491 /* free toolbar info data */
3492 doneControl(hwnd);
3493
3494 return 0;
3495}
3496
3497
3498static LRESULT
3499TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
3500{
3501 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3502
3503 //SvL: Check ptr
3504 if (infoPtr && infoPtr->bTransparent)
3505 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
3506
3507 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
3508}
3509
3510static LRESULT
3511TOOLBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
3512{
3513 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3514
3515 return infoPtr->hFont;
3516}
3517
3518static LRESULT
3519TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
3520{
3521 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3522 TBUTTON_INFO *btnPtr;
3523 POINT pt;
3524 INT nHit;
3525 HDC hdc;
3526
3527 pt.x = (INT)LOWORD(lParam);
3528 pt.y = (INT)HIWORD(lParam);
3529 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3530
3531 if (nHit >= 0) {
3532 btnPtr = &infoPtr->buttons[nHit];
3533 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3534 return 0;
3535 SetCapture (hwnd);
3536 infoPtr->bCaptured = TRUE;
3537 infoPtr->nButtonDown = nHit;
3538
3539 btnPtr->fsState |= TBSTATE_PRESSED;
3540
3541 hdc = GetDC (hwnd);
3542 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3543 ReleaseDC (hwnd, hdc);
3544 }
3545 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
3546 TOOLBAR_Customize (hwnd);
3547
3548 return 0;
3549}
3550
3551
3552static LRESULT
3553TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
3554{
3555 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3556 TBUTTON_INFO *btnPtr;
3557 POINT pt;
3558 INT nHit;
3559 HDC hdc;
3560
3561 if (infoPtr->hwndToolTip)
3562 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3563 WM_LBUTTONDOWN, wParam, lParam);
3564
3565 pt.x = (INT)LOWORD(lParam);
3566 pt.y = (INT)HIWORD(lParam);
3567 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3568
3569 if (nHit >= 0) {
3570 btnPtr = &infoPtr->buttons[nHit];
3571 if (!(btnPtr->fsState & TBSTATE_ENABLED))
3572 return 0;
3573
3574 if (btnPtr->fsStyle & TBSTYLE_DROPDOWN)
3575 {
3576 NMTOOLBARA nmtb;
3577
3578 nmtb.iItem = btnPtr->idCommand;
3579
3580 sendNotify(hwnd,TBN_DROPDOWN,&nmtb.hdr);
3581 }
3582
3583 SetCapture (hwnd);
3584 infoPtr->bCaptured = TRUE;
3585 infoPtr->nButtonDown = nHit;
3586 infoPtr->nOldHit = nHit;
3587
3588 btnPtr->fsState |= TBSTATE_PRESSED;
3589
3590 hdc = GetDC (hwnd);
3591 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3592 ReleaseDC (hwnd, hdc);
3593 }
3594
3595 return 0;
3596}
3597
3598
3599static LRESULT
3600TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
3601{
3602 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3603 TBUTTON_INFO *btnPtr;
3604 POINT pt;
3605 INT nHit;
3606 INT nOldIndex = -1;
3607 HDC hdc;
3608 BOOL bSendMessage = TRUE;
3609
3610 if (infoPtr->hwndToolTip)
3611 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
3612 WM_LBUTTONUP, wParam, lParam);
3613
3614 pt.x = (INT)LOWORD(lParam);
3615 pt.y = (INT)HIWORD(lParam);
3616 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
3617
3618 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
3619 infoPtr->bCaptured = FALSE;
3620 ReleaseCapture ();
3621 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3622 btnPtr->fsState &= ~TBSTATE_PRESSED;
3623
3624 if (nHit == infoPtr->nButtonDown) {
3625 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
3626 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
3627 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
3628 infoPtr->nButtonDown);
3629 if (nOldIndex == infoPtr->nButtonDown)
3630 bSendMessage = FALSE;
3631 if ((nOldIndex != infoPtr->nButtonDown) &&
3632 (nOldIndex != -1))
3633 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
3634 btnPtr->fsState |= TBSTATE_CHECKED;
3635 }
3636 else {
3637 if (btnPtr->fsState & TBSTATE_CHECKED)
3638 btnPtr->fsState &= ~TBSTATE_CHECKED;
3639 else
3640 btnPtr->fsState |= TBSTATE_CHECKED;
3641 }
3642 }
3643 }
3644 else
3645 bSendMessage = FALSE;
3646
3647 hdc = GetDC (hwnd);
3648 if (nOldIndex != -1)
3649 TOOLBAR_DrawButton (hwnd, &infoPtr->buttons[nOldIndex], hdc);
3650 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3651 ReleaseDC (hwnd, hdc);
3652
3653 if (bSendMessage) {
3654 SendMessageA (GetParent(hwnd), WM_COMMAND,
3655 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
3656
3657 if ((GetWindowLongA(hwnd, GWL_STYLE) & TBSTYLE_DROPDOWN) ||
3658 (btnPtr->fsStyle & 0x08/* BTNS_DROPDOWN */)) {
3659 NMTOOLBARW nmtb;
3660
3661 nmtb.iItem = nHit;
3662 /* nmtb.tbButton not used with TBN_DROPDOWN */
3663 if ((btnPtr->iString >= 0) && (btnPtr->iString < infoPtr->nNumStrings)) {
3664 nmtb.pszText = infoPtr->strings[btnPtr->iString];
3665 nmtb.cchText = lstrlenW(nmtb.pszText);
3666 } else {
3667 nmtb.pszText = NULL;
3668 nmtb.cchText = 0;
3669 }
3670 nmtb.rcButton = btnPtr->rect;
3671
3672 sendNotify(hwnd,TBN_DROPDOWN,&nmtb.hdr);
3673 }
3674 }
3675
3676 infoPtr->nButtonDown = -1;
3677 infoPtr->nOldHit = -1;
3678 }
3679
3680 return 0;
3681}
3682
3683
3684static LRESULT
3685TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
3686{
3687 TBUTTON_INFO *btnPtr, *oldBtnPtr;
3688 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3689 POINT pt;
3690 INT nHit;
3691 HDC hdc;
3692 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
3693
3694 if (infoPtr->hwndToolTip)
3695 TOOLBAR_RelayEvent (infoPtr->hwndToolTip,hwnd,
3696 WM_MOUSEMOVE,wParam,lParam);
3697
3698 pt.x = (INT)LOWORD(lParam);
3699 pt.y = (INT)HIWORD(lParam);
3700
3701 nHit = TOOLBAR_InternalHitTest(hwnd,&pt);
3702
3703 if (infoPtr->nOldHit != nHit)
3704 {
3705 /* Remove the effect of an old hot button */
3706 if(infoPtr->nOldHit == infoPtr->nHotItem)
3707 {
3708 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
3709 if (oldBtnPtr->bHot) //CB: dynamic buttons
3710 {
3711 oldBtnPtr->bHot = FALSE;
3712
3713 if (dwStyle & TBSTYLE_FLAT) InvalidateRect(hwnd,&oldBtnPtr->rect,TRUE);
3714 }
3715 }
3716
3717 /* It's not a separator or in nowhere. It's a hot button. */
3718 if (nHit >= 0)
3719 {
3720 btnPtr = &infoPtr->buttons[nHit];
3721 if (!btnPtr->bHot)
3722 {
3723 btnPtr->bHot = TRUE;
3724
3725 if (dwStyle & TBSTYLE_FLAT)
3726 {
3727 hdc = GetDC (hwnd);
3728 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
3729 ReleaseDC (hwnd, hdc);
3730 }
3731
3732 infoPtr->nHotItem = nHit;
3733 }
3734 }
3735
3736 if (infoPtr->bCaptured)
3737 {
3738 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
3739 if (infoPtr->nOldHit == infoPtr->nButtonDown)
3740 {
3741 btnPtr->fsState &= ~TBSTATE_PRESSED;
3742
3743 hdc = GetDC (hwnd);
3744 TOOLBAR_DrawButton(hwnd,btnPtr,hdc);
3745 ReleaseDC(hwnd,hdc);
3746 } else if (nHit == infoPtr->nButtonDown)
3747 {
3748 btnPtr->fsState |= TBSTATE_PRESSED;
3749
3750 hdc = GetDC(hwnd);
3751 TOOLBAR_DrawButton(hwnd,btnPtr,hdc);
3752 ReleaseDC(hwnd,hdc);
3753 }
3754 }
3755 infoPtr->nOldHit = nHit;
3756 }
3757 return 0;
3758}
3759
3760
3761static LRESULT
3762TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3763{
3764/* if (wndPtr->dwStyle & CCS_NODIVIDER) */
3765 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
3766/* else */
3767/* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
3768}
3769
3770
3771static LRESULT
3772TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3773{
3774 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
3775 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
3776
3777 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
3778}
3779
3780
3781static LRESULT
3782TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
3783{
3784 TOOLBAR_INFO *infoPtr;
3785
3786 /* allocate memory for info structure */
3787 infoPtr = (TOOLBAR_INFO*)initControl(hwnd,sizeof(TOOLBAR_INFO));
3788
3789 /* paranoid!! */
3790 infoPtr->dwStructSize = sizeof(TBBUTTON);
3791
3792 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
3793 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
3794 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
3795 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
3796 }
3797
3798 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
3799}
3800
3801
3802static LRESULT
3803TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3804{
3805 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3806 RECT rcWindow;
3807 HDC hdc;
3808
3809 if (dwStyle & WS_MINIMIZE)
3810 return 0; /* Nothing to do */
3811
3812 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
3813
3814 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
3815 return 0;
3816
3817 if (!(dwStyle & CCS_NODIVIDER))
3818 {
3819 GetWindowRect (hwnd, &rcWindow);
3820 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3821 if( dwStyle & WS_BORDER )
3822 OffsetRect (&rcWindow, 1, 1);
3823 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
3824 }
3825
3826 ReleaseDC( hwnd, hdc );
3827
3828 return 0;
3829}
3830
3831
3832static LRESULT
3833TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
3834{
3835 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3836 LPNMHDR lpnmh = (LPNMHDR)lParam;
3837
3838// TRACE (toolbar, "passing WM_NOTIFY!\n");
3839
3840 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
3841 SendMessageA (infoPtr->header.hwndNotify, WM_NOTIFY, wParam, lParam);
3842
3843#if 0
3844 if (lpnmh->code == TTN_GETDISPINFOA) {
3845 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
3846
3847// FIXME (toolbar, "retrieving ASCII string\n");
3848
3849 }
3850 else if (lpnmh->code == TTN_GETDISPINFOW) {
3851 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
3852
3853// FIXME (toolbar, "retrieving UNICODE string\n");
3854
3855 }
3856#endif
3857 }
3858
3859 return 0;
3860}
3861
3862
3863static LRESULT
3864TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
3865{
3866 HDC hdc;
3867 PAINTSTRUCT ps;
3868
3869 TOOLBAR_CalcToolbar(hwnd);
3870 hdc = wParam == 0 ? BeginPaint(hwnd,&ps) : (HDC)wParam;
3871 TOOLBAR_Refresh(hwnd,hdc);
3872 if (!wParam) EndPaint (hwnd, &ps);
3873 return 0;
3874}
3875
3876
3877static LRESULT
3878TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
3879{
3880 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3881 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3882 RECT parent_rect;
3883 HWND parent;
3884 INT x = 0,y = 0,cx,cy;
3885 INT flags;
3886 UINT uPosFlags = 0;
3887
3888 /* Resize deadlock check */
3889 if (infoPtr->bAutoSize) {
3890 infoPtr->bAutoSize = FALSE;
3891 return 0;
3892 }
3893
3894 flags = (INT) wParam;
3895
3896 /* FIXME for flags =
3897 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
3898 */
3899
3900 //TRACE (toolbar, "sizing toolbar!\n");
3901
3902 if (flags == SIZE_RESTORED) {
3903 /* width and height don't apply */
3904 parent = GetParent (hwnd);
3905 GetClientRect(parent, &parent_rect);
3906 x = parent_rect.left;
3907 y = parent_rect.top;
3908
3909 if (dwStyle & CCS_NORESIZE) {
3910 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
3911 /* FIXME */
3912/* infoPtr->nWidth = parent_rect.right - parent_rect.left; */
3913 cy = infoPtr->nHeight;
3914 cx = infoPtr->nWidth;
3915 TOOLBAR_CalcToolbar (hwnd);
3916 infoPtr->nWidth = cx;
3917 infoPtr->nHeight = cy;
3918 }
3919 else {
3920 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3921 TOOLBAR_CalcToolbar (hwnd);
3922 cy = infoPtr->nHeight;
3923 cx = infoPtr->nWidth;
3924 }
3925
3926 if (dwStyle & CCS_NOPARENTALIGN) {
3927 uPosFlags |= SWP_NOMOVE;
3928 cy = infoPtr->nHeight;
3929 cx = infoPtr->nWidth;
3930 }
3931
3932 if (!(dwStyle & CCS_NODIVIDER))
3933 cy += GetSystemMetrics(SM_CYEDGE);
3934
3935 if (dwStyle & WS_BORDER)
3936 {
3937 x = y = 1;
3938 cy += GetSystemMetrics(SM_CYEDGE);
3939 cx += GetSystemMetrics(SM_CYEDGE);
3940 }
3941
3942 SetWindowPos (hwnd, 0, parent_rect.left - x, parent_rect.top - y,
3943 cx, cy, uPosFlags | SWP_NOZORDER);
3944 }
3945 return 0;
3946}
3947
3948
3949static LRESULT
3950TOOLBAR_StyleChanged (HWND hwnd, INT nType, LPSTYLESTRUCT lpStyle)
3951{
3952 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3953
3954 if (nType == GWL_STYLE) {
3955 if (lpStyle->styleNew & TBSTYLE_LIST) {
3956 infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
3957 }
3958 else {
3959 infoPtr->dwDTFlags = DT_CENTER;
3960 }
3961 }
3962
3963 TOOLBAR_AutoSize (hwnd);
3964
3965 InvalidateRect(hwnd, NULL, FALSE);
3966
3967 return 0;
3968}
3969
3970
3971
3972static LRESULT WINAPI
3973ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3974{
3975 switch (uMsg)
3976 {
3977 case WM_DESTROY:
3978 return TOOLBAR_Destroy (hwnd, wParam, lParam);
3979
3980 case WM_NCCREATE:
3981 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
3982 }
3983
3984 if (!TOOLBAR_GetInfoPtr (hwnd))
3985 {
3986 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3987 }
3988
3989 switch (uMsg)
3990 {
3991 case TB_ADDBITMAP:
3992 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
3993
3994 case TB_ADDBUTTONSA:
3995 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
3996
3997 case TB_ADDBUTTONSW:
3998 return TOOLBAR_AddButtonsW(hwnd,wParam,lParam);
3999
4000 case TB_ADDSTRINGA:
4001 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
4002
4003 case TB_ADDSTRINGW:
4004 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
4005
4006 case TB_AUTOSIZE:
4007 return TOOLBAR_AutoSize (hwnd);
4008
4009 case TB_BUTTONCOUNT:
4010 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
4011
4012 case TB_BUTTONSTRUCTSIZE:
4013 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
4014
4015 case TB_CHANGEBITMAP:
4016 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
4017
4018 case TB_CHECKBUTTON:
4019 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
4020
4021 case TB_COMMANDTOINDEX:
4022 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
4023
4024 case TB_CUSTOMIZE:
4025 return TOOLBAR_Customize (hwnd);
4026
4027 case TB_DELETEBUTTON:
4028 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
4029
4030 case TB_ENABLEBUTTON:
4031 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
4032
4033 case TB_GETANCHORHIGHLIGHT:
4034 return TOOLBAR_GetAnchorHighlight (hwnd);
4035
4036 case TB_GETBITMAP:
4037 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
4038
4039 case TB_GETBITMAPFLAGS:
4040 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
4041
4042 case TB_GETBUTTON:
4043 return TOOLBAR_GetButton (hwnd, wParam, lParam);
4044
4045 case TB_GETBUTTONINFOA:
4046 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
4047
4048 case TB_GETBUTTONINFOW: /* 4.71 */
4049 return TOOLBAR_GetButtonInfoW(hwnd,wParam,lParam);
4050
4051 case TB_GETBUTTONSIZE:
4052 return TOOLBAR_GetButtonSize (hwnd);
4053
4054 case TB_GETBUTTONTEXTA:
4055 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
4056
4057 case TB_GETBUTTONTEXTW:
4058 return TOOLBAR_GetButtonTextW(hwnd,wParam,lParam);
4059
4060/* case TB_GETCOLORSCHEME: */ /* 4.71 */
4061
4062 case TB_GETDISABLEDIMAGELIST:
4063 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
4064
4065 case TB_GETEXTENDEDSTYLE:
4066 return TOOLBAR_GetExtendedStyle (hwnd);
4067
4068 case TB_GETHOTIMAGELIST:
4069 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
4070
4071 case TB_GETHOTITEM:
4072 return TOOLBAR_GetHotItem (hwnd);
4073
4074 case TB_GETIMAGELIST:
4075 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
4076
4077/* case TB_GETINSERTMARK: */ /* 4.71 */
4078/* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
4079
4080 case TB_GETITEMRECT:
4081 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
4082
4083 case TB_GETMAXSIZE:
4084 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
4085
4086/* case TB_GETOBJECT: */ /* 4.71 */
4087/* case TB_GETPADDING: */ /* 4.71 */
4088
4089 case TB_GETRECT:
4090 return TOOLBAR_GetRect (hwnd, wParam, lParam);
4091
4092 case TB_GETROWS:
4093 return TOOLBAR_GetRows (hwnd, wParam, lParam);
4094
4095 case TB_GETSTATE:
4096 return TOOLBAR_GetState (hwnd, wParam, lParam);
4097
4098 case TB_GETSTYLE:
4099 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
4100
4101 case TB_GETTEXTROWS:
4102 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
4103
4104 case TB_GETTOOLTIPS:
4105 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
4106
4107 case TB_HIDEBUTTON:
4108 return TOOLBAR_HideButton (hwnd, wParam, lParam);
4109
4110 case TB_HITTEST:
4111 return TOOLBAR_HitTest (hwnd, wParam, lParam);
4112
4113 case TB_INDETERMINATE:
4114 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
4115
4116 case TB_INSERTBUTTONA:
4117 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
4118
4119 case TB_INSERTBUTTONW:
4120 return TOOLBAR_InsertButtonW(hwnd,wParam,lParam);
4121
4122/* case TB_INSERTMARKHITTEST: */ /* 4.71 */
4123
4124 case TB_ISBUTTONCHECKED:
4125 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
4126
4127 case TB_ISBUTTONENABLED:
4128 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
4129
4130 case TB_ISBUTTONHIDDEN:
4131 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
4132
4133 case TB_ISBUTTONHIGHLIGHTED:
4134 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
4135
4136 case TB_ISBUTTONINDETERMINATE:
4137 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
4138
4139 case TB_ISBUTTONPRESSED:
4140 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
4141
4142 case TB_LOADIMAGES: /* 4.70 */
4143// FIXME("missing standard imagelists\n");
4144 return 0;
4145/* case TB_MAPACCELERATORA: */ /* 4.71 */
4146/* case TB_MAPACCELERATORW: */ /* 4.71 */
4147/* case TB_MARKBUTTON: */ /* 4.71 */
4148/* case TB_MOVEBUTTON: */ /* 4.71 */
4149
4150 case TB_PRESSBUTTON:
4151 return TOOLBAR_PressButton (hwnd, wParam, lParam);
4152
4153/* case TB_REPLACEBITMAP: */
4154
4155 case TB_SAVERESTOREA:
4156 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
4157
4158 case TB_SAVERESTOREW:
4159 return TOOLBAR_SaveRestoreW(hwnd,wParam,lParam);
4160
4161 case TB_SETANCHORHIGHLIGHT:
4162 return TOOLBAR_SetAnchorHighlight (hwnd, wParam);
4163
4164 case TB_SETBITMAPSIZE:
4165 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
4166
4167 case TB_SETBUTTONINFOA:
4168 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
4169
4170 case TB_SETBUTTONINFOW: /* 4.71 */
4171 return TOOLBAR_SetButtonInfoW(hwnd,wParam,lParam);
4172
4173 case TB_SETBUTTONSIZE:
4174 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
4175
4176 case TB_SETBUTTONWIDTH:
4177 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
4178
4179 case TB_SETCMDID:
4180 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
4181
4182/* case TB_SETCOLORSCHEME: */ /* 4.71 */
4183
4184 case TB_SETDISABLEDIMAGELIST:
4185 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
4186
4187 case TB_SETDRAWTEXTFLAGS:
4188 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
4189
4190 case TB_SETEXTENDEDSTYLE:
4191 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
4192
4193 case TB_SETHOTIMAGELIST:
4194 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
4195
4196 case TB_SETHOTITEM:
4197 return TOOLBAR_SetHotItem (hwnd, wParam);
4198
4199 case TB_SETIMAGELIST:
4200 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
4201
4202 case TB_SETINDENT:
4203 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
4204
4205/* case TB_SETINSERTMARK: */ /* 4.71 */
4206
4207 case TB_SETINSERTMARKCOLOR:
4208 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
4209
4210 case TB_SETMAXTEXTROWS:
4211 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
4212
4213/* case TB_SETPADDING: */ /* 4.71 */
4214
4215 case TB_SETPARENT:
4216 return TOOLBAR_SetParent (hwnd, wParam, lParam);
4217
4218 case TB_SETROWS:
4219 return TOOLBAR_SetRows (hwnd, wParam, lParam);
4220
4221 case TB_SETSTATE:
4222 return TOOLBAR_SetState (hwnd, wParam, lParam);
4223
4224 case TB_SETSTYLE:
4225 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
4226
4227 case TB_SETTOOLTIPS:
4228 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
4229
4230/* case WM_CHAR: */
4231
4232 case WM_CREATE:
4233 return TOOLBAR_Create (hwnd, wParam, lParam);
4234
4235 case WM_ERASEBKGND:
4236 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
4237
4238 case WM_GETFONT:
4239 return TOOLBAR_GetFont (hwnd, wParam, lParam);
4240
4241/* case WM_KEYDOWN: */
4242/* case WM_KILLFOCUS: */
4243
4244 case WM_LBUTTONDBLCLK:
4245 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
4246
4247 case WM_LBUTTONDOWN:
4248 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
4249
4250 case WM_LBUTTONUP:
4251 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
4252
4253 case WM_MOUSEMOVE:
4254 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
4255
4256 case WM_NCACTIVATE:
4257 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
4258
4259 case WM_NCCALCSIZE:
4260 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
4261
4262 case WM_NCPAINT:
4263 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
4264
4265 case WM_NOTIFY:
4266 return TOOLBAR_Notify (hwnd, wParam, lParam);
4267
4268 case WM_PAINT:
4269 return TOOLBAR_Paint (hwnd, wParam);
4270
4271 case WM_SIZE:
4272 return TOOLBAR_Size (hwnd, wParam, lParam);
4273
4274 case WM_STYLECHANGED:
4275 return TOOLBAR_StyleChanged (hwnd, (INT)wParam, (LPSTYLESTRUCT)lParam);
4276
4277/* case WM_SYSCOLORCHANGE: */
4278
4279/* case WM_WININICHANGE: */
4280
4281 case WM_CHARTOITEM:
4282 case WM_COMMAND:
4283 case WM_DRAWITEM:
4284 case WM_MEASUREITEM:
4285 case WM_VKEYTOITEM:
4286 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
4287
4288 default:
4289// if (uMsg >= WM_USER)
4290// ERR (toolbar, "unknown msg %04x wp=%08x lp=%08lx\n",
4291// uMsg, wParam, lParam);
4292 return defComCtl32ProcA (hwnd, uMsg, wParam, lParam);
4293 }
4294 return 0;
4295}
4296
4297
4298VOID
4299TOOLBAR_Register (VOID)
4300{
4301 WNDCLASSA wndClass;
4302
4303 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
4304 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
4305 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
4306 wndClass.cbClsExtra = 0;
4307 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
4308 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
4309 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
4310 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
4311
4312 RegisterClassA (&wndClass);
4313}
4314
4315
4316VOID
4317TOOLBAR_Unregister (VOID)
4318{
4319 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);
4320}
4321
Note: See TracBrowser for help on using the repository browser.