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

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

WM_SETREDRAW changes

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