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

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

Unicode and other extensions

File size: 94.5 KB
Line 
1/* $Id: toolbar.c,v 1.9 1999-07-04 21:06:00 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.
13 * - Notifications.
14 * - Fix TB_SETROWS.
15 * - Tooltip support (almost complete).
16 * - Internal COMMCTL32 bitmaps.
17 * - Fix TOOLBAR_SetButtonInfo32A.
18 * - Customize dialog (under construction).
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/* CB: Odin32/WINE bugs
31 - IMAGELIST_Draw draws a line too much at the bottom of the bitmap
32*/
33
34#include <string.h>
35
36#include "winbase.h"
37#include "commctrl.h"
38#include "cache.h"
39#include "comctl32.h"
40#include "toolbar.h"
41
42#define SEPARATOR_WIDTH 8
43#define TOP_BORDER 2
44#define BOTTOM_BORDER 2
45
46#define TOOLBAR_GetInfoPtr(wndPtr) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0))
47
48
49static void
50TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc)
51{
52 INT x = (lpRect->left + lpRect->right) / 2 - 1;
53 INT yBottom = lpRect->bottom - 3;
54 INT yTop = lpRect->top + 1;
55
56 SelectObject ( hdc, GetSysColorPen (COLOR_3DSHADOW));
57 MoveToEx (hdc, x, yBottom, NULL);
58 LineTo (hdc, x, yTop);
59 x++;
60 SelectObject ( hdc, GetSysColorPen (COLOR_3DHILIGHT));
61 MoveToEx (hdc, x, yBottom, NULL);
62 LineTo (hdc, x, yTop);
63}
64
65
66static void
67TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
68 HDC hdc, INT nState)
69{
70 RECT rcText = btnPtr->rect;
71 HFONT hOldFont;
72 INT nOldBkMode;
73 COLORREF clrOld;
74
75 /* draw text */
76 if ((btnPtr->iString > -1) && (btnPtr->iString < infoPtr->nNumStrings)) {
77 InflateRect (&rcText, -3, -3);
78 rcText.top += infoPtr->nBitmapHeight;
79 if (nState & (TBSTATE_PRESSED | TBSTATE_CHECKED))
80 OffsetRect (&rcText, 1, 1);
81
82 hOldFont = SelectObject (hdc, infoPtr->hFont);
83 nOldBkMode = SetBkMode (hdc, TRANSPARENT);
84 if (!(nState & TBSTATE_ENABLED)) {
85 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DHILIGHT));
86 OffsetRect (&rcText, 1, 1);
87 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
88 &rcText, infoPtr->dwDTFlags);
89 SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
90 OffsetRect (&rcText, -1, -1);
91 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
92 &rcText, infoPtr->dwDTFlags);
93 }
94 else if (nState & TBSTATE_INDETERMINATE) {
95 clrOld = SetTextColor (hdc, GetSysColor (COLOR_3DSHADOW));
96 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
97 &rcText, infoPtr->dwDTFlags);
98 }
99 else {
100 clrOld = SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
101 DrawTextW (hdc, infoPtr->strings[btnPtr->iString], -1,
102 &rcText, infoPtr->dwDTFlags);
103 }
104
105 SetTextColor (hdc, clrOld);
106 SelectObject (hdc, hOldFont);
107 if (nOldBkMode != TRANSPARENT)
108 SetBkMode (hdc, nOldBkMode);
109 }
110}
111
112
113static void
114TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
115{
116 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
117 INT cx = lpRect->right - lpRect->left;
118 INT cy = lpRect->bottom - lpRect->top;
119 PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
120 SelectObject (hdc, hbr);
121}
122
123
124static void
125TOOLBAR_DrawMasked (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
126 HDC hdc, INT x, INT y)
127{
128 /* FIXME: this function is a hack since it uses image list
129 internals directly */
130
131 HDC hdcImageList = CreateCompatibleDC (0);
132 HDC hdcMask = CreateCompatibleDC (0);
133 HIMAGELIST himl = infoPtr->himlStd;
134 HBITMAP hbmMask;
135
136 /* create new bitmap */
137 hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
138 SelectObject (hdcMask, hbmMask);
139
140 /* copy the mask bitmap */
141 SelectObject (hdcImageList, himl->hbmMask);
142 SetBkColor (hdcImageList, RGB(255, 255, 255));
143 SetTextColor (hdcImageList, RGB(0, 0, 0));
144 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
145 hdcImageList, himl->cx * btnPtr->iBitmap, 0, SRCCOPY);
146
147#if 0
148 /* add white mask from image */
149 SelectObject (hdcImageList, himl->hbmImage);
150 SetBkColor (hdcImageList, RGB(0, 0, 0));
151 BitBlt (hdcMask, 0, 0, himl->cx, himl->cy,
152 hdcImageList, himl->cx * btnPtr->iBitmap, 0, MERGEPAINT);
153#endif
154
155 /* draw the new mask */
156 SelectObject (hdc, GetSysColorBrush (COLOR_3DHILIGHT));
157 BitBlt (hdc, x+1, y+1, himl->cx, himl->cy,
158 hdcMask, 0, 0, 0xB8074A);
159
160 SelectObject (hdc, GetSysColorBrush (COLOR_3DSHADOW));
161 BitBlt (hdc, x, y, himl->cx, himl->cy,
162 hdcMask, 0, 0, 0xB8074A);
163
164 DeleteObject (hbmMask);
165 DeleteDC (hdcMask);
166 DeleteDC (hdcImageList);
167}
168
169
170static void
171TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
172{
173 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
174 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
175 RECT rc;
176
177 if (btnPtr->fsState & TBSTATE_HIDDEN) return;
178
179 rc = btnPtr->rect;
180 if (btnPtr->fsStyle & TBSTYLE_SEP)
181 {
182 if ((dwStyle & TBSTYLE_FLAT) && (btnPtr->idCommand == 0))
183 TOOLBAR_DrawFlatSeparator (&btnPtr->rect, hdc);
184 return;
185 }
186
187 /* disabled */
188 if (!(btnPtr->fsState & TBSTATE_ENABLED))
189 {
190 DrawEdge (hdc, &rc, EDGE_RAISED,
191 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
192
193 if (dwStyle & TBSTYLE_FLAT)
194 {
195/* if (infoPtr->himlDis) */
196 ImageList_Draw (infoPtr->himlDis, btnPtr->iBitmap, hdc,
197 rc.left+1, rc.top+1, ILD_NORMAL);
198/* else */
199/* TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1); */
200 } else
201 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
202
203 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
204 return;
205 }
206
207 /* pressed TBSTYLE_BUTTON */
208 if (btnPtr->fsState & TBSTATE_PRESSED)
209 {
210 DrawEdge (hdc, &rc, EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_ADJUST);
211 ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
212 rc.left+2, rc.top+2, ILD_NORMAL);
213 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
214 return;
215 }
216
217 /* checked TBSTYLE_CHECK*/
218 if ((btnPtr->fsStyle & TBSTYLE_CHECK) &&
219 (btnPtr->fsState & TBSTATE_CHECKED)) {
220 if (dwStyle & TBSTYLE_FLAT)
221 DrawEdge (hdc, &rc, BDR_SUNKENOUTER,
222 BF_RECT | BF_MIDDLE | BF_ADJUST);
223 else
224 DrawEdge (hdc, &rc, EDGE_SUNKEN,
225 BF_RECT | BF_MIDDLE | BF_ADJUST);
226
227 TOOLBAR_DrawPattern (hdc, &rc);
228 if (dwStyle & TBSTYLE_FLAT)
229 {
230 if (infoPtr->himlDef != NULL)
231 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
232 rc.left+2, rc.top+2, ILD_NORMAL);
233 else
234 ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
235 rc.left+2, rc.top+2, ILD_NORMAL);
236 } else
237 ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
238 rc.left+2, rc.top+2, ILD_NORMAL);
239 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
240 return;
241 }
242
243 /* indeterminate */
244 if (btnPtr->fsState & TBSTATE_INDETERMINATE)
245 {
246 DrawEdge (hdc, &rc, EDGE_RAISED,
247 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
248
249 TOOLBAR_DrawPattern (hdc, &rc);
250 TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rc.left+1, rc.top+1);
251 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
252 return;
253 }
254
255 if (dwStyle & TBSTYLE_FLAT)
256 {
257 if(btnPtr->bHot)
258 DrawEdge (hdc, &rc, BDR_RAISEDINNER,
259 BF_RECT | BF_MIDDLE | BF_SOFT);
260
261 if(infoPtr->himlDef != NULL)
262 ImageList_Draw (infoPtr->himlDef, btnPtr->iBitmap, hdc,
263 rc.left +2, rc.top +2, ILD_NORMAL);
264 else
265 ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
266 rc.left +2, rc.top +2, ILD_NORMAL);
267 } else
268 {
269 /* normal state */
270 DrawEdge (hdc, &rc, EDGE_RAISED,
271 BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
272
273 ImageList_Draw (infoPtr->himlStd, btnPtr->iBitmap, hdc,
274 rc.left+1, rc.top+1, ILD_NORMAL);
275 }
276
277 TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState);
278}
279
280
281static void
282TOOLBAR_Refresh (HWND hwnd, HDC hdc)
283{
284 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
285 TBUTTON_INFO *btnPtr;
286 INT i;
287
288 /* draw buttons */
289 btnPtr = infoPtr->buttons;
290 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
291 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
292}
293
294
295static void
296TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
297{
298 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
299 TBUTTON_INFO *btnPtr;
300 INT i;
301 HDC hdc;
302 HFONT hOldFont;
303 SIZE sz;
304
305 lpSize->cx = 0;
306 lpSize->cy = 0;
307 hdc = GetDC (0);
308 hOldFont = SelectObject (hdc, infoPtr->hFont);
309
310 btnPtr = infoPtr->buttons;
311 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
312 if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
313 (btnPtr->iString > -1) &&
314 (btnPtr->iString < infoPtr->nNumStrings)) {
315 LPWSTR lpText = infoPtr->strings[btnPtr->iString];
316 GetTextExtentPoint32W (hdc, lpText, lstrlenW (lpText), &sz);
317 if (sz.cx > lpSize->cx)
318 lpSize->cx = sz.cx;
319 if (sz.cy > lpSize->cy)
320 lpSize->cy = sz.cy;
321 }
322 }
323
324 SelectObject (hdc, hOldFont);
325 ReleaseDC (0, hdc);
326
327// TRACE (toolbar, "string size %d x %d!\n", lpSize->cx, lpSize->cy);
328}
329
330/***********************************************************************
331* TOOLBAR_WrapToolbar
332*
333* This function walks through the buttons and seperators in the
334* toolbar, and sets the TBSTATE_WRAP flag only on those items where
335* wrapping should occur based on the width of the toolbar window.
336* It does *not* calculate button placement itself. That task
337* takes place in TOOLBAR_CalcToolbar. If the program wants to manage
338* the toolbar wrapping on it's own, it can use the TBSTYLE_WRAPPABLE
339* flag, and set the TBSTATE_WRAP flags manually on the appropriate items.
340*/
341
342static void
343TOOLBAR_WrapToolbar( HWND hwnd )
344{
345 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
346 TBUTTON_INFO *btnPtr;
347 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
348 INT x, cx, i, j;
349 RECT rc;
350 BOOL bWrap, bButtonWrap;
351
352 /* When the toolbar window style is not TBSTYLE_WRAPABLE, */
353 /* no layout is necessary. Applications may use this style */
354 /* to perform their own layout on the toolbar. */
355 if( !(dwStyle & TBSTYLE_WRAPABLE) )
356 return;
357
358 btnPtr = infoPtr->buttons;
359 x = infoPtr->nIndent;
360
361 GetClientRect( GetParent(hwnd), &rc );
362 infoPtr->nWidth = rc.right - rc.left;
363 bButtonWrap = FALSE;
364
365 for (i = 0; i < infoPtr->nNumButtons; i++ )
366 {
367 bWrap = FALSE;
368 btnPtr[i].fsState &= ~TBSTATE_WRAP;
369
370 if (btnPtr[i].fsState & TBSTATE_HIDDEN)
371 continue;
372
373 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
374 /* it is the actual width of the separator. This is used for */
375 /* custom controls in toolbars. */
376 if (btnPtr[i].fsStyle & TBSTYLE_SEP)
377 cx = (btnPtr[i].iBitmap > 0) ?
378 btnPtr[i].iBitmap : SEPARATOR_WIDTH;
379 else
380 cx = infoPtr->nButtonWidth;
381
382 /* Two or more adjacent separators form a separator group. */
383 /* The first separator in a group should be wrapped to the */
384 /* next row if the previous wrapping is on a button. */
385 if( bButtonWrap &&
386 (btnPtr[i].fsStyle & TBSTYLE_SEP) &&
387 (i + 1 < infoPtr->nNumButtons ) &&
388 (btnPtr[i + 1].fsStyle & TBSTYLE_SEP) )
389 {
390 btnPtr[i].fsState |= TBSTATE_WRAP;
391 x = infoPtr->nIndent;
392 i++;
393 bButtonWrap = FALSE;
394 continue;
395 }
396
397 /* The layout makes sure the bitmap is visible, but not the button. */
398 if ( x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2
399 > infoPtr->nWidth )
400 {
401 BOOL bFound = FALSE;
402
403 /* If the current button is a separator and not hidden, */
404 /* go to the next until it reaches a non separator. */
405 /* Wrap the last separator if it is before a button. */
406 while( ( (btnPtr[i].fsStyle & TBSTYLE_SEP) ||
407 (btnPtr[i].fsState & TBSTATE_HIDDEN) ) &&
408 i < infoPtr->nNumButtons )
409 {
410 i++;
411 bFound = TRUE;
412 }
413
414 if( bFound && i < infoPtr->nNumButtons )
415 {
416 i--;
417 btnPtr[i].fsState |= TBSTATE_WRAP;
418 x = infoPtr->nIndent;
419 bButtonWrap = FALSE;
420 continue;
421 }
422 else if ( i >= infoPtr->nNumButtons)
423 break;
424
425 /* If the current button is not a separator, find the last */
426 /* separator and wrap it. */
427 for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
428 {
429 if ((btnPtr[j].fsStyle & TBSTYLE_SEP) &&
430 !(btnPtr[j].fsState & TBSTATE_HIDDEN))
431 {
432 bFound = TRUE;
433 i = j;
434 x = infoPtr->nIndent;
435 btnPtr[j].fsState |= TBSTATE_WRAP;
436 bButtonWrap = FALSE;
437 break;
438 }
439 }
440
441 /* If no separator available for wrapping, wrap one of */
442 /* non-hidden previous button. */
443 if (!bFound)
444 {
445 for ( j = i - 1;
446 j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--)
447 {
448 if (btnPtr[j].fsState & TBSTATE_HIDDEN)
449 continue;
450
451 bFound = TRUE;
452 i = j;
453 x = infoPtr->nIndent;
454 btnPtr[j].fsState |= TBSTATE_WRAP;
455 bButtonWrap = TRUE;
456 break;
457 }
458 }
459
460 /* If all above failed, wrap the current button. */
461 if (!bFound)
462 {
463 btnPtr[i].fsState |= TBSTATE_WRAP;
464 bFound = TRUE;
465 x = infoPtr->nIndent;
466 if (btnPtr[i].fsState & TBSTYLE_SEP )
467 bButtonWrap = FALSE;
468 else
469 bButtonWrap = TRUE;
470 }
471 }
472 else
473 x += cx;
474 }
475}
476
477/***********************************************************************
478* TOOLBAR_CalcToolbar
479*
480* This function calculates button and separator placement. It first
481* calculates the button sizes, gets the toolbar window width and then
482* calls TOOLBAR_WrapToolbar to determine which buttons we need to wrap
483* on. It assigns a new location to each item and sends this location to
484* the tooltip window if appropriate. Finally, it updates the rcBound
485* rect and calculates the new required toolbar window height.
486*/
487
488static void
489TOOLBAR_CalcToolbar (HWND hwnd)
490{
491 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
492 TBUTTON_INFO *btnPtr;
493 INT i, nRows, nSepRows;
494 INT x, y, cx, cy;
495 SIZE sizeString;
496 RECT rc;
497 BOOL bWrap;
498
499 TOOLBAR_CalcStrings (hwnd, &sizeString);
500
501 if (sizeString.cy > 0)
502 infoPtr->nButtonHeight = sizeString.cy + infoPtr->nBitmapHeight + 6;
503 else if (infoPtr->nButtonHeight < infoPtr->nBitmapHeight + 6)
504 infoPtr->nButtonHeight = infoPtr->nBitmapHeight + 6;
505
506 if (sizeString.cx > infoPtr->nBitmapWidth)
507 infoPtr->nButtonWidth = sizeString.cx + 6;
508 else if (infoPtr->nButtonWidth < infoPtr->nBitmapWidth + 6)
509 infoPtr->nButtonWidth = infoPtr->nBitmapWidth + 6;
510
511 TOOLBAR_WrapToolbar( hwnd );
512
513 x = infoPtr->nIndent;
514 y = TOP_BORDER;
515 cx = infoPtr->nButtonWidth;
516 cy = infoPtr->nButtonHeight;
517 nRows = nSepRows = 0;
518
519 infoPtr->rcBound.top = y;
520 infoPtr->rcBound.left = x;
521 infoPtr->rcBound.bottom = y + cy;
522 infoPtr->rcBound.right = x;
523
524 btnPtr = infoPtr->buttons;
525 GetClientRect( GetParent(hwnd), &rc );
526 infoPtr->nWidth = rc.right - rc.left;
527
528 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ )
529 {
530 bWrap = FALSE;
531 if (btnPtr->fsState & TBSTATE_HIDDEN)
532 {
533 SetRectEmpty (&btnPtr->rect);
534 continue;
535 }
536
537 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
538 /* it is the actual width of the separator. This is used for */
539 /* custom controls in toolbars. */
540 if (btnPtr->fsStyle & TBSTYLE_SEP)
541 cx = (btnPtr->iBitmap > 0) ?
542 btnPtr->iBitmap : SEPARATOR_WIDTH;
543 else
544 cx = infoPtr->nButtonWidth;
545
546 if (btnPtr->fsState & TBSTATE_WRAP )
547 bWrap = TRUE;
548
549 SetRect (&btnPtr->rect, x, y, x + cx, y + cy);
550
551 if (infoPtr->rcBound.left > x)
552 infoPtr->rcBound.left = x;
553 if (infoPtr->rcBound.right < x + cx)
554 infoPtr->rcBound.right = x + cx;
555 if (infoPtr->rcBound.bottom < y + cy)
556 infoPtr->rcBound.bottom = y + cy;
557
558 /* Set the toolTip only for non-hidden, non-separator button */
559 if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & TBSTYLE_SEP))
560 {
561 TTTOOLINFOA ti;
562
563 ZeroMemory (&ti,sizeof(TTTOOLINFOA));
564 ti.cbSize = sizeof(TTTOOLINFOA);
565 ti.hwnd = hwnd;
566 ti.uId = btnPtr->idCommand;
567 ti.rect = btnPtr->rect;
568 SendMessageA(infoPtr->hwndToolTip,TTM_NEWTOOLRECTA,0,(LPARAM)&ti);
569 }
570
571 /* btnPtr->nRow is zero based. The space between the rows is */
572 /* also considered as a row. */
573 btnPtr->nRow = nRows + nSepRows;
574 if( bWrap )
575 {
576 if ( !(btnPtr->fsStyle & TBSTYLE_SEP) )
577 y += cy;
578 else
579 {
580 /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
581 /* it is the actual width of the separator. This is used for */
582 /* custom controls in toolbars. */
583 y += cy + ( (btnPtr->iBitmap > 0 ) ?
584 btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
585
586 /* nSepRows is used to calculate the extra height follwoing */
587 /* the last row. */
588 nSepRows++;
589 }
590 x = infoPtr->nIndent;
591 nRows++;
592 }
593 else
594 x += cx;
595 }
596
597 /* infoPtr->nRows is the number of rows on the toolbar */
598 infoPtr->nRows = nRows + nSepRows + 1;
599
600 /* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
601 /* the last row. */
602 infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
603 nSepRows * SEPARATOR_WIDTH * 2 / 3 +
604 nSepRows * (infoPtr->nBitmapHeight + 1) +
605 BOTTOM_BORDER;
606// TRACE (toolbar, "toolbar height %d\n", infoPtr->nHeight);
607}
608
609
610static INT
611TOOLBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt)
612{
613 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
614 TBUTTON_INFO *btnPtr;
615 INT i;
616
617 btnPtr = infoPtr->buttons;
618 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
619 if (btnPtr->fsState & TBSTATE_HIDDEN)
620 continue;
621
622 if (btnPtr->fsStyle & TBSTYLE_SEP) {
623 if (PtInRect (&btnPtr->rect, *lpPt)) {
624// TRACE (toolbar, " ON SEPARATOR %d!\n", i);
625 return -i;
626 }
627 }
628 else {
629 if (PtInRect (&btnPtr->rect, *lpPt)) {
630// TRACE (toolbar, " ON BUTTON %d!\n", i);
631 return i;
632 }
633 }
634 }
635
636// TRACE (toolbar, " NOWHERE!\n");
637 return -1;
638}
639
640
641static INT
642TOOLBAR_GetButtonIndex (TOOLBAR_INFO *infoPtr, INT idCommand)
643{
644 TBUTTON_INFO *btnPtr;
645 INT i;
646
647 btnPtr = infoPtr->buttons;
648 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
649 if (btnPtr->idCommand == idCommand) {
650// TRACE (toolbar, "command=%d index=%d\n", idCommand, i);
651 return i;
652 }
653 }
654// TRACE (toolbar, "no index found for command=%d\n", idCommand);
655 return -1;
656}
657
658
659static INT
660TOOLBAR_GetCheckedGroupButtonIndex (TOOLBAR_INFO *infoPtr, INT nIndex)
661{
662 TBUTTON_INFO *btnPtr;
663 INT nRunIndex;
664
665 if ((nIndex < 0) || (nIndex > infoPtr->nNumButtons))
666 return -1;
667
668 /* check index button */
669 btnPtr = &infoPtr->buttons[nIndex];
670 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
671 if (btnPtr->fsState & TBSTATE_CHECKED)
672 return nIndex;
673 }
674
675 /* check previous buttons */
676 nRunIndex = nIndex - 1;
677 while (nRunIndex >= 0) {
678 btnPtr = &infoPtr->buttons[nRunIndex];
679 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
680 if (btnPtr->fsState & TBSTATE_CHECKED)
681 return nRunIndex;
682 }
683 else
684 break;
685 nRunIndex--;
686 }
687
688 /* check next buttons */
689 nRunIndex = nIndex + 1;
690 while (nRunIndex < infoPtr->nNumButtons) {
691 btnPtr = &infoPtr->buttons[nRunIndex];
692 if ((btnPtr->fsStyle & TBSTYLE_CHECKGROUP) == TBSTYLE_CHECKGROUP) {
693 if (btnPtr->fsState & TBSTATE_CHECKED)
694 return nRunIndex;
695 }
696 else
697 break;
698 nRunIndex++;
699 }
700
701 return -1;
702}
703
704
705static VOID
706TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
707 WPARAM wParam, LPARAM lParam)
708{
709 MSG msg;
710
711 msg.hwnd = hwndMsg;
712 msg.message = uMsg;
713 msg.wParam = wParam;
714 msg.lParam = lParam;
715 msg.time = GetMessageTime();
716 msg.pt.x = LOWORD(GetMessagePos());
717 msg.pt.y = HIWORD(GetMessagePos());
718
719 SendMessageA(hwndTip,TTM_RELAYEVENT,0,(LPARAM)&msg);
720}
721
722
723/***********************************************************************
724 * TOOLBAR_CustomizeDialogProc
725 * This function implements the toolbar customization dialog.
726 */
727BOOL WINAPI
728TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
729{
730 TOOLBAR_INFO *infoPtr;
731 static HDSA hDsa = NULL;
732
733 switch (uMsg)
734 {
735 case WM_INITDIALOG:
736 infoPtr = (TOOLBAR_INFO *)lParam;
737 SetWindowLongA (hwnd, DWL_USER, (DWORD)infoPtr);
738
739 hDsa = DSA_Create (sizeof(TBUTTON_INFO), 5);
740
741 if (infoPtr)
742 {
743 TBUTTON_INFO *btnPtr;
744 INT i;
745
746 /* insert 'virtual' separator button into 'available buttons' list */
747 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
748
749 /* copy all buttons and append them to the right listbox */
750 btnPtr = infoPtr->buttons;
751 for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
752 {
753 DSA_InsertItem (hDsa, i, btnPtr);
754
755 if (btnPtr->fsState & TBSTATE_HIDDEN)
756 {
757 SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
758 }
759 else
760 {
761 SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)"");
762 }
763 }
764
765 /* append 'virtual' sepatator button to the 'toolbar buttons' list */
766 /* TODO */
767 }
768 return TRUE;
769
770 case WM_CLOSE:
771 EndDialog(hwnd, FALSE);
772 return TRUE;
773
774 case WM_COMMAND:
775 switch (LOWORD(wParam))
776 {
777 case IDCANCEL:
778 EndDialog(hwnd, FALSE);
779 break;
780 }
781 return TRUE;
782
783 case WM_DESTROY:
784 if (hDsa)
785 DSA_Destroy (hDsa);
786 return TRUE;
787
788 case WM_DRAWITEM:
789 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
790 {
791 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
792 RECT rcButton;
793 RECT rcText;
794 HPEN hOldPen;
795 HBRUSH hOldBrush;
796 COLORREF oldText = 0;
797 COLORREF oldBk = 0;
798
799// FIXME(toolbar, "action: %x itemState: %x\n",
800// lpdis->itemAction, lpdis->itemState);
801
802 infoPtr = (TOOLBAR_INFO *)GetWindowLongA(hwnd,DWL_USER);
803
804 if (lpdis->itemState & ODS_FOCUS)
805 {
806 oldBk = SetBkColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
807 oldText = SetTextColor (lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
808 }
809
810 hOldPen = SelectObject (lpdis->hDC, GetSysColorPen ((lpdis->itemState & ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
811 hOldBrush = SelectObject (lpdis->hDC, GetSysColorBrush ((lpdis->itemState & ODS_FOCUS)?COLOR_HIGHLIGHT:COLOR_WINDOW));
812
813 /* fill background rectangle */
814 Rectangle (lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
815 lpdis->rcItem.right, lpdis->rcItem.bottom);
816
817 /* calculate button and text rectangles */
818 CopyRect (&rcButton, &lpdis->rcItem);
819 InflateRect (&rcButton, -1, -1);
820 CopyRect (&rcText, &rcButton);
821 rcButton.right = rcButton.left + infoPtr->nBitmapWidth + 6;
822 rcText.left = rcButton.right + 2;
823
824 /* draw focus rectangle */
825 if (lpdis->itemState & ODS_FOCUS)
826 DrawFocusRect (lpdis->hDC, &lpdis->rcItem);
827
828 /* draw button */
829 DrawEdge (lpdis->hDC, &rcButton, EDGE_RAISED, BF_RECT|BF_MIDDLE|BF_SOFT);
830
831 /* draw text */
832 if (wParam == IDC_AVAILBTN_LBOX && lpdis->itemID == 0)
833 DrawTextA (lpdis->hDC, "Separator", -1, &rcText,
834 DT_LEFT | DT_VCENTER | DT_SINGLELINE);
835
836 if (lpdis->itemState & ODS_FOCUS)
837 {
838 SetBkColor (lpdis->hDC, oldBk);
839 SetTextColor (lpdis->hDC, oldText);
840 }
841
842 SelectObject (lpdis->hDC, hOldBrush);
843 SelectObject (lpdis->hDC, hOldPen);
844
845 return TRUE;
846 }
847 return FALSE;
848
849 case WM_MEASUREITEM:
850 if (wParam == IDC_AVAILBTN_LBOX || wParam == IDC_TOOLBARBTN_LBOX)
851 {
852 MEASUREITEMSTRUCT *lpmis = (MEASUREITEMSTRUCT*)lParam;
853
854 infoPtr = (TOOLBAR_INFO *)GetWindowLongA(hwnd,DWL_USER);
855
856 if (infoPtr)
857 lpmis->itemHeight = infoPtr->nBitmapHeight + 8;
858 else
859 lpmis->itemHeight = 16 + 8; /* default height */
860
861 return TRUE;
862 }
863 return FALSE;
864
865 default:
866 return FALSE;
867 }
868}
869
870
871/***********************************************************************
872 * TOOLBAR_AddBitmap: Add the bitmaps to the default image list.
873 *
874 */
875static LRESULT
876TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
877{
878 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
879 LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
880 INT nIndex = 0;
881
882 if ((!lpAddBmp) || ((INT)wParam <= 0))
883 return -1;
884
885// TRACE (toolbar, "adding %d bitmaps!\n", wParam);
886
887 if (!(infoPtr->himlStd)) {
888 /* create new standard image list */
889
890// TRACE (toolbar, "creating standard image list!\n");
891
892
893 /* Windows resize all the buttons to the size of a newly added STandard Image*/
894 /* TODO: The resizing should be done each time a standard image is added*/
895 if (lpAddBmp->hInst == HINST_COMMCTRL)
896 {
897
898 if (lpAddBmp->nID & 1)
899 {
900 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
901 MAKELPARAM((WORD)26, (WORD)26));
902 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
903 MAKELPARAM((WORD)33, (WORD)33));
904 }
905 else
906 {
907 SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
908 MAKELPARAM((WORD)16, (WORD)16));
909
910 SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
911 MAKELPARAM((WORD)22, (WORD)22));
912 }
913
914 TOOLBAR_CalcToolbar (hwnd);
915 }
916
917 infoPtr->himlStd =
918 ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight,
919 ILC_COLOR | ILC_MASK, (INT)wParam, 2);
920 }
921
922 /* Add bitmaps to the standard image list */
923 if (lpAddBmp->hInst == (HINSTANCE)0) {
924 nIndex =
925 ImageList_AddMasked (infoPtr->himlStd, (HBITMAP)lpAddBmp->nID,
926 CLR_DEFAULT);
927 }
928 else if (lpAddBmp->hInst == HINST_COMMCTRL) {
929 /* add internal bitmaps */
930
931// FIXME (toolbar, "internal bitmaps not supported!\n");
932 /* TODO: Resize all the buttons when a new standard image is added */
933
934 /* Hack to "add" some reserved images within the image list
935 to get the right image indices */
936 nIndex = ImageList_GetImageCount (infoPtr->himlStd);
937 ImageList_SetImageCount (infoPtr->himlStd, nIndex + (INT)wParam);
938
939 }
940 else {
941 HBITMAP hBmp =
942 LoadBitmapA (lpAddBmp->hInst, (LPSTR)lpAddBmp->nID);
943 nIndex = ImageList_AddMasked (infoPtr->himlStd, hBmp, CLR_DEFAULT);
944
945 DeleteObject (hBmp);
946 }
947
948 infoPtr->nNumBitmaps += (INT)wParam;
949
950 return nIndex;
951}
952
953
954static LRESULT
955TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
956{
957 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
958 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
959 INT nOldButtons, nNewButtons, nAddButtons, nCount;
960
961// TRACE (toolbar, "adding %d buttons!\n", wParam);
962
963 nAddButtons = (UINT)wParam;
964 nOldButtons = infoPtr->nNumButtons;
965 nNewButtons = nOldButtons + nAddButtons;
966
967 if (infoPtr->nNumButtons == 0) {
968 infoPtr->buttons =
969 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
970 }
971 else {
972 TBUTTON_INFO *oldButtons = infoPtr->buttons;
973 infoPtr->buttons =
974 COMCTL32_Alloc (sizeof(TBUTTON_INFO) * nNewButtons);
975 memcpy (&infoPtr->buttons[0], &oldButtons[0],
976 nOldButtons * sizeof(TBUTTON_INFO));
977 COMCTL32_Free (oldButtons);
978 }
979
980 infoPtr->nNumButtons = nNewButtons;
981
982 /* insert new button data */
983 for (nCount = 0; nCount < nAddButtons; nCount++)
984 {
985 TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount];
986 btnPtr->iBitmap = lpTbb[nCount].iBitmap;
987 btnPtr->idCommand = lpTbb[nCount].idCommand;
988 btnPtr->fsState = lpTbb[nCount].fsState;
989 btnPtr->fsStyle = lpTbb[nCount].fsStyle;
990 btnPtr->dwData = lpTbb[nCount].dwData;
991 btnPtr->iString = lpTbb[nCount].iString;
992 btnPtr->bHot = FALSE;
993
994 if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & TBSTYLE_SEP))
995 {
996 TTTOOLINFOA ti;
997
998 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
999 ti.cbSize = sizeof (TTTOOLINFOA);
1000 ti.hwnd = hwnd;
1001 ti.uId = btnPtr->idCommand;
1002 ti.hinst = 0;
1003 ti.lpszText = LPSTR_TEXTCALLBACKA;
1004
1005 SendMessageA (infoPtr->hwndToolTip,TTM_ADDTOOLA,0,(LPARAM)&ti);
1006 }
1007 }
1008
1009 TOOLBAR_CalcToolbar(hwnd);
1010
1011 InvalidateRect(hwnd,NULL,FALSE);
1012
1013 return TRUE;
1014}
1015
1016
1017static LRESULT TOOLBAR_AddButtonsW(HWND hwnd,WPARAM wParam,LPARAM lParam)
1018{
1019 //CB: just call AddButtonsA, no Unicode used?!?
1020
1021 return TOOLBAR_AddButtonsA(hwnd,wParam,lParam);
1022}
1023
1024/* << TOOLBAR_AddButtons32W >> */
1025
1026
1027static LRESULT
1028TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1029{
1030 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1031 INT nIndex;
1032
1033 if ((wParam) && (HIWORD(lParam) == 0)) {
1034 char szString[256];
1035 INT len;
1036// TRACE (toolbar, "adding string from resource!\n");
1037
1038 len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam,
1039 szString, 256);
1040
1041// TRACE (toolbar, "len=%d \"%s\"\n", len, szString);
1042 nIndex = infoPtr->nNumStrings;
1043 if (infoPtr->nNumStrings == 0) {
1044 infoPtr->strings =
1045 COMCTL32_Alloc (sizeof(LPWSTR));
1046 }
1047 else {
1048 LPWSTR *oldStrings = infoPtr->strings;
1049 infoPtr->strings =
1050 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1051 memcpy (&infoPtr->strings[0], &oldStrings[0],
1052 sizeof(LPWSTR) * infoPtr->nNumStrings);
1053 COMCTL32_Free (oldStrings);
1054 }
1055
1056 infoPtr->strings[infoPtr->nNumStrings] =
1057 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1058 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], szString);
1059 infoPtr->nNumStrings++;
1060 }
1061 else {
1062 LPSTR p = (LPSTR)lParam;
1063 INT len;
1064
1065 if (p == NULL)
1066 return -1;
1067// TRACE (toolbar, "adding string(s) from array!\n");
1068 nIndex = infoPtr->nNumStrings;
1069 while (*p) {
1070 len = lstrlenA (p);
1071// TRACE (toolbar, "len=%d \"%s\"\n", len, p);
1072
1073 if (infoPtr->nNumStrings == 0) {
1074 infoPtr->strings =
1075 COMCTL32_Alloc (sizeof(LPWSTR));
1076 }
1077 else {
1078 LPWSTR *oldStrings = infoPtr->strings;
1079 infoPtr->strings =
1080 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1081 memcpy (&infoPtr->strings[0], &oldStrings[0],
1082 sizeof(LPWSTR) * infoPtr->nNumStrings);
1083 COMCTL32_Free (oldStrings);
1084 }
1085
1086 infoPtr->strings[infoPtr->nNumStrings] =
1087 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1088 lstrcpyAtoW (infoPtr->strings[infoPtr->nNumStrings], p);
1089 infoPtr->nNumStrings++;
1090
1091 p += (len+1);
1092 }
1093 }
1094
1095 return nIndex;
1096}
1097
1098
1099static LRESULT
1100TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1101{
1102 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1103 INT nIndex;
1104
1105 if ((wParam) && (HIWORD(lParam) == 0)) {
1106 WCHAR szString[256];
1107 INT len;
1108// TRACE (toolbar, "adding string from resource!\n");
1109
1110 len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam,
1111 szString, 256);
1112
1113// TRACE (toolbar, "len=%d \"%s\"\n", len, debugstr_w(szString));
1114 nIndex = infoPtr->nNumStrings;
1115 if (infoPtr->nNumStrings == 0) {
1116 infoPtr->strings =
1117 COMCTL32_Alloc (sizeof(LPWSTR));
1118 }
1119 else {
1120 LPWSTR *oldStrings = infoPtr->strings;
1121 infoPtr->strings =
1122 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1123 memcpy (&infoPtr->strings[0], &oldStrings[0],
1124 sizeof(LPWSTR) * infoPtr->nNumStrings);
1125 COMCTL32_Free (oldStrings);
1126 }
1127
1128 infoPtr->strings[infoPtr->nNumStrings] =
1129 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1130 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], szString);
1131 infoPtr->nNumStrings++;
1132 }
1133 else {
1134 LPWSTR p = (LPWSTR)lParam;
1135 INT len;
1136
1137 if (p == NULL)
1138 return -1;
1139// TRACE (toolbar, "adding string(s) from array!\n");
1140 nIndex = infoPtr->nNumStrings;
1141 while (*p) {
1142 len = lstrlenW (p);
1143// TRACE (toolbar, "len=%d \"%s\"\n", len, debugstr_w(p));
1144
1145 if (infoPtr->nNumStrings == 0) {
1146 infoPtr->strings =
1147 COMCTL32_Alloc (sizeof(LPWSTR));
1148 }
1149 else {
1150 LPWSTR *oldStrings = infoPtr->strings;
1151 infoPtr->strings =
1152 COMCTL32_Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1));
1153 memcpy (&infoPtr->strings[0], &oldStrings[0],
1154 sizeof(LPWSTR) * infoPtr->nNumStrings);
1155 COMCTL32_Free (oldStrings);
1156 }
1157
1158 infoPtr->strings[infoPtr->nNumStrings] =
1159 COMCTL32_Alloc (sizeof(WCHAR)*(len+1));
1160 lstrcpyW (infoPtr->strings[infoPtr->nNumStrings], p);
1161 infoPtr->nNumStrings++;
1162
1163 p += (len+1);
1164 }
1165 }
1166
1167 return nIndex;
1168}
1169
1170
1171static LRESULT
1172TOOLBAR_AutoSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1173{
1174 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1175 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1176 RECT parent_rect;
1177 HWND parent;
1178 /* INT32 x, y; */
1179 INT cx, cy;
1180 UINT uPosFlags = 0;
1181
1182// TRACE (toolbar, "resize forced!\n");
1183
1184 parent = GetParent (hwnd);
1185 GetClientRect(parent, &parent_rect);
1186
1187 if (dwStyle & CCS_NORESIZE) {
1188 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
1189 cx = 0;
1190 cy = 0;
1191 }
1192 else {
1193 infoPtr->nWidth = parent_rect.right - parent_rect.left;
1194 TOOLBAR_CalcToolbar (hwnd);
1195 InvalidateRect( hwnd, NULL, TRUE );
1196 cy = infoPtr->nHeight;
1197 cx = infoPtr->nWidth;
1198 }
1199
1200 if (dwStyle & CCS_NOPARENTALIGN)
1201 uPosFlags |= SWP_NOMOVE;
1202
1203 if (!(dwStyle & CCS_NODIVIDER))
1204 cy += GetSystemMetrics(SM_CYEDGE);
1205
1206 infoPtr->bAutoSize = TRUE;
1207 SetWindowPos (hwnd, HWND_TOP, parent_rect.left, parent_rect.top,
1208 cx, cy, uPosFlags);
1209
1210 return 0;
1211}
1212
1213
1214static LRESULT
1215TOOLBAR_ButtonCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
1216{
1217 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1218
1219 return infoPtr->nNumButtons;
1220}
1221
1222
1223static LRESULT
1224TOOLBAR_ButtonStructSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1225{
1226 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1227
1228 if (infoPtr == NULL) {
1229// ERR (toolbar, "(0x%x, 0x%x, 0x%lx)\n", hwnd, wParam, lParam);
1230// ERR (toolbar, "infoPtr == NULL!\n");
1231 return 0;
1232 }
1233
1234 infoPtr->dwStructSize = (DWORD)wParam;
1235
1236 return 0;
1237}
1238
1239
1240static LRESULT
1241TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1242{
1243 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1244 TBUTTON_INFO *btnPtr;
1245 HDC hdc;
1246 INT nIndex;
1247
1248 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1249 if (nIndex == -1)
1250 return FALSE;
1251
1252 btnPtr = &infoPtr->buttons[nIndex];
1253 btnPtr->iBitmap = LOWORD(lParam);
1254
1255 hdc = GetDC (hwnd);
1256 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
1257 ReleaseDC (hwnd, hdc);
1258
1259 return TRUE;
1260}
1261
1262
1263static LRESULT
1264TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1265{
1266 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1267 TBUTTON_INFO *btnPtr;
1268 HDC hdc;
1269 INT nIndex;
1270 INT nOldIndex = -1;
1271
1272 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1273 if (nIndex == -1)
1274 return FALSE;
1275
1276 btnPtr = &infoPtr->buttons[nIndex];
1277
1278 if (!(btnPtr->fsStyle & TBSTYLE_CHECK))
1279 return FALSE;
1280
1281 if (LOWORD(lParam) == FALSE)
1282 btnPtr->fsState &= ~TBSTATE_CHECKED;
1283 else {
1284 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
1285 nOldIndex =
1286 TOOLBAR_GetCheckedGroupButtonIndex (infoPtr, nIndex);
1287 if (nOldIndex == nIndex)
1288 return 0;
1289 if (nOldIndex != -1)
1290 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
1291 }
1292 btnPtr->fsState |= TBSTATE_CHECKED;
1293 }
1294
1295 hdc = GetDC (hwnd);
1296 if (nOldIndex != -1)
1297 TOOLBAR_DrawButton (hwnd, &infoPtr->buttons[nOldIndex], hdc);
1298 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
1299 ReleaseDC (hwnd, hdc);
1300
1301 /* FIXME: Send a WM_NOTIFY?? */
1302
1303 return TRUE;
1304}
1305
1306
1307static LRESULT
1308TOOLBAR_CommandToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
1309{
1310 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1311
1312 return TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1313}
1314
1315static LRESULT
1316TOOLBAR_Customize (HWND hwnd)
1317{
1318 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1319 LRESULT ret;
1320 LPCVOID template;
1321 HRSRC hRes;
1322 NMHDR nmhdr;
1323
1324 /* send TBN_BEGINADJUST notification */
1325 nmhdr.hwndFrom = hwnd;
1326 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1327 nmhdr.code = TBN_BEGINADJUST;
1328
1329 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1330 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1331
1332 //load OS/2 dialog
1333
1334 ret = NativeDlgBoxIP(COMCTL32_hModule,
1335 GetWindowLongA(hwnd,GWL_HINSTANCE),
1336 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
1337 hwnd,
1338 (DLGPROC)TOOLBAR_CustomizeDialogProc,
1339 (LPARAM)infoPtr);
1340
1341 if (ret == (INT)-1) return FALSE;
1342
1343/* //original WINE code
1344 if (!(hRes = FindResourceA (COMCTL32_hModule,
1345 MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
1346 RT_DIALOGA)))
1347 return FALSE;
1348
1349 if(!(template = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
1350 return FALSE;
1351
1352 ret = DialogBoxIndirectParamA (GetWindowLongA (hwnd, GWL_HINSTANCE),
1353 (LPDLGTEMPLATEA)template,
1354 hwnd,
1355 (DLGPROC)TOOLBAR_CustomizeDialogProc,
1356 (LPARAM)infoPtr);
1357*/
1358
1359 /* send TBN_ENDADJUST notification */
1360 nmhdr.code = TBN_ENDADJUST;
1361
1362 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
1363 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1364
1365 return ret;
1366}
1367
1368
1369static LRESULT
1370TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1371{
1372 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1373 INT nIndex = (INT)wParam;
1374
1375 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1376 return FALSE;
1377
1378 if ((infoPtr->hwndToolTip) &&
1379 !(infoPtr->buttons[nIndex].fsStyle & TBSTYLE_SEP)) {
1380 TTTOOLINFOA ti;
1381
1382 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1383 ti.cbSize = sizeof (TTTOOLINFOA);
1384 ti.hwnd = hwnd;
1385 ti.uId = infoPtr->buttons[nIndex].idCommand;
1386
1387 SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
1388 }
1389
1390 if (infoPtr->nNumButtons == 1) {
1391// TRACE (toolbar, " simple delete!\n");
1392 COMCTL32_Free (infoPtr->buttons);
1393 infoPtr->buttons = NULL;
1394 infoPtr->nNumButtons = 0;
1395 }
1396 else {
1397 TBUTTON_INFO *oldButtons = infoPtr->buttons;
1398// TRACE(toolbar, "complex delete! [nIndex=%d]\n", nIndex);
1399
1400 infoPtr->nNumButtons--;
1401 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
1402 if (nIndex > 0) {
1403 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1404 nIndex * sizeof(TBUTTON_INFO));
1405 }
1406
1407 if (nIndex < infoPtr->nNumButtons) {
1408 memcpy (&infoPtr->buttons[nIndex], &oldButtons[nIndex+1],
1409 (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO));
1410 }
1411
1412 COMCTL32_Free (oldButtons);
1413 }
1414
1415 TOOLBAR_CalcToolbar (hwnd);
1416
1417 InvalidateRect (hwnd, NULL, TRUE);
1418
1419 return TRUE;
1420}
1421
1422
1423static LRESULT
1424TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1425{
1426 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1427 TBUTTON_INFO *btnPtr;
1428 HDC hdc;
1429 INT nIndex;
1430
1431 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1432 if (nIndex == -1)
1433 return FALSE;
1434
1435 btnPtr = &infoPtr->buttons[nIndex];
1436 if (LOWORD(lParam) == FALSE)
1437 btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED);
1438 else
1439 btnPtr->fsState |= TBSTATE_ENABLED;
1440
1441 hdc = GetDC (hwnd);
1442 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
1443 ReleaseDC (hwnd, hdc);
1444
1445 return TRUE;
1446}
1447
1448
1449/* << TOOLBAR_GetAnchorHighlight >> */
1450
1451
1452static LRESULT
1453TOOLBAR_GetBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
1454{
1455 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1456 INT nIndex;
1457
1458 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1459 if (nIndex == -1)
1460 return -1;
1461
1462 return infoPtr->buttons[nIndex].iBitmap;
1463}
1464
1465
1466static LRESULT
1467TOOLBAR_GetBitmapFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
1468{
1469 return (GetDeviceCaps (0, LOGPIXELSX) >= 120) ? TBBF_LARGE : 0;
1470}
1471
1472
1473static LRESULT
1474TOOLBAR_GetButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1475{
1476 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1477 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1478 INT nIndex = (INT)wParam;
1479 TBUTTON_INFO *btnPtr;
1480
1481 if (infoPtr == NULL)
1482 return FALSE;
1483
1484 if (lpTbb == NULL)
1485 return FALSE;
1486
1487 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1488 return FALSE;
1489
1490 btnPtr = &infoPtr->buttons[nIndex];
1491 lpTbb->iBitmap = btnPtr->iBitmap;
1492 lpTbb->idCommand = btnPtr->idCommand;
1493 lpTbb->fsState = btnPtr->fsState;
1494 lpTbb->fsStyle = btnPtr->fsStyle;
1495 lpTbb->dwData = btnPtr->dwData;
1496 lpTbb->iString = btnPtr->iString;
1497
1498 return TRUE;
1499}
1500
1501
1502static LRESULT
1503TOOLBAR_GetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1504{
1505 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1506 LPTBBUTTONINFOA lpTbInfo = (LPTBBUTTONINFOA)lParam;
1507 TBUTTON_INFO *btnPtr;
1508 INT nIndex;
1509
1510 if (infoPtr == NULL)
1511 return -1;
1512 if (lpTbInfo == NULL)
1513 return -1;
1514 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOA))
1515 return -1;
1516
1517 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1518 if (nIndex == -1)
1519 return -1;
1520
1521 btnPtr = &infoPtr->buttons[nIndex];
1522
1523 if (lpTbInfo->dwMask & TBIF_COMMAND)
1524 lpTbInfo->idCommand = btnPtr->idCommand;
1525 if (lpTbInfo->dwMask & TBIF_IMAGE)
1526 lpTbInfo->iImage = btnPtr->iBitmap;
1527 if (lpTbInfo->dwMask & TBIF_LPARAM)
1528 lpTbInfo->lParam = btnPtr->dwData;
1529 if (lpTbInfo->dwMask & TBIF_SIZE)
1530 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1531 if (lpTbInfo->dwMask & TBIF_STATE)
1532 lpTbInfo->fsState = btnPtr->fsState;
1533 if (lpTbInfo->dwMask & TBIF_STYLE)
1534 lpTbInfo->fsStyle = btnPtr->fsStyle;
1535 if (lpTbInfo->dwMask & TBIF_TEXT) {
1536 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
1537 lstrcpynWtoA (lpTbInfo->pszText,
1538 infoPtr->strings[btnPtr->iString],
1539 lpTbInfo->cchText);
1540 }
1541
1542 return nIndex;
1543}
1544
1545static LRESULT TOOLBAR_GetButtonInfoW(HWND hwnd,WPARAM wParam,LPARAM lParam)
1546{
1547 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1548 LPTBBUTTONINFOW lpTbInfo = (LPTBBUTTONINFOW)lParam;
1549 TBUTTON_INFO *btnPtr;
1550 INT nIndex;
1551
1552 if (infoPtr == NULL)
1553 return -1;
1554 if (lpTbInfo == NULL)
1555 return -1;
1556 if (lpTbInfo->cbSize < sizeof(TBBUTTONINFOW))
1557 return -1;
1558
1559 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1560 if (nIndex == -1)
1561 return -1;
1562
1563 btnPtr = &infoPtr->buttons[nIndex];
1564
1565 if (lpTbInfo->dwMask & TBIF_COMMAND)
1566 lpTbInfo->idCommand = btnPtr->idCommand;
1567 if (lpTbInfo->dwMask & TBIF_IMAGE)
1568 lpTbInfo->iImage = btnPtr->iBitmap;
1569 if (lpTbInfo->dwMask & TBIF_LPARAM)
1570 lpTbInfo->lParam = btnPtr->dwData;
1571 if (lpTbInfo->dwMask & TBIF_SIZE)
1572 lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
1573 if (lpTbInfo->dwMask & TBIF_STATE)
1574 lpTbInfo->fsState = btnPtr->fsState;
1575 if (lpTbInfo->dwMask & TBIF_STYLE)
1576 lpTbInfo->fsStyle = btnPtr->fsStyle;
1577 if (lpTbInfo->dwMask & TBIF_TEXT) {
1578 if ((btnPtr->iString >= 0) || (btnPtr->iString < infoPtr->nNumStrings))
1579 lstrcpynW (lpTbInfo->pszText,
1580 infoPtr->strings[btnPtr->iString],
1581 lpTbInfo->cchText);
1582 }
1583
1584 return nIndex;
1585}
1586
1587/* << TOOLBAR_GetButtonInfo32W >> */
1588
1589
1590static LRESULT
1591TOOLBAR_GetButtonSize (HWND hwnd)
1592{
1593 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1594
1595 return MAKELONG((WORD)infoPtr->nButtonWidth,
1596 (WORD)infoPtr->nButtonHeight);
1597}
1598
1599
1600static LRESULT
1601TOOLBAR_GetButtonTextA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1602{
1603 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1604 INT nIndex, nStringIndex;
1605
1606 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1607 if (nIndex == -1)
1608 return -1;
1609
1610 nStringIndex = infoPtr->buttons[nIndex].iString;
1611
1612// TRACE (toolbar, "index=%d stringIndex=%d\n", nIndex, nStringIndex);
1613
1614 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
1615 return -1;
1616
1617 if (lParam == 0) return -1;
1618
1619 lstrcpyWtoA ((LPSTR)lParam, infoPtr->strings[nStringIndex]);
1620
1621 return lstrlenW (infoPtr->strings[nStringIndex]);
1622}
1623
1624static LRESULT TOOLBAR_GetButtonTextW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1625{
1626 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1627 INT nIndex, nStringIndex;
1628
1629 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1630 if (nIndex == -1)
1631 return -1;
1632
1633 nStringIndex = infoPtr->buttons[nIndex].iString;
1634
1635// TRACE (toolbar, "index=%d stringIndex=%d\n", nIndex, nStringIndex);
1636
1637 if ((nStringIndex < 0) || (nStringIndex >= infoPtr->nNumStrings))
1638 return -1;
1639
1640 if (lParam == 0) return -1;
1641
1642 lstrcpyW ((LPWSTR)lParam, infoPtr->strings[nStringIndex]);
1643
1644 return lstrlenW (infoPtr->strings[nStringIndex]);
1645}
1646
1647/* << TOOLBAR_GetButtonText32W >> */
1648/* << TOOLBAR_GetColorScheme >> */
1649
1650
1651static LRESULT
1652TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1653{
1654 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1655
1656 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
1657 return (LRESULT)infoPtr->himlDis;
1658 else
1659 return 0;
1660}
1661
1662
1663static LRESULT
1664TOOLBAR_GetExtendedStyle (HWND hwnd)
1665{
1666 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1667
1668 return infoPtr->dwExStyle;
1669}
1670
1671
1672static LRESULT
1673TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1674{
1675 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1676
1677 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
1678 return (LRESULT)infoPtr->himlHot;
1679 else
1680 return 0;
1681}
1682
1683
1684/* << TOOLBAR_GetHotItem >> */
1685
1686
1687static LRESULT
1688TOOLBAR_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
1689{
1690 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1691
1692 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT)
1693 return (LRESULT)infoPtr->himlDef;
1694 else
1695 return 0;
1696}
1697
1698
1699/* << TOOLBAR_GetInsertMark >> */
1700/* << TOOLBAR_GetInsertMarkColor >> */
1701
1702
1703static LRESULT
1704TOOLBAR_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
1705{
1706 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1707 TBUTTON_INFO *btnPtr;
1708 LPRECT lpRect;
1709 INT nIndex;
1710
1711 if (infoPtr == NULL)
1712 return FALSE;
1713 nIndex = (INT)wParam;
1714 btnPtr = &infoPtr->buttons[nIndex];
1715 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1716 return FALSE;
1717 lpRect = (LPRECT)lParam;
1718 if (lpRect == NULL)
1719 return FALSE;
1720 if (btnPtr->fsState & TBSTATE_HIDDEN)
1721 return FALSE;
1722
1723 TOOLBAR_CalcToolbar( hwnd );
1724
1725 lpRect->left = btnPtr->rect.left;
1726 lpRect->right = btnPtr->rect.right;
1727 lpRect->bottom = btnPtr->rect.bottom;
1728 lpRect->top = btnPtr->rect.top;
1729
1730 return TRUE;
1731}
1732
1733
1734static LRESULT
1735TOOLBAR_GetMaxSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1736{
1737 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1738 LPSIZE lpSize = (LPSIZE)lParam;
1739
1740 if (lpSize == NULL)
1741 return FALSE;
1742
1743 lpSize->cx = infoPtr->rcBound.right - infoPtr->rcBound.left;
1744 lpSize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
1745
1746// TRACE (toolbar, "maximum size %d x %d\n",
1747// infoPtr->rcBound.right - infoPtr->rcBound.left,
1748// infoPtr->rcBound.bottom - infoPtr->rcBound.top);
1749
1750 return TRUE;
1751}
1752
1753
1754/* << TOOLBAR_GetObject >> */
1755/* << TOOLBAR_GetPadding >> */
1756
1757
1758static LRESULT
1759TOOLBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
1760{
1761 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1762 TBUTTON_INFO *btnPtr;
1763 LPRECT lpRect;
1764 INT nIndex;
1765
1766 if (infoPtr == NULL)
1767 return FALSE;
1768 nIndex = (INT)wParam;
1769 btnPtr = &infoPtr->buttons[nIndex];
1770 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
1771 return FALSE;
1772 lpRect = (LPRECT)lParam;
1773 if (lpRect == NULL)
1774 return FALSE;
1775
1776 lpRect->left = btnPtr->rect.left;
1777 lpRect->right = btnPtr->rect.right;
1778 lpRect->bottom = btnPtr->rect.bottom;
1779 lpRect->top = btnPtr->rect.top;
1780
1781 return TRUE;
1782}
1783
1784
1785static LRESULT
1786TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
1787{
1788 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1789
1790 if (GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_WRAPABLE)
1791 return infoPtr->nRows;
1792 else
1793 return 1;
1794}
1795
1796
1797static LRESULT
1798TOOLBAR_GetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
1799{
1800 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1801 INT nIndex;
1802
1803 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1804 if (nIndex == -1)
1805 return -1;
1806
1807 return infoPtr->buttons[nIndex].fsState;
1808}
1809
1810
1811static LRESULT
1812TOOLBAR_GetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
1813{
1814 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1815 INT nIndex;
1816
1817 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1818 if (nIndex == -1)
1819 return -1;
1820
1821 return infoPtr->buttons[nIndex].fsStyle;
1822}
1823
1824
1825static LRESULT
1826TOOLBAR_GetTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
1827{
1828 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1829
1830 if (infoPtr == NULL)
1831 return 0;
1832
1833 return infoPtr->nMaxTextRows;
1834}
1835
1836
1837static LRESULT
1838TOOLBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
1839{
1840 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1841
1842 if (infoPtr == NULL) return 0;
1843 return infoPtr->hwndToolTip;
1844}
1845
1846
1847static LRESULT
1848TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
1849{
1850 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1851
1852// TRACE (toolbar, "%s hwnd=0x%x stub!\n",
1853// infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
1854
1855 return infoPtr->bUnicode;
1856}
1857
1858
1859static LRESULT
1860TOOLBAR_HideButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
1861{
1862 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1863 TBUTTON_INFO *btnPtr;
1864 INT nIndex;
1865
1866 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1867 if (nIndex == -1)
1868 return FALSE;
1869
1870 btnPtr = &infoPtr->buttons[nIndex];
1871 if (LOWORD(lParam) == FALSE)
1872 btnPtr->fsState &= ~TBSTATE_HIDDEN;
1873 else
1874 btnPtr->fsState |= TBSTATE_HIDDEN;
1875
1876 TOOLBAR_CalcToolbar (hwnd);
1877
1878 InvalidateRect (hwnd, NULL, TRUE);
1879
1880 return TRUE;
1881}
1882
1883
1884static LRESULT
1885TOOLBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1886{
1887 return TOOLBAR_InternalHitTest (hwnd, (LPPOINT)lParam);
1888}
1889
1890
1891static LRESULT
1892TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
1893{
1894 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1895 TBUTTON_INFO *btnPtr;
1896 HDC hdc;
1897 INT nIndex;
1898
1899 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
1900 if (nIndex == -1)
1901 return FALSE;
1902
1903 btnPtr = &infoPtr->buttons[nIndex];
1904 if (LOWORD(lParam) == FALSE)
1905 btnPtr->fsState &= ~TBSTATE_INDETERMINATE;
1906 else
1907 btnPtr->fsState |= TBSTATE_INDETERMINATE;
1908
1909 hdc = GetDC (hwnd);
1910 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
1911 ReleaseDC (hwnd, hdc);
1912
1913 return TRUE;
1914}
1915
1916
1917static LRESULT
1918TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1919{
1920 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1921 LPTBBUTTON lpTbb = (LPTBBUTTON)lParam;
1922 INT nIndex = (INT)wParam;
1923 TBUTTON_INFO *oldButtons;
1924
1925 if (lpTbb == NULL)
1926 return FALSE;
1927 if (nIndex < 0)
1928 return FALSE;
1929
1930// TRACE (toolbar, "inserting button index=%d\n", nIndex);
1931 if (nIndex > infoPtr->nNumButtons) {
1932 nIndex = infoPtr->nNumButtons;
1933// TRACE (toolbar, "adjust index=%d\n", nIndex);
1934 }
1935
1936 oldButtons = infoPtr->buttons;
1937 infoPtr->nNumButtons++;
1938 infoPtr->buttons = COMCTL32_Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons);
1939 /* pre insert copy */
1940 if (nIndex > 0) {
1941 memcpy (&infoPtr->buttons[0], &oldButtons[0],
1942 nIndex * sizeof(TBUTTON_INFO));
1943 }
1944
1945 /* insert new button */
1946 infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap;
1947 infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand;
1948 infoPtr->buttons[nIndex].fsState = lpTbb->fsState;
1949 infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle;
1950 infoPtr->buttons[nIndex].dwData = lpTbb->dwData;
1951 infoPtr->buttons[nIndex].iString = lpTbb->iString;
1952
1953 if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & TBSTYLE_SEP)) {
1954 TTTOOLINFOA ti;
1955
1956 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1957 ti.cbSize = sizeof (TTTOOLINFOA);
1958 ti.hwnd = hwnd;
1959 ti.uId = lpTbb->idCommand;
1960 ti.hinst = 0;
1961 ti.lpszText = LPSTR_TEXTCALLBACKA;
1962
1963 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
1964 0, (LPARAM)&ti);
1965 }
1966
1967 /* post insert copy */
1968 if (nIndex < infoPtr->nNumButtons - 1) {
1969 memcpy (&infoPtr->buttons[nIndex+1], &oldButtons[nIndex],
1970 (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO));
1971 }
1972
1973 COMCTL32_Free (oldButtons);
1974
1975 TOOLBAR_CalcToolbar (hwnd);
1976
1977 InvalidateRect (hwnd, NULL, FALSE);
1978
1979 return TRUE;
1980}
1981
1982static LRESULT TOOLBAR_InsertButtonW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1983{
1984 //CB: just call InsertButtonA, no Unicode used?!?
1985
1986 return TOOLBAR_InsertButtonA(hwnd,wParam,lParam);
1987}
1988
1989/* << TOOLBAR_InsertButton32W >> */
1990/* << TOOLBAR_InsertMarkHitTest >> */
1991
1992
1993static LRESULT
1994TOOLBAR_IsButtonChecked (HWND hwnd, WPARAM wParam, LPARAM lParam)
1995{
1996 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
1997 INT nIndex;
1998
1999 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2000 if (nIndex == -1)
2001 return FALSE;
2002
2003 return (infoPtr->buttons[nIndex].fsState & TBSTATE_CHECKED);
2004}
2005
2006
2007static LRESULT
2008TOOLBAR_IsButtonEnabled (HWND hwnd, WPARAM wParam, LPARAM lParam)
2009{
2010 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2011 INT nIndex;
2012
2013 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2014 if (nIndex == -1)
2015 return FALSE;
2016
2017 return (infoPtr->buttons[nIndex].fsState & TBSTATE_ENABLED);
2018}
2019
2020
2021static LRESULT
2022TOOLBAR_IsButtonHidden (HWND hwnd, WPARAM wParam, LPARAM lParam)
2023{
2024 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2025 INT nIndex;
2026
2027 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2028 if (nIndex == -1)
2029 return FALSE;
2030
2031 return (infoPtr->buttons[nIndex].fsState & TBSTATE_HIDDEN);
2032}
2033
2034
2035static LRESULT
2036TOOLBAR_IsButtonHighlighted (HWND hwnd, WPARAM wParam, LPARAM lParam)
2037{
2038 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2039 INT nIndex;
2040
2041 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2042 if (nIndex == -1)
2043 return FALSE;
2044
2045 return (infoPtr->buttons[nIndex].fsState & TBSTATE_MARKED);
2046}
2047
2048
2049static LRESULT
2050TOOLBAR_IsButtonIndeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2051{
2052 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2053 INT nIndex;
2054
2055 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2056 if (nIndex == -1)
2057 return FALSE;
2058
2059 return (infoPtr->buttons[nIndex].fsState & TBSTATE_INDETERMINATE);
2060}
2061
2062
2063static LRESULT
2064TOOLBAR_IsButtonPressed (HWND hwnd, WPARAM wParam, LPARAM lParam)
2065{
2066 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2067 INT nIndex;
2068
2069 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2070 if (nIndex == -1)
2071 return FALSE;
2072
2073 return (infoPtr->buttons[nIndex].fsState & TBSTATE_PRESSED);
2074}
2075
2076
2077/* << TOOLBAR_LoadImages >> */
2078/* << TOOLBAR_MapAccelerator >> */
2079/* << TOOLBAR_MarkButton >> */
2080/* << TOOLBAR_MoveButton >> */
2081
2082
2083static LRESULT
2084TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
2085{
2086 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2087 TBUTTON_INFO *btnPtr;
2088 HDC hdc;
2089 INT nIndex;
2090
2091 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2092 if (nIndex == -1)
2093 return FALSE;
2094
2095 btnPtr = &infoPtr->buttons[nIndex];
2096 if (LOWORD(lParam) == FALSE)
2097 btnPtr->fsState &= ~TBSTATE_PRESSED;
2098 else
2099 btnPtr->fsState |= TBSTATE_PRESSED;
2100
2101 hdc = GetDC (hwnd);
2102 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2103 ReleaseDC (hwnd, hdc);
2104
2105 return TRUE;
2106}
2107
2108
2109/* << TOOLBAR_ReplaceBitmap >> */
2110
2111
2112static LRESULT
2113TOOLBAR_SaveRestoreA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2114{
2115#if 0
2116 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2117 LPTBSAVEPARAMSA lpSave = (LPTBSAVEPARAMSA)lParam;
2118
2119 if (lpSave == NULL) return 0;
2120
2121 if ((BOOL)wParam) {
2122 /* save toolbar information */
2123// FIXME (toolbar, "save to \"%s\" \"%s\"\n",
2124// lpSave->pszSubKey, lpSave->pszValueName);
2125
2126
2127 }
2128 else {
2129 /* restore toolbar information */
2130
2131// FIXME (toolbar, "restore from \"%s\" \"%s\"\n",
2132// lpSave->pszSubKey, lpSave->pszValueName);
2133
2134
2135 }
2136#endif
2137
2138 return 0;
2139}
2140
2141static LRESULT TOOLBAR_SaveRestoreW(HWND hwnd,WPARAM wParam,LPARAM lParam)
2142{
2143#if 0
2144 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2145 LPTBSAVEPARAMSW lpSave = (LPTBSAVEPARAMSW)lParam;
2146
2147 if (lpSave == NULL) return 0;
2148
2149 if ((BOOL)wParam) {
2150 /* save toolbar information */
2151// FIXME (toolbar, "save to \"%s\" \"%s\"\n",
2152// lpSave->pszSubKey, lpSave->pszValueName);
2153
2154
2155 }
2156 else {
2157 /* restore toolbar information */
2158
2159// FIXME (toolbar, "restore from \"%s\" \"%s\"\n",
2160// lpSave->pszSubKey, lpSave->pszValueName);
2161
2162
2163 }
2164#endif
2165
2166 return 0;
2167}
2168
2169/* << TOOLBAR_SaveRestore32W >> */
2170/* << TOOLBAR_SetAnchorHighlight >> */
2171
2172
2173static LRESULT
2174TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2175{
2176 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2177
2178 if (((INT)LOWORD(lParam) <= 0) || ((INT)HIWORD(lParam) <= 0)) return FALSE;
2179
2180 infoPtr->nBitmapWidth = (INT)LOWORD(lParam);
2181 infoPtr->nBitmapHeight = (INT)HIWORD(lParam);
2182
2183 return TRUE;
2184}
2185
2186
2187static LRESULT
2188TOOLBAR_SetButtonInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2189{
2190 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2191 LPTBBUTTONINFOA lptbbi = (LPTBBUTTONINFOA)lParam;
2192 TBUTTON_INFO *btnPtr;
2193 INT nIndex;
2194
2195 if (lptbbi == NULL)
2196 return FALSE;
2197 if (lptbbi->cbSize < sizeof(TBBUTTONINFOA))
2198 return FALSE;
2199
2200 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2201 if (nIndex == -1)
2202 return FALSE;
2203
2204 btnPtr = &infoPtr->buttons[nIndex];
2205 if (lptbbi->dwMask & TBIF_COMMAND)
2206 btnPtr->idCommand = lptbbi->idCommand;
2207 if (lptbbi->dwMask & TBIF_IMAGE)
2208 btnPtr->iBitmap = lptbbi->iImage;
2209 if (lptbbi->dwMask & TBIF_LPARAM)
2210 btnPtr->dwData = lptbbi->lParam;
2211/* if (lptbbi->dwMask & TBIF_SIZE) */
2212/* btnPtr->cx = lptbbi->cx; */
2213 if (lptbbi->dwMask & TBIF_STATE)
2214 btnPtr->fsState = lptbbi->fsState;
2215 if (lptbbi->dwMask & TBIF_STYLE)
2216 btnPtr->fsStyle = lptbbi->fsStyle;
2217
2218 if (lptbbi->dwMask & TBIF_TEXT) {
2219 if ((btnPtr->iString >= 0) ||
2220 (btnPtr->iString < infoPtr->nNumStrings)) {
2221#if 0
2222 CHAR **lpString = &infoPtr->strings[btnPtr->iString]; //wrong, it's Unicode!!!
2223 INT len = lstrlenA (lptbbi->pszText);
2224 *lpString = COMCTL32_ReAlloc (lpString, sizeof(char)*(len+1));
2225#endif
2226
2227 /* this is the ultimate sollution */
2228/* Str_SetPtrA (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2229 }
2230 }
2231
2232 return TRUE;
2233}
2234
2235static LRESULT TOOLBAR_SetButtonInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2236{
2237 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2238 LPTBBUTTONINFOW lptbbi = (LPTBBUTTONINFOW)lParam;
2239 TBUTTON_INFO *btnPtr;
2240 INT nIndex;
2241
2242 if (lptbbi == NULL)
2243 return FALSE;
2244 if (lptbbi->cbSize < sizeof(TBBUTTONINFOW))
2245 return FALSE;
2246
2247 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2248 if (nIndex == -1)
2249 return FALSE;
2250
2251 btnPtr = &infoPtr->buttons[nIndex];
2252 if (lptbbi->dwMask & TBIF_COMMAND)
2253 btnPtr->idCommand = lptbbi->idCommand;
2254 if (lptbbi->dwMask & TBIF_IMAGE)
2255 btnPtr->iBitmap = lptbbi->iImage;
2256 if (lptbbi->dwMask & TBIF_LPARAM)
2257 btnPtr->dwData = lptbbi->lParam;
2258/* if (lptbbi->dwMask & TBIF_SIZE) */
2259/* btnPtr->cx = lptbbi->cx; */
2260 if (lptbbi->dwMask & TBIF_STATE)
2261 btnPtr->fsState = lptbbi->fsState;
2262 if (lptbbi->dwMask & TBIF_STYLE)
2263 btnPtr->fsStyle = lptbbi->fsStyle;
2264
2265 if (lptbbi->dwMask & TBIF_TEXT) {
2266 if ((btnPtr->iString >= 0) ||
2267 (btnPtr->iString < infoPtr->nNumStrings)) {
2268#if 0
2269 WCHAR **lpString = &infoPtr->strings[btnPtr->iString];
2270 INT len = lstrlenW (lptbbi->pszText);
2271 *lpString = COMCTL32_ReAlloc (lpString, sizeof(wchar)*(len+1));
2272#endif
2273
2274 /* this is the ultimate sollution */
2275/* Str_SetPtrW (&infoPtr->strings[btnPtr->iString], lptbbi->pszText); */
2276 }
2277 }
2278
2279 return TRUE;
2280}
2281
2282/* << TOOLBAR_SetButtonInfo32W >> */
2283
2284
2285static LRESULT
2286TOOLBAR_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2287{
2288 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2289
2290 if (((INT)LOWORD(lParam) <= 0) || ((INT)HIWORD(lParam) <= 0)) return FALSE;
2291
2292 infoPtr->nButtonWidth = (INT)LOWORD(lParam);
2293 infoPtr->nButtonHeight = (INT)HIWORD(lParam);
2294
2295 return TRUE;
2296}
2297
2298
2299static LRESULT
2300TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
2301{
2302 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2303
2304 if (infoPtr == NULL)
2305 return FALSE;
2306
2307 infoPtr->cxMin = (INT)LOWORD(lParam);
2308 infoPtr->cxMax = (INT)HIWORD(lParam);
2309
2310 return TRUE;
2311}
2312
2313
2314static LRESULT
2315TOOLBAR_SetCmdId (HWND hwnd, WPARAM wParam, LPARAM lParam)
2316{
2317 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2318 INT nIndex = (INT)wParam;
2319
2320 if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
2321 return FALSE;
2322
2323 infoPtr->buttons[nIndex].idCommand = (INT)lParam;
2324
2325 if (infoPtr->hwndToolTip) {
2326
2327// FIXME (toolbar, "change tool tip!\n");
2328
2329 }
2330
2331 return TRUE;
2332}
2333
2334
2335/* << TOOLBAR_SetColorScheme >> */
2336
2337
2338static LRESULT
2339TOOLBAR_SetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2340{
2341 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2342 HIMAGELIST himlTemp;
2343
2344 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2345 return 0;
2346
2347 himlTemp = infoPtr->himlDis;
2348 infoPtr->himlDis = (HIMAGELIST)lParam;
2349
2350 /* FIXME: redraw ? */
2351
2352 return (LRESULT)himlTemp;
2353}
2354
2355
2356static LRESULT
2357TOOLBAR_SetDrawTextFlags (HWND hwnd, WPARAM wParam, LPARAM lParam)
2358{
2359 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2360 DWORD dwTemp;
2361
2362 dwTemp = infoPtr->dwDTFlags;
2363 infoPtr->dwDTFlags =
2364 (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
2365
2366 return (LRESULT)dwTemp;
2367}
2368
2369
2370static LRESULT
2371TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2372{
2373 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2374 DWORD dwTemp;
2375
2376 dwTemp = infoPtr->dwExStyle;
2377 infoPtr->dwExStyle = (DWORD)lParam;
2378
2379 return (LRESULT)dwTemp;
2380}
2381
2382
2383static LRESULT
2384TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2385{
2386 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
2387 HIMAGELIST himlTemp;
2388
2389 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2390 return 0;
2391
2392 himlTemp = infoPtr->himlHot;
2393 infoPtr->himlHot = (HIMAGELIST)lParam;
2394
2395 /* FIXME: redraw ? */
2396
2397 return (LRESULT)himlTemp;
2398}
2399
2400
2401/* << TOOLBAR_SetHotItem >> */
2402
2403
2404static LRESULT
2405TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
2406{
2407 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2408 HIMAGELIST himlTemp;
2409
2410 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBSTYLE_FLAT))
2411 return 0;
2412
2413 himlTemp = infoPtr->himlDef;
2414 infoPtr->himlDef = (HIMAGELIST)lParam;
2415
2416 /* FIXME: redraw ? */
2417
2418 return (LRESULT)himlTemp;
2419}
2420
2421
2422static LRESULT
2423TOOLBAR_SetIndent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2424{
2425 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2426
2427 infoPtr->nIndent = (INT)wParam;
2428
2429 TOOLBAR_CalcToolbar (hwnd);
2430
2431 InvalidateRect(hwnd, NULL, FALSE);
2432
2433 return TRUE;
2434}
2435
2436
2437/* << TOOLBAR_SetInsertMark >> */
2438
2439
2440static LRESULT
2441TOOLBAR_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2442{
2443 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2444
2445 infoPtr->clrInsertMark = (COLORREF)lParam;
2446
2447 /* FIXME : redraw ??*/
2448
2449 return 0;
2450}
2451
2452
2453static LRESULT
2454TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2455{
2456 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2457
2458 if (infoPtr == NULL)
2459 return FALSE;
2460
2461 infoPtr->nMaxTextRows = (INT)wParam;
2462
2463 return TRUE;
2464}
2465
2466
2467/* << TOOLBAR_SetPadding >> */
2468
2469
2470static LRESULT
2471TOOLBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2472{
2473 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2474 HWND hwndOldNotify;
2475
2476 if (infoPtr == NULL)
2477 return 0;
2478 hwndOldNotify = infoPtr->hwndNotify;
2479 infoPtr->hwndNotify = (HWND)wParam;
2480
2481 return hwndOldNotify;
2482}
2483
2484
2485static LRESULT
2486TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
2487{
2488 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2489 LPRECT lprc = (LPRECT)lParam;
2490
2491 if (LOWORD(wParam) > 1) {
2492
2493// FIXME (toolbar, "multiple rows not supported!\n");
2494
2495 }
2496
2497 /* recalculate toolbar */
2498 TOOLBAR_CalcToolbar (hwnd);
2499
2500 /* return bounding rectangle */
2501 if (lprc) {
2502 lprc->left = infoPtr->rcBound.left;
2503 lprc->right = infoPtr->rcBound.right;
2504 lprc->top = infoPtr->rcBound.top;
2505 lprc->bottom = infoPtr->rcBound.bottom;
2506 }
2507
2508 /* repaint toolbar */
2509 InvalidateRect(hwnd, NULL, FALSE);
2510
2511 return 0;
2512}
2513
2514
2515static LRESULT
2516TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam)
2517{
2518 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2519 TBUTTON_INFO *btnPtr;
2520 HDC hdc;
2521 INT nIndex;
2522
2523 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2524 if (nIndex == -1)
2525 return FALSE;
2526
2527 btnPtr = &infoPtr->buttons[nIndex];
2528 btnPtr->fsState = LOWORD(lParam);
2529
2530 hdc = GetDC (hwnd);
2531 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2532 ReleaseDC (hwnd, hdc);
2533
2534 return TRUE;
2535}
2536
2537
2538static LRESULT
2539TOOLBAR_SetStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
2540{
2541 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2542 TBUTTON_INFO *btnPtr;
2543 HDC hdc;
2544 INT nIndex;
2545
2546 nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam);
2547 if (nIndex == -1)
2548 return FALSE;
2549
2550 btnPtr = &infoPtr->buttons[nIndex];
2551 btnPtr->fsStyle = LOWORD(lParam);
2552
2553 hdc = GetDC (hwnd);
2554 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2555 ReleaseDC (hwnd, hdc);
2556
2557 if (infoPtr->hwndToolTip) {
2558
2559// FIXME (toolbar, "change tool tip!\n");
2560
2561 }
2562
2563 return TRUE;
2564}
2565
2566
2567static LRESULT
2568TOOLBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
2569{
2570 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2571
2572 if (infoPtr == NULL)
2573 return 0;
2574 infoPtr->hwndToolTip = (HWND)wParam;
2575 return 0;
2576}
2577
2578
2579static LRESULT
2580TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
2581{
2582 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2583 BOOL bTemp;
2584
2585// TRACE (toolbar, "%s hwnd=0x%04x stub!\n",
2586// ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
2587
2588 bTemp = infoPtr->bUnicode;
2589 infoPtr->bUnicode = (BOOL)wParam;
2590
2591 return bTemp;
2592}
2593
2594
2595static LRESULT
2596TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
2597{
2598 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2599 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2600 LOGFONTA logFont;
2601
2602 /* initialize info structure */
2603 infoPtr->nButtonHeight = 22;
2604 infoPtr->nButtonWidth = 23;
2605 infoPtr->nBitmapHeight = 15;
2606 infoPtr->nBitmapWidth = 16;
2607
2608 infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
2609 infoPtr->nRows = 1;
2610 infoPtr->nMaxTextRows = 1;
2611 infoPtr->cxMin = -1;
2612 infoPtr->cxMax = -1;
2613
2614 infoPtr->bCaptured = FALSE;
2615 infoPtr->bUnicode = IsWindowUnicode(hwnd);
2616 infoPtr->nButtonDown = -1;
2617 infoPtr->nOldHit = -1;
2618 infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
2619 infoPtr->hwndNotify = GetParent (hwnd);
2620 infoPtr->bTransparent = (dwStyle & TBSTYLE_FLAT);
2621 infoPtr->dwDTFlags = DT_CENTER;
2622
2623 SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
2624 infoPtr->hFont = CreateFontIndirectA (&logFont);
2625
2626 if (dwStyle & TBSTYLE_TOOLTIPS)
2627 {
2628 /* Create tooltip control */
2629 infoPtr->hwndToolTip =
2630 CreateWindowExA (WS_EX_TOOLWINDOW,TOOLTIPS_CLASSA,NULL,WS_POPUP,
2631 CW_USEDEFAULT,CW_USEDEFAULT,
2632 CW_USEDEFAULT,CW_USEDEFAULT,
2633 hwnd,0,0,0);
2634
2635 /* Send NM_TOOLTIPSCREATED notification */
2636 if (infoPtr->hwndToolTip)
2637 {
2638 NMTOOLTIPSCREATED nmttc;
2639
2640 nmttc.hdr.hwndFrom = hwnd;
2641 nmttc.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
2642 nmttc.hdr.code = NM_TOOLTIPSCREATED;
2643 nmttc.hwndToolTips = infoPtr->hwndToolTip;
2644
2645 SendMessageA(infoPtr->hwndNotify,WM_NOTIFY,(WPARAM)nmttc.hdr.idFrom,(LPARAM)&nmttc);
2646 }
2647 }
2648
2649 return 0;
2650}
2651
2652
2653static LRESULT
2654TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
2655{
2656 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2657
2658 /* delete tooltip control */
2659 if (infoPtr->hwndToolTip)
2660 DestroyWindow (infoPtr->hwndToolTip);
2661
2662 /* delete button data */
2663 if (infoPtr->buttons)
2664 COMCTL32_Free (infoPtr->buttons);
2665
2666 /* delete strings */
2667 if (infoPtr->strings) {
2668 INT i;
2669 for (i = 0; i < infoPtr->nNumStrings; i++)
2670 if (infoPtr->strings[i])
2671 COMCTL32_Free (infoPtr->strings[i]);
2672
2673 COMCTL32_Free (infoPtr->strings);
2674 }
2675
2676 /* destroy default image list */
2677 if (infoPtr->himlDef)
2678 ImageList_Destroy (infoPtr->himlDef);
2679
2680 /* destroy disabled image list */
2681 if (infoPtr->himlDis)
2682 ImageList_Destroy (infoPtr->himlDis);
2683
2684 /* destroy hot image list */
2685 if (infoPtr->himlHot)
2686 ImageList_Destroy (infoPtr->himlHot);
2687
2688 /* delete default font */
2689 if (infoPtr->hFont)
2690 DeleteObject (infoPtr->hFont);
2691
2692 /* free toolbar info data */
2693 COMCTL32_Free (infoPtr);
2694
2695 return 0;
2696}
2697
2698
2699static LRESULT
2700TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
2701{
2702 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2703
2704 if (infoPtr->bTransparent)
2705 return SendMessageA (GetParent (hwnd), WM_ERASEBKGND, wParam, lParam);
2706
2707 return DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
2708}
2709
2710
2711static LRESULT
2712TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam)
2713{
2714 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2715 TBUTTON_INFO *btnPtr;
2716 POINT pt;
2717 INT nHit;
2718 HDC hdc;
2719
2720 pt.x = (INT)LOWORD(lParam);
2721 pt.y = (INT)HIWORD(lParam);
2722 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
2723
2724 if (nHit >= 0) {
2725 btnPtr = &infoPtr->buttons[nHit];
2726 if (!(btnPtr->fsState & TBSTATE_ENABLED))
2727 return 0;
2728 SetCapture (hwnd);
2729 infoPtr->bCaptured = TRUE;
2730 infoPtr->nButtonDown = nHit;
2731
2732 btnPtr->fsState |= TBSTATE_PRESSED;
2733
2734 hdc = GetDC (hwnd);
2735 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2736 ReleaseDC (hwnd, hdc);
2737 }
2738 else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE)
2739 TOOLBAR_Customize (hwnd);
2740
2741 return 0;
2742}
2743
2744
2745static LRESULT
2746TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
2747{
2748 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2749 TBUTTON_INFO *btnPtr;
2750 POINT pt;
2751 INT nHit;
2752 HDC hdc;
2753
2754 if (infoPtr->hwndToolTip)
2755 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
2756 WM_LBUTTONDOWN, wParam, lParam);
2757
2758 pt.x = (INT)LOWORD(lParam);
2759 pt.y = (INT)HIWORD(lParam);
2760 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
2761
2762 if (nHit >= 0) {
2763 btnPtr = &infoPtr->buttons[nHit];
2764 if (!(btnPtr->fsState & TBSTATE_ENABLED))
2765 return 0;
2766
2767 SetCapture (hwnd);
2768 infoPtr->bCaptured = TRUE;
2769 infoPtr->nButtonDown = nHit;
2770 infoPtr->nOldHit = nHit;
2771
2772 btnPtr->fsState |= TBSTATE_PRESSED;
2773
2774 hdc = GetDC (hwnd);
2775 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2776 ReleaseDC (hwnd, hdc);
2777 }
2778
2779 return 0;
2780}
2781
2782
2783static LRESULT
2784TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
2785{
2786 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2787 TBUTTON_INFO *btnPtr;
2788 POINT pt;
2789 INT nHit;
2790 INT nOldIndex = -1;
2791 HDC hdc;
2792 BOOL bSendMessage = TRUE;
2793
2794 if (infoPtr->hwndToolTip)
2795 TOOLBAR_RelayEvent (infoPtr->hwndToolTip, hwnd,
2796 WM_LBUTTONUP, wParam, lParam);
2797
2798 pt.x = (INT)LOWORD(lParam);
2799 pt.y = (INT)HIWORD(lParam);
2800 nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
2801
2802 if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
2803 infoPtr->bCaptured = FALSE;
2804 ReleaseCapture ();
2805 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
2806 btnPtr->fsState &= ~TBSTATE_PRESSED;
2807
2808 if (nHit == infoPtr->nButtonDown) {
2809 if (btnPtr->fsStyle & TBSTYLE_CHECK) {
2810 if (btnPtr->fsStyle & TBSTYLE_GROUP) {
2811 nOldIndex = TOOLBAR_GetCheckedGroupButtonIndex (infoPtr,
2812 infoPtr->nButtonDown);
2813 if (nOldIndex == infoPtr->nButtonDown)
2814 bSendMessage = FALSE;
2815 if ((nOldIndex != infoPtr->nButtonDown) &&
2816 (nOldIndex != -1))
2817 infoPtr->buttons[nOldIndex].fsState &= ~TBSTATE_CHECKED;
2818 btnPtr->fsState |= TBSTATE_CHECKED;
2819 }
2820 else {
2821 if (btnPtr->fsState & TBSTATE_CHECKED)
2822 btnPtr->fsState &= ~TBSTATE_CHECKED;
2823 else
2824 btnPtr->fsState |= TBSTATE_CHECKED;
2825 }
2826 }
2827 }
2828 else
2829 bSendMessage = FALSE;
2830
2831 hdc = GetDC (hwnd);
2832 if (nOldIndex != -1)
2833 TOOLBAR_DrawButton (hwnd, &infoPtr->buttons[nOldIndex], hdc);
2834 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2835 ReleaseDC (hwnd, hdc);
2836
2837 if (bSendMessage)
2838 SendMessageA (infoPtr->hwndNotify, WM_COMMAND,
2839 MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
2840
2841 infoPtr->nButtonDown = -1;
2842 infoPtr->nOldHit = -1;
2843 }
2844
2845 return 0;
2846}
2847
2848
2849static LRESULT
2850TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
2851{
2852 TBUTTON_INFO *btnPtr, *oldBtnPtr;
2853 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
2854 POINT pt;
2855 INT nHit;
2856 HDC hdc;
2857 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
2858
2859 if (infoPtr->hwndToolTip)
2860 TOOLBAR_RelayEvent (infoPtr->hwndToolTip,hwnd,
2861 WM_MOUSEMOVE,wParam,lParam);
2862
2863 pt.x = (INT)LOWORD(lParam);
2864 pt.y = (INT)HIWORD(lParam);
2865
2866 nHit = TOOLBAR_InternalHitTest(hwnd,&pt);
2867
2868 if (infoPtr->nOldHit != nHit)
2869 {
2870 /* Remove the effect of an old hot button */
2871 if(infoPtr->nOldHit == infoPtr->nHotItem)
2872 {
2873 oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
2874 if (oldBtnPtr->bHot)
2875 {
2876 oldBtnPtr->bHot = FALSE;
2877
2878 if (dwStyle & TBSTYLE_FLAT) InvalidateRect(hwnd,&oldBtnPtr->rect,TRUE);
2879 }
2880 }
2881
2882 /* It's not a separator or in nowhere. It's a hot button. */
2883 if (nHit >= 0)
2884 {
2885 btnPtr = &infoPtr->buttons[nHit];
2886 if (!btnPtr->bHot)
2887 {
2888 btnPtr->bHot = TRUE;
2889
2890 if (dwStyle & TBSTYLE_FLAT)
2891 {
2892 hdc = GetDC (hwnd);
2893 TOOLBAR_DrawButton (hwnd, btnPtr, hdc);
2894 ReleaseDC (hwnd, hdc);
2895 }
2896
2897 infoPtr->nHotItem = nHit;
2898 }
2899 }
2900
2901 if (infoPtr->bCaptured)
2902 {
2903 btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
2904 if (infoPtr->nOldHit == infoPtr->nButtonDown)
2905 {
2906 btnPtr->fsState &= ~TBSTATE_PRESSED;
2907
2908 hdc = GetDC (hwnd);
2909 TOOLBAR_DrawButton(hwnd,btnPtr,hdc);
2910 ReleaseDC(hwnd,hdc);
2911 } else if (nHit == infoPtr->nButtonDown)
2912 {
2913 btnPtr->fsState |= TBSTATE_PRESSED;
2914
2915 hdc = GetDC(hwnd);
2916 TOOLBAR_DrawButton(hwnd,btnPtr,hdc);
2917 ReleaseDC(hwnd,hdc);
2918 }
2919 }
2920 infoPtr->nOldHit = nHit;
2921 }
2922 return 0;
2923}
2924
2925
2926static LRESULT
2927TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2928{
2929/* if (wndPtr->dwStyle & CCS_NODIVIDER) */
2930 return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
2931/* else */
2932/* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
2933}
2934
2935
2936static LRESULT
2937TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2938{
2939 if (!(GetWindowLongA (hwnd, GWL_STYLE) & CCS_NODIVIDER))
2940 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
2941
2942 return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
2943}
2944
2945
2946static LRESULT
2947TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
2948{
2949 TOOLBAR_INFO *infoPtr;
2950
2951 /* allocate memory for info structure */
2952 infoPtr = (TOOLBAR_INFO *)COMCTL32_Alloc (sizeof(TOOLBAR_INFO));
2953 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
2954
2955 /* paranoid!! */
2956 infoPtr->dwStructSize = sizeof(TBBUTTON);
2957
2958 /* fix instance handle, if the toolbar was created by CreateToolbarEx() */
2959 if (!GetWindowLongA (hwnd, GWL_HINSTANCE)) {
2960 HINSTANCE hInst = (HINSTANCE)GetWindowLongA (GetParent (hwnd), GWL_HINSTANCE);
2961 SetWindowLongA (hwnd, GWL_HINSTANCE, (DWORD)hInst);
2962 }
2963
2964 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
2965}
2966
2967
2968static LRESULT
2969TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
2970{
2971 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2972 RECT rcWindow;
2973 HDC hdc;
2974
2975 if (dwStyle & WS_MINIMIZE)
2976 return 0; /* Nothing to do */
2977
2978 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
2979
2980 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
2981 return 0;
2982
2983 if (!(dwStyle & CCS_NODIVIDER))
2984 {
2985 GetWindowRect (hwnd, &rcWindow);
2986 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
2987 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_TOP);
2988 }
2989
2990 ReleaseDC( hwnd, hdc );
2991
2992 return 0;
2993}
2994
2995
2996static LRESULT
2997TOOLBAR_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
2998{
2999 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3000 LPNMHDR lpnmh = (LPNMHDR)lParam;
3001
3002// TRACE (toolbar, "passing WM_NOTIFY!\n");
3003
3004 if ((infoPtr->hwndToolTip) && (lpnmh->hwndFrom == infoPtr->hwndToolTip)) {
3005 SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
3006
3007#if 0
3008 if (lpnmh->code == TTN_GETDISPINFOA) {
3009 LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam;
3010
3011// FIXME (toolbar, "retrieving ASCII string\n");
3012
3013 }
3014 else if (lpnmh->code == TTN_GETDISPINFOW) {
3015 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
3016
3017// FIXME (toolbar, "retrieving UNICODE string\n");
3018
3019 }
3020#endif
3021 }
3022
3023 return 0;
3024}
3025
3026
3027static LRESULT
3028TOOLBAR_Paint (HWND hwnd, WPARAM wParam)
3029{
3030 HDC hdc;
3031 PAINTSTRUCT ps;
3032
3033 TOOLBAR_CalcToolbar(hwnd);
3034 hdc = wParam == 0 ? BeginPaint(hwnd,&ps) : (HDC)wParam;
3035 TOOLBAR_Refresh(hwnd,hdc);
3036 if (!wParam) EndPaint (hwnd, &ps);
3037 return 0;
3038}
3039
3040
3041static LRESULT
3042TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
3043{
3044 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
3045 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3046 RECT parent_rect;
3047 HWND parent;
3048 /* INT32 x, y; */
3049 INT cx, cy;
3050 INT flags;
3051 UINT uPosFlags = 0;
3052
3053 /* Resize deadlock check */
3054 if (infoPtr->bAutoSize) {
3055 infoPtr->bAutoSize = FALSE;
3056 return 0;
3057 }
3058
3059 flags = (INT) wParam;
3060
3061 /* FIXME for flags =
3062 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
3063 */
3064
3065// TRACE (toolbar, "sizing toolbar!\n");
3066
3067 if (flags == SIZE_RESTORED) {
3068 /* width and height don't apply */
3069 parent = GetParent (hwnd);
3070 GetClientRect(parent, &parent_rect);
3071
3072 if (dwStyle & CCS_NORESIZE) {
3073 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
3074
3075 /* FIXME */
3076/* infoPtr->nWidth = parent_rect.right - parent_rect.left; */
3077 cy = infoPtr->nHeight;
3078 cx = infoPtr->nWidth;
3079 TOOLBAR_CalcToolbar (hwnd);
3080 infoPtr->nWidth = cx;
3081 infoPtr->nHeight = cy;
3082 }
3083 else {
3084 infoPtr->nWidth = parent_rect.right - parent_rect.left;
3085 TOOLBAR_CalcToolbar (hwnd);
3086 cy = infoPtr->nHeight;
3087 cx = infoPtr->nWidth;
3088 }
3089
3090 if (dwStyle & CCS_NOPARENTALIGN) {
3091 uPosFlags |= SWP_NOMOVE;
3092 cy = infoPtr->nHeight;
3093 cx = infoPtr->nWidth;
3094 }
3095
3096 if (!(dwStyle & CCS_NODIVIDER))
3097 cy += GetSystemMetrics(SM_CYEDGE);
3098
3099 SetWindowPos (hwnd, 0, parent_rect.left, parent_rect.top,
3100 cx, cy, uPosFlags | SWP_NOZORDER);
3101 }
3102 return 0;
3103}
3104
3105
3106static LRESULT
3107TOOLBAR_StyleChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
3108{
3109 TOOLBAR_AutoSize (hwnd, wParam, lParam);
3110
3111 InvalidateRect(hwnd, NULL, FALSE);
3112
3113 return 0;
3114}
3115
3116
3117
3118LRESULT WINAPI
3119ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3120{
3121 switch (uMsg)
3122 {
3123 case TB_ADDBITMAP:
3124 return TOOLBAR_AddBitmap (hwnd, wParam, lParam);
3125
3126 case TB_ADDBUTTONSA:
3127 return TOOLBAR_AddButtonsA (hwnd, wParam, lParam);
3128
3129 case TB_ADDBUTTONSW:
3130 return TOOLBAR_AddButtonsW(hwnd,wParam,lParam);
3131
3132 case TB_ADDSTRINGA:
3133 return TOOLBAR_AddStringA (hwnd, wParam, lParam);
3134
3135 case TB_ADDSTRINGW:
3136 return TOOLBAR_AddStringW (hwnd, wParam, lParam);
3137
3138 case TB_AUTOSIZE:
3139 return TOOLBAR_AutoSize (hwnd, wParam, lParam);
3140
3141 case TB_BUTTONCOUNT:
3142 return TOOLBAR_ButtonCount (hwnd, wParam, lParam);
3143
3144 case TB_BUTTONSTRUCTSIZE:
3145 return TOOLBAR_ButtonStructSize (hwnd, wParam, lParam);
3146
3147 case TB_CHANGEBITMAP:
3148 return TOOLBAR_ChangeBitmap (hwnd, wParam, lParam);
3149
3150 case TB_CHECKBUTTON:
3151 return TOOLBAR_CheckButton (hwnd, wParam, lParam);
3152
3153 case TB_COMMANDTOINDEX:
3154 return TOOLBAR_CommandToIndex (hwnd, wParam, lParam);
3155
3156 case TB_CUSTOMIZE:
3157 return TOOLBAR_Customize (hwnd);
3158
3159 case TB_DELETEBUTTON:
3160 return TOOLBAR_DeleteButton (hwnd, wParam, lParam);
3161
3162 case TB_ENABLEBUTTON:
3163 return TOOLBAR_EnableButton (hwnd, wParam, lParam);
3164
3165/* case TB_GETANCHORHIGHLIGHT: */ /* 4.71 */
3166
3167 case TB_GETBITMAP:
3168 return TOOLBAR_GetBitmap (hwnd, wParam, lParam);
3169
3170 case TB_GETBITMAPFLAGS:
3171 return TOOLBAR_GetBitmapFlags (hwnd, wParam, lParam);
3172
3173 case TB_GETBUTTON:
3174 return TOOLBAR_GetButton (hwnd, wParam, lParam);
3175
3176 case TB_GETBUTTONINFOA:
3177 return TOOLBAR_GetButtonInfoA (hwnd, wParam, lParam);
3178
3179 case TB_GETBUTTONINFOW: /* 4.71 */
3180 return TOOLBAR_GetButtonInfoW(hwnd,wParam,lParam);
3181
3182 case TB_GETBUTTONSIZE:
3183 return TOOLBAR_GetButtonSize (hwnd);
3184
3185 case TB_GETBUTTONTEXTA:
3186 return TOOLBAR_GetButtonTextA (hwnd, wParam, lParam);
3187
3188 case TB_GETBUTTONTEXTW:
3189 return TOOLBAR_GetButtonTextW(hwnd,wParam,lParam);
3190
3191/* case TB_GETCOLORSCHEME: */ /* 4.71 */
3192
3193 case TB_GETDISABLEDIMAGELIST:
3194 return TOOLBAR_GetDisabledImageList (hwnd, wParam, lParam);
3195
3196 case TB_GETEXTENDEDSTYLE:
3197 return TOOLBAR_GetExtendedStyle (hwnd);
3198
3199 case TB_GETHOTIMAGELIST:
3200 return TOOLBAR_GetHotImageList (hwnd, wParam, lParam);
3201
3202/* case TB_GETHOTITEM: */ /* 4.71 */
3203
3204 case TB_GETIMAGELIST:
3205 return TOOLBAR_GetImageList (hwnd, wParam, lParam);
3206
3207/* case TB_GETINSERTMARK: */ /* 4.71 */
3208/* case TB_GETINSERTMARKCOLOR: */ /* 4.71 */
3209
3210 case TB_GETITEMRECT:
3211 return TOOLBAR_GetItemRect (hwnd, wParam, lParam);
3212
3213 case TB_GETMAXSIZE:
3214 return TOOLBAR_GetMaxSize (hwnd, wParam, lParam);
3215
3216/* case TB_GETOBJECT: */ /* 4.71 */
3217/* case TB_GETPADDING: */ /* 4.71 */
3218
3219 case TB_GETRECT:
3220 return TOOLBAR_GetRect (hwnd, wParam, lParam);
3221
3222 case TB_GETROWS:
3223 return TOOLBAR_GetRows (hwnd, wParam, lParam);
3224
3225 case TB_GETSTATE:
3226 return TOOLBAR_GetState (hwnd, wParam, lParam);
3227
3228 case TB_GETSTYLE:
3229 return TOOLBAR_GetStyle (hwnd, wParam, lParam);
3230
3231 case TB_GETTEXTROWS:
3232 return TOOLBAR_GetTextRows (hwnd, wParam, lParam);
3233
3234 case TB_GETTOOLTIPS:
3235 return TOOLBAR_GetToolTips (hwnd, wParam, lParam);
3236
3237 case TB_GETUNICODEFORMAT:
3238 return TOOLBAR_GetUnicodeFormat (hwnd, wParam, lParam);
3239
3240 case TB_HIDEBUTTON:
3241 return TOOLBAR_HideButton (hwnd, wParam, lParam);
3242
3243 case TB_HITTEST:
3244 return TOOLBAR_HitTest (hwnd, wParam, lParam);
3245
3246 case TB_INDETERMINATE:
3247 return TOOLBAR_Indeterminate (hwnd, wParam, lParam);
3248
3249 case TB_INSERTBUTTONA:
3250 return TOOLBAR_InsertButtonA (hwnd, wParam, lParam);
3251
3252 case TB_INSERTBUTTONW:
3253 return TOOLBAR_InsertButtonW(hwnd,wParam,lParam);
3254
3255/* case TB_INSERTMARKHITTEST: */ /* 4.71 */
3256
3257 case TB_ISBUTTONCHECKED:
3258 return TOOLBAR_IsButtonChecked (hwnd, wParam, lParam);
3259
3260 case TB_ISBUTTONENABLED:
3261 return TOOLBAR_IsButtonEnabled (hwnd, wParam, lParam);
3262
3263 case TB_ISBUTTONHIDDEN:
3264 return TOOLBAR_IsButtonHidden (hwnd, wParam, lParam);
3265
3266 case TB_ISBUTTONHIGHLIGHTED:
3267 return TOOLBAR_IsButtonHighlighted (hwnd, wParam, lParam);
3268
3269 case TB_ISBUTTONINDETERMINATE:
3270 return TOOLBAR_IsButtonIndeterminate (hwnd, wParam, lParam);
3271
3272 case TB_ISBUTTONPRESSED:
3273 return TOOLBAR_IsButtonPressed (hwnd, wParam, lParam);
3274
3275/* case TB_LOADIMAGES: */ /* 4.70 */
3276/* case TB_MAPACCELERATORA: */ /* 4.71 */
3277/* case TB_MAPACCELERATORW: */ /* 4.71 */
3278/* case TB_MARKBUTTON: */ /* 4.71 */
3279/* case TB_MOVEBUTTON: */ /* 4.71 */
3280
3281 case TB_PRESSBUTTON:
3282 return TOOLBAR_PressButton (hwnd, wParam, lParam);
3283
3284/* case TB_REPLACEBITMAP: */
3285
3286 case TB_SAVERESTOREA:
3287 return TOOLBAR_SaveRestoreA (hwnd, wParam, lParam);
3288
3289 case TB_SAVERESTOREW:
3290 return TOOLBAR_SaveRestoreW(hwnd,wParam,lParam);
3291
3292/* case TB_SETANCHORHIGHLIGHT: */ /* 4.71 */
3293
3294 case TB_SETBITMAPSIZE:
3295 return TOOLBAR_SetBitmapSize (hwnd, wParam, lParam);
3296
3297 case TB_SETBUTTONINFOA:
3298 return TOOLBAR_SetButtonInfoA (hwnd, wParam, lParam);
3299
3300 case TB_SETBUTTONINFOW: /* 4.71 */
3301 return TOOLBAR_SetButtonInfoW(hwnd,wParam,lParam);
3302
3303 case TB_SETBUTTONSIZE:
3304 return TOOLBAR_SetButtonSize (hwnd, wParam, lParam);
3305
3306 case TB_SETBUTTONWIDTH:
3307 return TOOLBAR_SetButtonWidth (hwnd, wParam, lParam);
3308
3309 case TB_SETCMDID:
3310 return TOOLBAR_SetCmdId (hwnd, wParam, lParam);
3311
3312/* case TB_SETCOLORSCHEME: */ /* 4.71 */
3313
3314 case TB_SETDISABLEDIMAGELIST:
3315 return TOOLBAR_SetDisabledImageList (hwnd, wParam, lParam);
3316
3317 case TB_SETDRAWTEXTFLAGS:
3318 return TOOLBAR_SetDrawTextFlags (hwnd, wParam, lParam);
3319
3320 case TB_SETEXTENDEDSTYLE:
3321 return TOOLBAR_SetExtendedStyle (hwnd, wParam, lParam);
3322
3323 case TB_SETHOTIMAGELIST:
3324 return TOOLBAR_SetHotImageList (hwnd, wParam, lParam);
3325
3326/* case TB_SETHOTITEM: */ /* 4.71 */
3327
3328 case TB_SETIMAGELIST:
3329 return TOOLBAR_SetImageList (hwnd, wParam, lParam);
3330
3331 case TB_SETINDENT:
3332 return TOOLBAR_SetIndent (hwnd, wParam, lParam);
3333
3334/* case TB_SETINSERTMARK: */ /* 4.71 */
3335
3336 case TB_SETINSERTMARKCOLOR:
3337 return TOOLBAR_SetInsertMarkColor (hwnd, wParam, lParam);
3338
3339 case TB_SETMAXTEXTROWS:
3340 return TOOLBAR_SetMaxTextRows (hwnd, wParam, lParam);
3341
3342/* case TB_SETPADDING: */ /* 4.71 */
3343
3344 case TB_SETPARENT:
3345 return TOOLBAR_SetParent (hwnd, wParam, lParam);
3346
3347 case TB_SETROWS:
3348 return TOOLBAR_SetRows (hwnd, wParam, lParam);
3349
3350 case TB_SETSTATE:
3351 return TOOLBAR_SetState (hwnd, wParam, lParam);
3352
3353 case TB_SETSTYLE:
3354 return TOOLBAR_SetStyle (hwnd, wParam, lParam);
3355
3356 case TB_SETTOOLTIPS:
3357 return TOOLBAR_SetToolTips (hwnd, wParam, lParam);
3358
3359 case TB_SETUNICODEFORMAT:
3360 return TOOLBAR_SetUnicodeFormat (hwnd, wParam, lParam);
3361
3362
3363/* case WM_CHAR: */
3364
3365 case WM_CREATE:
3366 return TOOLBAR_Create (hwnd, wParam, lParam);
3367
3368 case WM_DESTROY:
3369 return TOOLBAR_Destroy (hwnd, wParam, lParam);
3370
3371 case WM_ERASEBKGND:
3372 return TOOLBAR_EraseBackground (hwnd, wParam, lParam);
3373
3374/* case WM_GETFONT: */
3375/* case WM_KEYDOWN: */
3376/* case WM_KILLFOCUS: */
3377
3378 case WM_LBUTTONDBLCLK:
3379 return TOOLBAR_LButtonDblClk (hwnd, wParam, lParam);
3380
3381 case WM_LBUTTONDOWN:
3382 return TOOLBAR_LButtonDown (hwnd, wParam, lParam);
3383
3384 case WM_LBUTTONUP:
3385 return TOOLBAR_LButtonUp (hwnd, wParam, lParam);
3386
3387 case WM_MOUSEMOVE:
3388 return TOOLBAR_MouseMove (hwnd, wParam, lParam);
3389
3390 case WM_NCACTIVATE:
3391 return TOOLBAR_NCActivate (hwnd, wParam, lParam);
3392
3393 case WM_NCCALCSIZE:
3394 return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
3395
3396 case WM_NCCREATE:
3397 return TOOLBAR_NCCreate (hwnd, wParam, lParam);
3398
3399 case WM_NCPAINT:
3400 return TOOLBAR_NCPaint (hwnd, wParam, lParam);
3401
3402 case WM_NOTIFY:
3403 return TOOLBAR_Notify (hwnd, wParam, lParam);
3404
3405/* case WM_NOTIFYFORMAT: */
3406
3407 case WM_PAINT:
3408 return TOOLBAR_Paint (hwnd, wParam);
3409
3410 case WM_SIZE:
3411 return TOOLBAR_Size (hwnd, wParam, lParam);
3412
3413 case WM_STYLECHANGED:
3414 return TOOLBAR_StyleChanged (hwnd, wParam, lParam);
3415
3416/* case WM_SYSCOLORCHANGE: */
3417
3418/* case WM_WININICHANGE: */
3419
3420 case WM_CHARTOITEM:
3421 case WM_COMMAND:
3422 case WM_DRAWITEM:
3423 case WM_MEASUREITEM:
3424 case WM_VKEYTOITEM:
3425 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
3426
3427 default:
3428// if (uMsg >= WM_USER)
3429// ERR (toolbar, "unknown msg %04x wp=%08x lp=%08lx\n",
3430// uMsg, wParam, lParam);
3431 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3432 }
3433 return 0;
3434}
3435
3436
3437VOID
3438TOOLBAR_Register (VOID)
3439{
3440 WNDCLASSA wndClass;
3441
3442 if (GlobalFindAtomA (TOOLBARCLASSNAMEA)) return;
3443
3444 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
3445 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
3446 wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
3447 wndClass.cbClsExtra = 0;
3448 wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
3449 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
3450 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
3451 wndClass.lpszClassName = TOOLBARCLASSNAMEA;
3452
3453 RegisterClassA (&wndClass);
3454}
3455
3456
3457VOID
3458TOOLBAR_Unregister (VOID)
3459{
3460 if (GlobalFindAtomA (TOOLBARCLASSNAMEA))
3461 UnregisterClassA (TOOLBARCLASSNAMEA, (HINSTANCE)NULL);
3462}
3463
Note: See TracBrowser for help on using the repository browser.