Commented out unused variables to prevent needless compiler warnings.
[wine.git] / dlls / comctl32 / tab.c
blob128d41b6eb1db488dac298adf793786da21cb860
1 /*
2 * Tab control
4 * Copyright 1998 Anders Carlsson
6 * TODO:
7 * Image list support
8 * Multiline support
9 * Unicode support
10 * Updown control support
11 * Look and feel
12 * Messages to be added in commctrl.h
13 * ...
16 #include "windows.h"
17 #include "commctrl.h"
18 #include "tab.h"
19 #include "win.h"
20 #include "debug.h"
23 #define TAB_GetInfoPtr(wndPtr) ((TAB_INFO *)wndPtr->wExtra[0])
30 static BOOL32
31 TAB_SendSimpleNotify (WND *wndPtr, UINT32 code)
33 NMHDR nmhdr;
35 nmhdr.hwndFrom = wndPtr->hwndSelf;
36 nmhdr.idFrom = wndPtr->wIDmenu;
37 nmhdr.code = code;
39 return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
40 (WPARAM32) nmhdr.idFrom, (LPARAM) &nmhdr);
43 static LRESULT
44 TAB_GetCurSel (WND *wndPtr)
46 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
48 return infoPtr->iSelected;
52 static LRESULT
53 TAB_SetCurSel (WND *wndPtr,WPARAM32 wParam)
55 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
56 INT32 iItem=(INT32) wParam;
57 INT32 prevItem;
59 prevItem=-1;
60 if ((iItem >= 0) && (iItem < infoPtr->uNumItem)) {
61 prevItem=infoPtr->iSelected;
62 infoPtr->iSelected=iItem;
64 return prevItem;
67 static LRESULT
68 TAB_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
70 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
71 POINT32 pt;
72 RECT32 rect;
73 INT32 iCount;
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);
93 return 0;
98 return 0;
102 static LRESULT
103 TAB_AdjustRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
106 if (wParam==TRUE) {
107 FIXME (tab,"Should set display rectangle\n");
108 } else {
109 FIXME (tab,"Should set window rectangle\n");
112 return 0;
115 static void
116 TAB_SetItemBounds (WND *wndPtr)
118 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
119 RECT32 rect;
120 HFONT32 hFont, hOldFont;
121 INT32 i, left;
122 SIZE32 size;
123 HDC32 hdc;
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);
133 left = rect.left;
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);
158 static void
159 TAB_DrawItem (WND *wndPtr, HDC32 hdc, INT32 iItem)
161 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
162 TAB_ITEM *pti = &infoPtr->items[iItem];
163 RECT32 r;
164 INT32 oldBkMode;
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);
173 htmpPen = hwPen;
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);
191 r.left += 3;
192 r.right -= 3;
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);
200 static void
201 TAB_DrawBorder (WND *wndPtr, HDC32 hdc)
203 HPEN32 htmPen;
204 HPEN32 hwPen = GetSysColorPen32 (COLOR_3DHILIGHT);
205 HPEN32 hbPen = GetSysColorPen32 (COLOR_3DDKSHADOW);
206 HPEN32 hShade = GetSysColorPen32 (COLOR_BTNSHADOW);
208 RECT32 rect;
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);
229 static void
230 TAB_Refresh (WND *wndPtr, HDC32 hdc)
232 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
233 HFONT32 hOldFont;
234 INT32 i;
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);
245 static LRESULT
246 TAB_Paint (WND *wndPtr, WPARAM32 wParam)
248 HDC32 hdc;
249 PAINTSTRUCT32 ps;
251 hdc = wParam== 0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
252 TAB_Refresh (wndPtr, hdc);
254 if(!wParam)
255 EndPaint32 (wndPtr->hwndSelf, &ps);
256 return 0;
259 static LRESULT
260 TAB_InsertItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
262 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
263 TCITEM32A *pti;
264 HDC32 hdc;
265 INT32 iItem, len;
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));
276 infoPtr->uNumItem++;
278 else {
279 TAB_ITEM *oldItems = infoPtr->items;
281 infoPtr->uNumItem++;
282 infoPtr->items = COMCTL32_Alloc (sizeof (TAB_ITEM) * infoPtr->uNumItem);
284 /* pre insert copy */
285 if (iItem > 0) {
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);
322 return iItem;
325 static LRESULT
326 TAB_SetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
328 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
329 TCITEM32A *tabItem;
330 TAB_ITEM *wineItem;
331 INT32 iItem,len;
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);
359 return TRUE;
362 static LRESULT
363 TAB_GetItemCount (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
365 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
367 return infoPtr->uNumItem;
371 static LRESULT
372 TAB_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
374 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
375 TCITEM32A *tabItem;
376 TAB_ITEM *wineItem;
377 INT32 iItem;
379 iItem=(INT32) wParam;
380 tabItem=(LPTCITEM32A) lParam;
381 TRACE (tab,"\n");
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);
401 return TRUE;
404 static LRESULT
405 TAB_DeleteItem (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
407 /* TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr); */
409 FIXME (tab,"stub \n");
410 return TRUE;
412 static LRESULT
413 TAB_DeleteAllItems (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
415 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
417 COMCTL32_Free (infoPtr->items);
418 infoPtr->uNumItem=0;
420 return TRUE;
424 static LRESULT
425 TAB_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
427 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
429 TRACE (tab,"\n");
430 return (LRESULT)infoPtr->hFont;
433 static LRESULT
434 TAB_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
437 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
438 TEXTMETRIC32A tm;
439 HFONT32 hFont, hOldFont;
440 HDC32 hdc;
442 TRACE (tab,"%x %lx\n",wParam, lParam);
444 infoPtr->hFont = (HFONT32)wParam;
446 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
448 hdc = GetDC32 (0);
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);
457 return 0;
461 static LRESULT
462 TAB_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
464 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
466 TRACE (tab,"\n");
467 return (LRESULT)infoPtr->himl;
470 static LRESULT
471 TAB_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
473 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
474 HIMAGELIST himlPrev;
476 TRACE (tab,"\n");
477 himlPrev = infoPtr->himl;
478 infoPtr->himl= (HIMAGELIST)lParam;
479 return (LRESULT)himlPrev;
482 static LRESULT
483 TAB_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
485 TAB_INFO *infoPtr;
487 infoPtr = (TAB_INFO *)COMCTL32_Alloc (sizeof(TAB_INFO));
488 wndPtr->wExtra[0] = (DWORD)infoPtr;
490 infoPtr->uNumItem = 0;
491 infoPtr->hFont = 0;
492 infoPtr->items = 0;
493 infoPtr->hcurArrow = LoadCursor32A (0, IDC_ARROW32A);
494 infoPtr->iSelected = -1;
496 TRACE(tab, "Created tab control, hwnd [%04x]\n", wndPtr->hwndSelf);
497 return 0;
500 static LRESULT
501 TAB_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
503 TAB_INFO *infoPtr = TAB_GetInfoPtr(wndPtr);
504 INT32 iItem;
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);
516 return 0;
519 LRESULT WINAPI
520 TAB_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
522 WND *wndPtr = WIN_FindWndPtr(hwnd);
524 switch (uMsg)
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);
536 case TCM_GETITEM32A:
537 return TAB_GetItem32A (wndPtr, wParam, lParam);
539 case TCM_GETITEM32W:
540 FIXME (tab, "Unimplemented msg TCM_GETITEM32W\n");
541 return 0;
543 case TCM_SETITEM32A:
544 return TAB_SetItem32A (wndPtr, wParam, lParam);
546 case TCM_SETITEM32W:
547 FIXME (tab, "Unimplemented msg TCM_GETITEM32W\n");
548 return 0;
550 case TCM_DELETEITEM:
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");
558 return 0;
560 case TCM_GETCURSEL:
561 return TAB_GetCurSel (wndPtr);
563 case TCM_SETCURSEL:
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");
571 return 0;
573 case TCM_SETITEMEXTRA:
574 FIXME (tab, "Unimplemented msg TCM_SETITEMEXTRA\n");
575 return 0;
577 case TCM_ADJUSTRECT:
578 return TAB_AdjustRect (wndPtr, wParam, lParam);
580 case TCM_SETITEMSIZE:
581 FIXME (tab, "Unimplemented msg TCM_SETITEMSIZE\n");
582 return 0;
584 case TCM_REMOVEIMAGE:
585 FIXME (tab, "Unimplemented msg TCM_REMOVEIMAGE\n");
586 return 0;
588 case TCM_SETPADDING:
589 FIXME (tab, "Unimplemented msg TCM_SETPADDING\n");
590 return 0;
592 case TCM_GETROWCOUNT:
593 FIXME (tab, "Unimplemented msg TCM_GETROWCOUNT\n");
594 return 0;
596 case TCM_GETTOOLTIPS:
597 FIXME (tab, "Unimplemented msg TCM_GETTOOLTIPS\n");
598 return 0;
600 case TCM_SETTOOLTIPS:
601 FIXME (tab, "Unimplemented msg TCM_SETTOOLTIPS\n");
602 return 0;
604 case TCM_GETCURFOCUS:
605 FIXME (tab, "Unimplemented msg TCM_GETCURFOCUS\n");
606 return 0;
608 case TCM_SETCURFOCUS:
609 FIXME (tab, "Unimplemented msg TCM_SETCURFOCUS\n");
610 return 0;
612 case TCM_SETMINTTABWIDTH:
613 FIXME (tab, "Unimplemented msg TCM_SETMINTTABWIDTH\n");
614 return 0;
616 case TCM_DESELECTALL:
617 FIXME (tab, "Unimplemented msg TCM_DESELECTALL\n");
618 return 0;
620 case WM_GETFONT:
621 return TAB_GetFont (wndPtr, wParam, lParam);
623 case WM_SETFONT:
624 return TAB_SetFont (wndPtr, wParam, lParam);
626 case WM_CREATE:
627 return TAB_Create (wndPtr, wParam, lParam);
629 case WM_DESTROY:
630 return TAB_Destroy (wndPtr, wParam, lParam);
632 case WM_GETDLGCODE:
633 return DLGC_WANTARROWS | DLGC_WANTCHARS;
635 case WM_LBUTTONUP:
636 return TAB_LButtonUp (wndPtr, wParam, lParam);
638 case WM_PAINT:
639 return TAB_Paint (wndPtr, wParam);
642 default:
643 if (uMsg >= WM_USER)
644 ERR (tab, "unknown msg %04x wp=%08x lp=%08lx\n",
645 uMsg, wParam, lParam);
646 return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
648 return 0;
652 VOID
653 TAB_Register (VOID)
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);
672 VOID
673 TAB_Unregister (VOID)
675 if (GlobalFindAtom32A (WC_TABCONTROL32A))
676 UnregisterClass32A (WC_TABCONTROL32A, (HINSTANCE32)NULL);