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
7dafa617
Commit
7dafa617
authored
Sep 25, 2002
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed a number of bugs in the handling of window parent and owner and
added a regression test (based on the work of Bill Medland).
parent
e70d08be
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
503 additions
and
71 deletions
+503
-71
.cvsignore
dlls/user/tests/.cvsignore
+1
-0
Makefile.in
dlls/user/tests/Makefile.in
+1
-0
win.c
dlls/user/tests/win.c
+401
-0
win.h
include/win.h
+1
-1
server_protocol.h
include/wine/server_protocol.h
+2
-1
protocol.def
server/protocol.def
+1
-0
trace.c
server/trace.c
+2
-1
window.c
server/window.c
+19
-26
win.c
windows/win.c
+75
-42
No files found.
dlls/user/tests/.cvsignore
View file @
7dafa617
...
...
@@ -3,4 +3,5 @@ class.ok
sysparams.ok
testlist.c
user32_test.exe.spec.c
win.ok
wsprintf.ok
dlls/user/tests/Makefile.in
View file @
7dafa617
...
...
@@ -8,6 +8,7 @@ IMPORTS = user32 gdi32 advapi32
CTESTS
=
\
class.c
\
sysparams.c
\
win.c
\
wsprintf.c
@MAKE_TEST_RULES@
...
...
dlls/user/tests/win.c
0 → 100644
View file @
7dafa617
/*
* Unit tests for window handling
*
* Copyright 2002 Bill Medland
* Copyright 2002 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "wine/test.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
static
HWND
(
WINAPI
*
pGetAncestor
)(
HWND
,
UINT
);
static
HWND
hwndMain
,
hwndMain2
;
/* check the values returned by the various parent/owner functions on a given window */
static
void
check_parents
(
HWND
hwnd
,
HWND
ga_parent
,
HWND
gwl_parent
,
HWND
get_parent
,
HWND
gw_owner
,
HWND
ga_root
,
HWND
ga_root_owner
)
{
HWND
res
;
if
(
pGetAncestor
)
{
res
=
pGetAncestor
(
hwnd
,
GA_PARENT
);
ok
(
res
==
ga_parent
,
"Wrong result for GA_PARENT %x expected %x"
,
res
,
ga_parent
);
}
res
=
GetWindowLongW
(
hwnd
,
GWL_HWNDPARENT
);
ok
(
res
==
gwl_parent
,
"Wrong result for GWL_HWNDPARENT %x expected %x"
,
res
,
gwl_parent
);
res
=
GetParent
(
hwnd
);
ok
(
res
==
get_parent
,
"Wrong result for GetParent %x expected %x"
,
res
,
get_parent
);
res
=
GetWindow
(
hwnd
,
GW_OWNER
);
ok
(
res
==
gw_owner
,
"Wrong result for GW_OWNER %x expected %x"
,
res
,
gw_owner
);
if
(
pGetAncestor
)
{
res
=
pGetAncestor
(
hwnd
,
GA_ROOT
);
ok
(
res
==
ga_root
,
"Wrong result for GA_ROOT %x expected %x"
,
res
,
ga_root
);
res
=
pGetAncestor
(
hwnd
,
GA_ROOTOWNER
);
ok
(
res
==
ga_root_owner
,
"Wrong result for GA_ROOTOWNER %x expected %x"
,
res
,
ga_root_owner
);
}
}
static
HWND
create_tool_window
(
LONG
style
,
HWND
parent
)
{
HWND
ret
=
CreateWindowExA
(
0
,
"ToolWindowClass"
,
"Tool window 1"
,
style
,
0
,
0
,
100
,
100
,
parent
,
0
,
0
,
NULL
);
ok
(
ret
!=
0
,
"Creation failed"
);
return
ret
;
}
/* test parent and owner values for various combinations */
static
void
test_parent_owner
(
void
)
{
LONG
style
;
HWND
test
,
owner
,
ret
;
HWND
desktop
=
GetDesktopWindow
();
HWND
child
=
create_tool_window
(
WS_CHILD
,
hwndMain
);
trace
(
"main window %x main2 %x desktop %x child %x
\n
"
,
hwndMain
,
hwndMain2
,
desktop
,
child
);
/* child without parent, should fail */
test
=
CreateWindowExA
(
0
,
"ToolWindowClass"
,
"Tool window 1"
,
WS_CHILD
,
0
,
0
,
100
,
100
,
0
,
0
,
0
,
NULL
);
ok
(
!
test
,
"WS_CHILD without parent created"
);
/* desktop window */
check_parents
(
desktop
,
0
,
0
,
0
,
0
,
0
,
0
);
style
=
GetWindowLongW
(
desktop
,
GWL_STYLE
);
ok
(
!
SetWindowLongW
(
desktop
,
GWL_STYLE
,
WS_POPUP
),
"Set GWL_STYLE on desktop succeeded"
);
ok
(
!
SetWindowLongW
(
desktop
,
GWL_STYLE
,
0
),
"Set GWL_STYLE on desktop succeeded"
);
ok
(
GetWindowLongW
(
desktop
,
GWL_STYLE
)
==
style
,
"Desktop style changed"
);
/* normal child window */
test
=
create_tool_window
(
WS_CHILD
,
hwndMain
);
trace
(
"created child %x
\n
"
,
test
);
check_parents
(
test
,
hwndMain
,
hwndMain
,
hwndMain
,
0
,
hwndMain
,
hwndMain
);
SetWindowLongW
(
test
,
GWL_STYLE
,
0
);
check_parents
(
test
,
hwndMain
,
hwndMain
,
0
,
0
,
hwndMain
,
test
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_POPUP
);
check_parents
(
test
,
hwndMain
,
hwndMain
,
0
,
0
,
hwndMain
,
test
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_POPUP
|
WS_CHILD
);
check_parents
(
test
,
hwndMain
,
hwndMain
,
0
,
0
,
hwndMain
,
test
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_CHILD
);
DestroyWindow
(
test
);
/* child of desktop */
test
=
create_tool_window
(
WS_CHILD
,
desktop
);
trace
(
"created child of desktop %x
\n
"
,
test
);
check_parents
(
test
,
desktop
,
0
,
desktop
,
0
,
test
,
desktop
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_POPUP
);
check_parents
(
test
,
desktop
,
0
,
0
,
0
,
test
,
test
);
SetWindowLongW
(
test
,
GWL_STYLE
,
0
);
check_parents
(
test
,
desktop
,
0
,
0
,
0
,
test
,
test
);
DestroyWindow
(
test
);
/* child of child */
test
=
create_tool_window
(
WS_CHILD
,
child
);
trace
(
"created child of child %x
\n
"
,
test
);
check_parents
(
test
,
child
,
child
,
child
,
0
,
hwndMain
,
hwndMain
);
SetWindowLongW
(
test
,
GWL_STYLE
,
0
);
check_parents
(
test
,
child
,
child
,
0
,
0
,
hwndMain
,
test
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_POPUP
);
check_parents
(
test
,
child
,
child
,
0
,
0
,
hwndMain
,
test
);
DestroyWindow
(
test
);
/* not owned top-level window */
test
=
create_tool_window
(
0
,
0
);
trace
(
"created top-level %x
\n
"
,
test
);
check_parents
(
test
,
desktop
,
0
,
0
,
0
,
test
,
test
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_POPUP
);
check_parents
(
test
,
desktop
,
0
,
0
,
0
,
test
,
test
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_CHILD
);
check_parents
(
test
,
desktop
,
0
,
desktop
,
0
,
test
,
desktop
);
DestroyWindow
(
test
);
/* owned top-level window */
test
=
create_tool_window
(
0
,
hwndMain
);
trace
(
"created owned top-level %x
\n
"
,
test
);
check_parents
(
test
,
desktop
,
hwndMain
,
0
,
hwndMain
,
test
,
test
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_POPUP
);
check_parents
(
test
,
desktop
,
hwndMain
,
hwndMain
,
hwndMain
,
test
,
hwndMain
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_CHILD
);
check_parents
(
test
,
desktop
,
hwndMain
,
desktop
,
hwndMain
,
test
,
desktop
);
DestroyWindow
(
test
);
/* not owned popup */
test
=
create_tool_window
(
WS_POPUP
,
0
);
trace
(
"created popup %x
\n
"
,
test
);
check_parents
(
test
,
desktop
,
0
,
0
,
0
,
test
,
test
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_CHILD
);
check_parents
(
test
,
desktop
,
0
,
desktop
,
0
,
test
,
desktop
);
SetWindowLongW
(
test
,
GWL_STYLE
,
0
);
check_parents
(
test
,
desktop
,
0
,
0
,
0
,
test
,
test
);
DestroyWindow
(
test
);
/* owned popup */
test
=
create_tool_window
(
WS_POPUP
,
hwndMain
);
trace
(
"created owned popup %x
\n
"
,
test
);
check_parents
(
test
,
desktop
,
hwndMain
,
hwndMain
,
hwndMain
,
test
,
hwndMain
);
SetWindowLongW
(
test
,
GWL_STYLE
,
WS_CHILD
);
check_parents
(
test
,
desktop
,
hwndMain
,
desktop
,
hwndMain
,
test
,
desktop
);
SetWindowLongW
(
test
,
GWL_STYLE
,
0
);
check_parents
(
test
,
desktop
,
hwndMain
,
0
,
hwndMain
,
test
,
test
);
DestroyWindow
(
test
);
/* top-level window owned by child (same as owned by top-level) */
test
=
create_tool_window
(
0
,
child
);
trace
(
"created top-level owned by child %x
\n
"
,
test
);
check_parents
(
test
,
desktop
,
hwndMain
,
0
,
hwndMain
,
test
,
test
);
DestroyWindow
(
test
);
/* popup owned by desktop (same as not owned) */
test
=
create_tool_window
(
WS_POPUP
,
desktop
);
trace
(
"created popup owned by desktop %x
\n
"
,
test
);
check_parents
(
test
,
desktop
,
0
,
0
,
0
,
test
,
test
);
DestroyWindow
(
test
);
/* popup owned by child (same as owned by top-level) */
test
=
create_tool_window
(
WS_POPUP
,
child
);
trace
(
"created popup owned by child %x
\n
"
,
test
);
check_parents
(
test
,
desktop
,
hwndMain
,
hwndMain
,
hwndMain
,
test
,
hwndMain
);
DestroyWindow
(
test
);
/* not owned popup with WS_CHILD (same as WS_POPUP only) */
test
=
create_tool_window
(
WS_POPUP
|
WS_CHILD
,
0
);
trace
(
"created WS_CHILD popup %x
\n
"
,
test
);
check_parents
(
test
,
desktop
,
0
,
0
,
0
,
test
,
test
);
DestroyWindow
(
test
);
/* owned popup with WS_CHILD (same as WS_POPUP only) */
test
=
create_tool_window
(
WS_POPUP
|
WS_CHILD
,
hwndMain
);
trace
(
"created owned WS_CHILD popup %x
\n
"
,
test
);
check_parents
(
test
,
desktop
,
hwndMain
,
hwndMain
,
hwndMain
,
test
,
hwndMain
);
DestroyWindow
(
test
);
/******************** parent changes *************************/
trace
(
"testing parent changes
\n
"
);
/* desktop window */
check_parents
(
desktop
,
0
,
0
,
0
,
0
,
0
,
0
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
hwndMain2
);
ok
(
!
ret
,
"Set GWL_HWNDPARENT succeeded on desktop"
);
check_parents
(
desktop
,
0
,
0
,
0
,
0
,
0
,
0
);
ok
(
!
SetParent
(
desktop
,
hwndMain
),
"SetParent succeeded on desktop"
);
check_parents
(
desktop
,
0
,
0
,
0
,
0
,
0
,
0
);
/* normal child window */
test
=
create_tool_window
(
WS_CHILD
,
hwndMain
);
trace
(
"created child %x
\n
"
,
test
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
hwndMain2
);
ok
(
ret
==
hwndMain
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
hwndMain
);
check_parents
(
test
,
hwndMain2
,
hwndMain2
,
hwndMain2
,
0
,
hwndMain2
,
hwndMain2
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
child
);
ok
(
ret
==
hwndMain2
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
hwndMain2
);
check_parents
(
test
,
child
,
child
,
child
,
0
,
hwndMain
,
hwndMain
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
desktop
);
ok
(
ret
==
child
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
child
);
check_parents
(
test
,
desktop
,
0
,
desktop
,
0
,
test
,
desktop
);
/* window is now child of desktop so GWL_HWNDPARENT changes owner from now on */
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
child
);
ok
(
ret
==
0
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
0
);
check_parents
(
test
,
desktop
,
child
,
desktop
,
child
,
test
,
desktop
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
0
);
ok
(
ret
==
child
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
child
);
check_parents
(
test
,
desktop
,
0
,
desktop
,
0
,
test
,
desktop
);
DestroyWindow
(
test
);
/* not owned top-level window */
test
=
create_tool_window
(
0
,
0
);
trace
(
"created top-level %x
\n
"
,
test
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
hwndMain2
);
ok
(
ret
==
0
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
0
);
check_parents
(
test
,
desktop
,
hwndMain2
,
0
,
hwndMain2
,
test
,
test
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
child
);
ok
(
ret
==
hwndMain2
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
hwndMain2
);
check_parents
(
test
,
desktop
,
child
,
0
,
child
,
test
,
test
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
0
);
ok
(
ret
==
child
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
child
);
check_parents
(
test
,
desktop
,
0
,
0
,
0
,
test
,
test
);
DestroyWindow
(
test
);
/* not owned popup */
test
=
create_tool_window
(
WS_POPUP
,
0
);
trace
(
"created popup %x
\n
"
,
test
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
hwndMain2
);
ok
(
ret
==
0
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
0
);
check_parents
(
test
,
desktop
,
hwndMain2
,
hwndMain2
,
hwndMain2
,
test
,
hwndMain2
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
child
);
ok
(
ret
==
hwndMain2
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
hwndMain2
);
check_parents
(
test
,
desktop
,
child
,
child
,
child
,
test
,
hwndMain
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
0
);
ok
(
ret
==
child
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
child
);
check_parents
(
test
,
desktop
,
0
,
0
,
0
,
test
,
test
);
DestroyWindow
(
test
);
/* normal child window */
test
=
create_tool_window
(
WS_CHILD
,
hwndMain
);
trace
(
"created child %x
\n
"
,
test
);
ret
=
SetParent
(
test
,
desktop
);
ok
(
ret
==
hwndMain
,
"SetParent return value %x expected %x"
,
ret
,
hwndMain
);
check_parents
(
test
,
desktop
,
0
,
desktop
,
0
,
test
,
desktop
);
ret
=
SetParent
(
test
,
child
);
ok
(
ret
==
desktop
,
"SetParent return value %x expected %x"
,
ret
,
desktop
);
check_parents
(
test
,
child
,
child
,
child
,
0
,
hwndMain
,
hwndMain
);
ret
=
SetParent
(
test
,
hwndMain2
);
ok
(
ret
==
child
,
"SetParent return value %x expected %x"
,
ret
,
child
);
check_parents
(
test
,
hwndMain2
,
hwndMain2
,
hwndMain2
,
0
,
hwndMain2
,
hwndMain2
);
DestroyWindow
(
test
);
/* not owned top-level window */
test
=
create_tool_window
(
0
,
0
);
trace
(
"created top-level %x
\n
"
,
test
);
ret
=
SetParent
(
test
,
child
);
ok
(
ret
==
desktop
,
"SetParent return value %x expected %x"
,
ret
,
desktop
);
check_parents
(
test
,
child
,
child
,
0
,
0
,
hwndMain
,
test
);
DestroyWindow
(
test
);
/* owned popup */
test
=
create_tool_window
(
WS_POPUP
,
hwndMain2
);
trace
(
"created owned popup %x
\n
"
,
test
);
ret
=
SetParent
(
test
,
child
);
ok
(
ret
==
desktop
,
"SetParent return value %x expected %x"
,
ret
,
desktop
);
check_parents
(
test
,
child
,
child
,
hwndMain2
,
hwndMain2
,
hwndMain
,
hwndMain2
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
hwndMain
);
ok
(
ret
==
child
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
child
);
check_parents
(
test
,
hwndMain
,
hwndMain
,
hwndMain2
,
hwndMain2
,
hwndMain
,
hwndMain2
);
DestroyWindow
(
test
);
/**************** test owner destruction *******************/
/* owned child popup */
owner
=
create_tool_window
(
0
,
0
);
test
=
create_tool_window
(
WS_POPUP
,
owner
);
trace
(
"created owner %x and popup %x
\n
"
,
owner
,
test
);
ret
=
SetParent
(
test
,
child
);
ok
(
ret
==
desktop
,
"SetParent return value %x expected %x"
,
ret
,
desktop
);
check_parents
(
test
,
child
,
child
,
owner
,
owner
,
hwndMain
,
owner
);
/* window is now child of 'child' but owned by 'owner' */
DestroyWindow
(
owner
);
ok
(
IsWindow
(
test
),
"Window %x destroyed by owner destruction"
,
test
);
check_parents
(
test
,
child
,
child
,
owner
,
owner
,
hwndMain
,
owner
);
ok
(
!
IsWindow
(
owner
),
"Owner %x not destroyed"
,
owner
);
DestroyWindow
(
test
);
/* owned top-level popup */
owner
=
create_tool_window
(
0
,
0
);
test
=
create_tool_window
(
WS_POPUP
,
owner
);
trace
(
"created owner %x and popup %x
\n
"
,
owner
,
test
);
check_parents
(
test
,
desktop
,
owner
,
owner
,
owner
,
test
,
owner
);
DestroyWindow
(
owner
);
ok
(
!
IsWindow
(
test
),
"Window %x not destroyed by owner destruction"
,
test
);
/* top-level popup owned by child */
owner
=
create_tool_window
(
WS_CHILD
,
hwndMain2
);
test
=
create_tool_window
(
WS_POPUP
,
0
);
trace
(
"created owner %x and popup %x
\n
"
,
owner
,
test
);
ret
=
(
HWND
)
SetWindowLongW
(
test
,
GWL_HWNDPARENT
,
owner
);
ok
(
ret
==
0
,
"GWL_HWNDPARENT return value %x expected %x"
,
ret
,
0
);
check_parents
(
test
,
desktop
,
owner
,
owner
,
owner
,
test
,
hwndMain2
);
DestroyWindow
(
owner
);
ok
(
IsWindow
(
test
),
"Window %x destroyed by owner destruction"
,
test
);
ok
(
!
IsWindow
(
owner
),
"Owner %x not destroyed"
,
owner
);
check_parents
(
test
,
desktop
,
owner
,
owner
,
owner
,
test
,
owner
);
DestroyWindow
(
test
);
/* final cleanup */
DestroyWindow
(
child
);
}
static
BOOL
RegisterWindowClasses
(
void
)
{
WNDCLASSA
cls
;
cls
.
style
=
0
;
cls
.
lpfnWndProc
=
DefWindowProcA
;
cls
.
cbClsExtra
=
0
;
cls
.
cbWndExtra
=
0
;
cls
.
hInstance
=
GetModuleHandleA
(
0
);
cls
.
hIcon
=
0
;
cls
.
hCursor
=
LoadCursorA
(
0
,
IDC_ARROWA
);
cls
.
hbrBackground
=
GetStockObject
(
WHITE_BRUSH
);
cls
.
lpszMenuName
=
NULL
;
cls
.
lpszClassName
=
"MainWindowClass"
;
if
(
!
RegisterClassA
(
&
cls
))
return
FALSE
;
cls
.
style
=
0
;
cls
.
lpfnWndProc
=
DefWindowProcA
;
cls
.
cbClsExtra
=
0
;
cls
.
cbWndExtra
=
0
;
cls
.
hInstance
=
GetModuleHandleA
(
0
);
cls
.
hIcon
=
0
;
cls
.
hCursor
=
LoadCursorA
(
0
,
IDC_ARROWA
);
cls
.
hbrBackground
=
GetStockObject
(
WHITE_BRUSH
);
cls
.
lpszMenuName
=
NULL
;
cls
.
lpszClassName
=
"ToolWindowClass"
;
if
(
!
RegisterClassA
(
&
cls
))
return
FALSE
;
return
TRUE
;
}
START_TEST
(
win
)
{
pGetAncestor
=
(
void
*
)
GetProcAddress
(
GetModuleHandleA
(
"user32.dll"
),
"GetAncestor"
);
if
(
!
RegisterWindowClasses
())
assert
(
0
);
hwndMain
=
CreateWindowExA
(
/*WS_EX_TOOLWINDOW*/
0
,
"MainWindowClass"
,
"Main window"
,
WS_CAPTION
|
WS_SYSMENU
|
WS_MINIMIZEBOX
|
WS_MAXIMIZEBOX
|
WS_POPUP
,
100
,
100
,
200
,
200
,
0
,
0
,
0
,
NULL
);
hwndMain2
=
CreateWindowExA
(
/*WS_EX_TOOLWINDOW*/
0
,
"MainWindowClass"
,
"Main window 2"
,
WS_CAPTION
|
WS_SYSMENU
|
WS_MINIMIZEBOX
|
WS_MAXIMIZEBOX
|
WS_POPUP
,
100
,
100
,
200
,
200
,
0
,
0
,
0
,
NULL
);
assert
(
hwndMain
);
assert
(
hwndMain2
);
test_parent_owner
();
}
include/win.h
View file @
7dafa617
...
...
@@ -102,7 +102,7 @@ extern HWND WIN_IsCurrentProcess( HWND hwnd );
extern
HWND
WIN_IsCurrentThread
(
HWND
hwnd
);
extern
void
WIN_LinkWindow
(
HWND
hwnd
,
HWND
parent
,
HWND
hwndInsertAfter
);
extern
void
WIN_UnlinkWindow
(
HWND
hwnd
);
extern
void
WIN_SetOwner
(
HWND
hwnd
,
HWND
owner
);
extern
HWND
WIN_SetOwner
(
HWND
hwnd
,
HWND
owner
);
extern
LONG
WIN_SetStyle
(
HWND
hwnd
,
LONG
style
);
extern
LONG
WIN_SetExStyle
(
HWND
hwnd
,
LONG
style
);
extern
void
WIN_SetRectangles
(
HWND
hwnd
,
const
RECT
*
rectWindow
,
const
RECT
*
rectClient
);
...
...
include/wine/server_protocol.h
View file @
7dafa617
...
...
@@ -2491,6 +2491,7 @@ struct set_window_owner_reply
{
struct
reply_header
__header
;
user_handle_t
full_owner
;
user_handle_t
prev_owner
;
};
...
...
@@ -3210,6 +3211,6 @@ union generic_reply
struct
get_window_properties_reply
get_window_properties_reply
;
};
#define SERVER_PROTOCOL_VERSION 8
2
#define SERVER_PROTOCOL_VERSION 8
3
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/protocol.def
View file @
7dafa617
...
...
@@ -1751,6 +1751,7 @@ enum message_type
user_handle_t owner; /* new owner */
@REPLY
user_handle_t full_owner; /* full handle of new owner */
user_handle_t prev_owner; /* full handle of previous owner */
@END
...
...
server/trace.c
View file @
7dafa617
...
...
@@ -1993,7 +1993,8 @@ static void dump_set_window_owner_request( const struct set_window_owner_request
static
void
dump_set_window_owner_reply
(
const
struct
set_window_owner_reply
*
req
)
{
fprintf
(
stderr
,
" full_owner=%08x"
,
req
->
full_owner
);
fprintf
(
stderr
,
" full_owner=%08x,"
,
req
->
full_owner
);
fprintf
(
stderr
,
" prev_owner=%08x"
,
req
->
prev_owner
);
}
static
void
dump_get_window_info_request
(
const
struct
get_window_info_request
*
req
)
...
...
server/window.c
View file @
7dafa617
...
...
@@ -53,7 +53,7 @@ enum property_type
struct
window
{
struct
window
*
parent
;
/* parent window */
struct
window
*
owner
;
/* owner of this window */
user_handle_t
owner
;
/* owner of this window */
struct
window
*
first_child
;
/* first child in Z-order */
struct
window
*
last_child
;
/* last child in Z-order */
struct
window
*
first_unlinked
;
/* first child not linked in the Z-order list */
...
...
@@ -110,11 +110,7 @@ static void link_window( struct window *win, struct window *parent, struct windo
if
(
parent
)
{
if
(
win
->
parent
!=
parent
)
{
win
->
owner
=
NULL
;
/* reset owner if changing parent */
win
->
parent
=
parent
;
}
win
->
parent
=
parent
;
if
((
win
->
prev
=
previous
))
{
if
((
win
->
next
=
previous
->
next
))
win
->
next
->
prev
=
win
;
...
...
@@ -241,16 +237,6 @@ static void destroy_window( struct window *win )
while
(
win
->
first_child
)
destroy_window
(
win
->
first_child
);
while
(
win
->
first_unlinked
)
destroy_window
(
win
->
first_unlinked
);
/* reset siblings owner */
if
(
win
->
parent
)
{
struct
window
*
ptr
;
for
(
ptr
=
win
->
parent
->
first_child
;
ptr
;
ptr
=
ptr
->
next
)
if
(
ptr
->
owner
==
win
)
ptr
->
owner
=
NULL
;
for
(
ptr
=
win
->
parent
->
first_unlinked
;
ptr
;
ptr
=
ptr
->
next
)
if
(
ptr
->
owner
==
win
)
ptr
->
owner
=
NULL
;
}
if
(
win
->
thread
->
queue
)
{
if
(
win
->
paint_count
)
inc_queue_paint_count
(
win
->
thread
,
-
win
->
paint_count
);
...
...
@@ -276,7 +262,7 @@ static struct window *create_window( struct window *parent, struct window *owner
return
NULL
;
}
win
->
parent
=
parent
;
win
->
owner
=
owner
;
win
->
owner
=
owner
?
owner
->
handle
:
0
;
win
->
first_child
=
NULL
;
win
->
last_child
=
NULL
;
win
->
first_unlinked
=
NULL
;
...
...
@@ -390,6 +376,7 @@ DECL_HANDLER(create_window)
{
if
(
!
(
top_window
=
create_window
(
NULL
,
NULL
,
req
->
atom
)))
return
;
top_window
->
thread
=
NULL
;
/* no thread owns the desktop */
top_window
->
style
=
WS_POPUP
|
WS_VISIBLE
|
WS_CLIPSIBLINGS
|
WS_CLIPCHILDREN
;
}
reply
->
handle
=
top_window
->
handle
;
}
...
...
@@ -400,9 +387,9 @@ DECL_HANDLER(create_window)
if
(
!
(
parent
=
get_window
(
req
->
parent
)))
return
;
if
(
req
->
owner
&&
!
(
owner
=
get_window
(
req
->
owner
)))
return
;
if
(
owner
==
top_window
)
owner
=
NULL
;
else
if
(
owner
&&
owner
->
parent
!=
parent
)
else
if
(
owner
&&
parent
!=
top_window
)
{
/*
owner must be a sibling of the new window
*/
/*
an owned window must be created as top-level
*/
set_error
(
STATUS_ACCESS_DENIED
);
return
;
}
...
...
@@ -464,17 +451,17 @@ DECL_HANDLER(destroy_window)
DECL_HANDLER
(
set_window_owner
)
{
struct
window
*
win
=
get_window
(
req
->
handle
);
struct
window
*
owner
=
get_window
(
req
->
owner
)
;
struct
window
*
owner
=
NULL
;
if
(
!
win
||
!
owner
)
return
;
if
(
owner
->
parent
!=
win
->
parent
)
if
(
!
win
)
return
;
if
(
req
->
owner
&&
!
(
owner
=
get_window
(
req
->
owner
)))
return
;
if
(
win
==
top_window
)
{
/* owner has to be a sibling of window */
set_error
(
STATUS_ACCESS_DENIED
);
return
;
}
win
->
owner
=
owner
;
reply
->
full_owner
=
owner
->
handle
;
reply
->
prev_owner
=
win
->
owner
;
reply
->
full_owner
=
win
->
owner
=
owner
?
owner
->
handle
:
0
;
}
...
...
@@ -502,7 +489,13 @@ DECL_HANDLER(get_window_info)
DECL_HANDLER
(
set_window_info
)
{
struct
window
*
win
=
get_window
(
req
->
handle
);
if
(
!
win
)
return
;
if
(
req
->
flags
&&
win
==
top_window
)
{
set_error
(
STATUS_ACCESS_DENIED
);
return
;
}
reply
->
old_style
=
win
->
style
;
reply
->
old_ex_style
=
win
->
ex_style
;
reply
->
old_id
=
win
->
id
;
...
...
@@ -578,7 +571,7 @@ DECL_HANDLER(get_window_tree)
{
struct
window
*
parent
=
win
->
parent
;
reply
->
parent
=
parent
->
handle
;
reply
->
owner
=
win
->
owner
?
win
->
owner
->
handle
:
0
;
reply
->
owner
=
win
->
owner
;
reply
->
next_sibling
=
win
->
next
?
win
->
next
->
handle
:
0
;
reply
->
prev_sibling
=
win
->
prev
?
win
->
prev
->
handle
:
0
;
reply
->
first_sibling
=
parent
->
first_child
?
parent
->
first_child
->
handle
:
0
;
...
...
windows/win.c
View file @
7dafa617
...
...
@@ -422,11 +422,7 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
req
->
previous
=
hwndInsertAfter
;
if
(
!
wine_server_call
(
req
))
{
if
(
reply
->
full_parent
&&
reply
->
full_parent
!=
wndPtr
->
parent
)
{
wndPtr
->
owner
=
0
;
/* reset owner when changing parent */
wndPtr
->
parent
=
reply
->
full_parent
;
}
if
(
reply
->
full_parent
)
wndPtr
->
parent
=
reply
->
full_parent
;
}
}
...
...
@@ -440,24 +436,30 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
*
* Change the owner of a window.
*/
void
WIN_SetOwner
(
HWND
hwnd
,
HWND
owner
)
HWND
WIN_SetOwner
(
HWND
hwnd
,
HWND
owner
)
{
WND
*
win
=
WIN_GetPtr
(
hwnd
);
HWND
ret
=
0
;
if
(
!
win
)
return
;
if
(
!
win
)
return
0
;
if
(
win
==
WND_OTHER_PROCESS
)
{
if
(
IsWindow
(
hwnd
))
ERR
(
"cannot set owner %x on other process window %x
\n
"
,
owner
,
hwnd
);
return
;
return
0
;
}
SERVER_START_REQ
(
set_window_owner
)
{
req
->
handle
=
hwnd
;
req
->
owner
=
owner
;
if
(
!
wine_server_call
(
req
))
win
->
owner
=
reply
->
full_owner
;
if
(
!
wine_server_call
(
req
))
{
win
->
owner
=
reply
->
full_owner
;
ret
=
reply
->
prev_owner
;
}
}
SERVER_END_REQ
;
WIN_ReleasePtr
(
win
);
return
ret
;
}
...
...
@@ -758,22 +760,17 @@ BOOL WIN_CreateDesktopWindow(void)
pWndDesktop
->
parent
=
0
;
pWndDesktop
->
owner
=
0
;
pWndDesktop
->
class
=
class
;
pWndDesktop
->
hInstance
=
0
;
pWndDesktop
->
text
=
NULL
;
pWndDesktop
->
hmemTaskQ
=
0
;
pWndDesktop
->
hrgnUpdate
=
0
;
pWndDesktop
->
hwndLastActive
=
hwndDesktop
;
pWndDesktop
->
dwStyle
=
0
;
pWndDesktop
->
dwExStyle
=
0
;
pWndDesktop
->
clsStyle
=
clsStyle
;
pWndDesktop
->
dce
=
NULL
;
pWndDesktop
->
pVScroll
=
NULL
;
pWndDesktop
->
pHScroll
=
NULL
;
pWndDesktop
->
wIDmenu
=
0
;
pWndDesktop
->
helpContext
=
0
;
pWndDesktop
->
flags
=
0
;
pWndDesktop
->
hSysMenu
=
0
;
pWndDesktop
->
userdata
=
0
;
pWndDesktop
->
winproc
=
winproc
;
pWndDesktop
->
cbWndExtra
=
wndExtra
;
...
...
@@ -792,7 +789,19 @@ BOOL WIN_CreateDesktopWindow(void)
SetRect
(
&
rect
,
0
,
0
,
cs
.
cx
,
cs
.
cy
);
WIN_SetRectangles
(
hwndDesktop
,
&
rect
,
&
rect
);
WIN_SetStyle
(
hwndDesktop
,
WS_VISIBLE
|
WS_CLIPCHILDREN
|
WS_CLIPSIBLINGS
);
SERVER_START_REQ
(
set_window_info
)
{
req
->
handle
=
hwndDesktop
;
req
->
flags
=
0
;
/* don't set anything, just retrieve */
wine_server_call
(
req
);
pWndDesktop
->
dwStyle
=
reply
->
old_style
;
pWndDesktop
->
dwExStyle
=
reply
->
old_ex_style
;
pWndDesktop
->
hInstance
=
(
ULONG_PTR
)
reply
->
old_instance
;
pWndDesktop
->
userdata
=
(
ULONG_PTR
)
reply
->
old_user_data
;
pWndDesktop
->
wIDmenu
=
reply
->
old_id
;
}
SERVER_END_REQ
;
if
(
!
USER_Driver
.
pCreateWindow
(
hwndDesktop
,
&
cs
,
FALSE
))
{
...
...
@@ -1033,10 +1042,12 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
WARN
(
"Bad parent %04x
\n
"
,
cs
->
hwndParent
);
return
0
;
}
if
(
cs
->
style
&
WS_CHILD
)
parent
=
WIN_GetFullHandle
(
cs
->
hwndParent
);
else
owner
=
GetAncestor
(
cs
->
hwndParent
,
GA_ROOT
);
if
((
cs
->
style
&
(
WS_CHILD
|
WS_POPUP
))
==
WS_CHILD
)
parent
=
WIN_GetFullHandle
(
cs
->
hwndParent
);
else
owner
=
GetAncestor
(
cs
->
hwndParent
,
GA_ROOT
);
}
else
if
((
cs
->
style
&
WS_CHILD
)
&&
!
(
cs
->
style
&
WS_POPUP
)
)
else
if
((
cs
->
style
&
(
WS_CHILD
|
WS_POPUP
))
==
WS_CHILD
)
{
WARN
(
"No parent for child window
\n
"
);
return
0
;
/* WS_CHILD needs a parent, but WS_POPUP doesn't */
...
...
@@ -1864,7 +1875,12 @@ static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
LONG
retvalue
=
0
;
WND
*
wndPtr
;
if
(
offset
==
GWL_HWNDPARENT
)
return
(
LONG
)
GetParent
(
hwnd
);
if
(
offset
==
GWL_HWNDPARENT
)
{
HWND
parent
=
GetAncestor
(
hwnd
,
GA_PARENT
);
if
(
parent
==
GetDesktopWindow
())
parent
=
GetWindow
(
hwnd
,
GW_OWNER
);
return
(
LONG
)
parent
;
}
if
(
!
(
wndPtr
=
WIN_GetPtr
(
hwnd
)))
{
...
...
@@ -1991,6 +2007,12 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
}
wndPtr
=
WIN_GetPtr
(
hwnd
);
if
(
wndPtr
->
hwndSelf
==
GetDesktopWindow
())
{
/* can't change anything on the desktop window */
SetLastError
(
ERROR_ACCESS_DENIED
);
return
0
;
}
if
(
offset
>=
0
)
{
...
...
@@ -2033,8 +2055,16 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
newval
=
style
.
styleNew
;
break
;
case
GWL_HWNDPARENT
:
WIN_ReleasePtr
(
wndPtr
);
return
(
LONG
)
SetParent
(
hwnd
,
(
HWND
)
newval
);
if
(
wndPtr
->
parent
==
GetDesktopWindow
())
{
WIN_ReleasePtr
(
wndPtr
);
return
(
LONG
)
WIN_SetOwner
(
hwnd
,
(
HWND
)
newval
);
}
else
{
WIN_ReleasePtr
(
wndPtr
);
return
(
LONG
)
SetParent
(
hwnd
,
(
HWND
)
newval
);
}
case
GWL_WNDPROC
:
retval
=
(
LONG
)
WINPROC_GetProc
(
wndPtr
->
winproc
,
type
);
WINPROC_SetProc
(
&
wndPtr
->
winproc
,
(
WNDPROC16
)
newval
,
...
...
@@ -2436,8 +2466,8 @@ HWND WINAPI GetParent( HWND hwnd )
req
->
handle
=
hwnd
;
if
(
!
wine_server_call_err
(
req
))
{
if
(
style
&
WS_
CHILD
)
retvalue
=
reply
->
parent
;
else
retvalue
=
reply
->
owner
;
if
(
style
&
WS_
POPUP
)
retvalue
=
reply
->
owner
;
else
if
(
style
&
WS_CHILD
)
retvalue
=
reply
->
parent
;
}
}
SERVER_END_REQ
;
...
...
@@ -2445,8 +2475,8 @@ HWND WINAPI GetParent( HWND hwnd )
}
else
{
if
(
wndPtr
->
dwStyle
&
WS_
CHILD
)
retvalue
=
wndPtr
->
parent
;
else
if
(
wndPtr
->
dwStyle
&
WS_
POPUP
)
retvalue
=
wndPtr
->
owner
;
if
(
wndPtr
->
dwStyle
&
WS_
POPUP
)
retvalue
=
wndPtr
->
owner
;
else
if
(
wndPtr
->
dwStyle
&
WS_
CHILD
)
retvalue
=
wndPtr
->
parent
;
WIN_ReleasePtr
(
wndPtr
);
}
return
retvalue
;
...
...
@@ -2461,8 +2491,9 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type )
WND
*
win
;
HWND
*
list
,
ret
=
0
;
if
(
type
==
GA_PARENT
)
switch
(
type
)
{
case
GA_PARENT
:
if
(
!
(
win
=
WIN_GetPtr
(
hwnd
)))
{
SetLastError
(
ERROR_INVALID_WINDOW_HANDLE
);
...
...
@@ -2482,28 +2513,30 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type )
}
SERVER_END_REQ
;
}
return
ret
;
}
break
;
if
(
!
(
list
=
WIN_ListParents
(
hwnd
)))
return
0
;
case
GA_ROOT
:
if
(
!
(
list
=
WIN_ListParents
(
hwnd
)))
return
0
;
if
(
!
list
[
0
]
||
!
list
[
1
])
ret
=
WIN_GetFullHandle
(
hwnd
);
/* top-level window */
else
{
int
count
=
2
;
while
(
list
[
count
])
count
++
;
ret
=
list
[
count
-
2
];
/* get the one before the desktop */
}
HeapFree
(
GetProcessHeap
(),
0
,
list
);
if
(
!
list
[
0
]
||
!
list
[
1
])
ret
=
WIN_GetFullHandle
(
hwnd
);
/* top-level window */
else
{
int
count
=
2
;
while
(
list
[
count
])
count
++
;
ret
=
list
[
count
-
2
];
/* get the one before the desktop */
}
HeapFree
(
GetProcessHeap
(),
0
,
list
);
break
;
if
(
ret
&&
type
==
GA_ROOTOWNER
)
{
case
GA_ROOTOWNER
:
if
((
ret
=
WIN_GetFullHandle
(
hwnd
))
==
GetDesktopWindow
())
return
0
;
for
(;;)
{
HWND
owner
=
GetWindow
(
ret
,
GW_OWNER
);
if
(
!
owner
)
break
;
ret
=
owner
;
HWND
parent
=
GetParent
(
ret
);
if
(
!
parent
)
break
;
ret
=
parent
;
}
break
;
}
return
ret
;
}
...
...
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