Changeset 6709 for trunk/src/comctl32/tab.c
- Timestamp:
- Sep 15, 2001, 11:26:26 AM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/comctl32/tab.c
r6705 r6709 36 36 LPARAM lParam; 37 37 RECT rect; /* bounding rectangle of the item relative to the 38 * leftmost item (the leftmost item, 0, would have a 39 * "left" member of 0 in this rectangle) 40 * 38 * leftmost item (the leftmost item, 0, would have a 39 * "left" member of 0 in this rectangle) 40 * 41 41 * additionally the top member hold the row number 42 42 * and bottom is unused and should be 0 */ … … 49 49 #endif 50 50 UINT uNumItem; /* number of tab items */ 51 UINT uNumRows; 51 UINT uNumRows; /* number of tab rows */ 52 52 INT tabHeight; /* height of the tab row */ 53 53 INT tabWidth; /* width of tabs */ … … 57 57 HWND hwndToolTip; /* handle to tab's tooltip */ 58 58 INT leftmostVisible; /* Used for scrolling, this member contains 59 59 * the index of the first visible item */ 60 60 INT iSelected; /* the currently selected item */ 61 61 INT iHotTracked; /* the highlighted item under the mouse */ … … 63 63 TAB_ITEM* items; /* pointer to an array of TAB_ITEM's */ 64 64 BOOL DoRedraw; /* flag for redrawing when tab contents is changed*/ 65 BOOL needsScrolling; /* TRUE if the size of the tabs is greater than 66 67 BOOL fSizeSet;/* was the size of the tabs explicitly set? */65 BOOL needsScrolling; /* TRUE if the size of the tabs is greater than 66 * the size of the control */ 67 BOOL fSizeSet; /* was the size of the tabs explicitly set? */ 68 68 BOOL bUnicode; /* Unicode control? */ 69 69 HWND hwndUpDown; /* Updown control used for scrolling */ … … 81 81 #define CONTROL_BORDER_SIZEX 2 82 82 #define CONTROL_BORDER_SIZEY 2 83 #define BUTTON_SPACINGX 4 83 #define BUTTON_SPACINGX 4 84 84 #define BUTTON_SPACINGY 4 85 85 #define FLAT_BTN_SPACINGX 8 … … 137 137 { 138 138 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 139 139 140 140 return infoPtr->iSelected; 141 141 } … … 145 145 { 146 146 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 147 147 148 148 return infoPtr->uFocus; 149 149 } … … 164 164 INT iItem = (INT)wParam; 165 165 INT prevItem; 166 166 167 167 prevItem = -1; 168 168 if ((iItem >= 0) && (iItem < infoPtr->uNumItem)) { … … 180 180 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 181 181 INT iItem=(INT) wParam; 182 182 183 183 if ((iItem < 0) || (iItem >= infoPtr->uNumItem)) return 0; 184 184 185 185 if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BUTTONS) { 186 186 FIXME("Should set input focus\n"); 187 } else { 187 } else { 188 188 int oldFocus = infoPtr->uFocus; 189 189 if (infoPtr->iSelected != iItem || infoPtr->uFocus == -1 ) { … … 232 232 RECT tmpItemRect,clientRect; 233 233 LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE); 234 234 235 235 /* Perform a sanity check and a trivial visibility check. */ 236 236 if ( (infoPtr->uNumItem <= 0) || … … 245 245 if (itemRect == NULL) 246 246 itemRect = &tmpItemRect; 247 247 248 248 /* Retrieve the unmodified item rect. */ 249 249 *itemRect = infoPtr->items[itemIndex].rect; … … 280 280 else if(!(lStyle & TCS_VERTICAL) && !(lStyle & TCS_BOTTOM)) /* not TCS_BOTTOM and not TCS_VERTICAL */ 281 281 { 282 itemRect->bottom = clientRect.top + 282 itemRect->bottom = clientRect.top + 283 283 infoPtr->tabHeight + 284 284 itemRect->top * (infoPtr->tabHeight - 2) + 285 285 ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : 0); 286 itemRect->top = clientRect.top + 286 itemRect->top = clientRect.top + 287 287 SELECTED_TAB_OFFSET + 288 288 itemRect->top * (infoPtr->tabHeight - 2) + … … 291 291 292 292 /* 293 * "scroll" it to make sure the item at the very left of the 293 * "scroll" it to make sure the item at the very left of the 294 294 * tab control is the leftmost visible tab. 295 295 */ … … 297 297 { 298 298 OffsetRect(itemRect, 299 300 299 0, 300 -(clientRect.bottom - infoPtr->items[infoPtr->leftmostVisible].rect.bottom)); 301 301 302 302 /* … … 305 305 */ 306 306 OffsetRect(itemRect, 307 308 307 0, 308 -SELECTED_TAB_OFFSET); 309 309 310 310 } else 311 311 { 312 312 OffsetRect(itemRect, 313 -infoPtr->items[infoPtr->leftmostVisible].rect.left, 314 313 -infoPtr->items[infoPtr->leftmostVisible].rect.left, 314 0); 315 315 316 316 /* … … 319 319 */ 320 320 OffsetRect(itemRect, 321 322 321 SELECTED_TAB_OFFSET, 322 0); 323 323 } 324 324 … … 336 336 /* If it also a bit higher. */ 337 337 if ((lStyle & TCS_BOTTOM) && !(lStyle & TCS_VERTICAL)) 338 { 338 { 339 339 selectedRect->top -= 2; /* the border is thicker on the bottom */ 340 340 selectedRect->bottom += SELECTED_TAB_OFFSET; … … 362 362 static BOOL TAB_GetItemRect(HWND hwnd, WPARAM wParam, LPARAM lParam) 363 363 { 364 return TAB_InternalGetItemRect(hwnd, TAB_GetInfoPtr(hwnd), (INT)wParam, 364 return TAB_InternalGetItemRect(hwnd, TAB_GetInfoPtr(hwnd), (INT)wParam, 365 365 (LPRECT)lParam, (LPRECT)NULL); 366 366 } … … 372 372 */ 373 373 static LRESULT TAB_KeyUp( 374 HWND hwnd, 374 HWND hwnd, 375 375 WPARAM keyCode) 376 376 { … … 387 387 break; 388 388 } 389 389 390 390 /* 391 391 * If we changed to a valid item, change the selection … … 416 416 */ 417 417 static LRESULT TAB_FocusChanging( 418 HWND hwnd, 419 UINT uMsg, 420 WPARAM wParam, 418 HWND hwnd, 419 UINT uMsg, 420 WPARAM wParam, 421 421 LPARAM lParam) 422 422 { … … 429 429 */ 430 430 isVisible = TAB_InternalGetItemRect(hwnd, 431 432 433 434 435 431 infoPtr, 432 infoPtr->uFocus, 433 NULL, 434 &selectedRect); 435 436 436 /* 437 437 * If the rectangle is not completely invisible, invalidate that … … 451 451 static HWND TAB_InternalHitTest ( 452 452 HWND hwnd, 453 TAB_INFO* infoPtr, 454 POINT pt, 453 TAB_INFO* infoPtr, 454 POINT pt, 455 455 UINT* flags) 456 456 457 457 { 458 458 RECT rect; 459 int iCount; 460 459 int iCount; 460 461 461 for (iCount = 0; iCount < infoPtr->uNumItem; iCount++) 462 462 { … … 479 479 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 480 480 LPTCHITTESTINFO lptest = (LPTCHITTESTINFO) lParam; 481 481 482 482 return TAB_InternalHitTest (hwnd, infoPtr, lptest->pt, &lptest->flags); 483 483 } … … 521 521 if (infoPtr->hwndToolTip) 522 522 TAB_RelayEvent (infoPtr->hwndToolTip, hwnd, 523 523 WM_LBUTTONDOWN, wParam, lParam); 524 524 525 525 if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_FOCUSONBUTTONDOWN ) { … … 529 529 if (infoPtr->hwndToolTip) 530 530 TAB_RelayEvent (infoPtr->hwndToolTip, hwnd, 531 532 531 WM_LBUTTONDOWN, wParam, lParam); 532 533 533 pt.x = (INT)LOWORD(lParam); 534 534 pt.y = (INT)HIWORD(lParam); 535 535 536 536 newItem = TAB_InternalHitTest (hwnd, infoPtr, pt, &dummy); 537 537 538 538 TRACE("On Tab, item %d\n", newItem); 539 539 … … 619 619 ** overlaps. Note also that the case where the cursor stayed within our 620 620 ** window but has moved off the hot-tracked tab will be handled by the 621 ** WM_MOUSEMOVE event. 621 ** WM_MOUSEMOVE event. 622 622 */ 623 623 if (!GetCursorPos(&pt) || WindowFromPoint(pt) != hwnd) … … 721 721 if (item >= 0) 722 722 { 723 723 /* Mark new hot-tracked to be redrawn to look highlighted */ 724 724 if (out_redrawEnter != NULL) 725 725 *out_redrawEnter = item; … … 743 743 if (infoPtr->hwndToolTip) 744 744 TAB_RelayEvent (infoPtr->hwndToolTip, hwnd, 745 745 WM_LBUTTONDOWN, wParam, lParam); 746 746 747 747 /* Determine which tab to highlight. Redraw tabs which change highlight … … 764 764 */ 765 765 static LRESULT TAB_AdjustRect( 766 HWND hwnd, 767 WPARAM fLarger, 766 HWND hwnd, 767 WPARAM fLarger, 768 768 LPRECT prc) 769 769 { … … 845 845 */ 846 846 static LRESULT TAB_OnHScroll( 847 HWND hwnd, 847 HWND hwnd, 848 848 int nScrollCode, 849 849 int nPos, … … 871 871 * TAB_SetupScrolling 872 872 * 873 * This method will check the current scrolling state and make sure the 873 * This method will check the current scrolling state and make sure the 874 874 * scrolling control is displayed (or not). 875 875 */ … … 930 930 { 931 931 infoPtr->hwndUpDown = CreateWindowA("msctls_updown32", 932 933 934 935 936 937 938 (HMENU)NULL, 939 (HINSTANCE)NULL, 940 NULL); 932 "", 933 WS_VISIBLE | WS_CHILD | UDS_HORZ, 934 controlPos.left, controlPos.top, 935 controlPos.right - controlPos.left, 936 controlPos.bottom - controlPos.top, 937 hwnd, 938 (HMENU)NULL, 939 (HINSTANCE)NULL, 940 NULL); 941 941 } 942 942 else 943 943 { 944 SetWindowPos(infoPtr->hwndUpDown, 945 946 947 948 949 SWP_SHOWWINDOW | SWP_NOZORDER); 944 SetWindowPos(infoPtr->hwndUpDown, 945 (HWND)NULL, 946 controlPos.left, controlPos.top, 947 controlPos.right - controlPos.left, 948 controlPos.bottom - controlPos.top, 949 SWP_SHOWWINDOW | SWP_NOZORDER); 950 950 } 951 951 … … 1010 1010 * a font. 1011 1011 */ 1012 hdc = GetDC(hwnd); 1013 1012 hdc = GetDC(hwnd); 1013 1014 1014 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT); 1015 1015 hOldFont = SelectObject (hdc, hFont); … … 1022 1022 1023 1023 /* if TCS_VERTICAL then swap the height and width so this code places the 1024 tabs along the top of the rectangle and we can just rotate them after 1024 tabs along the top of the rectangle and we can just rotate them after 1025 1025 rather than duplicate all of the below code */ 1026 1026 if(lStyle & TCS_VERTICAL) … … 1054 1054 1055 1055 /* 1056 * Make sure there is enough space for the letters + icon + growing the 1057 * selected item + extra space for the selected item. 1056 * Make sure there is enough space for the letters + icon + growing the 1057 * selected item + extra space for the selected item. 1058 1058 */ 1059 1059 infoPtr->tabHeight = item_height + 2 * VERTICAL_ITEM_PADDING + … … 1085 1085 * for button style tabs */ 1086 1086 if (lStyle & TCS_BUTTONS) 1087 1087 size.cx = max(size.cx, 2 * (infoPtr->tabHeight - 2)); 1088 1088 1089 1089 /* Add the icon width */ … … 1095 1095 1096 1096 infoPtr->items[curItem].rect.right = infoPtr->items[curItem].rect.left + 1097 size.cx + icon_width + 1097 size.cx + icon_width + 1098 1098 num * HORIZONTAL_ITEM_PADDING; 1099 1099 } … … 1114 1114 infoPtr->items[curItem].rect.left; 1115 1115 1116 1116 infoPtr->items[curItem].rect.left = 0; 1117 1117 curItemRowCount++; 1118 1118 } … … 1122 1122 1123 1123 TRACE("TextSize: %li\n", size.cx); 1124 TRACE("Rect: T %i, L %i, B %i, R %i\n", 1125 1126 1127 1128 infoPtr->items[curItem].rect.right); 1124 TRACE("Rect: T %i, L %i, B %i, R %i\n", 1125 infoPtr->items[curItem].rect.top, 1126 infoPtr->items[curItem].rect.left, 1127 infoPtr->items[curItem].rect.bottom, 1128 infoPtr->items[curItem].rect.right); 1129 1129 1130 1130 /* … … 1152 1152 /* Don't need scrolling, then update infoPtr->leftmostVisible */ 1153 1153 if(!infoPtr->needsScrolling) 1154 infoPtr->leftmostVisible = 0; 1154 infoPtr->leftmostVisible = 0; 1155 1155 1156 1156 TAB_SetupScrolling(hwnd, infoPtr, &clientRect); … … 1193 1193 1194 1194 /* shift the item to the left side of the clientRect */ 1195 infoPtr->items[iItm].rect.right -= 1195 infoPtr->items[iItm].rect.right -= 1196 1196 infoPtr->items[iItm].rect.left; 1197 1197 infoPtr->items[iItm].rect.left = 0; … … 1202 1202 infoPtr->items[iItm].rect.top = iRow; 1203 1203 if (lStyle & TCS_BUTTONS) 1204 1204 { 1205 1205 curItemLeftPos = infoPtr->items[iItm].rect.right + 1; 1206 1206 if (lStyle & TCS_FLATBUTTONS) 1207 1208 1207 curItemLeftPos += FLAT_BTN_SPACINGX; 1208 } 1209 1209 else 1210 1210 curItemLeftPos = infoPtr->items[iItm].rect.right; 1211 1211 } 1212 1212 1213 1213 /* 1214 1214 * Justify the rows … … 1217 1217 while(iIndexStart < infoPtr->uNumItem) 1218 1218 { 1219 /* 1219 /* 1220 1220 * find the indexs of the row 1221 1221 */ 1222 1222 /* find the first item on the next row */ 1223 1223 for (iIndexEnd=iIndexStart; 1224 (iIndexEnd < infoPtr->uNumItem) && 1225 1224 (iIndexEnd < infoPtr->uNumItem) && 1225 (infoPtr->items[iIndexEnd].rect.top == 1226 1226 infoPtr->items[iIndexStart].rect.top) ; 1227 1227 iIndexEnd++) 1228 1228 /* intentionaly blank */; 1229 1229 1230 /* 1230 /* 1231 1231 * we need to justify these tabs so they fill the whole given 1232 1232 * client area … … 1246 1246 widthDiff = widthDiff / iCount; 1247 1247 /* add widthDiff/iCount, or extra space/items on row, to each item on this row */ 1248 for (iIndex=iIndexStart,iCount=0; iIndex < iIndexEnd; 1248 for (iIndex=iIndexStart,iCount=0; iIndex < iIndexEnd; 1249 1249 iIndex++,iCount++) 1250 1250 { … … 1297 1297 * This method is used to draw the interior (text and icon) of a single tab 1298 1298 * into the tab control. 1299 */ 1299 */ 1300 1300 static void 1301 1301 TAB_DrawItemInterior … … 1390 1390 id = GetWindowLongA( hwnd, GWL_ID ); 1391 1391 1392 /* 1392 /* 1393 1393 * put together the DRAWITEMSTRUCT 1394 1394 */ 1395 dis.CtlType = ODT_TAB; 1396 dis.CtlID = id; 1397 dis.itemID = iItem; 1398 dis.itemAction = ODA_DRAWENTIRE; 1395 dis.CtlType = ODT_TAB; 1396 dis.CtlID = id; 1397 dis.itemID = iItem; 1398 dis.itemAction = ODA_DRAWENTIRE; 1399 1399 if ( iItem == infoPtr->iSelected ) 1400 dis.itemState = ODS_SELECTED; 1401 else 1402 dis.itemState = 0; 1403 dis.hwndItem = hwnd; 1404 dis.hDC = hdc; 1405 dis.rcItem = *drawRect; 1400 dis.itemState = ODS_SELECTED; 1401 else 1402 dis.itemState = 0; 1403 dis.hwndItem = hwnd; /* */ 1404 dis.hDC = hdc; 1405 dis.rcItem = *drawRect; /* */ 1406 1406 dis.itemData = infoPtr->items[iItem].lParam; 1407 1407 … … 1538 1538 if(lStyle & TCS_VERTICAL) 1539 1539 { 1540 if (!GetObjectA((infoPtr->hFont) ? 1540 if (!GetObjectA((infoPtr->hFont) ? 1541 1541 infoPtr->hFont : GetStockObject(SYSTEM_FONT), 1542 1542 sizeof(LOGFONTA),&logfont)) … … 1545 1545 1546 1546 lstrcpyA(logfont.lfFaceName, "Arial"); 1547 logfont.lfHeight = -MulDiv(iPointSize, GetDeviceCaps(hdc, LOGPIXELSY), 1547 logfont.lfHeight = -MulDiv(iPointSize, GetDeviceCaps(hdc, LOGPIXELSY), 1548 1548 72); 1549 1549 logfont.lfWeight = FW_NORMAL; … … 1604 1604 * 1605 1605 * This method is used to draw a single tab into the tab control. 1606 */ 1606 */ 1607 1607 static void TAB_DrawItem( 1608 HWND hwnd, 1609 HDC hdc, 1608 HWND hwnd, 1609 HDC hdc, 1610 1610 INT iItem) 1611 1611 { … … 1621 1621 */ 1622 1622 isVisible = TAB_InternalGetItemRect(hwnd, 1623 1624 1625 1626 1623 infoPtr, 1624 iItem, 1625 &itemRect, 1626 &selectedRect); 1627 1627 1628 1628 if (isVisible) 1629 1629 { 1630 HBRUSH hbr = CreateSolidBrush (GetSysColor(COLOR_BTNFACE)); 1630 HBRUSH hbr = CreateSolidBrush (GetSysColor(COLOR_BTNFACE)); 1631 1631 HPEN hwPen = GetSysColorPen (COLOR_3DHILIGHT); 1632 1632 HPEN hbPen = GetSysColorPen (COLOR_3DDKSHADOW); … … 1645 1645 /* Separators between flat buttons */ 1646 1646 /* FIXME: test and correct this if necessary for TCS_FLATBUTTONS style */ 1647 if (lStyle & TCS_FLATBUTTONS) 1647 if (lStyle & TCS_FLATBUTTONS) 1648 1648 { 1649 1649 int x = r.right + FLAT_BTN_SPACINGX - 2; … … 1669 1669 /* Background color */ 1670 1670 if (!((lStyle & TCS_OWNERDRAWFIXED) && infoPtr->fSizeSet)) 1671 1671 { 1672 1672 COLORREF bk = GetSysColor(COLOR_3DHILIGHT); 1673 1673 DeleteObject(hbr); … … 1685 1685 1686 1686 deleteBrush = FALSE; 1687 1687 } 1688 1688 1689 1689 /* Erase the background */ … … 1704 1704 LineTo (hdc, r.right, r.bottom); 1705 1705 LineTo (hdc, r.right, r.top + 1); 1706 1706 1707 1707 /* shadow */ 1708 1708 SelectObject(hdc, hbPen); … … 1721 1721 FillRect(hdc, &r, hbr); 1722 1722 1723 1724 1723 if (!(lStyle & TCS_FLATBUTTONS)) 1724 { 1725 1725 /* highlight */ 1726 1726 MoveToEx (hdc, r.left, r.bottom, NULL); 1727 1727 LineTo (hdc, r.left, r.top); 1728 1728 LineTo (hdc, r.right, r.top); 1729 1729 1730 1730 /* shadow */ 1731 1731 SelectObject(hdc, hbPen); … … 1738 1738 LineTo (hdc, r.right - 1, r.bottom - 1); 1739 1739 LineTo (hdc, r.left + 1, r.bottom - 1); 1740 1740 } 1741 1741 } 1742 1742 } … … 1745 1745 /* Background color */ 1746 1746 DeleteObject(hbr); 1747 hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); 1747 hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); 1748 1748 1749 1749 /* We draw a rectangle of different sizes depending on the selection … … 1756 1756 /* 1757 1757 * Erase the background. 1758 * This is necessary when drawing the selected item since it is larger 1759 * than the others, it might overlap with stuff already drawn by the 1758 * This is necessary when drawing the selected item since it is larger 1759 * than the others, it might overlap with stuff already drawn by the 1760 1760 * other tabs 1761 */ 1761 */ 1762 1762 FillRect(hdc, &r, hbr); 1763 1763 … … 1770 1770 r.right--; 1771 1771 r.bottom--; 1772 1772 1773 1773 holdPen = SelectObject (hdc, hwPen); 1774 1774 if(lStyle & TCS_VERTICAL) … … 1859 1859 } 1860 1860 } 1861 1861 1862 1862 /* This modifies r to be the text rectangle. */ 1863 1863 { … … 1868 1868 /* Draw the focus rectangle */ 1869 1869 if (((lStyle & TCS_FOCUSNEVER) == 0) && 1870 1871 1870 (GetFocus() == hwnd) && 1871 (iItem == infoPtr->uFocus) ) 1872 1872 { 1873 1873 r = itemRect; … … 1888 1888 * This method is used to draw the raised border around the tab control 1889 1889 * "content" area. 1890 */ 1890 */ 1891 1891 static void TAB_DrawBorder (HWND hwnd, HDC hdc) 1892 1892 { … … 1957 1957 * 1958 1958 * This method repaints the tab control.. 1959 */ 1959 */ 1960 1960 static void TAB_Refresh (HWND hwnd, HDC hdc) 1961 1961 { … … 1971 1971 if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BUTTONS) 1972 1972 { 1973 for (i = 0; i < infoPtr->uNumItem; i++) 1973 for (i = 0; i < infoPtr->uNumItem; i++) 1974 1974 TAB_DrawItem (hwnd, hdc, i); 1975 1975 } … … 1977 1977 { 1978 1978 /* Draw all the non selected item first */ 1979 for (i = 0; i < infoPtr->uNumItem; i++) 1979 for (i = 0; i < infoPtr->uNumItem; i++) 1980 1980 { 1981 1981 if (i != infoPtr->iSelected) 1982 1982 TAB_DrawItem (hwnd, hdc, i); 1983 1983 } 1984 1984 … … 2011 2011 { 2012 2012 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 2013 2013 2014 2014 infoPtr->DoRedraw=(BOOL) wParam; 2015 2015 return 0; … … 2017 2017 2018 2018 static LRESULT TAB_EraseBackground( 2019 HWND hwnd, 2019 HWND hwnd, 2020 2020 HDC givenDC) 2021 2021 { … … 2207 2207 HDC hdc; 2208 2208 PAINTSTRUCT ps; 2209 2209 2210 2210 hdc = wParam== 0 ? BeginPaint (hwnd, &ps) : (HDC)wParam; 2211 2211 TAB_Refresh (hwnd, hdc); 2212 2212 2213 2213 if(!wParam) 2214 2214 EndPaint (hwnd, &ps); … … 2219 2219 static LRESULT 2220 2220 TAB_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) 2221 { 2221 { 2222 2222 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 2223 2223 TCITEMA *pti; 2224 2224 INT iItem; 2225 2225 RECT rect; 2226 2226 2227 2227 GetClientRect (hwnd, &rect); 2228 2228 TRACE("Rect: %x T %i, L %i, B %i, R %i\n", hwnd, 2229 rect.top, rect.left, rect.bottom, rect.right); 2230 2229 rect.top, rect.left, rect.bottom, rect.right); 2230 2231 2231 pti = (TCITEMA *)lParam; 2232 2232 iItem = (INT)wParam; 2233 2233 2234 2234 if (iItem < 0) return -1; 2235 2235 if (iItem > infoPtr->uNumItem) 2236 2236 iItem = infoPtr->uNumItem; 2237 2237 2238 2238 if (infoPtr->uNumItem == 0) { 2239 2239 infoPtr->items = COMCTL32_Alloc (sizeof (TAB_ITEM)); … … 2243 2243 else { 2244 2244 TAB_ITEM *oldItems = infoPtr->items; 2245 2245 2246 2246 infoPtr->uNumItem++; 2247 2247 infoPtr->items = COMCTL32_Alloc (sizeof (TAB_ITEM) * infoPtr->uNumItem); 2248 2248 2249 2249 /* pre insert copy */ 2250 2250 if (iItem > 0) { 2251 2251 memcpy (&infoPtr->items[0], &oldItems[0], 2252 2253 } 2254 2252 iItem * sizeof(TAB_ITEM)); 2253 } 2254 2255 2255 /* post insert copy */ 2256 2256 if (iItem < infoPtr->uNumItem - 1) { 2257 2257 memcpy (&infoPtr->items[iItem+1], &oldItems[iItem], 2258 2259 2258 (infoPtr->uNumItem - iItem - 1) * sizeof(TAB_ITEM)); 2259 2260 2260 } 2261 2261 … … 2265 2265 COMCTL32_Free (oldItems); 2266 2266 } 2267 2267 2268 2268 infoPtr->items[iItem].mask = pti->mask; 2269 2269 if (pti->mask & TCIF_TEXT) … … 2272 2272 if (pti->mask & TCIF_IMAGE) 2273 2273 infoPtr->items[iItem].iImage = pti->iImage; 2274 2274 2275 2275 if (pti->mask & TCIF_PARAM) 2276 2276 infoPtr->items[iItem].lParam = pti->lParam; 2277 2277 2278 2278 TAB_SetItemBounds(hwnd); 2279 2279 TAB_InvalidateTabArea(hwnd, infoPtr); 2280 2280 2281 2281 TRACE("[%04x]: added item %d '%s'\n", 2282 2282 hwnd, iItem, debugstr_w(infoPtr->items[iItem].pszText)); 2283 2283 2284 2284 return iItem; … … 2319 2319 if (iItem > 0) { 2320 2320 memcpy (&infoPtr->items[0], &oldItems[0], 2321 2321 iItem * sizeof(TAB_ITEM)); 2322 2322 } 2323 2323 … … 2325 2325 if (iItem < infoPtr->uNumItem - 1) { 2326 2326 memcpy (&infoPtr->items[iItem+1], &oldItems[iItem], 2327 2328 2329 } 2330 2327 (infoPtr->uNumItem - iItem - 1) * sizeof(TAB_ITEM)); 2328 2329 } 2330 2331 2331 if (iItem <= infoPtr->iSelected) 2332 2332 infoPtr->iSelected++; … … 2341 2341 if (pti->mask & TCIF_IMAGE) 2342 2342 infoPtr->items[iItem].iImage = pti->iImage; 2343 2343 2344 2344 if (pti->mask & TCIF_PARAM) 2345 2345 infoPtr->items[iItem].lParam = pti->lParam; 2346 2346 2347 2347 TAB_SetItemBounds(hwnd); 2348 2348 TAB_InvalidateTabArea(hwnd, infoPtr); 2349 2349 2350 2350 TRACE("[%04x]: added item %d '%s'\n", 2351 2351 hwnd, iItem, debugstr_w(infoPtr->items[iItem].pszText)); 2352 2352 2353 2353 return iItem; … … 2355 2355 2356 2356 2357 static LRESULT 2357 static LRESULT 2358 2358 TAB_SetItemSize (HWND hwnd, WPARAM wParam, LPARAM lParam) 2359 2359 { … … 2373 2373 } 2374 2374 2375 static LRESULT 2375 static LRESULT 2376 2376 TAB_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) 2377 2377 { 2378 2378 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 2379 TCITEMA *tabItem; 2379 TCITEMA *tabItem; 2380 2380 TAB_ITEM *wineItem; 2381 2381 INT iItem; … … 2395 2395 wineItem->lParam = tabItem->lParam; 2396 2396 2397 if (tabItem->mask & TCIF_RTLREADING) 2397 if (tabItem->mask & TCIF_RTLREADING) 2398 2398 FIXME("TCIF_RTLREADING\n"); 2399 2399 2400 if (tabItem->mask & TCIF_STATE) 2400 if (tabItem->mask & TCIF_STATE) 2401 2401 wineItem->dwState = tabItem->dwState; 2402 2402 … … 2451 2451 2452 2452 2453 static LRESULT 2453 static LRESULT 2454 2454 TAB_GetItemCount (HWND hwnd, WPARAM wParam, LPARAM lParam) 2455 2455 { … … 2460 2460 2461 2461 2462 static LRESULT 2462 static LRESULT 2463 2463 TAB_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) 2464 2464 { … … 2476 2476 wineItem = &infoPtr->items[iItem]; 2477 2477 2478 if (tabItem->mask & TCIF_IMAGE) 2478 if (tabItem->mask & TCIF_IMAGE) 2479 2479 tabItem->iImage = wineItem->iImage; 2480 2480 2481 if (tabItem->mask & TCIF_PARAM) 2481 if (tabItem->mask & TCIF_PARAM) 2482 2482 tabItem->lParam = wineItem->lParam; 2483 2483 2484 if (tabItem->mask & TCIF_RTLREADING) 2484 if (tabItem->mask & TCIF_RTLREADING) 2485 2485 FIXME("TCIF_RTLREADING\n"); 2486 2486 2487 if (tabItem->mask & TCIF_STATE) 2487 if (tabItem->mask & TCIF_STATE) 2488 2488 tabItem->dwState = wineItem->dwState; 2489 2489 2490 if (tabItem->mask & TCIF_TEXT) 2490 if (tabItem->mask & TCIF_TEXT) 2491 2491 Str_GetPtrWtoA (wineItem->pszText, tabItem->pszText, tabItem->cchTextMax); 2492 2492 … … 2495 2495 2496 2496 2497 static LRESULT 2497 static LRESULT 2498 2498 TAB_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam) 2499 2499 { … … 2530 2530 2531 2531 2532 static LRESULT 2532 static LRESULT 2533 2533 TAB_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam) 2534 2534 { … … 2540 2540 { 2541 2541 TAB_ITEM *oldItems = infoPtr->items; 2542 2542 2543 2543 infoPtr->uNumItem--; 2544 2544 infoPtr->items = COMCTL32_Alloc(sizeof (TAB_ITEM) * infoPtr->uNumItem); 2545 2546 if (iItem > 0) 2545 2546 if (iItem > 0) 2547 2547 memcpy(&infoPtr->items[0], &oldItems[0], iItem * sizeof(TAB_ITEM)); 2548 2549 if (iItem < infoPtr->uNumItem) 2548 2549 if (iItem < infoPtr->uNumItem) 2550 2550 memcpy(&infoPtr->items[iItem], &oldItems[iItem + 1], 2551 2551 (infoPtr->uNumItem - iItem) * sizeof(TAB_ITEM)); 2552 2552 2553 2553 COMCTL32_Free(oldItems); 2554 2554 … … 2556 2556 if ((iItem == infoPtr->iSelected) && (iItem > 0)) 2557 2557 infoPtr->iSelected--; 2558 2558 2559 2559 if (iItem < infoPtr->iSelected) 2560 2560 infoPtr->iSelected--; … … 2573 2573 } 2574 2574 2575 static LRESULT 2575 static LRESULT 2576 2576 TAB_DeleteAllItems (HWND hwnd, WPARAM wParam, LPARAM lParam) 2577 2577 { … … 2584 2584 KillTimer(hwnd, TAB_HOTTRACK_TIMER); 2585 2585 infoPtr->iHotTracked = -1; 2586 2586 2587 2587 TAB_SetItemBounds(hwnd); 2588 2588 TAB_InvalidateTabArea(hwnd,infoPtr); … … 2605 2605 { 2606 2606 TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd); 2607 2607 2608 2608 TRACE("%x %lx\n",wParam, lParam); 2609 2609 2610 2610 infoPtr->hFont = (HFONT)wParam; 2611 2611 2612 2612 TAB_SetItemBounds(hwnd); 2613 2613 … … 2676 2676 cx=LOWORD (lParam); 2677 2677 cy=HIWORD (lParam); 2678 if (GetWindowLongA(hwnd, GWL_STYLE) & CCS_NORESIZE) 2678 if (GetWindowLongA(hwnd, GWL_STYLE) & CCS_NORESIZE) 2679 2679 uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE); 2680 2680 … … 2695 2695 2696 2696 2697 static LRESULT 2697 static LRESULT 2698 2698 TAB_Create (HWND hwnd, WPARAM wParam, LPARAM lParam) 2699 2699 { … … 2711 2711 2712 2712 SetWindowLongA(hwnd, 0, (DWORD)infoPtr); 2713 2713 2714 2714 infoPtr->uNumItem = 0; 2715 2715 infoPtr->uNumRows = 0; … … 2719 2719 infoPtr->iSelected = -1; 2720 2720 infoPtr->iHotTracked = -1; 2721 infoPtr->uFocus = -1; 2721 infoPtr->uFocus = -1; 2722 2722 infoPtr->hwndToolTip = 0; 2723 2723 infoPtr->DoRedraw = TRUE; … … 2725 2725 infoPtr->hwndUpDown = 0; 2726 2726 infoPtr->leftmostVisible = 0; 2727 infoPtr->fSizeSet 2728 infoPtr->bUnicode 2729 2730 TRACE("Created tab control, hwnd [%04x]\n", hwnd); 2731 2732 /* The tab control always has the WS_CLIPSIBLINGS style. Even 2733 if you don't specify it in CreateWindow. This is necessary in 2727 infoPtr->fSizeSet = FALSE; 2728 infoPtr->bUnicode = IsWindowUnicode (hwnd); 2729 2730 TRACE("Created tab control, hwnd [%04x]\n", hwnd); 2731 2732 /* The tab control always has the WS_CLIPSIBLINGS style. Even 2733 if you don't specify it in CreateWindow. This is necessary in 2734 2734 order for paint to work correctly. This follows windows behaviour. */ 2735 2735 dwStyle = GetWindowLongA(hwnd, GWL_STYLE); … … 2740 2740 infoPtr->hwndToolTip = 2741 2741 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0, 2742 2743 2744 2745 2742 CW_USEDEFAULT, CW_USEDEFAULT, 2743 CW_USEDEFAULT, CW_USEDEFAULT, 2744 hwnd, 0, 0, 0); 2745 2746 2746 /* Send NM_TOOLTIPSCREATED notification */ 2747 2747 if (infoPtr->hwndToolTip) { 2748 2748 NMTOOLTIPSCREATED nmttc; 2749 2749 2750 2750 nmttc.hdr.hwndFrom = hwnd; 2751 2751 nmttc.hdr.idFrom = GetWindowLongA(hwnd, GWL_ID); 2752 2752 nmttc.hdr.code = NM_TOOLTIPSCREATED; 2753 2753 nmttc.hwndToolTips = infoPtr->hwndToolTip; 2754 2754 2755 2755 SendMessageA (GetParent (hwnd), WM_NOTIFY, 2756 2757 } 2758 } 2759 2756 (WPARAM)GetWindowLongA(hwnd, GWL_ID), (LPARAM)&nmttc); 2757 } 2758 } 2759 2760 2760 /* 2761 2761 * We need to get text information so we need a DC and we need to select 2762 2762 * a font. 2763 2763 */ 2764 hdc = GetDC(hwnd); 2764 hdc = GetDC(hwnd); 2765 2765 hOldFont = SelectObject (hdc, GetStockObject (SYSTEM_FONT)); 2766 2766 … … 2769 2769 2770 2770 /* 2771 * Make sure there is enough space for the letters + growing the 2772 * selected item + extra space for the selected item. 2771 * Make sure there is enough space for the letters + growing the 2772 * selected item + extra space for the selected item. 2773 2773 */ 2774 2774 infoPtr->tabHeight = fontMetrics.tmHeight + 2 * VERTICAL_ITEM_PADDING + … … 2796 2796 for (iItem = 0; iItem < infoPtr->uNumItem; iItem++) { 2797 2797 if (infoPtr->items[iItem].pszText) 2798 2798 COMCTL32_Free (infoPtr->items[iItem].pszText); 2799 2799 } 2800 2800 COMCTL32_Free (infoPtr->items); 2801 2801 } 2802 2803 if (infoPtr->hwndToolTip) 2802 2803 if (infoPtr->hwndToolTip) 2804 2804 DestroyWindow (infoPtr->hwndToolTip); 2805 2805 2806 2806 if (infoPtr->hwndUpDown) 2807 2807 DestroyWindow(infoPtr->hwndUpDown); … … 2827 2827 case TCM_GETIMAGELIST: 2828 2828 return TAB_GetImageList (hwnd, wParam, lParam); 2829 2829 2830 2830 case TCM_SETIMAGELIST: 2831 2831 return TAB_SetImageList (hwnd, wParam, lParam); 2832 2832 2833 2833 case TCM_GETITEMCOUNT: 2834 2834 return TAB_GetItemCount (hwnd, wParam, lParam); 2835 2835 2836 2836 case TCM_GETITEMA: 2837 2837 return TAB_GetItemA (hwnd, wParam, lParam); 2838 2838 2839 2839 case TCM_GETITEMW: 2840 2840 return TAB_GetItemW (hwnd, wParam, lParam); 2841 2841 2842 2842 case TCM_SETITEMA: 2843 2843 return TAB_SetItemA (hwnd, wParam, lParam); 2844 2844 2845 2845 case TCM_SETITEMW: 2846 2846 return TAB_SetItemW (hwnd, wParam, lParam); 2847 2847 2848 2848 case TCM_DELETEITEM: 2849 2849 return TAB_DeleteItem (hwnd, wParam, lParam); 2850 2850 2851 2851 case TCM_DELETEALLITEMS: 2852 2852 return TAB_DeleteAllItems (hwnd, wParam, lParam); 2853 2853 2854 2854 case TCM_GETITEMRECT: 2855 2855 return TAB_GetItemRect (hwnd, wParam, lParam); 2856 2856 2857 2857 case TCM_GETCURSEL: 2858 2858 return TAB_GetCurSel (hwnd); 2859 2859 2860 2860 case TCM_HITTEST: 2861 2861 return TAB_HitTest (hwnd, wParam, lParam); 2862 2862 2863 2863 case TCM_SETCURSEL: 2864 2864 return TAB_SetCurSel (hwnd, wParam); 2865 2865 2866 2866 case TCM_INSERTITEMA: 2867 2867 return TAB_InsertItemA (hwnd, wParam, lParam); 2868 2868 2869 2869 case TCM_INSERTITEMW: 2870 2870 return TAB_InsertItemW (hwnd, wParam, lParam); 2871 2871 2872 2872 case TCM_SETITEMEXTRA: 2873 2873 FIXME("Unimplemented msg TCM_SETITEMEXTRA\n"); 2874 2874 return 0; 2875 2875 2876 2876 case TCM_ADJUSTRECT: 2877 2877 return TAB_AdjustRect (hwnd, (BOOL)wParam, (LPRECT)lParam); 2878 2878 2879 2879 case TCM_SETITEMSIZE: 2880 2880 return TAB_SetItemSize (hwnd, wParam, lParam); 2881 2881 2882 2882 case TCM_REMOVEIMAGE: 2883 2883 FIXME("Unimplemented msg TCM_REMOVEIMAGE\n"); 2884 2884 return 0; 2885 2885 2886 2886 case TCM_SETPADDING: 2887 2887 FIXME("Unimplemented msg TCM_SETPADDING\n"); 2888 2888 return 0; 2889 2889 2890 2890 case TCM_GETROWCOUNT: 2891 2891 return TAB_GetRowCount(hwnd); … … 2900 2900 FIXME("Unimplemented msg TCM_HIGHLIGHTITEM\n"); 2901 2901 return 0; 2902 2902 2903 2903 case TCM_GETTOOLTIPS: 2904 2904 return TAB_GetToolTips (hwnd, wParam, lParam); 2905 2905 2906 2906 case TCM_SETTOOLTIPS: 2907 2907 return TAB_SetToolTips (hwnd, wParam, lParam); 2908 2908 2909 2909 case TCM_GETCURFOCUS: 2910 2910 return TAB_GetCurFocus (hwnd); 2911 2911 2912 2912 case TCM_SETCURFOCUS: 2913 2913 return TAB_SetCurFocus (hwnd, wParam); 2914 2914 2915 2915 case TCM_SETMINTABWIDTH: 2916 2916 FIXME("Unimplemented msg TCM_SETMINTABWIDTH\n"); 2917 2917 return 0; 2918 2918 2919 2919 case TCM_DESELECTALL: 2920 2920 FIXME("Unimplemented msg TCM_DESELECTALL\n"); 2921 2921 return 0; 2922 2922 2923 2923 case TCM_GETEXTENDEDSTYLE: 2924 2924 FIXME("Unimplemented msg TCM_GETEXTENDEDSTYLE\n"); … … 2931 2931 case WM_GETFONT: 2932 2932 return TAB_GetFont (hwnd, wParam, lParam); 2933 2933 2934 2934 case WM_SETFONT: 2935 2935 return TAB_SetFont (hwnd, wParam, lParam); 2936 2936 2937 2937 case WM_CREATE: 2938 2938 return TAB_Create (hwnd, wParam, lParam); 2939 2939 2940 2940 case WM_NCDESTROY: 2941 2941 return TAB_Destroy (hwnd, wParam, lParam); 2942 2942 2943 2943 case WM_GETDLGCODE: 2944 2944 return DLGC_WANTARROWS | DLGC_WANTCHARS; 2945 2945 2946 2946 case WM_LBUTTONDOWN: 2947 2947 return TAB_LButtonDown (hwnd, wParam, lParam); 2948 2948 2949 2949 case WM_LBUTTONUP: 2950 2950 return TAB_LButtonUp (hwnd, wParam, lParam); 2951 2951 2952 2952 case WM_RBUTTONDOWN: 2953 2953 return TAB_RButtonDown (hwnd, wParam, lParam); 2954 2954 2955 2955 case WM_MOUSEMOVE: 2956 2956 return TAB_MouseMove (hwnd, wParam, lParam); 2957 2957 2958 2958 case WM_ERASEBKGND: 2959 2959 return TAB_EraseBackground (hwnd, (HDC)wParam); … … 2964 2964 case WM_SIZE: 2965 2965 return TAB_Size (hwnd, wParam, lParam); 2966 2966 2967 2967 case WM_SETREDRAW: 2968 2968 return TAB_SetRedraw (hwnd, wParam); … … 2975 2975 InvalidateRect(hwnd, NULL, TRUE); 2976 2976 return 0; 2977 2977 2978 2978 case WM_KILLFOCUS: 2979 2979 case WM_SETFOCUS: … … 2987 2987 default: 2988 2988 if (uMsg >= WM_USER) 2989 2990 2989 WARN("unknown msg %04x wp=%08x lp=%08lx\n", 2990 uMsg, wParam, lParam); 2991 2991 #ifdef __WIN32OS2__ 2992 2992 return defComCtl32ProcA (hwnd, uMsg, wParam, lParam); … … 3013 3013 wndClass.hbrBackground = (HBRUSH)NULL; 3014 3014 wndClass.lpszClassName = WC_TABCONTROLA; 3015 3015 3016 3016 RegisterClassA (&wndClass); 3017 3017 }
Note:
See TracChangeset
for help on using the changeset viewer.