Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
80593bf8
Commit
80593bf8
authored
Oct 11, 2001
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Removed next and child fields in the window structure and use
WIN_ListChildren instead.
parent
d30d2d8e
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
319 additions
and
297 deletions
+319
-297
wnd.c
dlls/ttydrv/wnd.c
+36
-24
scroll.c
dlls/x11drv/scroll.c
+20
-14
winpos.c
dlls/x11drv/winpos.c
+41
-48
win.h
include/win.h
+2
-4
property.c
windows/property.c
+4
-1
win.c
windows/win.c
+106
-106
winpos.c
windows/winpos.c
+110
-100
No files found.
dlls/ttydrv/wnd.c
View file @
80593bf8
...
...
@@ -175,28 +175,36 @@ fail:
* adding to the clip region the intersection of the target rectangle
* with an offset window rectangle.
*/
static
BOOL
DCE_AddClipRects
(
HWND
star
t
,
HWND
end
,
HRGN
hrgnClip
,
LPRECT
lpRect
,
int
x
,
int
y
)
static
void
DCE_AddClipRects
(
HWND
paren
t
,
HWND
end
,
HRGN
hrgnClip
,
LPRECT
lpRect
,
int
x
,
int
y
)
{
RECT
rect
;
WND
*
pWnd
;
int
i
;
HWND
*
list
=
WIN_ListChildren
(
parent
);
for
(
pWnd
=
WIN_FindWndPtr
(
start
);
(
pWnd
&&
(
pWnd
->
hwndSelf
!=
end
));
WIN_UpdateWndPtr
(
&
pWnd
,
pWnd
->
next
))
if
(
!
list
)
return
;
for
(
i
=
0
;
list
[
i
];
i
++
)
{
if
(
!
(
pWnd
->
dwStyle
&
WS_VISIBLE
)
)
continue
;
rect
.
left
=
pWnd
->
rectWindow
.
left
+
x
;
rect
.
top
=
pWnd
->
rectWindow
.
top
+
y
;
rect
.
right
=
pWnd
->
rectWindow
.
right
+
x
;
rect
.
bottom
=
pWnd
->
rectWindow
.
bottom
+
y
;
if
(
IntersectRect
(
&
rect
,
&
rect
,
lpRect
))
if
(
list
[
i
]
==
end
)
break
;
if
(
!
(
pWnd
=
WIN_FindWndPtr
(
list
[
i
]
)))
continue
;
if
(
pWnd
->
dwStyle
&
WS_VISIBLE
)
{
if
(
!
REGION_UnionRectWithRgn
(
hrgnClip
,
&
rect
))
break
;
rect
.
left
=
pWnd
->
rectWindow
.
left
+
x
;
rect
.
top
=
pWnd
->
rectWindow
.
top
+
y
;
rect
.
right
=
pWnd
->
rectWindow
.
right
+
x
;
rect
.
bottom
=
pWnd
->
rectWindow
.
bottom
+
y
;
if
(
IntersectRect
(
&
rect
,
&
rect
,
lpRect
))
{
if
(
!
REGION_UnionRectWithRgn
(
hrgnClip
,
&
rect
))
{
WIN_ReleaseWndPtr
(
pWnd
);
break
;
}
}
}
WIN_ReleaseWndPtr
(
pWnd
);
}
start
=
pWnd
->
hwndSelf
;
WIN_ReleaseWndPtr
(
pWnd
);
return
(
start
==
end
);
HeapFree
(
GetProcessHeap
(),
0
,
list
);
}
...
...
@@ -230,7 +238,7 @@ static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
* DCE_GetVisRect() returns a rectangle either in client
* or in window coordinates (for DCX_WINDOW request). */
if
(
(
flags
&
DCX_CLIPCHILDREN
)
&&
wndPtr
->
child
)
if
(
flags
&
DCX_CLIPCHILDREN
)
{
if
(
flags
&
DCX_WINDOW
)
{
...
...
@@ -243,7 +251,7 @@ static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
else
xoffset
=
yoffset
=
0
;
DCE_AddClipRects
(
wndPtr
->
child
->
hwndSelf
,
0
,
hrgnClip
,
&
rect
,
xoffset
,
yoffset
);
DCE_AddClipRects
(
wndPtr
->
hwndSelf
,
0
,
hrgnClip
,
&
rect
,
xoffset
,
yoffset
);
}
/* We may need to clip children of child window, if a window with PARENTDC
...
...
@@ -251,7 +259,7 @@ static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
* preference dialogs) gets here, we take the region for the parent window
* but apparently still need to clip the children of the child window... */
if
(
(
cflags
&
DCX_CLIPCHILDREN
)
&&
childWnd
&&
childWnd
->
child
)
if
(
(
cflags
&
DCX_CLIPCHILDREN
)
&&
childWnd
)
{
if
(
flags
&
DCX_WINDOW
)
{
...
...
@@ -268,7 +276,7 @@ static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
xoffset
+=
childWnd
->
rectClient
.
left
;
yoffset
+=
childWnd
->
rectClient
.
top
;
DCE_AddClipRects
(
childWnd
->
child
->
hwndSelf
,
0
,
hrgnClip
,
DCE_AddClipRects
(
childWnd
->
hwndSelf
,
0
,
hrgnClip
,
&
rect
,
xoffset
,
yoffset
);
}
...
...
@@ -287,8 +295,8 @@ static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
}
if
(
flags
&
DCX_CLIPSIBLINGS
&&
wndPtr
->
parent
)
DCE_AddClipRects
(
GetWindow
(
wndPtr
->
hwndSelf
,
GW_HWNDFIRST
)
,
wndPtr
->
hwndSelf
,
hrgnClip
,
&
rect
,
xoffset
,
yoffset
);
DCE_AddClipRects
(
wndPtr
->
parent
,
wndPtr
->
hwndSelf
,
hrgnClip
,
&
rect
,
xoffset
,
yoffset
);
/* Clip siblings of all ancestors that have the
* WS_CLIPSIBLINGS style
...
...
@@ -303,8 +311,8 @@ static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags, HWND hwndChild, WORD cflags )
yoffset
-=
wndPtr
->
rectClient
.
top
;
if
(
wndPtr
->
dwStyle
&
WS_CLIPSIBLINGS
&&
wndPtr
->
parent
)
{
DCE_AddClipRects
(
GetWindow
(
wndPtr
->
hwndSelf
,
GW_HWNDFIRST
)
,
wndPtr
->
hwndSelf
,
hrgnClip
,
&
rect
,
xoffset
,
yoffset
);
DCE_AddClipRects
(
wndPtr
->
parent
,
wndPtr
->
hwndSelf
,
hrgnClip
,
&
rect
,
xoffset
,
yoffset
);
}
}
...
...
@@ -501,7 +509,8 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
/* don't need to change the Zorder of hwnd if it's already inserted
* after hwndInsertAfter or when inserting hwnd after itself.
*/
if
((
wnd
->
next
==
wndPtr
)
||
(
winpos
->
hwnd
==
winpos
->
hwndInsertAfter
))
if
((
winpos
->
hwnd
==
winpos
->
hwndInsertAfter
)
||
(
winpos
->
hwnd
==
GetWindow
(
winpos
->
hwndInsertAfter
,
GW_HWNDNEXT
)))
winpos
->
flags
|=
SWP_NOZORDER
;
}
WIN_ReleaseWndPtr
(
wnd
);
...
...
@@ -543,7 +552,10 @@ BOOL TTYDRV_SetWindowPos( WINDOWPOS *winpos )
}
else
if
(
winpos
->
hwndInsertAfter
==
HWND_BOTTOM
)
winpos
->
flags
|=
(
wndPtr
->
next
)
?
0
:
SWP_NOZORDER
;
{
if
(
!
GetWindow
(
wndPtr
->
hwndSelf
,
GW_HWNDNEXT
))
winpos
->
flags
|=
SWP_NOZORDER
;
}
else
if
(
!
(
winpos
->
flags
&
SWP_NOZORDER
)
)
if
(
GetWindow
(
winpos
->
hwndInsertAfter
,
GW_HWNDNEXT
)
==
wndPtr
->
hwndSelf
)
...
...
dlls/x11drv/scroll.c
View file @
80593bf8
...
...
@@ -144,12 +144,14 @@ INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy,
RECT
rc
,
cliprc
;
WND
*
wnd
=
WIN_FindWndPtr
(
hwnd
);
if
(
!
wnd
||
!
WIN_IsWindowDrawable
(
wnd
,
TRUE
))
if
(
!
wnd
)
return
ERROR
;
if
(
!
WIN_IsWindowDrawable
(
wnd
,
TRUE
))
{
retVal
=
ERROR
;
goto
END
;
WIN_ReleaseWndPtr
(
wnd
)
;
return
ERROR
;
}
hwnd
=
wnd
->
hwndSelf
;
/* make it a full handle */
WIN_ReleaseWndPtr
(
wnd
);
GetClientRect
(
hwnd
,
&
rc
);
if
(
rect
)
IntersectRect
(
&
rc
,
&
rc
,
rect
);
...
...
@@ -203,16 +205,22 @@ INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy,
if
(
flags
&
SW_SCROLLCHILDREN
)
{
RECT
r
;
WND
*
w
;
for
(
w
=
WIN_LockWndPtr
(
wnd
->
child
);
w
;
WIN_UpdateWndPtr
(
&
w
,
w
->
next
)
)
HWND
*
list
=
WIN_ListChildren
(
hwnd
)
;
if
(
list
)
{
r
=
w
->
rectWindow
;
if
(
!
rect
||
IntersectRect
(
&
r
,
&
r
,
&
rc
)
)
SetWindowPos
(
w
->
hwndSelf
,
0
,
w
->
rectWindow
.
left
+
dx
,
w
->
rectWindow
.
top
+
dy
,
0
,
0
,
SWP_NOZORDER
|
SWP_NOSIZE
|
SWP_NOACTIVATE
|
SWP_NOREDRAW
|
SWP_DEFERERASE
);
int
i
;
RECT
r
,
dummy
;
for
(
i
=
0
;
list
[
i
];
i
++
)
{
GetWindowRect
(
list
[
i
],
&
r
);
MapWindowPoints
(
0
,
hwnd
,
(
POINT
*
)
&
r
,
2
);
if
(
!
rect
||
IntersectRect
(
&
dummy
,
&
r
,
&
rc
))
SetWindowPos
(
list
[
i
],
0
,
r
.
left
+
dx
,
r
.
top
+
dy
,
0
,
0
,
SWP_NOZORDER
|
SWP_NOSIZE
|
SWP_NOACTIVATE
|
SWP_NOREDRAW
|
SWP_DEFERERASE
);
}
HeapFree
(
GetProcessHeap
(),
0
,
list
);
}
}
...
...
@@ -230,7 +238,5 @@ INT X11DRV_ScrollWindowEx( HWND hwnd, INT dx, INT dy,
if
(
bOwnRgn
&&
hrgnUpdate
)
DeleteObject
(
hrgnUpdate
);
DeleteObject
(
hrgnClip
);
}
END:
WIN_ReleaseWndPtr
(
wnd
);
return
retVal
;
}
dlls/x11drv/winpos.c
View file @
80593bf8
...
...
@@ -707,7 +707,8 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
/* don't need to change the Zorder of hwnd if it's already inserted
* after hwndInsertAfter or when inserting hwnd after itself.
*/
if
((
wnd
->
next
==
wndPtr
)
||
(
winpos
->
hwnd
==
winpos
->
hwndInsertAfter
))
if
((
winpos
->
hwnd
==
winpos
->
hwndInsertAfter
)
||
(
winpos
->
hwnd
==
GetWindow
(
winpos
->
hwndInsertAfter
,
GW_HWNDNEXT
)))
winpos
->
flags
|=
SWP_NOZORDER
;
}
WIN_ReleaseWndPtr
(
wnd
);
...
...
@@ -1306,20 +1307,6 @@ void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event )
*
* Synchronize internal z-order with the window manager's.
*/
static
BOOL
__check_query_condition
(
WND
**
pWndA
,
WND
**
pWndB
)
{
/* return TRUE if we have at least two managed windows */
for
(
*
pWndB
=
NULL
;
*
pWndA
;
*
pWndA
=
(
*
pWndA
)
->
next
)
if
(
((
*
pWndA
)
->
dwExStyle
&
WS_EX_MANAGED
)
&&
((
*
pWndA
)
->
dwStyle
&
WS_VISIBLE
))
break
;
if
(
*
pWndA
)
for
(
*
pWndB
=
(
*
pWndA
)
->
next
;
*
pWndB
;
*
pWndB
=
(
*
pWndB
)
->
next
)
if
(
((
*
pWndB
)
->
dwExStyle
&
WS_EX_MANAGED
)
&&
((
*
pWndB
)
->
dwStyle
&
WS_VISIBLE
))
break
;
return
((
*
pWndB
)
!=
NULL
);
}
static
Window
__get_common_ancestor
(
Display
*
display
,
Window
A
,
Window
B
,
Window
**
children
,
unsigned
*
total
)
{
...
...
@@ -1369,29 +1356,39 @@ static unsigned __td_lookup( Window w, Window* list, unsigned max )
static
HWND
query_zorder
(
Display
*
display
,
HWND
hWndCheck
)
{
HWND
hwndInsertAfter
=
HWND_TOP
;
WND
*
pWndCheck
=
WIN_FindWndPtr
(
hWndCheck
);
WND
*
top
=
WIN_FindWndPtr
(
GetTopWindow
(
0
)
);
WND
*
pWnd
,
*
pWndZ
=
top
;
Window
w
,
parent
,
*
children
=
NULL
;
unsigned
total
,
check
,
pos
,
best
;
HWND
*
list
=
WIN_ListChildren
(
GetDesktopWindow
()
);
HWND
hwndA
=
0
,
hwndB
=
0
;
WND
*
win
;
int
i
;
if
(
!
__check_query_condition
(
&
pWndZ
,
&
pWnd
)
)
/* find at least two managed windows */
if
(
!
list
)
return
0
;
for
(
i
=
0
;
list
[
i
];
i
++
)
{
WIN_ReleaseWndPtr
(
pWndCheck
);
WIN_ReleaseWndPtr
(
top
);
return
hwndInsertAfter
;
if
(
!
(
win
=
WIN_FindWndPtr
(
list
[
i
]
)))
continue
;
if
((
win
->
dwExStyle
&
WS_EX_MANAGED
)
&&
(
win
->
dwStyle
&
WS_VISIBLE
))
{
if
(
!
hwndA
)
hwndA
=
list
[
i
];
else
{
hwndB
=
list
[
i
];
WIN_ReleaseWndPtr
(
win
);
break
;
}
}
WIN_ReleaseWndPtr
(
win
);
}
WIN_LockWndPtr
(
pWndZ
);
WIN_LockWndPtr
(
pWnd
);
WIN_ReleaseWndPtr
(
top
);
if
(
!
hwndA
||
!
hwndB
)
goto
done
;
parent
=
__get_common_ancestor
(
display
,
get_whole_window
(
pWndZ
),
get_whole_window
(
pWnd
),
&
children
,
&
total
);
parent
=
__get_common_ancestor
(
display
,
X11DRV_get_whole_window
(
hwndA
),
X11DRV_get_whole_window
(
hwndB
),
&
children
,
&
total
);
if
(
parent
&&
children
)
{
/* w is the ancestor if
p
WndCheck that is a direct descendant of 'parent' */
/* w is the ancestor if
h
WndCheck that is a direct descendant of 'parent' */
w
=
__get_top_decoration
(
display
,
get_whole_window
(
p
WndCheck
),
parent
);
w
=
__get_top_decoration
(
display
,
X11DRV_get_whole_window
(
h
WndCheck
),
parent
);
if
(
w
!=
children
[
total
-
1
]
)
/* check if at the top */
{
...
...
@@ -1399,32 +1396,28 @@ static HWND query_zorder( Display *display, HWND hWndCheck)
check
=
__td_lookup
(
w
,
children
,
total
);
best
=
total
;
for
(
WIN_UpdateWndPtr
(
&
pWnd
,
pWndZ
);
pWnd
;
WIN_UpdateWndPtr
(
&
pWnd
,
pWnd
->
next
))
/* go through all windows in Wine z-order... */
for
(
i
=
0
;
list
[
i
];
i
++
)
{
/* go through all windows in Wine z-order... */
if
(
pWnd
!=
pWndCheck
)
if
(
list
[
i
]
==
hWndCheck
)
continue
;
if
(
!
(
GetWindowLongW
(
list
[
i
],
GWL_EXSTYLE
)
&
WS_EX_MANAGED
))
continue
;
if
(
!
(
w
=
__get_top_decoration
(
display
,
X11DRV_get_whole_window
(
list
[
i
]),
parent
)))
continue
;
pos
=
__td_lookup
(
w
,
children
,
total
);
if
(
pos
<
best
&&
pos
>
check
)
{
if
(
!
(
pWnd
->
dwExStyle
&
WS_EX_MANAGED
)
||
!
(
w
=
__get_top_decoration
(
display
,
get_whole_window
(
pWnd
),
parent
))
)
continue
;
pos
=
__td_lookup
(
w
,
children
,
total
);
if
(
pos
<
best
&&
pos
>
check
)
{
/* find a nearest Wine window precedes
* pWndCheck in the real z-order... */
best
=
pos
;
hwndInsertAfter
=
pWnd
->
hwndSelf
;
}
if
(
best
-
check
==
1
)
break
;
/* find a nearest Wine window precedes hWndCheck in the real z-order */
best
=
pos
;
hwndInsertAfter
=
list
[
i
];
}
if
(
best
-
check
==
1
)
break
;
}
}
}
if
(
children
)
TSXFree
(
children
);
WIN_ReleaseWndPtr
(
pWnd
);
WIN_ReleaseWndPtr
(
pWndZ
);
WIN_ReleaseWndPtr
(
pWndCheck
);
done:
HeapFree
(
GetProcessHeap
(),
0
,
list
);
return
hwndInsertAfter
;
}
...
...
include/win.h
View file @
80593bf8
...
...
@@ -22,15 +22,13 @@ struct tagMESSAGEQUEUE;
typedef
struct
tagWND
{
struct
tagWND
*
next
;
/* Next sibling */
struct
tagWND
*
child
;
/* First child */
HWND
hwndSelf
;
/* Handle of this window */
HWND
parent
;
/* Window parent */
HWND
owner
;
/* Window owner */
struct
tagCLASS
*
class
;
/* Window class */
HWINDOWPROC
winproc
;
/* Window procedure */
DWORD
dwMagic
;
/* Magic number (must be WND_MAGIC) */
DWORD
tid
;
/* Owner thread id */
HWND
hwndSelf
;
/* Handle of this window */
HINSTANCE
hInstance
;
/* Window hInstance (from CreateWindow) */
RECT
rectClient
;
/* Client area rel. to parent client area */
RECT
rectWindow
;
/* Whole window rel. to parent client area */
...
...
@@ -124,7 +122,7 @@ extern void CARET_GetRect(LPRECT lprc); /* windows/caret.c */
extern
BOOL16
DRAG_QueryUpdate
(
HWND
,
SEGPTR
,
BOOL
);
extern
HBRUSH
DEFWND_ControlColor
(
HDC
hDC
,
UINT
ctlType
);
/* windows/defwnd.c */
extern
void
PROPERTY_RemoveWindowProps
(
WND
*
pWnd
);
/* windows/property.c */
extern
void
PROPERTY_RemoveWindowProps
(
HWND
hwnd
);
/* windows/property.c */
/* Classes functions */
struct
tagCLASS
;
/* opaque structure */
...
...
windows/property.c
View file @
80593bf8
...
...
@@ -231,10 +231,12 @@ HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
*
* Remove all properties of a window.
*/
void
PROPERTY_RemoveWindowProps
(
WND
*
pW
nd
)
void
PROPERTY_RemoveWindowProps
(
HWND
hw
nd
)
{
PROPERTY
*
prop
,
*
next
;
WND
*
pWnd
=
WIN_FindWndPtr
(
hwnd
);
if
(
!
pWnd
)
return
;
for
(
prop
=
pWnd
->
pProp
;
(
prop
);
prop
=
next
)
{
next
=
prop
->
next
;
...
...
@@ -242,6 +244,7 @@ void PROPERTY_RemoveWindowProps( WND *pWnd )
HeapFree
(
GetProcessHeap
(),
0
,
prop
);
}
pWnd
->
pProp
=
NULL
;
WIN_ReleaseWndPtr
(
pWnd
);
}
...
...
windows/win.c
View file @
80593bf8
...
...
@@ -383,16 +383,8 @@ void WIN_UnlinkWindow( HWND hwnd )
*/
void
WIN_LinkWindow
(
HWND
hwnd
,
HWND
parent
,
HWND
hwndInsertAfter
)
{
WND
*
wndPtr
,
**
ppWnd
,
*
parentPtr
=
NULL
;
BOOL
ret
;
if
(
!
(
wndPtr
=
WIN_FindWndPtr
(
hwnd
)))
return
;
if
(
parent
&&
!
(
parentPtr
=
WIN_FindWndPtr
(
parent
)))
{
WIN_ReleaseWndPtr
(
wndPtr
);
return
;
}
SERVER_START_REQ
(
link_window
)
{
req
->
handle
=
hwnd
;
...
...
@@ -401,42 +393,88 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
ret
=
!
SERVER_CALL_ERR
();
}
SERVER_END_REQ
;
if
(
!
ret
)
goto
done
;
/* first unlink it if it is linked */
if
(
wndPtr
->
parent
)
if
(
ret
&&
parent
)
{
WND
*
ptr
=
WIN_FindWndPtr
(
wndPtr
->
parent
);
ppWnd
=
&
ptr
->
child
;
while
(
*
ppWnd
&&
*
ppWnd
!=
wndPtr
)
ppWnd
=
&
(
*
ppWnd
)
->
next
;
if
(
*
ppWnd
)
*
ppWnd
=
wndPtr
->
next
;
WIN_ReleaseWndPtr
(
ptr
);
WND
*
wndPtr
=
WIN_FindWndPtr
(
hwnd
);
if
(
wndPtr
)
{
wndPtr
->
parent
=
WIN_GetFullHandle
(
parent
);
WIN_ReleaseWndPtr
(
wndPtr
);
}
}
}
/***********************************************************************
* find_child_to_repaint
*
* Find a window that needs repaint among the children of the specified window.
*/
static
HWND
find_child_to_repaint
(
HWND
parent
)
{
int
i
;
HWND
ret
=
0
;
HWND
*
list
;
if
(
!
parent
)
parent
=
GetDesktopWindow
();
if
(
!
(
list
=
list_window_children
(
parent
,
0
,
0
)))
return
0
;
if
(
parentPtr
)
for
(
i
=
0
;
list
[
i
]
&&
!
ret
;
i
++
)
{
wndPtr
->
parent
=
parentPtr
->
hwndSelf
;
if
((
hwndInsertAfter
==
HWND_TOP
)
||
(
hwndInsertAfter
==
HWND_BOTTOM
))
WND
*
win
=
WIN_GetWndPtr
(
list
[
i
]
);
if
(
win
==
BAD_WND_PTR
)
continue
;
/* ignore it */
if
(
!
win
)
{
ppWnd
=
&
parentPtr
->
child
;
/* Point to first sibling hwnd
*/
if
(
hwndInsertAfter
==
HWND_BOTTOM
)
/* Find last sibling hwnd */
while
(
*
ppWnd
)
ppWnd
=
&
(
*
ppWnd
)
->
next
;
/* doesn't belong to this process, but check children
*/
ret
=
find_child_to_repaint
(
list
[
i
]
);
continue
;
}
else
/* Normal case */
if
(
!
(
win
->
dwStyle
&
WS_VISIBLE
))
{
WND
*
afterPtr
=
WIN_FindWndPtr
(
hwndInsertAfter
);
if
(
!
afterPtr
)
goto
done
;
ppWnd
=
&
afterPtr
->
next
;
WIN_ReleaseWndPtr
(
afterPtr
);
USER_Unlock
();
continue
;
}
if
((
win
->
tid
!=
GetCurrentThreadId
())
||
(
!
win
->
hrgnUpdate
&&
!
(
win
->
flags
&
WIN_INTERNAL_PAINT
)))
{
/* does not need repaint, check children */
USER_Unlock
();
ret
=
find_child_to_repaint
(
list
[
i
]
);
continue
;
}
wndPtr
->
next
=
*
ppWnd
;
*
ppWnd
=
wndPtr
;
}
else
wndPtr
->
next
=
NULL
;
/* unlinked */
done:
WIN_ReleaseWndPtr
(
parentPtr
);
WIN_ReleaseWndPtr
(
wndPtr
);
/* now we have something */
ret
=
list
[
i
];
if
(
!
(
win
->
dwExStyle
&
WS_EX_TRANSPARENT
))
{
/* not transparent, we can repaint it */
USER_Unlock
();
break
;
}
USER_Unlock
();
/* transparent window, look for non-transparent sibling to paint first */
for
(
i
++
;
list
[
i
];
i
++
)
{
if
(
!
(
win
=
WIN_GetWndPtr
(
list
[
i
]
)))
continue
;
if
(
win
==
BAD_WND_PTR
)
continue
;
if
(
!
(
win
->
dwStyle
&
WS_VISIBLE
))
{
USER_Unlock
();
continue
;
}
if
(
!
(
win
->
dwExStyle
&
WS_EX_TRANSPARENT
)
&&
(
win
->
hrgnUpdate
||
(
win
->
flags
&
WIN_INTERNAL_PAINT
)))
{
ret
=
list
[
i
];
USER_Unlock
();
break
;
}
USER_Unlock
();
}
}
HeapFree
(
GetProcessHeap
(),
0
,
list
);
return
ret
;
}
...
...
@@ -447,55 +485,27 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
*/
HWND
WIN_FindWinToRepaint
(
HWND
hwnd
)
{
HWND
hwndRet
;
WND
*
pWnd
;
/* Note: the desktop window never gets WM_PAINT messages
* The real reason why is because Windows DesktopWndProc
* does ValidateRgn inside WM_ERASEBKGND handler.
*/
if
(
hwnd
==
GetDesktopWindow
())
hwnd
=
0
;
pWnd
=
hwnd
?
WIN_FindWndPtr
(
hwnd
)
:
WIN_LockWndPtr
(
pWndDesktop
->
child
);
for
(
;
pWnd
;
WIN_UpdateWndPtr
(
&
pWnd
,
pWnd
->
next
))
{
if
(
!
(
pWnd
->
dwStyle
&
WS_VISIBLE
))
continue
;
if
((
pWnd
->
hrgnUpdate
||
(
pWnd
->
flags
&
WIN_INTERNAL_PAINT
))
&&
WIN_IsCurrentThread
(
pWnd
->
hwndSelf
))
break
;
if
(
pWnd
->
child
)
{
if
((
hwndRet
=
WIN_FindWinToRepaint
(
pWnd
->
child
->
hwndSelf
))
)
{
WIN_ReleaseWndPtr
(
pWnd
);
return
hwndRet
;
}
}
}
if
(
!
pWnd
)
if
(
hwnd
)
{
TRACE
(
"nothing found
\n
"
);
return
0
;
}
hwndRet
=
pWnd
->
hwndSelf
;
/* look among siblings if we got a transparent window */
while
(
pWnd
)
{
if
(
!
(
pWnd
->
dwExStyle
&
WS_EX_TRANSPARENT
)
&&
(
pWnd
->
hrgnUpdate
||
(
pWnd
->
flags
&
WIN_INTERNAL_PAINT
))
&&
WIN_IsCurrentThread
(
pWnd
->
hwndSelf
))
/* check the window itself first */
WND
*
win
=
WIN_FindWndPtr
(
hwnd
);
if
(
!
win
)
return
0
;
if
((
win
->
dwStyle
&
WS_VISIBLE
)
&&
(
win
->
hrgnUpdate
||
(
win
->
flags
&
WIN_INTERNAL_PAINT
)))
{
hwndRet
=
pWnd
->
hwndSelf
;
WIN_ReleaseWndPtr
(
pWnd
);
break
;
WIN_ReleaseWndPtr
(
win
);
return
hwnd
;
}
WIN_
UpdateWndPtr
(
&
pWnd
,
pWnd
->
next
);
WIN_
ReleaseWndPtr
(
win
);
}
TRACE
(
"found %04x
\n
"
,
hwndRet
);
return
hwndRet
;
/* now check its children */
return
find_child_to_repaint
(
hwnd
)
;
}
...
...
@@ -503,34 +513,33 @@ HWND WIN_FindWinToRepaint( HWND hwnd )
* WIN_DestroyWindow
*
* Destroy storage associated to a window. "Internals" p.358
* returns a locked wndPtr->next
*/
static
WND
*
WIN_DestroyWindow
(
WND
*
wndPtr
)
static
void
WIN_DestroyWindow
(
HWND
hwnd
)
{
HWND
hwnd
=
wndPtr
->
hwndSelf
;
WND
*
pWnd
;
WND
*
wndPtr
;
HWND
*
list
;
TRACE
(
"%04x
\n
"
,
wndPtr
->
hwndSelf
);
TRACE
(
"%04x
\n
"
,
hwnd
);
/* free child windows */
WIN_LockWndPtr
(
wndPtr
->
child
);
while
((
pWnd
=
wndPtr
->
child
))
if
((
list
=
WIN_ListChildren
(
hwnd
)))
{
wndPtr
->
child
=
WIN_DestroyWindow
(
pWnd
);
WIN_ReleaseWndPtr
(
pWnd
);
int
i
;
for
(
i
=
0
;
list
[
i
];
i
++
)
WIN_DestroyWindow
(
list
[
i
]
);
HeapFree
(
GetProcessHeap
(),
0
,
list
);
}
/*
* Clear the update region to make sure no WM_PAINT messages will be
* generated for this window while processing the WM_NCDESTROY.
*/
RedrawWindow
(
wndPtr
->
hwndSelf
,
NULL
,
0
,
RedrawWindow
(
hwnd
,
NULL
,
0
,
RDW_VALIDATE
|
RDW_NOFRAME
|
RDW_NOERASE
|
RDW_NOINTERNALPAINT
|
RDW_NOCHILDREN
);
/*
* Send the WM_NCDESTROY to the window being destroyed.
*/
SendMessageA
(
wndPtr
->
hwndSelf
,
WM_NCDESTROY
,
0
,
0
);
SendMessageA
(
hwnd
,
WM_NCDESTROY
,
0
,
0
);
/* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
...
...
@@ -539,12 +548,10 @@ static WND* WIN_DestroyWindow( WND* wndPtr )
/* free resources associated with the window */
TIMER_RemoveWindowTimers
(
wndPtr
->
hwndSelf
);
PROPERTY_RemoveWindowProps
(
wndPtr
);
/* toss stale messages from the queue */
TIMER_RemoveWindowTimers
(
hwnd
);
PROPERTY_RemoveWindowProps
(
hwnd
);
QUEUE_CleanupWindow
(
hwnd
)
;
if
(
!
(
wndPtr
=
WIN_FindWndPtr
(
hwnd
)))
return
;
wndPtr
->
hmemTaskQ
=
0
;
if
(
!
(
wndPtr
->
dwStyle
&
WS_CHILD
))
...
...
@@ -558,16 +565,13 @@ static WND* WIN_DestroyWindow( WND* wndPtr )
DestroyMenu
(
wndPtr
->
hSysMenu
);
wndPtr
->
hSysMenu
=
0
;
}
USER_Driver
.
pDestroyWindow
(
wndPtr
->
hwndSelf
);
DCE_FreeWindowDCE
(
wndPtr
->
hwndSelf
);
/* Always do this to catch orphaned DCs */
USER_Driver
.
pDestroyWindow
(
hwnd
);
DCE_FreeWindowDCE
(
hwnd
);
/* Always do this to catch orphaned DCs */
WINPROC_FreeProc
(
wndPtr
->
winproc
,
WIN_PROC_WINDOW
);
CLASS_RemoveWindow
(
wndPtr
->
class
);
wndPtr
->
class
=
NULL
;
wndPtr
->
dwMagic
=
0
;
/* Mark it as invalid */
WIN_UpdateWndPtr
(
&
pWnd
,
wndPtr
->
next
);
return
pWnd
;
WIN_ReleaseWndPtr
(
wndPtr
);
}
/***********************************************************************
...
...
@@ -622,8 +626,6 @@ BOOL WIN_CreateDesktopWindow(void)
hwndDesktop
=
pWndDesktop
->
hwndSelf
;
pWndDesktop
->
tid
=
0
;
/* nobody owns the desktop */
pWndDesktop
->
next
=
NULL
;
pWndDesktop
->
child
=
NULL
;
pWndDesktop
->
parent
=
0
;
pWndDesktop
->
owner
=
0
;
pWndDesktop
->
class
=
class
;
...
...
@@ -838,10 +840,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
/* Fill the window structure */
wndPtr
->
tid
=
GetCurrentThreadId
();
wndPtr
->
next
=
NULL
;
wndPtr
->
child
=
NULL
;
wndPtr
->
owner
=
owner
;
wndPtr
->
tid
=
GetCurrentThreadId
();
wndPtr
->
owner
=
owner
;
wndPtr
->
parent
=
parent
;
wndPtr
->
class
=
classPtr
;
wndPtr
->
winproc
=
winproc
;
...
...
@@ -960,12 +960,12 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
}
else
wndPtr
->
wIDmenu
=
(
UINT
)
cs
->
hMenu
;
if
(
!
USER_Driver
.
pCreateWindow
(
wndPtr
->
hwndSelf
,
cs
,
unicode
))
if
(
!
USER_Driver
.
pCreateWindow
(
hwnd
,
cs
,
unicode
))
{
WARN
(
"aborted by WM_xxCREATE!
\n
"
);
WIN_ReleaseWndPtr
(
WIN_DestroyWindow
(
wndPtr
));
WIN_ReleaseWndPtr
(
wndPtr
);
WIN_DestroyWindow
(
hwnd
);
CLASS_RemoveWindow
(
classPtr
);
WIN_ReleaseWndPtr
(
wndPtr
);
return
0
;
}
...
...
@@ -1352,7 +1352,7 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
/* Destroy the window storage */
WIN_
ReleaseWndPtr
(
WIN_DestroyWindow
(
wndPtr
)
);
WIN_
DestroyWindow
(
hwnd
);
retvalue
=
TRUE
;
end:
WIN_ReleaseWndPtr
(
wndPtr
);
...
...
windows/winpos.c
View file @
80593bf8
...
...
@@ -283,15 +283,99 @@ BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
/***********************************************************************
* find_child_from_point
*
* Find the child that contains pt. Helper for WindowFromPoint.
* pt is in parent client coordinates.
* lparam is the param to pass in the WM_NCHITTEST message.
*/
static
HWND
find_child_from_point
(
HWND
parent
,
POINT
pt
,
INT
*
hittest
,
LPARAM
lparam
)
{
int
i
,
res
;
WND
*
wndPtr
;
HWND
*
list
=
WIN_ListChildren
(
parent
);
if
(
!
list
)
return
0
;
for
(
i
=
0
;
list
[
i
];
i
++
)
{
if
(
!
(
wndPtr
=
WIN_FindWndPtr
(
list
[
i
]
)))
continue
;
/* If point is in window, and window is visible, and it */
/* is enabled (or it's a top-level window), then explore */
/* its children. Otherwise, go to the next window. */
if
(
!
(
wndPtr
->
dwStyle
&
WS_VISIBLE
))
goto
next
;
/* not visible -> skip */
if
((
wndPtr
->
dwStyle
&
(
WS_POPUP
|
WS_CHILD
|
WS_DISABLED
))
==
(
WS_CHILD
|
WS_DISABLED
))
goto
next
;
/* disabled child -> skip */
if
((
wndPtr
->
dwExStyle
&
(
WS_EX_LAYERED
|
WS_EX_TRANSPARENT
))
==
(
WS_EX_LAYERED
|
WS_EX_TRANSPARENT
))
goto
next
;
/* transparent -> skip */
if
(
wndPtr
->
hrgnWnd
)
{
if
(
!
PtInRegion
(
wndPtr
->
hrgnWnd
,
pt
.
x
-
wndPtr
->
rectWindow
.
left
,
pt
.
y
-
wndPtr
->
rectWindow
.
top
))
goto
next
;
/* point outside window region -> skip */
}
else
if
(
!
PtInRect
(
&
wndPtr
->
rectWindow
,
pt
))
goto
next
;
/* not in window -> skip */
TRACE
(
"%ld,%ld is inside %04x
\n
"
,
pt
.
x
,
pt
.
y
,
list
[
i
]
);
/* If window is minimized or disabled, return at once */
if
(
wndPtr
->
dwStyle
&
WS_MINIMIZE
)
{
WIN_ReleaseWndPtr
(
wndPtr
);
*
hittest
=
HTCAPTION
;
return
list
[
i
];
}
if
(
wndPtr
->
dwStyle
&
WS_DISABLED
)
{
WIN_ReleaseWndPtr
(
wndPtr
);
*
hittest
=
HTERROR
;
return
list
[
i
];
}
/* If point is in client area, explore children */
if
(
PtInRect
(
&
wndPtr
->
rectClient
,
pt
))
{
POINT
new_pt
;
HWND
ret
;
new_pt
.
x
=
pt
.
x
-
wndPtr
->
rectClient
.
left
;
new_pt
.
y
=
pt
.
y
-
wndPtr
->
rectClient
.
top
;
WIN_ReleaseWndPtr
(
wndPtr
);
if
((
ret
=
find_child_from_point
(
list
[
i
],
new_pt
,
hittest
,
lparam
)))
return
ret
;
}
else
WIN_ReleaseWndPtr
(
wndPtr
);
/* Now it's inside window, send WM_NCCHITTEST (if same thread) */
if
(
!
WIN_IsCurrentThread
(
list
[
i
]
))
{
*
hittest
=
HTCLIENT
;
return
list
[
i
];
}
if
((
res
=
SendMessageA
(
list
[
i
],
WM_NCHITTEST
,
0
,
lparam
))
!=
HTTRANSPARENT
)
{
*
hittest
=
res
;
/* Found the window */
return
list
[
i
];
}
continue
;
/* continue search with next sibling */
next:
WIN_ReleaseWndPtr
(
wndPtr
);
}
return
0
;
}
/***********************************************************************
* WINPOS_WindowFromPoint
*
* Find the window and hittest for a given point.
*/
HWND
WINPOS_WindowFromPoint
(
HWND
hwndScope
,
POINT
pt
,
INT
*
hittest
)
{
WND
*
wndScope
,
*
wndPtr
,
*
wndTmp
;
HWND
hwnd_ret
=
0
;
WND
*
wndScope
;
POINT
xy
=
pt
;
int
res
;
TRACE
(
"scope %04x %ld,%ld
\n
"
,
hwndScope
,
pt
.
x
,
pt
.
y
);
...
...
@@ -300,115 +384,41 @@ HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
hwndScope
=
wndScope
->
hwndSelf
;
/* make it a full handle */
*
hittest
=
HTERROR
;
wndPtr
=
WIN_LockWndPtr
(
wndScope
->
child
);
if
(
wndScope
->
dwStyle
&
WS_DISABLED
)
{
*
hittest
=
HTERROR
;
goto
end
;
WIN_ReleaseWndPtr
(
wndScope
)
;
return
0
;
}
if
(
wndScope
->
parent
)
MapWindowPoints
(
GetDesktopWindow
(),
wndScope
->
parent
,
&
xy
,
1
);
if
(
xy
.
x
<
wndScope
->
rectClient
.
left
||
pt
.
x
>=
wndScope
->
rectClient
.
right
||
xy
.
y
<
wndScope
->
rectClient
.
top
||
pt
.
y
>=
wndScope
->
rectClient
.
bottom
||
wndScope
->
dwStyle
&
WS_MINIMIZE
)
goto
hittest
;
xy
.
x
-=
wndScope
->
rectClient
.
left
;
xy
.
y
-=
wndScope
->
rectClient
.
top
;
for
(;;)
if
(
!
(
wndScope
->
dwStyle
&
WS_MINIMIZE
)
&&
PtInRect
(
&
wndScope
->
rectClient
,
xy
))
{
while
(
wndPtr
)
{
/* If point is in window, and window is visible, and it */
/* is enabled (or it's a top-level window), then explore */
/* its children. Otherwise, go to the next window. */
if
((
wndPtr
->
dwStyle
&
WS_VISIBLE
)
&&
((
wndPtr
->
dwExStyle
&
(
WS_EX_LAYERED
|
WS_EX_TRANSPARENT
))
!=
(
WS_EX_LAYERED
|
WS_EX_TRANSPARENT
))
&&
(
!
(
wndPtr
->
dwStyle
&
WS_DISABLED
)
||
((
wndPtr
->
dwStyle
&
(
WS_POPUP
|
WS_CHILD
))
!=
WS_CHILD
))
&&
(
wndPtr
->
hrgnWnd
?
PtInRegion
(
wndPtr
->
hrgnWnd
,
xy
.
x
-
wndPtr
->
rectWindow
.
left
,
xy
.
y
-
wndPtr
->
rectWindow
.
top
)
:
((
xy
.
x
>=
wndPtr
->
rectWindow
.
left
)
&&
(
xy
.
x
<
wndPtr
->
rectWindow
.
right
)
&&
(
xy
.
y
>=
wndPtr
->
rectWindow
.
top
)
&&
(
xy
.
y
<
wndPtr
->
rectWindow
.
bottom
))))
{
TRACE
(
"%ld,%ld is inside %04x
\n
"
,
xy
.
x
,
xy
.
y
,
wndPtr
->
hwndSelf
);
hwnd_ret
=
wndPtr
->
hwndSelf
;
/* Got a suitable window */
/* If window is minimized or disabled, return at once */
if
(
wndPtr
->
dwStyle
&
WS_MINIMIZE
)
{
*
hittest
=
HTCAPTION
;
goto
end
;
}
if
(
wndPtr
->
dwStyle
&
WS_DISABLED
)
{
*
hittest
=
HTERROR
;
goto
end
;
}
/* If point is not in client area, ignore the children */
if
((
xy
.
x
<
wndPtr
->
rectClient
.
left
)
||
(
xy
.
x
>=
wndPtr
->
rectClient
.
right
)
||
(
xy
.
y
<
wndPtr
->
rectClient
.
top
)
||
(
xy
.
y
>=
wndPtr
->
rectClient
.
bottom
))
break
;
xy
.
x
-=
wndPtr
->
rectClient
.
left
;
xy
.
y
-=
wndPtr
->
rectClient
.
top
;
WIN_UpdateWndPtr
(
&
wndPtr
,
wndPtr
->
child
);
}
else
{
WIN_UpdateWndPtr
(
&
wndPtr
,
wndPtr
->
next
);
}
}
hittest:
/* If nothing found, try the scope window */
if
(
!
hwnd_ret
)
hwnd_ret
=
hwndScope
;
/* Send the WM_NCHITTEST message (only if to the same task) */
if
(
WIN_IsCurrentThread
(
hwnd_ret
))
{
INT
res
=
SendMessageA
(
hwnd_ret
,
WM_NCHITTEST
,
0
,
MAKELONG
(
pt
.
x
,
pt
.
y
)
);
if
(
res
!=
HTTRANSPARENT
)
{
*
hittest
=
res
;
/* Found the window */
goto
end
;
}
}
else
{
*
hittest
=
HTCLIENT
;
goto
end
;
}
if
(
!
(
wndTmp
=
WIN_FindWndPtr
(
hwnd_ret
)))
break
;
HWND
ret
;
/* If no children found in last search, make point relative to parent */
if
(
!
wndPtr
)
{
xy
.
x
+=
wndTmp
->
rectClient
.
left
;
xy
.
y
+=
wndTmp
->
rectClient
.
top
;
}
/* Restart the search from the next sibling */
WIN_UpdateWndPtr
(
&
wndPtr
,
wndTmp
->
next
);
hwnd_ret
=
wndTmp
->
parent
;
WIN_ReleaseWndPtr
(
wndTmp
);
xy
.
x
-=
wndScope
->
rectClient
.
left
;
xy
.
y
-=
wndScope
->
rectClient
.
top
;
WIN_ReleaseWndPtr
(
wndScope
);
if
((
ret
=
find_child_from_point
(
hwndScope
,
xy
,
hittest
,
MAKELONG
(
pt
.
x
,
pt
.
y
)
)))
return
ret
;
}
else
WIN_ReleaseWndPtr
(
wndScope
);
end:
WIN_ReleaseWndPtr
(
wndPtr
);
WIN_ReleaseWndPtr
(
wndScope
);
return
hwnd_ret
;
/* If nothing found, try the scope window */
if
(
!
WIN_IsCurrentThread
(
hwndScope
))
{
*
hittest
=
HTCLIENT
;
return
hwndScope
;
}
res
=
SendMessageA
(
hwndScope
,
WM_NCHITTEST
,
0
,
MAKELONG
(
pt
.
x
,
pt
.
y
)
);
if
(
res
!=
HTTRANSPARENT
)
{
*
hittest
=
res
;
/* Found the window */
return
hwndScope
;
}
*
hittest
=
HTNOWHERE
;
return
0
;
}
...
...
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