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

Last change on this file since 3154 was 3154, checked in by cbratschi, 25 years ago

Corel 20000317 merge, ccbase finished, bug fixes

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