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

Last change on this file since 2144 was 2126, checked in by achimha, 26 years ago

WINE 991212 updates - treeview missing

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