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

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

trackbar buddy fix, tooltip enhancements

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