4 * Copyright 1998 Anders Carlsson
10 * Updown control support
12 * Messages to be added in commctrl.h
24 #define TAB_GetInfoPtr(wndPtr) ((TAB_INFO *)wndPtr->wExtra[0])
27 TAB_SendSimpleNotify (WND
*wndPtr
, UINT32 code
)
31 nmhdr
.hwndFrom
= wndPtr
->hwndSelf
;
32 nmhdr
.idFrom
= wndPtr
->wIDmenu
;
35 return (BOOL32
) SendMessage32A (GetParent32 (wndPtr
->hwndSelf
), WM_NOTIFY
,
36 (WPARAM32
) nmhdr
.idFrom
, (LPARAM
) &nmhdr
);
40 TAB_GetCurSel (WND
*wndPtr
)
42 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
44 return infoPtr
->iSelected
;
48 TAB_LButtonUp (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
50 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
55 pt
.x
= (INT32
)LOWORD(lParam
);
56 pt
.y
= (INT32
)HIWORD(lParam
);
58 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
60 if (PtInRect32 (&rect
, pt
))
62 for (iCount
= 0; iCount
< infoPtr
->uNumItem
; iCount
++) {
63 rect
= infoPtr
->items
[iCount
].rect
;
64 if (PtInRect32 (&rect
, pt
)) {
65 TRACE(tab
, "On Tab, item %d\n", iCount
);
67 if (infoPtr
->iSelected
!= iCount
) {
68 infoPtr
->iSelected
= iCount
;
70 TAB_SendSimpleNotify(wndPtr
, TCN_SELCHANGE
);
82 TAB_SetItemBounds (WND
*wndPtr
)
84 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
86 HFONT32 hFont
, hOldFont
;
91 /* FIXME: Is this needed? */
92 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
94 hdc
= GetDC32(wndPtr
->hwndSelf
);
96 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject32 (SYSTEM_FONT
);
97 hOldFont
= SelectObject32 (hdc
, hFont
);
101 for (i
= 0; i
< infoPtr
->uNumItem
; i
++)
103 infoPtr
->items
[i
].rect
.left
= left
;
104 infoPtr
->items
[i
].rect
.top
= infoPtr
->rect
.top
;
106 GetTextExtentPoint32A(hdc
,
107 infoPtr
->items
[i
].pszText
,
108 lstrlen32A(infoPtr
->items
[i
].pszText
), &size
);
109 infoPtr
->items
[i
].rect
.right
= left
+ size
.cx
+2*5;
110 infoPtr
->items
[i
].rect
.bottom
= infoPtr
->rect
.top
+ 20;
111 TRACE(tab
, "TextSize: %i - ", size
.cx
);
112 TRACE(tab
, "Rect: T %i, L %i, B %i, R %i\n",
113 infoPtr
->items
[i
].rect
.top
,
114 infoPtr
->items
[i
].rect
.left
,
115 infoPtr
->items
[i
].rect
.bottom
,
116 infoPtr
->items
[i
].rect
.right
);
117 left
+= (size
.cx
+ 11);
120 SelectObject32 (hdc
, hOldFont
);
121 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
125 TAB_DrawItem (WND
*wndPtr
, HDC32 hdc
, INT32 iItem
)
127 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
128 TAB_ITEM
*pti
= &infoPtr
->items
[iItem
];
132 HPEN32 hwPen
= CreatePen32 (PS_SOLID
, 1, RGB (255, 255, 255 ));
133 HPEN32 hbPen
= CreatePen32 (PS_SOLID
, 1, GetSysColor32 (COLOR_BTNSHADOW
));
134 HPEN32 hsdPen
= CreatePen32(PS_SOLID
, 1, GetSysColor32 (COLOR_BTNTEXT
));
135 HPEN32 htmpPen
= (HPEN32
)NULL
;
137 CopyRect32(&r
, &pti
->rect
);
140 htmpPen
= SelectObject32 (hdc
, htmpPen
);
141 MoveToEx32 (hdc
, r
.left
, r
.bottom
, NULL
);
142 LineTo32 (hdc
, r
.left
, r
.top
+ 2);
143 LineTo32 (hdc
, r
.left
+2, r
.top
);
145 LineTo32 (hdc
, r
.right
-1, r
.top
);
146 htmpPen
= SelectObject32 (hdc
, htmpPen
);
148 htmpPen
= SelectObject32 (hdc
, hbPen
);
149 MoveToEx32 (hdc
, r
.right
-1, r
.top
, NULL
);
150 LineTo32 (hdc
,r
.right
-1, r
.bottom
-1);
151 hbPen
= SelectObject32 (hdc
, hsdPen
);
152 MoveToEx32 (hdc
, r
.right
, r
.top
+1, NULL
);
153 LineTo32(hdc
, r
.right
,r
.bottom
);
154 hsdPen
= SelectObject32(hdc
,htmpPen
);
155 DeleteObject32(hwPen
);
156 DeleteObject32(hbPen
);
157 DeleteObject32(hsdPen
);
159 oldBkMode
= SetBkMode32(hdc
, TRANSPARENT
);
162 SetTextColor32 (hdc
, COLOR_BTNTEXT
);
163 DrawText32A(hdc
, pti
->pszText
, lstrlen32A(pti
->pszText
),
164 &r
, DT_LEFT
|DT_SINGLELINE
|DT_VCENTER
);
165 if (oldBkMode
!= TRANSPARENT
)
166 SetBkMode32(hdc
, oldBkMode
);
170 TAB_DrawBorder (WND
*wndPtr
, HDC32 hdc
)
173 HPEN32 hwPen
= GetStockObject32(WHITE_PEN
);
174 HPEN32 hbPen
= GetStockObject32(BLACK_PEN
);
175 HPEN32 hShade
= CreatePen32 ( PS_SOLID
, 1, GetSysColor32 (COLOR_BTNSHADOW
));
178 htmPen
= SelectObject32 (hdc
, hwPen
);
179 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
181 MoveToEx32 (hdc
, rect
.left
, rect
.bottom
, NULL
);
182 LineTo32 (hdc
, rect
.left
, rect
.top
+20);
184 LineTo32 (hdc
, rect
.right
, rect
.top
+20);
186 hwPen
= SelectObject32 (hdc
, htmPen
);
187 LineTo32 (hdc
, rect
.right
, rect
.bottom
);
188 LineTo32 (hdc
, rect
.left
, rect
.bottom
);
189 hbPen
= SelectObject32 (hdc
, hShade
);
190 MoveToEx32 (hdc
, rect
.right
-1, rect
.top
+20, NULL
);
191 LineTo32 (hdc
, rect
.right
-1, rect
.bottom
-1);
192 LineTo32 (hdc
, rect
.left
, rect
.bottom
-1);
193 hShade
= SelectObject32(hdc
, hShade
);
194 DeleteObject32 (hShade
);
199 TAB_Refresh (WND
*wndPtr
, HDC32 hdc
)
201 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
202 HFONT32 hFont
, hOldFont
;
207 TAB_DrawBorder (wndPtr
, hdc
);
209 for (i
= 0; i
< infoPtr
->uNumItem
; i
++) {
210 TAB_DrawItem (wndPtr
, hdc
, i
);
216 TAB_Paint (WND
*wndPtr
, WPARAM32 wParam
)
221 hdc
= wParam
== 0 ? BeginPaint32 (wndPtr
->hwndSelf
, &ps
) : (HDC32
)wParam
;
222 TAB_Refresh (wndPtr
, hdc
);
225 EndPaint32 (wndPtr
->hwndSelf
, &ps
);
230 TAB_InsertItem (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
232 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
237 pti
= (TCITEM
*)lParam
;
238 iItem
= (INT32
)wParam
;
240 if (iItem
< 0) return -1;
241 if (iItem
> infoPtr
->uNumItem
)
242 iItem
= infoPtr
->uNumItem
;
244 if (infoPtr
->uNumItem
== 0) {
245 infoPtr
->items
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
,
250 TAB_ITEM
*oldItems
= infoPtr
->items
;
253 infoPtr
->items
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
,
254 sizeof (TAB_ITEM
) * infoPtr
->uNumItem
);
256 /* pre insert copy */
258 memcpy (&infoPtr
->items
[0], &oldItems
[0],
259 iItem
* sizeof(TAB_ITEM
));
262 /* post insert copy */
263 if (iItem
< infoPtr
->uNumItem
- 1) {
264 memcpy (&infoPtr
->items
[iItem
+1], &oldItems
[iItem
],
265 (infoPtr
->uNumItem
- iItem
- 1) * sizeof(TAB_ITEM
));
269 HeapFree (GetProcessHeap (), 0, oldItems
);
272 infoPtr
->items
[iItem
].mask
= pti
->mask
;
273 if (pti
->mask
& TCIF_TEXT
) {
274 len
= lstrlen32A (pti
->pszText
);
275 infoPtr
->items
[iItem
].pszText
=
276 HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, len
+1);
277 lstrcpy32A (infoPtr
->items
[iItem
].pszText
, pti
->pszText
);
278 infoPtr
->items
[iItem
].cchTextMax
= pti
->cchTextMax
;
283 if (pti
->mask
& TCIF_IMAGE
)
284 infoPtr
->items
[iItem
].iImage
= pti
->iImage
;
286 if (pti
->mask
& TCIF_PARAM
)
287 infoPtr
->items
[iItem
].lParam
= pti
->lParam
;
289 hdc
= GetDC32 (wndPtr
->hwndSelf
);
290 TAB_Refresh (wndPtr
, hdc
);
291 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
293 TRACE(tab
, "[%04x]: added item %d '%s'\n",
294 wndPtr
->hwndSelf
, iItem
, infoPtr
->items
[iItem
].pszText
);
296 TAB_SetItemBounds(wndPtr
);
301 TAB_Create (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
305 infoPtr
= (TAB_INFO
*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
,
307 wndPtr
->wExtra
[0] = (DWORD
)infoPtr
;
309 infoPtr
->uNumItem
= 0;
312 infoPtr
->hcurArrow
= LoadCursor32A (0, IDC_ARROW32A
);
313 infoPtr
->iSelected
= -1;
315 TRACE(tab
, "Created tab control, hwnd [%04x]\n", wndPtr
->hwndSelf
);
320 TAB_Destroy (WND
*wndPtr
, WPARAM32 wParam
, LPARAM lParam
)
322 TAB_INFO
*infoPtr
= TAB_GetInfoPtr(wndPtr
);
325 if (infoPtr
->items
) {
326 for (iItem
= 0; iItem
< infoPtr
->uNumItem
; iItem
++) {
327 if (infoPtr
->items
[iItem
].pszText
)
328 HeapFree (GetProcessHeap (), 0, infoPtr
->items
[iItem
].pszText
);
330 HeapFree (GetProcessHeap (), 0, infoPtr
->items
);
333 HeapFree (GetProcessHeap (), 0, infoPtr
);
339 TAB_WindowProc (HWND32 hwnd
, UINT32 uMsg
, WPARAM32 wParam
, LPARAM lParam
)
341 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
347 return TAB_GetCurSel (wndPtr
);
350 return TAB_InsertItem (wndPtr
, wParam
, lParam
);
353 return TAB_Create (wndPtr
, wParam
, lParam
);
356 return TAB_Destroy (wndPtr
, wParam
, lParam
);
359 return TAB_LButtonUp (wndPtr
, wParam
, lParam
);
361 return TAB_Paint (wndPtr
, wParam
);
366 ERR (tab
, "unknown msg %04x wp=%08x lp=%08lx\n",
367 uMsg
, wParam
, lParam
);
368 return DefWindowProc32A (hwnd
, uMsg
, wParam
, lParam
);
377 WNDCLASS32A wndClass
;
379 if (GlobalFindAtom32A (WC_TABCONTROL32A
)) return;
381 ZeroMemory (&wndClass
, sizeof(WNDCLASS32A
));
382 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
| CS_SAVEBITS
;
383 wndClass
.lpfnWndProc
= (WNDPROC32
)TAB_WindowProc
;
384 wndClass
.cbClsExtra
= 0;
385 wndClass
.cbWndExtra
= sizeof(TAB_INFO
*);
386 wndClass
.hCursor
= LoadCursor32A (0, IDC_ARROW32A
);
387 wndClass
.hbrBackground
= 0;
388 wndClass
.lpszClassName
= WC_TABCONTROL32A
;
390 RegisterClass32A (&wndClass
);
395 TAB_Unregister (VOID
)
397 if (GlobalFindAtom32A (WC_TABCONTROL32A
))
398 UnregisterClass32A (WC_TABCONTROL32A
, (HINSTANCE32
)NULL
);