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

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

check for null pointers before freeing memory

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