[PATCH 10/10] Store item data in DPA
Nikolay Sivov
nsivov at codeweavers.com
Sun Sep 26 18:05:24 CDT 2010
---
dlls/comctl32/tab.c | 166 ++++++++++++++++++++++----------------------------
1 files changed, 73 insertions(+), 93 deletions(-)
diff --git a/dlls/comctl32/tab.c b/dlls/comctl32/tab.c
index 28c8bfd..7c8f782 100644
--- a/dlls/comctl32/tab.c
+++ b/dlls/comctl32/tab.c
@@ -52,6 +52,7 @@
*
*/
+#include <assert.h>
#include <stdarg.h>
#include <string.h>
@@ -108,7 +109,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 */
@@ -120,6 +120,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;
/******************************************************************************
@@ -139,9 +141,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)
@@ -153,6 +152,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
*/
@@ -207,9 +212,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",
@@ -427,9 +431,15 @@ static BOOL TAB_InternalGetItemRect(
} else
{
- OffsetRect(itemRect,
- -TAB_GetItem(infoPtr, infoPtr->leftmostVisible)->rect.left,
- 0);
+ const TAB_ITEM *item;
+
+ /* FIXME: temporary fix for invalid index */
+ if (infoPtr->leftmostVisible < 0)
+ item = TAB_GetItem(infoPtr, 0);
+ else
+ item = TAB_GetItem(infoPtr, infoPtr->leftmostVisible);
+
+ OffsetRect(itemRect, -item->rect.left, 0);
/*
* Move the rectangle so the first item is slightly offset from
@@ -2634,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)
@@ -2879,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))
- {
- TAB_ITEM *item = TAB_GetItem(infoPtr, iItem);
- LPBYTE oldItems = (LPBYTE)infoPtr->items;
+ 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);
- Free(item->pszText);
- infoPtr->uNumItem--;
+ TAB_InvalidateTabArea(infoPtr);
- if (!infoPtr->uNumItem)
+ if (infoPtr->uNumItem == 0)
+ {
+ 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;
+ infoPtr->iSelected = -1;
+ }
+ else
+ {
+ if (iItem <= infoPtr->iHotTracked)
+ {
+ /* When tabs move left/up, the hot track item may change */
+ FIXME("Recalc hot track\n");
+ }
+ }
- /* Reposition and repaint tabs */
- TAB_SetItemBounds(infoPtr);
+ /* adjust the selected index */
+ if (iItem == infoPtr->iSelected)
+ infoPtr->iSelected = -1;
+ else if (iItem < infoPtr->iSelected)
+ infoPtr->iSelected--;
- bResult = TRUE;
- }
+ /* reposition and repaint tabs */
+ TAB_SetItemBounds(infoPtr);
- return bResult;
+ return TRUE;
}
static inline LRESULT TAB_DeleteAllItems (TAB_INFO *infoPtr)
@@ -3057,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;
@@ -3141,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);
--
1.5.6.5
--------------010401050902080901070707--
More information about the wine-patches
mailing list