comctl32/tab: Use dpa to store item data.
This commit is contained in:
parent
6867735e20
commit
82258f4f25
|
@ -52,6 +52,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -110,7 +111,6 @@ typedef struct
|
|||
INT iSelected; /* the currently selected item */
|
||||
INT iHotTracked; /* the highlighted item under the mouse */
|
||||
INT uFocus; /* item which has the focus */
|
||||
TAB_ITEM* items; /* pointer to an array of TAB_ITEM's */
|
||||
BOOL DoRedraw; /* flag for redrawing when tab contents is changed*/
|
||||
BOOL needsScrolling; /* TRUE if the size of the tabs is greater than
|
||||
* the size of the control */
|
||||
|
@ -122,6 +122,8 @@ typedef struct
|
|||
DWORD exStyle; /* Extended style used, currently:
|
||||
TCS_EX_FLATSEPARATORS, TCS_EX_REGISTERDROP */
|
||||
DWORD dwStyle; /* the cached window GWL_STYLE */
|
||||
|
||||
HDPA items; /* dynamic array of TAB_ITEM* pointers */
|
||||
} TAB_INFO;
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -141,9 +143,6 @@ typedef struct
|
|||
#define EXTRA_ICON_PADDING 3
|
||||
|
||||
#define TAB_GetInfoPtr(hwnd) ((TAB_INFO *)GetWindowLongPtrW(hwnd,0))
|
||||
/* Since items are variable sized, cannot directly access them */
|
||||
#define TAB_GetItem(info,i) \
|
||||
((TAB_ITEM*)((LPBYTE)info->items + (i) * TAB_ITEM_SIZE(info)))
|
||||
|
||||
#define GET_DEFAULT_MIN_TAB_WIDTH(infoPtr) (DEFAULT_MIN_TAB_WIDTH - (DEFAULT_PADDING_X - (infoPtr)->uHItemPadding) * 2)
|
||||
|
||||
|
@ -155,6 +154,12 @@ typedef struct
|
|||
|
||||
static const WCHAR themeClass[] = { 'T','a','b',0 };
|
||||
|
||||
static inline TAB_ITEM* TAB_GetItem(const TAB_INFO *infoPtr, INT i)
|
||||
{
|
||||
assert(i >= 0 && i < infoPtr->uNumItem);
|
||||
return DPA_GetPtr(infoPtr->items, i);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Prototypes
|
||||
*/
|
||||
|
@ -209,9 +214,8 @@ static void
|
|||
TAB_DumpItemInternal(const TAB_INFO *infoPtr, UINT iItem)
|
||||
{
|
||||
if (TRACE_ON(tab)) {
|
||||
TAB_ITEM *ti;
|
||||
TAB_ITEM *ti = TAB_GetItem(infoPtr, iItem);
|
||||
|
||||
ti = TAB_GetItem(infoPtr, iItem);
|
||||
TRACE("tab %d, dwState=0x%08x, pszText=%s, iImage=%d\n",
|
||||
iItem, ti->dwState, debugstr_w(ti->pszText), ti->iImage);
|
||||
TRACE("tab %d, rect.left=%d, rect.top(row)=%d\n",
|
||||
|
@ -2640,42 +2644,21 @@ TAB_InsertItemT (TAB_INFO *infoPtr, INT iItem, const TCITEMW *pti, BOOL bUnicode
|
|||
|
||||
TAB_DumpItemExternalT(pti, iItem, bUnicode);
|
||||
|
||||
|
||||
if (infoPtr->uNumItem == 0) {
|
||||
infoPtr->items = Alloc (TAB_ITEM_SIZE(infoPtr));
|
||||
infoPtr->uNumItem++;
|
||||
infoPtr->iSelected = 0;
|
||||
if (!(item = Alloc(sizeof(TAB_ITEM_SIZE(infoPtr))))) return FALSE;
|
||||
if (DPA_InsertPtr(infoPtr->items, iItem, item) == -1)
|
||||
{
|
||||
Free(item);
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
LPBYTE oldItems = (LPBYTE)infoPtr->items;
|
||||
|
||||
infoPtr->uNumItem++;
|
||||
infoPtr->items = Alloc (TAB_ITEM_SIZE(infoPtr) * infoPtr->uNumItem);
|
||||
|
||||
/* pre insert copy */
|
||||
if (iItem > 0) {
|
||||
memcpy (infoPtr->items, oldItems,
|
||||
iItem * TAB_ITEM_SIZE(infoPtr));
|
||||
}
|
||||
|
||||
/* post insert copy */
|
||||
if (iItem < infoPtr->uNumItem - 1) {
|
||||
memcpy (TAB_GetItem(infoPtr, iItem + 1),
|
||||
oldItems + iItem * TAB_ITEM_SIZE(infoPtr),
|
||||
(infoPtr->uNumItem - iItem - 1) * TAB_ITEM_SIZE(infoPtr));
|
||||
|
||||
}
|
||||
|
||||
if (iItem <= infoPtr->iSelected)
|
||||
if (infoPtr->uNumItem == 0)
|
||||
infoPtr->iSelected = 0;
|
||||
else if (iItem <= infoPtr->iSelected)
|
||||
infoPtr->iSelected++;
|
||||
|
||||
Free (oldItems);
|
||||
}
|
||||
|
||||
item = TAB_GetItem(infoPtr, iItem);
|
||||
infoPtr->uNumItem++;
|
||||
|
||||
item->pszText = NULL;
|
||||
|
||||
if (pti->mask & TCIF_TEXT)
|
||||
{
|
||||
if (bUnicode)
|
||||
|
@ -2885,64 +2868,49 @@ TAB_GetItemT (TAB_INFO *infoPtr, INT iItem, LPTCITEMW tabItem, BOOL bUnicode)
|
|||
|
||||
static LRESULT TAB_DeleteItem (TAB_INFO *infoPtr, INT iItem)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
TAB_ITEM *item;
|
||||
|
||||
TRACE("(%p, %d)\n", infoPtr, iItem);
|
||||
|
||||
if ((iItem >= 0) && (iItem < infoPtr->uNumItem))
|
||||
if (iItem < 0 || iItem >= infoPtr->uNumItem) return FALSE;
|
||||
|
||||
item = TAB_GetItem(infoPtr, iItem);
|
||||
Free(item->pszText);
|
||||
Free(item);
|
||||
infoPtr->uNumItem--;
|
||||
DPA_DeletePtr(infoPtr->items, iItem);
|
||||
|
||||
TAB_InvalidateTabArea(infoPtr);
|
||||
|
||||
if (infoPtr->uNumItem == 0)
|
||||
{
|
||||
TAB_ITEM *item = TAB_GetItem(infoPtr, iItem);
|
||||
LPBYTE oldItems = (LPBYTE)infoPtr->items;
|
||||
|
||||
TAB_InvalidateTabArea(infoPtr);
|
||||
Free(item->pszText);
|
||||
infoPtr->uNumItem--;
|
||||
|
||||
if (!infoPtr->uNumItem)
|
||||
if (infoPtr->iHotTracked >= 0)
|
||||
{
|
||||
infoPtr->items = NULL;
|
||||
if (infoPtr->iHotTracked >= 0)
|
||||
{
|
||||
KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);
|
||||
infoPtr->iHotTracked = -1;
|
||||
}
|
||||
KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);
|
||||
infoPtr->iHotTracked = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
infoPtr->items = Alloc(TAB_ITEM_SIZE(infoPtr) * infoPtr->uNumItem);
|
||||
|
||||
if (iItem > 0)
|
||||
memcpy(infoPtr->items, oldItems, iItem * TAB_ITEM_SIZE(infoPtr));
|
||||
|
||||
if (iItem < infoPtr->uNumItem)
|
||||
memcpy(TAB_GetItem(infoPtr, iItem),
|
||||
oldItems + (iItem + 1) * TAB_ITEM_SIZE(infoPtr),
|
||||
(infoPtr->uNumItem - iItem) * TAB_ITEM_SIZE(infoPtr));
|
||||
|
||||
if (iItem <= infoPtr->iHotTracked)
|
||||
{
|
||||
/* When tabs move left/up, the hot track item may change */
|
||||
FIXME("Recalc hot track\n");
|
||||
}
|
||||
}
|
||||
Free(oldItems);
|
||||
|
||||
/* Readjust the selected index */
|
||||
if (iItem == infoPtr->iSelected)
|
||||
infoPtr->iSelected = -1;
|
||||
else if (iItem < infoPtr->iSelected)
|
||||
infoPtr->iSelected--;
|
||||
|
||||
if (infoPtr->uNumItem == 0)
|
||||
infoPtr->iSelected = -1;
|
||||
|
||||
/* Reposition and repaint tabs */
|
||||
TAB_SetItemBounds(infoPtr);
|
||||
|
||||
bResult = TRUE;
|
||||
infoPtr->iSelected = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iItem <= infoPtr->iHotTracked)
|
||||
{
|
||||
/* When tabs move left/up, the hot track item may change */
|
||||
FIXME("Recalc hot track\n");
|
||||
}
|
||||
}
|
||||
|
||||
return bResult;
|
||||
/* adjust the selected index */
|
||||
if (iItem == infoPtr->iSelected)
|
||||
infoPtr->iSelected = -1;
|
||||
else if (iItem < infoPtr->iSelected)
|
||||
infoPtr->iSelected--;
|
||||
|
||||
/* reposition and repaint tabs */
|
||||
TAB_SetItemBounds(infoPtr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline LRESULT TAB_DeleteAllItems (TAB_INFO *infoPtr)
|
||||
|
@ -3063,7 +3031,7 @@ static LRESULT TAB_Create (HWND hwnd, LPARAM lParam)
|
|||
infoPtr->uHItemPadding_s = 6;
|
||||
infoPtr->uVItemPadding_s = 3;
|
||||
infoPtr->hFont = 0;
|
||||
infoPtr->items = 0;
|
||||
infoPtr->items = DPA_Create(8);
|
||||
infoPtr->hcurArrow = LoadCursorW (0, (LPWSTR)IDC_ARROW);
|
||||
infoPtr->iSelected = -1;
|
||||
infoPtr->iHotTracked = -1;
|
||||
|
@ -3147,16 +3115,22 @@ static LRESULT TAB_Create (HWND hwnd, LPARAM lParam)
|
|||
static LRESULT
|
||||
TAB_Destroy (TAB_INFO *infoPtr)
|
||||
{
|
||||
UINT iItem;
|
||||
INT iItem;
|
||||
|
||||
SetWindowLongPtrW(infoPtr->hwnd, 0, 0);
|
||||
|
||||
if (infoPtr->items) {
|
||||
for (iItem = 0; iItem < infoPtr->uNumItem; iItem++) {
|
||||
Free (TAB_GetItem(infoPtr, iItem)->pszText);
|
||||
}
|
||||
Free (infoPtr->items);
|
||||
for (iItem = infoPtr->uNumItem - 1; iItem >= 0; iItem--)
|
||||
{
|
||||
TAB_ITEM *tab = TAB_GetItem(infoPtr, iItem);
|
||||
|
||||
DPA_DeletePtr(infoPtr->items, iItem);
|
||||
infoPtr->uNumItem--;
|
||||
|
||||
Free(tab->pszText);
|
||||
Free(tab);
|
||||
}
|
||||
DPA_Destroy(infoPtr->items);
|
||||
infoPtr->items = NULL;
|
||||
|
||||
if (infoPtr->hwndToolTip)
|
||||
DestroyWindow (infoPtr->hwndToolTip);
|
||||
|
|
Loading…
Reference in New Issue