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
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
Expand all
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
This diff is collapsed.
Click to expand it.
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