Added the ability to use multiline tab controls to wine.
This commit is contained in:
parent
b7ed6df279
commit
8ee3144a77
|
@ -174,14 +174,15 @@ static BOOL TAB_InternalGetItemRect(
|
||||||
RECT* itemRect,
|
RECT* itemRect,
|
||||||
RECT* selectedRect)
|
RECT* selectedRect)
|
||||||
{
|
{
|
||||||
RECT tmpItemRect;
|
RECT tmpItemRect,clientRect;
|
||||||
|
LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform a sanity check and a trivial visibility check.
|
* Perform a sanity check and a trivial visibility check.
|
||||||
*/
|
*/
|
||||||
if ( (infoPtr->uNumItem <=0) ||
|
if ( (infoPtr->uNumItem <=0) ||
|
||||||
(itemIndex >= infoPtr->uNumItem) ||
|
(itemIndex >= infoPtr->uNumItem) ||
|
||||||
(itemIndex < infoPtr->leftmostVisible) )
|
(!(lStyle &TCS_MULTILINE) && (itemIndex < infoPtr->leftmostVisible)) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -196,6 +197,31 @@ static BOOL TAB_InternalGetItemRect(
|
||||||
*/
|
*/
|
||||||
*itemRect = infoPtr->items[itemIndex].rect;
|
*itemRect = infoPtr->items[itemIndex].rect;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculate the times bottom and top based on the row
|
||||||
|
*/
|
||||||
|
GetClientRect(hwnd, &clientRect);
|
||||||
|
|
||||||
|
if (lStyle & TCS_BOTTOM)
|
||||||
|
{
|
||||||
|
itemRect->bottom = clientRect.bottom -
|
||||||
|
SELECTED_TAB_OFFSET -
|
||||||
|
itemRect->top * (infoPtr->tabHeight - 2);
|
||||||
|
|
||||||
|
itemRect->top = clientRect.bottom -
|
||||||
|
infoPtr->tabHeight -
|
||||||
|
itemRect->top * ( infoPtr->tabHeight - 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemRect->bottom = clientRect.top +
|
||||||
|
infoPtr->tabHeight +
|
||||||
|
itemRect->top * (infoPtr->tabHeight - 2);
|
||||||
|
itemRect->top = clientRect.top +
|
||||||
|
SELECTED_TAB_OFFSET+
|
||||||
|
itemRect->top * (infoPtr->tabHeight - 2);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "scroll" it to make sure the item at the very left of the
|
* "scroll" it to make sure the item at the very left of the
|
||||||
* tab control is the leftmost visible tab.
|
* tab control is the leftmost visible tab.
|
||||||
|
@ -463,9 +489,9 @@ static LRESULT TAB_AdjustRect(
|
||||||
* Add the height of the tabs.
|
* Add the height of the tabs.
|
||||||
*/
|
*/
|
||||||
if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BOTTOM)
|
if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BOTTOM)
|
||||||
prc->bottom += infoPtr->tabHeight;
|
prc->bottom += (infoPtr->tabHeight - 2) * (infoPtr->uNumRows + 1) + 2;
|
||||||
else
|
else
|
||||||
prc->top -= infoPtr->tabHeight;
|
prc->top -= (infoPtr->tabHeight - 2) * (infoPtr->uNumRows + 1) + 2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inflate the rectangle for the padding
|
* Inflate the rectangle for the padding
|
||||||
|
@ -497,9 +523,9 @@ static LRESULT TAB_AdjustRect(
|
||||||
* Remove the height of the tabs.
|
* Remove the height of the tabs.
|
||||||
*/
|
*/
|
||||||
if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BOTTOM)
|
if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BOTTOM)
|
||||||
prc->bottom -= infoPtr->tabHeight;
|
prc->bottom -= (infoPtr->tabHeight - 2) * (infoPtr->uNumRows + 1) + 2;
|
||||||
else
|
else
|
||||||
prc->top += infoPtr->tabHeight;
|
prc->top += (infoPtr->tabHeight - 2) * (infoPtr->uNumRows + 1) + 2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,10 +601,6 @@ static void TAB_SetupScrolling(
|
||||||
*/
|
*/
|
||||||
if (infoPtr->hwndUpDown==0)
|
if (infoPtr->hwndUpDown==0)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* I use a scrollbar since it seems to be more stable than the Updown
|
|
||||||
* control.
|
|
||||||
*/
|
|
||||||
infoPtr->hwndUpDown = CreateWindowA("msctls_updown32",
|
infoPtr->hwndUpDown = CreateWindowA("msctls_updown32",
|
||||||
"",
|
"",
|
||||||
WS_VISIBLE | WS_CHILD | UDS_HORZ,
|
WS_VISIBLE | WS_CHILD | UDS_HORZ,
|
||||||
|
@ -651,6 +673,7 @@ static void TAB_SetItemBounds (HWND hwnd)
|
||||||
TEXTMETRICA fontMetrics;
|
TEXTMETRICA fontMetrics;
|
||||||
INT curItem;
|
INT curItem;
|
||||||
INT curItemLeftPos;
|
INT curItemLeftPos;
|
||||||
|
INT curItemRowCount;
|
||||||
HFONT hFont, hOldFont;
|
HFONT hFont, hOldFont;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
RECT clientRect;
|
RECT clientRect;
|
||||||
|
@ -675,6 +698,7 @@ static void TAB_SetItemBounds (HWND hwnd)
|
||||||
* The leftmost item will be "0" aligned
|
* The leftmost item will be "0" aligned
|
||||||
*/
|
*/
|
||||||
curItemLeftPos = 0;
|
curItemLeftPos = 0;
|
||||||
|
curItemRowCount = 0;
|
||||||
|
|
||||||
if ( !(lStyle & TCS_FIXEDWIDTH) && !((lStyle & TCS_OWNERDRAWFIXED) && infoPtr->fSizeSet) )
|
if ( !(lStyle & TCS_FIXEDWIDTH) && !((lStyle & TCS_OWNERDRAWFIXED) && infoPtr->fSizeSet) )
|
||||||
{
|
{
|
||||||
|
@ -710,24 +734,6 @@ static void TAB_SetItemBounds (HWND hwnd)
|
||||||
|
|
||||||
for (curItem = 0; curItem < infoPtr->uNumItem; curItem++)
|
for (curItem = 0; curItem < infoPtr->uNumItem; curItem++)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Calculate the vertical position of the tab
|
|
||||||
*/
|
|
||||||
if (lStyle & TCS_BOTTOM)
|
|
||||||
{
|
|
||||||
infoPtr->items[curItem].rect.bottom = clientRect.bottom -
|
|
||||||
SELECTED_TAB_OFFSET;
|
|
||||||
infoPtr->items[curItem].rect.top = clientRect.bottom -
|
|
||||||
infoPtr->tabHeight;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
infoPtr->items[curItem].rect.top = clientRect.top +
|
|
||||||
SELECTED_TAB_OFFSET;
|
|
||||||
infoPtr->items[curItem].rect.bottom = clientRect.top +
|
|
||||||
infoPtr->tabHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the leftmost position of the tab.
|
* Set the leftmost position of the tab.
|
||||||
*/
|
*/
|
||||||
|
@ -764,6 +770,27 @@ static void TAB_SetItemBounds (HWND hwnd)
|
||||||
num*HORIZONTAL_ITEM_PADDING;
|
num*HORIZONTAL_ITEM_PADDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if this is a multiline tab control and if so
|
||||||
|
* check to see if we should wrap the tabs
|
||||||
|
*
|
||||||
|
* Because we are going to arange all these tabs evenly
|
||||||
|
* really we are basically just counting rows at this point
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((lStyle & TCS_MULTILINE)&&
|
||||||
|
(infoPtr->items[curItem].rect.right > clientRect.right))
|
||||||
|
{
|
||||||
|
infoPtr->items[curItem].rect.right -=
|
||||||
|
infoPtr->items[curItem].rect.left;
|
||||||
|
infoPtr->items[curItem].rect.left = 0;
|
||||||
|
curItemRowCount ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
infoPtr->items[curItem].rect.bottom = 0;
|
||||||
|
infoPtr->items[curItem].rect.top = curItemRowCount;
|
||||||
|
|
||||||
TRACE("TextSize: %i\n ", size.cx);
|
TRACE("TextSize: %i\n ", size.cx);
|
||||||
TRACE("Rect: T %i, L %i, B %i, R %i\n",
|
TRACE("Rect: T %i, L %i, B %i, R %i\n",
|
||||||
infoPtr->items[curItem].rect.top,
|
infoPtr->items[curItem].rect.top,
|
||||||
|
@ -781,18 +808,113 @@ static void TAB_SetItemBounds (HWND hwnd)
|
||||||
curItemLeftPos = infoPtr->items[curItem].rect.right;
|
curItemLeftPos = infoPtr->items[curItem].rect.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(lStyle & TCS_MULTILINE))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Check if we need a scrolling control.
|
||||||
|
*/
|
||||||
|
infoPtr->needsScrolling = (curItemLeftPos + (2*SELECTED_TAB_OFFSET) >
|
||||||
|
clientRect.right);
|
||||||
|
|
||||||
|
TAB_SetupScrolling(hwnd, infoPtr, &clientRect);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if we need a scrolling control.
|
* Set the number of rows
|
||||||
*/
|
*/
|
||||||
infoPtr->needsScrolling = (curItemLeftPos + (2*SELECTED_TAB_OFFSET) >
|
|
||||||
clientRect.right);
|
|
||||||
|
|
||||||
/* Don't need scrolling, then update infoPtr->leftmostVisible */
|
infoPtr->uNumRows = curItemRowCount;
|
||||||
if(!infoPtr->needsScrolling)
|
|
||||||
infoPtr->leftmostVisible = 0;
|
|
||||||
|
|
||||||
TAB_SetupScrolling(hwnd, infoPtr, &clientRect);
|
if ((lStyle & TCS_MULTILINE)&&(infoPtr->uNumItem > 0))
|
||||||
|
{
|
||||||
|
INT widthDiff,remainder;
|
||||||
|
INT tabPerRow,remTab;
|
||||||
|
INT iRow,iItm;
|
||||||
|
INT iIndexStart=0,iIndexEnd=0, iCount=0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ok Microsoft trys to even out the rows. place the same
|
||||||
|
* number of tabs in each row. So lets give that a shot
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
tabPerRow = infoPtr->uNumItem / (infoPtr->uNumRows + 1);
|
||||||
|
remTab = infoPtr->uNumItem % (infoPtr->uNumRows + 1);
|
||||||
|
|
||||||
|
for (iItm=0,iRow=0,iCount=0,curItemLeftPos=0;
|
||||||
|
iItm<infoPtr->uNumItem;
|
||||||
|
iItm++,iCount++)
|
||||||
|
{
|
||||||
|
if (iCount >= ((iRow<remTab)?tabPerRow+1:tabPerRow))
|
||||||
|
{
|
||||||
|
iRow++;
|
||||||
|
curItemLeftPos = 0;
|
||||||
|
iCount = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* normalize the current rect
|
||||||
|
*/
|
||||||
|
infoPtr->items[iItm].rect.right -=
|
||||||
|
infoPtr->items[iItm].rect.left;
|
||||||
|
infoPtr->items[iItm].rect.left = 0;
|
||||||
|
|
||||||
|
infoPtr->items[iItm].rect.top = iRow;
|
||||||
|
infoPtr->items[iItm].rect.left +=curItemLeftPos;
|
||||||
|
infoPtr->items[iItm].rect.right +=curItemLeftPos;
|
||||||
|
if (lStyle & TCS_BUTTONS)
|
||||||
|
curItemLeftPos = infoPtr->items[iItm].rect.right +
|
||||||
|
BUTTON_SPACINGX;
|
||||||
|
else
|
||||||
|
curItemLeftPos = infoPtr->items[iItm].rect.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Justify the rows
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
while(iIndexStart < infoPtr->uNumItem)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* find the indexs of the row
|
||||||
|
*/
|
||||||
|
for (iIndexEnd=iIndexStart;
|
||||||
|
(iIndexEnd < infoPtr->uNumItem) &&
|
||||||
|
(infoPtr->items[iIndexEnd].rect.top ==
|
||||||
|
infoPtr->items[iIndexStart].rect.top) ;
|
||||||
|
iIndexEnd++)
|
||||||
|
/* intentionaly blank */;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we need to justify these tabs so they fill the whole given
|
||||||
|
* client area
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
widthDiff = clientRect.right - (2*SELECTED_TAB_OFFSET) -
|
||||||
|
infoPtr->items[iIndexEnd-1].rect.right;
|
||||||
|
|
||||||
|
iCount = iIndexEnd-iIndexStart;
|
||||||
|
|
||||||
|
if (iCount)
|
||||||
|
{
|
||||||
|
INT iIndex;
|
||||||
|
remainder = widthDiff % iCount;
|
||||||
|
widthDiff = widthDiff / iCount;
|
||||||
|
for (iIndex=iIndexStart,iCount=0; iIndex < iIndexEnd;
|
||||||
|
iIndex++,iCount++)
|
||||||
|
{
|
||||||
|
infoPtr->items[iIndex].rect.left +=iCount*widthDiff;
|
||||||
|
infoPtr->items[iIndex].rect.right +=(iCount+1)*widthDiff;
|
||||||
|
}
|
||||||
|
infoPtr->items[iIndex-1].rect.right += remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
iIndexStart=iIndexEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TAB_EnsureSelectionVisible(hwnd,infoPtr);
|
||||||
/*
|
/*
|
||||||
* Cleanup
|
* Cleanup
|
||||||
*/
|
*/
|
||||||
|
@ -1044,7 +1166,14 @@ static void TAB_DrawItem(
|
||||||
/*
|
/*
|
||||||
* Draw the text;
|
* Draw the text;
|
||||||
*/
|
*/
|
||||||
DrawTextA(hdc,
|
if (lStyle & TCS_RIGHTJUSTIFY)
|
||||||
|
DrawTextA(hdc,
|
||||||
|
infoPtr->items[iItem].pszText,
|
||||||
|
lstrlenA(infoPtr->items[iItem].pszText),
|
||||||
|
&r,
|
||||||
|
DT_CENTER|DT_SINGLELINE|DT_VCENTER);
|
||||||
|
else
|
||||||
|
DrawTextA(hdc,
|
||||||
infoPtr->items[iItem].pszText,
|
infoPtr->items[iItem].pszText,
|
||||||
lstrlenA(infoPtr->items[iItem].pszText),
|
lstrlenA(infoPtr->items[iItem].pszText),
|
||||||
&r,
|
&r,
|
||||||
|
@ -1101,11 +1230,11 @@ static void TAB_DrawBorder (HWND hwnd, HDC hdc)
|
||||||
*/
|
*/
|
||||||
if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BOTTOM)
|
if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BOTTOM)
|
||||||
{
|
{
|
||||||
rect.bottom -= infoPtr->tabHeight;
|
rect.bottom -= (infoPtr->tabHeight - 2) * (infoPtr->uNumRows + 1) + 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rect.top += infoPtr->tabHeight;
|
rect.top += (infoPtr->tabHeight - 2) * (infoPtr->uNumRows + 1) + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1185,8 +1314,8 @@ static void TAB_Refresh (HWND hwnd, HDC hdc)
|
||||||
* If we haven't set the current focus yet, set it now.
|
* If we haven't set the current focus yet, set it now.
|
||||||
* Only happens when we first paint the tab controls.
|
* Only happens when we first paint the tab controls.
|
||||||
*/
|
*/
|
||||||
if (infoPtr->uFocus == -1)
|
if (infoPtr->uFocus == -1)
|
||||||
TAB_SetCurFocus(hwnd, infoPtr->iSelected);
|
TAB_SetCurFocus(hwnd, infoPtr->iSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectObject (hdc, hOldFont);
|
SelectObject (hdc, hOldFont);
|
||||||
|
@ -1236,6 +1365,41 @@ static void TAB_EnsureSelectionVisible(
|
||||||
{
|
{
|
||||||
INT iSelected = infoPtr->iSelected;
|
INT iSelected = infoPtr->iSelected;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set the items row to the bottommost row or topmost row depending on
|
||||||
|
* style
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (infoPtr->uNumRows > 0)
|
||||||
|
{
|
||||||
|
INT newselected=infoPtr->items[iSelected].rect.top;
|
||||||
|
INT iTargetRow;
|
||||||
|
LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);
|
||||||
|
|
||||||
|
if (lStyle & TCS_BOTTOM)
|
||||||
|
iTargetRow = 0;
|
||||||
|
else
|
||||||
|
iTargetRow = infoPtr->uNumRows;
|
||||||
|
|
||||||
|
if (newselected != iTargetRow)
|
||||||
|
{
|
||||||
|
INT i;
|
||||||
|
for (i=0; i < infoPtr->uNumItem; i++)
|
||||||
|
if (infoPtr->items[i].rect.top == newselected )
|
||||||
|
infoPtr->items[i].rect.top = iTargetRow;
|
||||||
|
else if (lStyle&TCS_BOTTOM)
|
||||||
|
{
|
||||||
|
if (infoPtr->items[i].rect.top < newselected)
|
||||||
|
infoPtr->items[i].rect.top+=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (infoPtr->items[i].rect.top > newselected)
|
||||||
|
infoPtr->items[i].rect.top-=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the trivial cases first.
|
* Do the trivial cases first.
|
||||||
*/
|
*/
|
||||||
|
@ -1301,11 +1465,13 @@ static void TAB_InvalidateTabArea(
|
||||||
|
|
||||||
if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BOTTOM)
|
if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BOTTOM)
|
||||||
{
|
{
|
||||||
clientRect.top = clientRect.bottom - (infoPtr->tabHeight + 3);
|
clientRect.top = clientRect.bottom - (infoPtr->tabHeight *
|
||||||
|
(infoPtr->uNumRows + 1) + 3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clientRect.bottom = clientRect.top + (infoPtr->tabHeight + 1);
|
clientRect.bottom = clientRect.top + (infoPtr->tabHeight *
|
||||||
|
(infoPtr->uNumRows + 1) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
InvalidateRect(hwnd, &clientRect, TRUE);
|
InvalidateRect(hwnd, &clientRect, TRUE);
|
||||||
|
@ -1389,12 +1555,12 @@ TAB_InsertItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
if (pti->mask & TCIF_PARAM)
|
if (pti->mask & TCIF_PARAM)
|
||||||
infoPtr->items[iItem].lParam = pti->lParam;
|
infoPtr->items[iItem].lParam = pti->lParam;
|
||||||
|
|
||||||
TAB_SetItemBounds(hwnd);
|
|
||||||
TAB_InvalidateTabArea(hwnd, infoPtr);
|
TAB_InvalidateTabArea(hwnd, infoPtr);
|
||||||
|
|
||||||
TRACE("[%04x]: added item %d '%s'\n",
|
TRACE("[%04x]: added item %d '%s'\n",
|
||||||
hwnd, iItem, infoPtr->items[iItem].pszText);
|
hwnd, iItem, infoPtr->items[iItem].pszText);
|
||||||
|
|
||||||
|
TAB_SetItemBounds(hwnd);
|
||||||
return iItem;
|
return iItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1668,6 +1834,7 @@ TAB_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
SetWindowLongA(hwnd, 0, (DWORD)infoPtr);
|
SetWindowLongA(hwnd, 0, (DWORD)infoPtr);
|
||||||
|
|
||||||
infoPtr->uNumItem = 0;
|
infoPtr->uNumItem = 0;
|
||||||
|
infoPtr->uNumRows = 0;
|
||||||
infoPtr->hFont = 0;
|
infoPtr->hFont = 0;
|
||||||
infoPtr->items = 0;
|
infoPtr->items = 0;
|
||||||
infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
|
infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
|
||||||
|
@ -1938,7 +2105,7 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (uMsg >= WM_USER)
|
if (uMsg >= WM_USER)
|
||||||
WARN("unknown msg %04x wp=%08x lp=%08lx\n",
|
ERR("unknown msg %04x wp=%08x lp=%08lx\n",
|
||||||
uMsg, wParam, lParam);
|
uMsg, wParam, lParam);
|
||||||
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
|
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,16 @@ typedef struct tagTAB_ITEM
|
||||||
LPARAM lParam;
|
LPARAM lParam;
|
||||||
RECT rect; /* bounding rectangle of the item relative to the
|
RECT rect; /* bounding rectangle of the item relative to the
|
||||||
* leftmost item (the leftmost item, 0, would have a
|
* leftmost item (the leftmost item, 0, would have a
|
||||||
* "left" member of 0 in this rectangle) */
|
* "left" member of 0 in this rectangle)
|
||||||
|
*
|
||||||
|
* additionally the top member hold the row number
|
||||||
|
* and bottom is unused and should be 0 */
|
||||||
} TAB_ITEM;
|
} TAB_ITEM;
|
||||||
|
|
||||||
typedef struct tagTAB_INFO
|
typedef struct tagTAB_INFO
|
||||||
{
|
{
|
||||||
UINT uNumItem; /* number of tab items */
|
UINT uNumItem; /* number of tab items */
|
||||||
|
UINT uNumRows; /* number of tab rows */
|
||||||
INT tabHeight; /* height of the tab row */
|
INT tabHeight; /* height of the tab row */
|
||||||
INT tabWidth; /* width of tabs */
|
INT tabWidth; /* width of tabs */
|
||||||
HFONT hFont; /* handle to the current font */
|
HFONT hFont; /* handle to the current font */
|
||||||
|
|
Loading…
Reference in New Issue