source: trunk/src/comctl32/toolbar.c@ 2523

Last change on this file since 2523 was 2523, checked in by cbratschi, 26 years ago

added API logging, removed progress frame

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