ownerdraw paint recursion in listbox
Alexander Yaworsky
yaworsky at migusoft.ru
Mon Nov 22 21:20:48 CST 2004
Dmitry Timoshkov wrote:
>
> If you have a small test case or a snippet of the +relay log showing
> the problem I'll have a look.
>
http://migusoft.ru/misc/trace.bz2
with added ERR()s, see attachment
I cut the tail of log just before the first err:listbox. Note that
there are two listboxes on the form. Both are initialized ok,
wrong things begin after WM_KEYDOWN.
-------------- next part --------------
Index: listbox.c
===================================================================
RCS file: /home/wine/wine/dlls/user/listbox.c,v
retrieving revision 1.5
diff -u -r1.5 listbox.c
--- listbox.c 26 Oct 2004 22:03:00 -0000 1.5
+++ listbox.c 23 Nov 2004 04:00:07 -0000
@@ -103,6 +103,7 @@
HFONT font; /* Current font */
LCID locale; /* Current locale for string comparisons */
LPHEADCOMBO lphc; /* ComboLBox */
+// BOOL painting;
} LB_DESCR;
@@ -204,6 +205,7 @@
static INT LISTBOX_GetCurrentPageSize( LB_DESCR *descr )
{
INT i, height;
+ERR("\n");
if (!(descr->style & LBS_OWNERDRAWVARIABLE)) return descr->page_size;
for (i = descr->top_item, height = 0; i < descr->nb_items; i++)
{
@@ -223,6 +225,7 @@
{
INT max, page;
+ERR("\n");
if (descr->style & LBS_OWNERDRAWVARIABLE)
{
page = descr->height;
@@ -255,6 +258,7 @@
{
SCROLLINFO info;
+ERR("\n");
/* Check the listbox scroll bar flags individually before we call
SetScrollInfo otherwise when the listbox style is WS_HSCROLL and
no WS_VSCROLL, we end up with an uninitialized, visible horizontal
@@ -325,7 +329,9 @@
*/
static LRESULT LISTBOX_SetTopItem( LB_DESCR *descr, INT index, BOOL scroll )
{
- INT max = LISTBOX_GetMaxTopIndex( descr );
+ INT max;
+ERR("\n");
+max = LISTBOX_GetMaxTopIndex( descr );
if (index > max) index = max;
if (index < 0) index = 0;
if (descr->style & LBS_MULTICOLUMN) index -= index % descr->page_size;
@@ -383,6 +389,7 @@
static void LISTBOX_UpdatePage( LB_DESCR *descr )
{
INT page_size;
+ERR("\n");
if ((descr->item_height == 0) || (page_size = descr->height / descr->item_height) < 1)
page_size = 1;
@@ -403,6 +410,7 @@
static void LISTBOX_UpdateSize( LB_DESCR *descr )
{
RECT rect;
+ERR("\n");
GetClientRect( descr->self, &rect );
descr->width = rect.right - rect.left;
@@ -455,6 +463,7 @@
*/
static LRESULT LISTBOX_GetItemRect( LB_DESCR *descr, INT index, RECT *rect )
{
+ERR("\n");
/* Index <= 0 is legal even on empty listboxes */
if (index && (index >= descr->nb_items)) return -1;
SetRect( rect, 0, 0, descr->width, descr->height );
@@ -508,6 +517,7 @@
{
INT index = descr->top_item;
+ERR("\n");
if (!descr->nb_items) return -1; /* No items */
if (descr->style & LBS_OWNERDRAWVARIABLE)
{
@@ -555,6 +565,7 @@
INT index, UINT action, BOOL ignoreFocus )
{
LB_ITEMDATA *item = NULL;
+ERR("index=%d\n",index);
if (index < descr->nb_items) item = &descr->items[index];
if (IS_OWNERDRAW(descr))
@@ -654,6 +665,7 @@
*/
static void LISTBOX_SetRedraw( LB_DESCR *descr, BOOL on )
{
+ERR("\n");
if (on)
{
if (!(descr->style & LBS_NOREDRAW)) return;
@@ -686,6 +698,7 @@
HFONT oldFont = 0;
HBRUSH hbrush, oldBrush = 0;
+ERR("\n");
/* Do not repaint the item if the item is not visible */
if (!IsWindowVisible(descr->self)) return;
if (descr->style & LBS_NOREDRAW)
@@ -716,6 +729,7 @@
{
LB_ITEMDATA *item;
+ERR("\n");
nb_items += LB_ARRAY_GRANULARITY - 1;
nb_items -= (nb_items % LB_ARRAY_GRANULARITY);
if (descr->items) {
@@ -743,6 +757,7 @@
*/
static BOOL LISTBOX_SetTabStops( LB_DESCR *descr, INT count, LPINT tabs, BOOL short_ints )
{
+ERR("\n");
if (!(descr->style & LBS_USETABSTOPS)) return TRUE;
if (descr->tabs) HeapFree( GetProcessHeap(), 0, descr->tabs );
if (!(descr->nb_tabs = count))
@@ -777,6 +792,7 @@
*/
static LRESULT LISTBOX_GetText( LB_DESCR *descr, INT index, LPWSTR buffer, BOOL unicode )
{
+ERR("\n");
if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
if (HAS_STRINGS(descr))
{
@@ -818,6 +834,7 @@
{
INT index, min, max, res = -1;
+ERR("\n");
if (!(descr->style & LBS_SORT)) return -1; /* Add it at the end */
min = 0;
max = descr->nb_items;
@@ -861,6 +878,7 @@
{
INT min, max, res = -1;
+ERR("\n");
if (!HAS_STRINGS(descr))
return LISTBOX_FindStringPos( descr, str, FALSE );
min = 0;
@@ -906,6 +924,7 @@
INT i;
LB_ITEMDATA *item;
+ERR("\n");
if (start >= descr->nb_items) start = -1;
item = descr->items + start + 1;
if (HAS_STRINGS(descr))
@@ -967,6 +986,7 @@
INT i, count;
LB_ITEMDATA *item = descr->items;
+ERR("\n");
if (!(descr->style & LBS_MULTIPLESEL) ||
(descr->style & LBS_NOSEL))
return LB_ERR;
@@ -984,6 +1004,7 @@
INT i, count;
LB_ITEMDATA *item = descr->items;
+ERR("\n");
if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
for (i = count = 0; (i < descr->nb_items) && (count < max); i++, item++)
if (item->selected) array[count++] = (INT16)i;
@@ -999,6 +1020,7 @@
INT i, count;
LB_ITEMDATA *item = descr->items;
+ERR("\n");
if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
for (i = count = 0; (i < descr->nb_items) && (count < max); i++, item++)
if (item->selected) array[count++] = i;
@@ -1017,8 +1039,12 @@
HFONT oldFont = 0;
HBRUSH hbrush, oldBrush = 0;
+ERR("\n");
if (descr->style & LBS_NOREDRAW) return 0;
+// if( descr->painting ) return 0;
+// descr->painting = TRUE;
+
SetRect( &rect, 0, 0, descr->width, descr->height );
if (descr->style & LBS_MULTICOLUMN)
rect.right = rect.left + descr->column_width;
@@ -1118,6 +1144,7 @@
}
if (oldFont) SelectObject( hdc, oldFont );
if (oldBrush) SelectObject( hdc, oldBrush );
+// descr->painting = FALSE;
return 0;
}
@@ -1132,6 +1159,7 @@
{
RECT rect;
+ERR("\n");
if (LISTBOX_GetItemRect( descr, index, &rect ) == 1)
{
if (descr->style & LBS_NOREDRAW)
@@ -1165,6 +1193,7 @@
*/
static LRESULT LISTBOX_GetItemHeight( LB_DESCR *descr, INT index )
{
+ERR("\n");
if (descr->style & LBS_OWNERDRAWVARIABLE)
{
if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
@@ -1179,6 +1208,7 @@
*/
static LRESULT LISTBOX_SetItemHeight( LB_DESCR *descr, INT index, INT height, BOOL repaint )
{
+ERR("\n");
if (!height) height = 1;
if (descr->style & LBS_OWNERDRAWVARIABLE)
@@ -1210,6 +1240,7 @@
{
INT diff;
+ERR("\n");
if (pos > descr->horz_extent - descr->width)
pos = descr->horz_extent - descr->width;
if (pos < 0) pos = 0;
@@ -1236,6 +1267,7 @@
*/
static LRESULT LISTBOX_SetHorizontalExtent( LB_DESCR *descr, INT extent )
{
+ERR("\n");
if (!descr->horz_extent || (descr->style & LBS_MULTICOLUMN))
return LB_OKAY;
if (extent <= 0) extent = 1;
@@ -1255,6 +1287,7 @@
*/
static LRESULT LISTBOX_SetColumnWidth( LB_DESCR *descr, INT width)
{
+ERR("\n");
if (width == descr->column_width) return LB_OKAY;
TRACE("[%p]: new column width = %d\n", descr->self, width );
descr->column_width = width;
@@ -1274,6 +1307,7 @@
HFONT oldFont = 0;
TEXTMETRICW tm;
+ERR("\n");
descr->font = font;
if (!(hdc = GetDCEx( descr->self, 0, DCX_CACHE )))
@@ -1300,6 +1334,7 @@
{
INT top;
+ERR("\n");
if (index <= descr->top_item) top = index;
else if (descr->style & LBS_MULTICOLUMN)
{
@@ -1337,6 +1372,7 @@
{
INT oldfocus = descr->focus_item;
+ERR("\n");
if (descr->style & LBS_NOSEL) return LB_ERR;
if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
if (index == oldfocus) return LB_OKAY;
@@ -1362,6 +1398,7 @@
{
INT i;
+ERR("\n");
/* A few sanity checks */
if (descr->style & LBS_NOSEL) return LB_ERR;
@@ -1401,6 +1438,7 @@
static LRESULT LISTBOX_SetSelection( LB_DESCR *descr, INT index,
BOOL on, BOOL send_notify )
{
+ERR("\n");
TRACE( "index=%d notify=%s\n", index, send_notify ? "YES" : "NO" );
if (descr->style & LBS_NOSEL)
@@ -1444,6 +1482,7 @@
{
INT oldfocus = descr->focus_item;
+ERR("\n");
if ((index < 0) || (index >= descr->nb_items))
return;
@@ -1497,6 +1536,7 @@
INT max_items;
INT oldfocus = descr->focus_item;
+ERR("\n");
if (index == -1) index = descr->nb_items;
else if ((index < 0) || (index > descr->nb_items)) return LB_ERR;
if (!descr->items) max_items = 0;
@@ -1585,6 +1625,7 @@
DWORD data = 0;
LRESULT ret;
+ERR("\n");
if (HAS_STRINGS(descr))
{
static const WCHAR empty_stringW[] = { 0 };
@@ -1623,6 +1664,7 @@
* It's probably better to send it too often than not
* often enough, so this is what we do here.
*/
+ERR("\n");
if (IS_OWNERDRAW(descr) || descr->items[index].data)
{
DELETEITEMSTRUCT dis;
@@ -1650,6 +1692,7 @@
LB_ITEMDATA *item;
INT max_items;
+ERR("\n");
if ((index == -1) && (descr->nb_items > 0)) index = descr->nb_items - 1;
else if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
@@ -1714,6 +1757,7 @@
{
INT i;
+ERR("\n");
for (i = 0; i < descr->nb_items; i++) LISTBOX_DeleteItem( descr, i );
if (descr->items) HeapFree( GetProcessHeap(), 0, descr->items );
descr->nb_items = 0;
@@ -1732,6 +1776,7 @@
{
LRESULT ret;
+ERR("\n");
if (HAS_STRINGS(descr)) return LB_ERR;
/* FIXME: this is far from optimal... */
if (count > descr->nb_items)
@@ -1761,6 +1806,7 @@
WIN32_FIND_DATAW entry;
int pos;
+ERR("\n");
/* don't scan directory if we just want drives exclusively */
if (attrib != (DDL_DRIVES | DDL_EXCLUSIVE)) {
/* scan directory */
@@ -1834,6 +1880,7 @@
{
SCROLLINFO info;
+ERR("\n");
if (descr->style & LBS_MULTICOLUMN) return 0;
switch(scrollReq)
{
@@ -1879,6 +1926,7 @@
SCROLLINFO info;
INT page;
+ERR("\n");
if (descr->style & LBS_MULTICOLUMN)
{
switch(scrollReq)
@@ -1965,6 +2013,7 @@
short gcWheelDelta = 0;
UINT pulScrollLines = 3;
+ERR("\n");
SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
gcWheelDelta -= delta;
@@ -1983,7 +2032,9 @@
*/
static LRESULT LISTBOX_HandleLButtonDown( LB_DESCR *descr, DWORD keys, INT x, INT y )
{
- INT index = LISTBOX_GetItemFromPoint( descr, x, y );
+ INT index;
+ERR("\n");
+index = LISTBOX_GetItemFromPoint( descr, x, y );
TRACE("[%p]: lbuttondown %d,%d item %d\n", descr->self, x, y, index );
if (!descr->caret_on && (descr->in_focus)) return 0;
@@ -2079,6 +2130,7 @@
RECT clientRect, screenRect;
POINT mousePos;
+ERR("\n");
mousePos.x = x;
mousePos.y = y;
@@ -2154,6 +2206,7 @@
*/
static LRESULT LISTBOX_HandleLButtonUp( LB_DESCR *descr )
{
+ERR("\n");
if (LISTBOX_Timer != LB_TIMER_NONE)
KillSystemTimer( descr->self, LB_TIMER_ID );
LISTBOX_Timer = LB_TIMER_NONE;
@@ -2176,6 +2229,7 @@
*/
static LRESULT LISTBOX_HandleTimer( LB_DESCR *descr, INT index, TIMER_DIRECTION dir )
{
+ERR("\n");
switch(dir)
{
case LB_TIMER_UP:
@@ -2210,6 +2264,7 @@
*/
static LRESULT LISTBOX_HandleSystemTimer( LB_DESCR *descr )
{
+ERR("\n");
if (!LISTBOX_HandleTimer( descr, descr->focus_item, LISTBOX_Timer ))
{
KillSystemTimer( descr->self, LB_TIMER_ID );
@@ -2230,6 +2285,7 @@
INT index;
TIMER_DIRECTION dir = LB_TIMER_NONE;
+ERR("\n");
if (!descr->captured) return;
if (descr->style & LBS_MULTICOLUMN)
@@ -2276,6 +2332,7 @@
{
INT caret = -1;
BOOL bForceSelection = TRUE; /* select item pointed to by focus_item */
+ERR("\n");
if ((IS_MULTISELECT(descr)) || (descr->selected_item == descr->focus_item))
bForceSelection = FALSE; /* only for single select list */
@@ -2389,6 +2446,7 @@
INT caret = -1;
WCHAR str[2];
+ERR("\n");
str[0] = charW;
str[1] = '\0';
@@ -2422,6 +2480,7 @@
MEASUREITEMSTRUCT mis;
RECT rect;
+ERR("\n");
if (!(descr = HeapAlloc( GetProcessHeap(), 0, sizeof(*descr) )))
return FALSE;
@@ -2451,6 +2510,7 @@
descr->font = 0;
descr->locale = 0; /* FIXME */
descr->lphc = lphc;
+// descr->painting = FALSE;
if (is_old_app(descr) && ( descr->style & ( WS_VSCROLL | WS_HSCROLL ) ) )
{
@@ -2508,6 +2568,7 @@
*/
static BOOL LISTBOX_Destroy( LB_DESCR *descr )
{
+ERR("\n");
LISTBOX_ResetContent( descr );
SetWindowLongW( descr->self, 0, 0 );
HeapFree( GetProcessHeap(), 0, descr );
@@ -2525,6 +2586,7 @@
LPHEADCOMBO lphc = 0;
LRESULT ret;
+ERR("msg=%u\n",msg);
if (!descr)
{
if (!IsWindow(hwnd)) return 0;
@@ -3148,6 +3210,7 @@
*/
static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
+ERR("\n");
return ListBoxWndProc_common( hwnd, msg, wParam, lParam, FALSE );
}
@@ -3156,5 +3219,6 @@
*/
static LRESULT WINAPI ListBoxWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
+ERR("\n");
return ListBoxWndProc_common( hwnd, msg, wParam, lParam, TRUE );
}
More information about the wine-devel
mailing list