Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
71be0944
Commit
71be0944
authored
Apr 18, 2005
by
Vitaliy Margolen
Committed by
Alexandre Julliard
Apr 18, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Don't redraw if no information has changed.
Fixed endless redraw loop if app using callback for images and/or text. Keep color changes made by app for the current draw cycle.
parent
a8d8b52d
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
104 additions
and
84 deletions
+104
-84
treeview.c
dlls/comctl32/treeview.c
+104
-84
No files found.
dlls/comctl32/treeview.c
View file @
71be0944
...
...
@@ -241,6 +241,39 @@ TREEVIEW_GetItemIndex(TREEVIEW_INFO *infoPtr, HTREEITEM handle)
return
DPA_GetPtrIndex
(
infoPtr
->
items
,
handle
);
}
/* Checks if item has changed and needs to be redrawn */
static
inline
BOOL
item_changed
(
TREEVIEW_ITEM
*
tiOld
,
TREEVIEW_ITEM
*
tiNew
,
LPTVITEMEXW
tvChange
)
{
/* Number of children has changed */
if
((
tvChange
->
mask
&
TVIF_CHILDREN
)
&&
(
tiOld
->
cChildren
!=
tiNew
->
cChildren
))
return
TRUE
;
/* Image has changed and it's not a callback */
if
((
tvChange
->
mask
&
TVIF_IMAGE
)
&&
(
tiOld
->
iImage
!=
tiNew
->
iImage
)
&&
tiNew
->
iImage
!=
I_IMAGECALLBACK
)
return
TRUE
;
/* Selected image has changed and it's not a callback */
if
((
tvChange
->
mask
&
TVIF_SELECTEDIMAGE
)
&&
(
tiOld
->
iSelectedImage
!=
tiNew
->
iSelectedImage
)
&&
tiNew
->
iSelectedImage
!=
I_IMAGECALLBACK
)
return
TRUE
;
/* Text has changed and it's not a callback */
if
((
tvChange
->
mask
&
TVIF_TEXT
)
&&
(
tiOld
->
pszText
!=
tiNew
->
pszText
)
&&
tiNew
->
pszText
!=
LPSTR_TEXTCALLBACKW
)
return
TRUE
;
/* Indent has changed */
if
((
tvChange
->
mask
&
TVIF_INTEGRAL
)
&&
(
tiOld
->
iIntegral
!=
tiNew
->
iIntegral
))
return
TRUE
;
/* Item state has changed */
if
((
tvChange
->
mask
&
TVIF_STATE
)
&&
((
tiOld
->
state
^
tiNew
->
state
)
&
tvChange
->
stateMask
))
return
TRUE
;
return
FALSE
;
}
/***************************************************************************
* This method checks that handle is an item for this tree.
*/
...
...
@@ -616,10 +649,10 @@ TREEVIEW_SendCustomDrawNotify(TREEVIEW_INFO *infoPtr, DWORD dwDrawStage,
static
BOOL
TREEVIEW_SendCustomDrawItemNotify
(
TREEVIEW_INFO
*
infoPtr
,
HDC
hdc
,
TREEVIEW_ITEM
*
wineItem
,
UINT
uItemDrawState
)
TREEVIEW_ITEM
*
wineItem
,
UINT
uItemDrawState
,
NMTVCUSTOMDRAW
*
nmcdhdr
)
{
HWND
hwnd
=
infoPtr
->
hwnd
;
NMTVCUSTOMDRAW
nmcdhdr
;
LPNMCUSTOMDRAW
nmcd
;
DWORD
dwDrawStage
,
dwItemSpec
;
UINT
uItemState
;
...
...
@@ -635,7 +668,7 @@ TREEVIEW_SendCustomDrawItemNotify(TREEVIEW_INFO *infoPtr, HDC hdc,
if
(
wineItem
==
infoPtr
->
hotItem
)
uItemState
|=
CDIS_HOT
;
nmcd
=
&
nmcdhdr
.
nmcd
;
nmcd
=
&
nmcdhdr
->
nmcd
;
nmcd
->
hdr
.
hwndFrom
=
hwnd
;
nmcd
->
hdr
.
idFrom
=
GetWindowLongPtrW
(
hwnd
,
GWLP_ID
);
nmcd
->
hdr
.
code
=
NM_CUSTOMDRAW
;
...
...
@@ -645,9 +678,7 @@ TREEVIEW_SendCustomDrawItemNotify(TREEVIEW_INFO *infoPtr, HDC hdc,
nmcd
->
dwItemSpec
=
dwItemSpec
;
nmcd
->
uItemState
=
uItemState
;
nmcd
->
lItemlParam
=
wineItem
->
lParam
;
nmcdhdr
.
clrText
=
infoPtr
->
clrText
;
nmcdhdr
.
clrTextBk
=
infoPtr
->
clrBk
;
nmcdhdr
.
iLevel
=
wineItem
->
iLevel
;
nmcdhdr
->
iLevel
=
wineItem
->
iLevel
;
TRACE
(
"drawstage:%lx hdc:%p item:%lx, itemstate:%x, lItemlParam:%lx
\n
"
,
nmcd
->
dwDrawStage
,
nmcd
->
hdc
,
nmcd
->
dwItemSpec
,
...
...
@@ -655,7 +686,7 @@ TREEVIEW_SendCustomDrawItemNotify(TREEVIEW_INFO *infoPtr, HDC hdc,
retval
=
TREEVIEW_SendRealNotify
(
infoPtr
,
(
WPARAM
)
nmcd
->
hdr
.
idFrom
,
(
LPARAM
)
&
nmcdhdr
);
(
LPARAM
)
nmcdhdr
);
return
(
BOOL
)
retval
;
}
...
...
@@ -2114,9 +2145,8 @@ TREEVIEW_SetItemT(TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
/* The refresh updates everything, but we can't wait until then. */
TREEVIEW_ComputeItemInternalMetrics
(
infoPtr
,
wineItem
);
/* if any of the items values changed, redraw the item */
if
(
memcmp
(
&
originalItem
,
wineItem
,
sizeof
(
TREEVIEW_ITEM
))
||
(
tvItem
->
stateMask
&
TVIS_BOLD
))
/* if any of the item's values changed and it's not a callback, redraw the item */
if
(
item_changed
(
&
originalItem
,
wineItem
,
tvItem
))
{
if
(
tvItem
->
mask
&
TVIF_INTEGRAL
)
{
...
...
@@ -2265,10 +2295,14 @@ TREEVIEW_DrawItemLines(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *item)
BOOL
lar
=
((
infoPtr
->
dwStyle
&
(
TVS_LINESATROOT
|
TVS_HASLINES
|
TVS_HASBUTTONS
))
>
TVS_LINESATROOT
);
HBRUSH
hbr
,
hbrOld
;
if
(
!
lar
&&
item
->
iLevel
==
0
)
return
;
hbr
=
CreateSolidBrush
(
infoPtr
->
clrBk
);
hbrOld
=
SelectObject
(
hdc
,
hbr
);
centerx
=
(
item
->
linesOffset
+
item
->
stateOffset
)
/
2
;
centery
=
(
item
->
rect
.
top
+
item
->
rect
.
bottom
)
/
2
;
...
...
@@ -2335,15 +2369,10 @@ TREEVIEW_DrawItemLines(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *item)
HPEN
hNewPen
=
CreatePen
(
PS_SOLID
,
0
,
infoPtr
->
clrLine
);
HPEN
hOldPen
=
SelectObject
(
hdc
,
hNewPen
);
HBRUSH
hbr
=
CreateSolidBrush
(
infoPtr
->
clrBk
);
HBRUSH
hbrOld
=
SelectObject
(
hdc
,
hbr
);
Rectangle
(
hdc
,
centerx
-
rectsize
-
1
,
centery
-
rectsize
-
1
,
centerx
+
rectsize
+
2
,
centery
+
rectsize
+
2
);
SelectObject
(
hdc
,
hbrOld
);
DeleteObject
(
hbr
);
SelectObject
(
hdc
,
hOldPen
);
DeleteObject
(
hNewPen
);
...
...
@@ -2373,6 +2402,8 @@ TREEVIEW_DrawItemLines(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *item)
}
}
}
SelectObject
(
hdc
,
hbrOld
);
DeleteObject
(
hbr
);
}
static
void
...
...
@@ -2380,12 +2411,50 @@ TREEVIEW_DrawItem(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem)
{
INT
cditem
;
HFONT
hOldFont
;
COLORREF
oldTextColor
,
oldTextBkColor
;
int
centery
;
hOldFont
=
SelectObject
(
hdc
,
TREEVIEW_FontForItem
(
infoPtr
,
wineItem
))
;
BOOL
inFocus
=
(
GetFocus
()
==
infoPtr
->
hwnd
);
NMTVCUSTOMDRAW
nmcdhdr
;
TREEVIEW_UpdateDispInfo
(
infoPtr
,
wineItem
,
CALLBACK_MASK_ALL
);
/* - If item is drop target or it is selected and window is in focus -
* use blue background (COLOR_HIGHLIGHT).
* - If item is selected, window is not in focus, but it has style
* TVS_SHOWSELALWAYS - use grey background (COLOR_BTNFACE)
* - Otherwise - use background color
*/
if
((
wineItem
->
state
&
TVIS_DROPHILITED
)
||
((
wineItem
==
infoPtr
->
focusedItem
)
&&
!
(
wineItem
->
state
&
TVIS_SELECTED
))
||
((
wineItem
->
state
&
TVIS_SELECTED
)
&&
(
!
infoPtr
->
focusedItem
)
&&
(
inFocus
||
(
infoPtr
->
dwStyle
&
TVS_SHOWSELALWAYS
))))
{
if
((
wineItem
->
state
&
TVIS_DROPHILITED
)
||
inFocus
)
{
nmcdhdr
.
clrTextBk
=
GetSysColor
(
COLOR_HIGHLIGHT
);
nmcdhdr
.
clrText
=
GetSysColor
(
COLOR_HIGHLIGHTTEXT
);
}
else
{
nmcdhdr
.
clrTextBk
=
GetSysColor
(
COLOR_BTNFACE
);
if
(
infoPtr
->
clrText
==
-
1
)
nmcdhdr
.
clrText
=
GetSysColor
(
COLOR_WINDOWTEXT
);
else
nmcdhdr
.
clrText
=
infoPtr
->
clrText
;
}
}
else
{
nmcdhdr
.
clrTextBk
=
infoPtr
->
clrBk
;
if
((
infoPtr
->
dwStyle
&
TVS_TRACKSELECT
)
&&
(
wineItem
==
infoPtr
->
hotItem
))
nmcdhdr
.
clrText
=
comctl32_color
.
clrHighlight
;
else
if
(
infoPtr
->
clrText
==
-
1
)
nmcdhdr
.
clrText
=
GetSysColor
(
COLOR_WINDOWTEXT
);
else
nmcdhdr
.
clrText
=
infoPtr
->
clrText
;
}
hOldFont
=
SelectObject
(
hdc
,
TREEVIEW_FontForItem
(
infoPtr
,
wineItem
));
/* The custom draw handler can query the text rectangle,
* so get ready. */
/* should already be known, set to 0 when changed */
...
...
@@ -2397,7 +2466,7 @@ TREEVIEW_DrawItem(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem)
if
(
infoPtr
->
cdmode
&
CDRF_NOTIFYITEMDRAW
)
{
cditem
=
TREEVIEW_SendCustomDrawItemNotify
(
infoPtr
,
hdc
,
wineItem
,
CDDS_ITEMPREPAINT
);
(
infoPtr
,
hdc
,
wineItem
,
CDDS_ITEMPREPAINT
,
&
nmcdhdr
);
TRACE
(
"prepaint:cditem-app returns 0x%x
\n
"
,
cditem
);
if
(
cditem
&
CDRF_SKIPDEFAULT
)
...
...
@@ -2412,6 +2481,10 @@ TREEVIEW_DrawItem(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem)
TREEVIEW_DrawItemLines
(
infoPtr
,
hdc
,
wineItem
);
/* Set colors. Custom draw handler can change these so we do this after it. */
oldTextColor
=
SetTextColor
(
hdc
,
nmcdhdr
.
clrText
);
oldTextBkColor
=
SetBkColor
(
hdc
,
nmcdhdr
.
clrTextBk
);
centery
=
(
wineItem
->
rect
.
top
+
wineItem
->
rect
.
bottom
)
/
2
;
/*
...
...
@@ -2469,87 +2542,31 @@ TREEVIEW_DrawItem(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem)
{
if
(
wineItem
->
pszText
)
{
COLORREF
oldTextColor
=
0
;
INT
oldBkMode
;
HBRUSH
hbrBk
=
0
;
BOOL
inFocus
=
(
GetFocus
()
==
infoPtr
->
hwnd
);
RECT
rcText
;
oldBkMode
=
SetBkMode
(
hdc
,
TRANSPARENT
);
/* - If item is drop target or it is selected and window is in focus -
* use blue background (COLOR_HIGHLIGHT).
* - If item is selected, window is not in focus, but it has style
* TVS_SHOWSELALWAYS - use grey background (COLOR_BTNFACE)
* - Otherwise - don't fill background
*/
if
((
wineItem
->
state
&
TVIS_DROPHILITED
)
||
((
wineItem
==
infoPtr
->
focusedItem
)
&&
!
(
wineItem
->
state
&
TVIS_SELECTED
))
||
((
wineItem
->
state
&
TVIS_SELECTED
)
&&
(
!
infoPtr
->
focusedItem
)
&&
(
inFocus
||
(
infoPtr
->
dwStyle
&
TVS_SHOWSELALWAYS
))))
{
if
((
wineItem
->
state
&
TVIS_DROPHILITED
)
||
inFocus
)
{
hbrBk
=
CreateSolidBrush
(
GetSysColor
(
COLOR_HIGHLIGHT
));
oldTextColor
=
SetTextColor
(
hdc
,
GetSysColor
(
COLOR_HIGHLIGHTTEXT
));
}
else
{
hbrBk
=
CreateSolidBrush
(
GetSysColor
(
COLOR_BTNFACE
));
if
(
infoPtr
->
clrText
==
-
1
)
oldTextColor
=
SetTextColor
(
hdc
,
GetSysColor
(
COLOR_WINDOWTEXT
));
else
oldTextColor
=
SetTextColor
(
hdc
,
infoPtr
->
clrText
);
}
}
else
{
if
((
infoPtr
->
dwStyle
&
TVS_TRACKSELECT
)
&&
(
wineItem
==
infoPtr
->
hotItem
))
oldTextColor
=
SetTextColor
(
hdc
,
comctl32_color
.
clrHighlight
);
else
if
(
infoPtr
->
clrText
==
-
1
)
oldTextColor
=
SetTextColor
(
hdc
,
GetSysColor
(
COLOR_WINDOWTEXT
));
else
oldTextColor
=
SetTextColor
(
hdc
,
infoPtr
->
clrText
);
}
rcText
.
top
=
wineItem
->
rect
.
top
;
rcText
.
bottom
=
wineItem
->
rect
.
bottom
;
rcText
.
left
=
wineItem
->
textOffset
;
rcText
.
right
=
rcText
.
left
+
wineItem
->
textWidth
+
4
;
if
(
hbrBk
)
{
FillRect
(
hdc
,
&
rcText
,
hbrBk
);
DeleteObject
(
hbrBk
);
}
/* Draw the box around the selected item */
if
((
wineItem
==
infoPtr
->
selectedItem
)
&&
inFocus
)
{
DrawFocusRect
(
hdc
,
&
rcText
);
}
InflateRect
(
&
rcText
,
-
2
,
-
1
);
/* allow for the focus rect */
TRACE
(
"drawing text %s at (%ld,%ld)-(%ld,%ld)
\n
"
,
debugstr_w
(
wineItem
->
pszText
),
rcText
.
left
,
rcText
.
top
,
rcText
.
right
,
rcText
.
bottom
);
/* Draw it */
DrawTextW
(
hdc
,
ExtTextOutW
(
hdc
,
rcText
.
left
+
2
,
rcText
.
top
+
1
,
ETO_CLIPPED
|
ETO_OPAQUE
,
&
rcText
,
wineItem
->
pszText
,
lstrlenW
(
wineItem
->
pszText
),
&
rcText
,
DT_CENTER
|
DT_VCENTER
|
DT_SINGLELINE
|
DT_NOPREFIX
);
NULL
);
/* Restore the hdc state */
SetTextColor
(
hdc
,
oldTextColor
);
/* Draw the box around the selected item */
if
((
wineItem
==
infoPtr
->
selectedItem
)
&&
inFocus
)
{
DrawFocusRect
(
hdc
,
&
rcText
);
}
if
(
oldBkMode
!=
TRANSPARENT
)
SetBkMode
(
hdc
,
oldBkMode
);
}
}
...
...
@@ -2593,10 +2610,13 @@ TREEVIEW_DrawItem(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem)
if
(
cditem
&
CDRF_NOTIFYPOSTPAINT
)
{
cditem
=
TREEVIEW_SendCustomDrawItemNotify
(
infoPtr
,
hdc
,
wineItem
,
CDDS_ITEMPOSTPAINT
);
(
infoPtr
,
hdc
,
wineItem
,
CDDS_ITEMPOSTPAINT
,
&
nmcdhdr
);
TRACE
(
"postpaint:cditem-app returns 0x%x
\n
"
,
cditem
);
}
/* Restore the hdc state */
SetTextColor
(
hdc
,
oldTextColor
);
SetBkColor
(
hdc
,
oldTextBkColor
);
SelectObject
(
hdc
,
hOldFont
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment