4 * Copyright 1998 Anders Carlsson
10 * Updown control support
12 * Messages to be added in commctrl.h
23 #define TAB_GetInfoPtr(wndPtr) ((TAB_INFO *)wndPtr->wExtra[0])
31 TAB_SendSimpleNotify (WND
*wndPtr
, UINT32 code
)
35 nmhdr
.hwndFrom
= wndPtr
->hwndSelf
;
36 nmhdr
.idFrom
= wndPtr
->wIDmenu
;
39 return (BOOL32
) SendMessage32A (GetParent32 (wndPtr
->hwndSelf
), WM_NOTIFY
,
40 (WPARAM32
) nmhdr
.idFrom
, (LPARAM
) &nmhdr
);
44 TAB_GetCurSel (WND
*wndPtr
)
46 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
48 return infoPtr
->iSelected
;
53 TAB_SetCurSel (WND
*wndPtr
,WPARAM32 wParam
)
55 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
56 INT32 iItem
=(INT32
) wParam
;
60 if ((iItem
>= 0) && (iItem
< infoPtr
->uNumItem
)) {
61 prevItem
=infoPtr
->iSelected
;
62 infoPtr
->iSelected
=iItem
;
68 TAB_LButtonUp (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
70 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
75 pt
.x
= (INT32
)LOWORD(lParam
);
76 pt
.y
= (INT32
)HIWORD(lParam
);
78 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
80 if (PtInRect32 (&rect
, pt
))
82 for (iCount
= 0; iCount
< infoPtr
->uNumItem
; iCount
++) {
83 rect
= infoPtr
->items
[iCount
].rect
;
84 if (PtInRect32 (&rect
, pt
)) {
85 TRACE(tab
, "On Tab, item %d\n", iCount
);
87 if (infoPtr
->iSelected
!= iCount
) {
88 infoPtr
->iSelected
= iCount
;
90 TAB_SendSimpleNotify(wndPtr
, TCN_SELCHANGE
);
103 TAB_AdjustRect (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
107 FIXME (tab
,"Should set display rectangle\n");
109 FIXME (tab
,"Should set window rectangle\n");
116 TAB_SetItemBounds (WND
*wndPtr
)
118 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
120 HFONT32 hFont
, hOldFont
;
125 /* FIXME: Is this needed? */
126 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
128 hdc
= GetDC32(wndPtr
->hwndSelf
);
130 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject32 (SYSTEM_FONT
);
131 hOldFont
= SelectObject32 (hdc
, hFont
);
135 for (i
= 0; i
< infoPtr
->uNumItem
; i
++)
137 infoPtr
->items
[i
].rect
.left
= left
;
138 infoPtr
->items
[i
].rect
.top
= infoPtr
->rect
.top
;
140 GetTextExtentPoint32A(hdc
,
141 infoPtr
->items
[i
].pszText
,
142 lstrlen32A(infoPtr
->items
[i
].pszText
), &size
);
143 infoPtr
->items
[i
].rect
.right
= left
+ size
.cx
+2*5;
144 infoPtr
->items
[i
].rect
.bottom
= infoPtr
->rect
.top
+ 20;
145 TRACE(tab
, "TextSize: %i - ", size
.cx
);
146 TRACE(tab
, "Rect: T %i, L %i, B %i, R %i\n",
147 infoPtr
->items
[i
].rect
.top
,
148 infoPtr
->items
[i
].rect
.left
,
149 infoPtr
->items
[i
].rect
.bottom
,
150 infoPtr
->items
[i
].rect
.right
);
151 left
+= (size
.cx
+ 11);
154 SelectObject32 (hdc
, hOldFont
);
155 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
159 TAB_DrawItem (WND
*wndPtr
, HDC32 hdc
, INT32 iItem
)
161 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
162 TAB_ITEM
*pti
= &infoPtr
->items
[iItem
];
166 HPEN32 hwPen
= GetSysColorPen32 (COLOR_3DHILIGHT
);
167 HPEN32 hbPen
= GetSysColorPen32 (COLOR_BTNSHADOW
);
168 HPEN32 hsdPen
= GetSysColorPen32 (COLOR_BTNTEXT
);
169 HPEN32 htmpPen
= (HPEN32
)NULL
;
171 CopyRect32(&r
, &pti
->rect
);
174 htmpPen
= SelectObject32 (hdc
, htmpPen
);
175 MoveToEx32 (hdc
, r
.left
, r
.bottom
, NULL
);
176 LineTo32 (hdc
, r
.left
, r
.top
+ 2);
177 LineTo32 (hdc
, r
.left
+2, r
.top
);
179 LineTo32 (hdc
, r
.right
-1, r
.top
);
180 htmpPen
= SelectObject32 (hdc
, htmpPen
);
182 htmpPen
= SelectObject32 (hdc
, hbPen
);
183 MoveToEx32 (hdc
, r
.right
-1, r
.top
, NULL
);
184 LineTo32 (hdc
,r
.right
-1, r
.bottom
-1);
185 hbPen
= SelectObject32 (hdc
, hsdPen
);
186 MoveToEx32 (hdc
, r
.right
, r
.top
+1, NULL
);
187 LineTo32(hdc
, r
.right
,r
.bottom
);
188 hsdPen
= SelectObject32(hdc
,htmpPen
);
190 oldBkMode
= SetBkMode32(hdc
, TRANSPARENT
);
193 SetTextColor32 (hdc
, COLOR_BTNTEXT
);
194 DrawText32A(hdc
, pti
->pszText
, lstrlen32A(pti
->pszText
),
195 &r
, DT_LEFT
|DT_SINGLELINE
|DT_VCENTER
);
196 if (oldBkMode
!= TRANSPARENT
)
197 SetBkMode32(hdc
, oldBkMode
);
201 TAB_DrawBorder (WND
*wndPtr
, HDC32 hdc
)
204 HPEN32 hwPen
= GetSysColorPen32 (COLOR_3DHILIGHT
);
205 HPEN32 hbPen
= GetSysColorPen32 (COLOR_3DDKSHADOW
);
206 HPEN32 hShade
= GetSysColorPen32 (COLOR_BTNSHADOW
);
210 htmPen
= SelectObject32 (hdc
, hwPen
);
211 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
213 MoveToEx32 (hdc
, rect
.left
, rect
.bottom
, NULL
);
214 LineTo32 (hdc
, rect
.left
, rect
.top
+20);
216 LineTo32 (hdc
, rect
.right
, rect
.top
+20);
218 hwPen
= SelectObject32 (hdc
, htmPen
);
219 LineTo32 (hdc
, rect
.right
, rect
.bottom
);
220 LineTo32 (hdc
, rect
.left
, rect
.bottom
);
221 hbPen
= SelectObject32 (hdc
, hShade
);
222 MoveToEx32 (hdc
, rect
.right
-1, rect
.top
+20, NULL
);
223 LineTo32 (hdc
, rect
.right
-1, rect
.bottom
-1);
224 LineTo32 (hdc
, rect
.left
, rect
.bottom
-1);
225 hShade
= SelectObject32(hdc
, hShade
);
230 TAB_Refresh (WND
*wndPtr
, HDC32 hdc
)
232 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
236 TAB_DrawBorder (wndPtr
, hdc
);
238 hOldFont
= SelectObject32 (hdc
, infoPtr
->hFont
);
239 for (i
= 0; i
< infoPtr
->uNumItem
; i
++) {
240 TAB_DrawItem (wndPtr
, hdc
, i
);
242 SelectObject32 (hdc
, hOldFont
);
246 TAB_Paint (WND
*wndPtr
, WPARAM32 wParam
)
251 hdc
= wParam
== 0 ? BeginPaint32 (wndPtr
->hwndSelf
, &ps
) : (HDC32
)wParam
;
252 TAB_Refresh (wndPtr
, hdc
);
255 EndPaint32 (wndPtr
->hwndSelf
, &ps
);
260 TAB_InsertItem (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
262 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
267 pti
= (TCITEM32A
*)lParam
;
268 iItem
= (INT32
)wParam
;
270 if (iItem
< 0) return -1;
271 if (iItem
> infoPtr
->uNumItem
)
272 iItem
= infoPtr
->uNumItem
;
274 if (infoPtr
->uNumItem
== 0) {
275 infoPtr
->items
= COMCTL32_Alloc (sizeof (TAB_ITEM
));
279 TAB_ITEM
*oldItems
= infoPtr
->items
;
282 infoPtr
->items
= COMCTL32_Alloc (sizeof (TAB_ITEM
) * infoPtr
->uNumItem
);
284 /* pre insert copy */
286 memcpy (&infoPtr
->items
[0], &oldItems
[0],
287 iItem
* sizeof(TAB_ITEM
));
290 /* post insert copy */
291 if (iItem
< infoPtr
->uNumItem
- 1) {
292 memcpy (&infoPtr
->items
[iItem
+1], &oldItems
[iItem
],
293 (infoPtr
->uNumItem
- iItem
- 1) * sizeof(TAB_ITEM
));
297 COMCTL32_Free (oldItems
);
300 infoPtr
->items
[iItem
].mask
= pti
->mask
;
301 if (pti
->mask
& TCIF_TEXT
) {
302 len
= lstrlen32A (pti
->pszText
);
303 infoPtr
->items
[iItem
].pszText
= COMCTL32_Alloc (len
+1);
304 lstrcpy32A (infoPtr
->items
[iItem
].pszText
, pti
->pszText
);
305 infoPtr
->items
[iItem
].cchTextMax
= pti
->cchTextMax
;
308 if (pti
->mask
& TCIF_IMAGE
)
309 infoPtr
->items
[iItem
].iImage
= pti
->iImage
;
311 if (pti
->mask
& TCIF_PARAM
)
312 infoPtr
->items
[iItem
].lParam
= pti
->lParam
;
314 hdc
= GetDC32 (wndPtr
->hwndSelf
);
315 TAB_Refresh (wndPtr
, hdc
);
316 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
318 TRACE(tab
, "[%04x]: added item %d '%s'\n",
319 wndPtr
->hwndSelf
, iItem
, infoPtr
->items
[iItem
].pszText
);
321 TAB_SetItemBounds(wndPtr
);
326 TAB_SetItem32A (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
328 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
333 iItem
=(INT32
) wParam
;
334 tabItem
=(LPTCITEM32A
) lParam
;
335 TRACE (tab
,"%d %p\n",iItem
, tabItem
);
336 if ((iItem
<0) || (iItem
>infoPtr
->uNumItem
)) return FALSE
;
338 wineItem
=& infoPtr
->items
[iItem
];
340 if (tabItem
->mask
& TCIF_IMAGE
)
341 wineItem
->iImage
=tabItem
->iImage
;
343 if (tabItem
->mask
& TCIF_PARAM
)
344 wineItem
->lParam
=tabItem
->lParam
;
346 if (tabItem
->mask
& TCIF_RTLREADING
)
347 FIXME (tab
,"TCIF_RTLREADING\n");
349 if (tabItem
->mask
& TCIF_STATE
)
350 wineItem
->dwState
=tabItem
->dwState
;
352 if (tabItem
->mask
& TCIF_TEXT
) {
353 len
=lstrlen32A (tabItem
->pszText
);
354 if (len
>wineItem
->cchTextMax
)
355 wineItem
->pszText
= COMCTL32_ReAlloc (wineItem
->pszText
, len
+1);
356 lstrcpyn32A (wineItem
->pszText
, tabItem
->pszText
, len
);
363 TAB_GetItemCount (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
365 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
367 return infoPtr
->uNumItem
;
372 TAB_GetItem32A (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
374 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
379 iItem
=(INT32
) wParam
;
380 tabItem
=(LPTCITEM32A
) lParam
;
382 if ((iItem
<0) || (iItem
>infoPtr
->uNumItem
)) return FALSE
;
384 wineItem
=& infoPtr
->items
[iItem
];
386 if (tabItem
->mask
& TCIF_IMAGE
)
387 tabItem
->iImage
=wineItem
->iImage
;
389 if (tabItem
->mask
& TCIF_PARAM
)
390 tabItem
->lParam
=wineItem
->lParam
;
392 if (tabItem
->mask
& TCIF_RTLREADING
)
393 FIXME (tab
, "TCIF_RTLREADING\n");
395 if (tabItem
->mask
& TCIF_STATE
)
396 tabItem
->dwState
=wineItem
->dwState
;
398 if (tabItem
->mask
& TCIF_TEXT
)
399 lstrcpyn32A (tabItem
->pszText
, wineItem
->pszText
, tabItem
->cchTextMax
);
405 TAB_DeleteItem (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
407 /* TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr); */
409 FIXME (tab
,"stub \n");
413 TAB_DeleteAllItems (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
415 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
417 COMCTL32_Free (infoPtr
->items
);
425 TAB_GetFont (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
427 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
430 return (LRESULT
)infoPtr
->hFont
;
434 TAB_SetFont (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
437 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
439 HFONT32 hFont
, hOldFont
;
442 TRACE (tab
,"%x %lx\n",wParam
, lParam
);
444 infoPtr
->hFont
= (HFONT32
)wParam
;
446 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject32 (SYSTEM_FONT
);
449 hOldFont
= SelectObject32 (hdc
, hFont
);
450 GetTextMetrics32A (hdc
, &tm
);
451 infoPtr
->nHeight
= tm
.tmHeight
+ tm
.tmExternalLeading
;
452 SelectObject32 (hdc
, hOldFont
);
454 if (lParam
) TAB_Refresh (wndPtr
,hdc
);
455 ReleaseDC32 (0, hdc
);
462 TAB_GetImageList (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
464 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
467 return (LRESULT
)infoPtr
->himl
;
471 TAB_SetImageList (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
473 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
477 himlPrev
= infoPtr
->himl
;
478 infoPtr
->himl
= (HIMAGELIST
)lParam
;
479 return (LRESULT
)himlPrev
;
483 TAB_Create (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
487 infoPtr
= (TAB_INFO
*)COMCTL32_Alloc (sizeof(TAB_INFO
));
488 wndPtr
->wExtra
[0] = (DWORD
)infoPtr
;
490 infoPtr
->uNumItem
= 0;
493 infoPtr
->hcurArrow
= LoadCursor32A (0, IDC_ARROW32A
);
494 infoPtr
->iSelected
= -1;
496 TRACE(tab
, "Created tab control, hwnd [%04x]\n", wndPtr
->hwndSelf
);
501 TAB_Destroy (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
503 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
506 if (infoPtr
->items
) {
507 for (iItem
= 0; iItem
< infoPtr
->uNumItem
; iItem
++) {
508 if (infoPtr
->items
[iItem
].pszText
)
509 COMCTL32_Free (infoPtr
->items
[iItem
].pszText
);
511 COMCTL32_Free (infoPtr
->items
);
514 COMCTL32_Free (infoPtr
);
520 TAB_WindowProc (HWND32 hwnd
, UINT32 uMsg
, WPARAM32 wParam
, LPARAM lParam
)
522 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
527 case TCM_GETIMAGELIST
:
528 return TAB_GetImageList (wndPtr
, wParam
, lParam
);
530 case TCM_SETIMAGELIST
:
531 return TAB_SetImageList (wndPtr
, wParam
, lParam
);
533 case TCM_GETITEMCOUNT
:
534 return TAB_GetItemCount (wndPtr
, wParam
, lParam
);
537 return TAB_GetItem32A (wndPtr
, wParam
, lParam
);
540 FIXME (tab
, "Unimplemented msg TCM_GETITEM32W\n");
544 return TAB_SetItem32A (wndPtr
, wParam
, lParam
);
547 FIXME (tab
, "Unimplemented msg TCM_GETITEM32W\n");
551 return TAB_DeleteItem (wndPtr
, wParam
, lParam
);
553 case TCM_DELETEALLITEMS
:
554 return TAB_DeleteAllItems (wndPtr
, wParam
, lParam
);
556 case TCM_GETITEMRECT
:
557 FIXME (tab
, "Unimplemented msg TCM_GETITEMRECT\n");
561 return TAB_GetCurSel (wndPtr
);
564 return TAB_SetCurSel (wndPtr
, wParam
);
566 case TCM_INSERTITEM32A
:
567 return TAB_InsertItem (wndPtr
, wParam
, lParam
);
569 case TCM_INSERTITEM32W
:
570 FIXME (tab
, "Unimplemented msg TCM_INSERTITEM32W\n");
573 case TCM_SETITEMEXTRA
:
574 FIXME (tab
, "Unimplemented msg TCM_SETITEMEXTRA\n");
578 return TAB_AdjustRect (wndPtr
, wParam
, lParam
);
580 case TCM_SETITEMSIZE
:
581 FIXME (tab
, "Unimplemented msg TCM_SETITEMSIZE\n");
584 case TCM_REMOVEIMAGE
:
585 FIXME (tab
, "Unimplemented msg TCM_REMOVEIMAGE\n");
589 FIXME (tab
, "Unimplemented msg TCM_SETPADDING\n");
592 case TCM_GETROWCOUNT
:
593 FIXME (tab
, "Unimplemented msg TCM_GETROWCOUNT\n");
596 case TCM_GETTOOLTIPS
:
597 FIXME (tab
, "Unimplemented msg TCM_GETTOOLTIPS\n");
600 case TCM_SETTOOLTIPS
:
601 FIXME (tab
, "Unimplemented msg TCM_SETTOOLTIPS\n");
604 case TCM_GETCURFOCUS
:
605 FIXME (tab
, "Unimplemented msg TCM_GETCURFOCUS\n");
608 case TCM_SETCURFOCUS
:
609 FIXME (tab
, "Unimplemented msg TCM_SETCURFOCUS\n");
612 case TCM_SETMINTTABWIDTH
:
613 FIXME (tab
, "Unimplemented msg TCM_SETMINTTABWIDTH\n");
616 case TCM_DESELECTALL
:
617 FIXME (tab
, "Unimplemented msg TCM_DESELECTALL\n");
621 return TAB_GetFont (wndPtr
, wParam
, lParam
);
624 return TAB_SetFont (wndPtr
, wParam
, lParam
);
627 return TAB_Create (wndPtr
, wParam
, lParam
);
630 return TAB_Destroy (wndPtr
, wParam
, lParam
);
633 return DLGC_WANTARROWS
| DLGC_WANTCHARS
;
636 return TAB_LButtonUp (wndPtr
, wParam
, lParam
);
639 return TAB_Paint (wndPtr
, wParam
);
644 ERR (tab
, "unknown msg %04x wp=%08x lp=%08lx\n",
645 uMsg
, wParam
, lParam
);
646 return DefWindowProc32A (hwnd
, uMsg
, wParam
, lParam
);
655 WNDCLASS32A wndClass
;
657 if (GlobalFindAtom32A (WC_TABCONTROL32A
)) return;
659 ZeroMemory (&wndClass
, sizeof(WNDCLASS32A
));
660 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
| CS_SAVEBITS
;
661 wndClass
.lpfnWndProc
= (WNDPROC32
)TAB_WindowProc
;
662 wndClass
.cbClsExtra
= 0;
663 wndClass
.cbWndExtra
= sizeof(TAB_INFO
*);
664 wndClass
.hCursor
= LoadCursor32A (0, IDC_ARROW32A
);
665 wndClass
.hbrBackground
= 0;
666 wndClass
.lpszClassName
= WC_TABCONTROL32A
;
668 RegisterClass32A (&wndClass
);
673 TAB_Unregister (VOID
)
675 if (GlobalFindAtom32A (WC_TABCONTROL32A
))
676 UnregisterClass32A (WC_TABCONTROL32A
, (HINSTANCE32
)NULL
);