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
c03409e9
Commit
c03409e9
authored
Jul 08, 2022
by
Zhiyi Zhang
Committed by
Alexandre Julliard
Jul 15, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shell32: Implement SHOpenFolderAndSelectItems().
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=39987
Signed-off-by:
Zhiyi Zhang
<
zzhang@codeweavers.com
>
parent
7c60e623
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
175 additions
and
13 deletions
+175
-13
shlfolder.c
dlls/shell32/shlfolder.c
+136
-2
shlfolder.c
dlls/shell32/tests/shlfolder.c
+0
-11
explorer.c
programs/explorer/explorer.c
+39
-0
No files found.
dlls/shell32/shlfolder.c
View file @
c03409e9
...
...
@@ -618,8 +618,142 @@ HRESULT WINAPI SHCreateLinks( HWND hWnd, LPCSTR lpszDir, LPDATAOBJECT lpDataObje
HRESULT
WINAPI
SHOpenFolderAndSelectItems
(
PCIDLIST_ABSOLUTE
pidlFolder
,
UINT
cidl
,
PCUITEMID_CHILD_ARRAY
apidl
,
DWORD
flags
)
{
FIXME
(
"%p %u %p 0x%lx: stub
\n
"
,
pidlFolder
,
cidl
,
apidl
,
flags
);
return
E_NOTIMPL
;
static
const
unsigned
int
magic
=
0xe32ee32e
;
unsigned
int
i
,
uint_flags
,
size
,
child_count
=
0
;
const
ITEMIDLIST
*
pidl_parent
,
*
pidl_child
;
VARIANT
var_parent
,
var_empty
;
ITEMIDLIST
*
pidl_tmp
=
NULL
;
SHELLEXECUTEINFOW
sei
=
{
0
};
COPYDATASTRUCT
cds
=
{
0
};
IDispatch
*
dispatch
;
int
timeout
=
1000
;
unsigned
char
*
ptr
;
IShellWindows
*
sw
;
BOOL
ret
=
FALSE
;
HRESULT
hr
;
LONG
hwnd
;
TRACE
(
"%p %u %p 0x%lx
\n
"
,
pidlFolder
,
cidl
,
apidl
,
flags
);
if
(
!
pidlFolder
)
return
E_INVALIDARG
;
if
(
flags
&
OFASI_OPENDESKTOP
)
FIXME
(
"Ignoring unsupported OFASI_OPENDESKTOP flag.
\n
"
);
if
(
flags
&
OFASI_EDIT
&&
cidl
>
1
)
flags
&=
~
OFASI_EDIT
;
hr
=
CoCreateInstance
(
&
CLSID_ShellWindows
,
NULL
,
CLSCTX_LOCAL_SERVER
,
&
IID_IShellWindows
,
(
void
**
)
&
sw
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
!
cidl
)
{
pidl_tmp
=
ILClone
(
pidlFolder
);
ILRemoveLastID
(
pidl_tmp
);
pidl_parent
=
pidl_tmp
;
pidl_child
=
ILFindLastID
(
pidlFolder
);
apidl
=
&
pidl_child
;
cidl
=
1
;
}
else
{
pidl_parent
=
pidlFolder
;
}
/* Find the existing explorer window for the parent path. Create a new one if not present. */
VariantInit
(
&
var_empty
);
VariantInit
(
&
var_parent
);
size
=
ILGetSize
(
pidl_parent
);
V_VT
(
&
var_parent
)
=
VT_ARRAY
|
VT_UI1
;
V_ARRAY
(
&
var_parent
)
=
SafeArrayCreateVector
(
VT_UI1
,
0
,
size
);
memcpy
(
V_ARRAY
(
&
var_parent
)
->
pvData
,
pidl_parent
,
size
);
hr
=
IShellWindows_FindWindowSW
(
sw
,
&
var_parent
,
&
var_empty
,
SWC_EXPLORER
,
&
hwnd
,
0
,
&
dispatch
);
if
(
hr
!=
S_OK
)
{
sei
.
cbSize
=
sizeof
(
sei
);
sei
.
fMask
=
SEE_MASK_FLAG_NO_UI
|
SEE_MASK_IDLIST
|
SEE_MASK_NOASYNC
|
SEE_MASK_WAITFORINPUTIDLE
;
sei
.
lpVerb
=
L"explore"
;
sei
.
lpIDList
=
(
void
*
)
pidl_parent
;
sei
.
nShow
=
SW_NORMAL
;
if
(
!
ShellExecuteExW
(
&
sei
))
{
WARN
(
"Failed to create a explorer window.
\n
"
);
goto
done
;
}
while
(
timeout
>
0
)
{
hr
=
IShellWindows_FindWindowSW
(
sw
,
&
var_parent
,
&
var_empty
,
SWC_EXPLORER
,
&
hwnd
,
0
,
&
dispatch
);
if
(
hr
==
S_OK
)
break
;
timeout
-=
100
;
Sleep
(
100
);
}
if
(
hr
!=
S_OK
)
{
WARN
(
"Failed to find the explorer window.
\n
"
);
goto
done
;
}
}
/* Send WM_COPYDATA to tell explorer.exe to open windows */
size
=
sizeof
(
cidl
)
+
sizeof
(
uint_flags
);
for
(
i
=
0
;
i
<
cidl
;
++
i
)
size
+=
ILGetSize
(
apidl
[
i
]);
cds
.
dwData
=
magic
;
cds
.
cbData
=
size
;
cds
.
lpData
=
malloc
(
size
);
if
(
!
cds
.
lpData
)
{
hr
=
E_OUTOFMEMORY
;
goto
done
;
}
/* Add the count of child ITEMIDLIST, set its value at the end */
ptr
=
(
unsigned
char
*
)
cds
.
lpData
+
sizeof
(
cidl
);
/* Add flags. Have to use unsigned int because DWORD may have a different size */
uint_flags
=
flags
;
memcpy
(
ptr
,
&
uint_flags
,
sizeof
(
uint_flags
));
ptr
+=
sizeof
(
uint_flags
);
/* Add child ITEMIDLIST */
for
(
i
=
0
;
i
<
cidl
;
++
i
)
{
if
(
apidl
!=
&
pidl_child
)
pidl_child
=
ILFindChild
(
pidl_parent
,
apidl
[
i
]);
if
(
pidl_child
)
{
size
=
ILGetSize
(
pidl_child
);
memcpy
(
ptr
,
pidl_child
,
size
);
ptr
+=
size
;
++
child_count
;
}
}
/* Set the count of child ITEMIDLIST */
memcpy
(
cds
.
lpData
,
&
child_count
,
sizeof
(
child_count
));
SetForegroundWindow
(
GetAncestor
((
HWND
)(
LONG_PTR
)
hwnd
,
GA_ROOT
));
ret
=
SendMessageW
((
HWND
)(
LONG_PTR
)
hwnd
,
WM_COPYDATA
,
0
,
(
LPARAM
)
&
cds
);
hr
=
ret
?
S_OK
:
E_FAIL
;
done:
free
(
cds
.
lpData
);
VariantClear
(
&
var_parent
);
if
(
pidl_tmp
)
ILFree
(
pidl_tmp
);
IShellWindows_Release
(
sw
);
return
hr
;
}
/***********************************************************************
...
...
dlls/shell32/tests/shlfolder.c
View file @
c03409e9
...
...
@@ -5448,15 +5448,12 @@ static void test_SHOpenFolderAndSelectItems(void)
/* NULL folder */
hr
=
SHOpenFolderAndSelectItems
(
NULL
,
0
,
NULL
,
0
);
todo_wine
ok
(
hr
==
E_INVALIDARG
,
"Got unexpected hr %#lx.
\n
"
,
hr
);
/* Open and select folder without child items */
folder
=
ILCreateFromPathW
(
L"C:
\\
Windows
\\
System32"
);
hr
=
SHOpenFolderAndSelectItems
(
folder
,
0
,
NULL
,
0
);
todo_wine
ok
(
hr
==
S_OK
,
"Got unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
ok
(
check_window_exists
(
"Windows"
),
"Failed to create window.
\n
"
);
ILFree
(
folder
);
...
...
@@ -5464,9 +5461,7 @@ static void test_SHOpenFolderAndSelectItems(void)
folder
=
ILCreateFromPathW
(
L"C:
\\
Windows"
);
items
[
0
]
=
ILCreateFromPathW
(
L"C:
\\
Windows
\\
System32"
);
hr
=
SHOpenFolderAndSelectItems
(
folder
,
1
,
(
PCUITEMID_CHILD_ARRAY
)
items
,
0
);
todo_wine
ok
(
hr
==
S_OK
,
"Got unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
ok
(
check_window_exists
(
"Windows"
),
"Failed to create window.
\n
"
);
ILFree
(
items
[
0
]);
ILFree
(
folder
);
...
...
@@ -5476,9 +5471,7 @@ static void test_SHOpenFolderAndSelectItems(void)
items
[
0
]
=
ILCreateFromPathW
(
L"C:
\\
Windows
\\
System32"
);
items
[
1
]
=
ILCreateFromPathW
(
L"C:
\\
Windows
\\
Resources"
);
hr
=
SHOpenFolderAndSelectItems
(
folder
,
2
,
(
PCUITEMID_CHILD_ARRAY
)
items
,
0
);
todo_wine
ok
(
hr
==
S_OK
,
"Got unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
ok
(
check_window_exists
(
"Windows"
),
"Failed to create window.
\n
"
);
ILFree
(
items
[
1
]);
ILFree
(
items
[
0
]);
...
...
@@ -5488,9 +5481,7 @@ static void test_SHOpenFolderAndSelectItems(void)
folder
=
ILCreateFromPathW
(
L"C:
\\
Windows"
);
items
[
0
]
=
ILCreateFromPathW
(
L"C:
\\
Windows
\\
System32"
);
hr
=
SHOpenFolderAndSelectItems
(
folder
,
1
,
(
PCUITEMID_CHILD_ARRAY
)
items
,
OFASI_EDIT
);
todo_wine
ok
(
hr
==
S_OK
,
"Got unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
ok
(
check_window_exists
(
"Windows"
),
"Failed to create window.
\n
"
);
ILFree
(
items
[
0
]);
ILFree
(
folder
);
...
...
@@ -5500,9 +5491,7 @@ static void test_SHOpenFolderAndSelectItems(void)
items
[
0
]
=
ILCreateFromPathW
(
L"C:
\\
Windows
\\
System32"
);
items
[
1
]
=
ILCreateFromPathW
(
L"C:
\\
Windows
\\
Resources"
);
hr
=
SHOpenFolderAndSelectItems
(
folder
,
2
,
(
PCUITEMID_CHILD_ARRAY
)
items
,
0
);
todo_wine
ok
(
hr
==
S_OK
,
"Got unexpected hr %#lx.
\n
"
,
hr
);
todo_wine
ok
(
check_window_exists
(
"Windows"
),
"Failed to create window.
\n
"
);
ILFree
(
items
[
1
]);
ILFree
(
items
[
0
]);
...
...
programs/explorer/explorer.c
View file @
c03409e9
...
...
@@ -667,6 +667,43 @@ static LRESULT explorer_on_notify(explorer_info* info,NMHDR* notification)
return
0
;
}
static
BOOL
handle_copydata
(
const
explorer_info
*
info
,
const
COPYDATASTRUCT
*
cds
)
{
static
const
unsigned
int
magic
=
0xe32ee32e
;
unsigned
int
i
,
flags
,
count
;
const
ITEMIDLIST
*
child
;
unsigned
char
*
ptr
;
IShellView
*
sv
;
SVSIF
sv_flags
;
TRACE
(
"
\n
"
);
/* For SHOpenFolderAndSelectItems() */
if
(
cds
->
dwData
!=
magic
)
return
FALSE
;
ptr
=
cds
->
lpData
;
memcpy
(
&
count
,
ptr
,
sizeof
(
count
));
ptr
+=
sizeof
(
count
);
memcpy
(
&
flags
,
ptr
,
sizeof
(
flags
));
ptr
+=
sizeof
(
flags
);
sv_flags
=
flags
&
OFASI_EDIT
?
SVSI_EDIT
:
SVSI_SELECT
;
IExplorerBrowser_GetCurrentView
(
info
->
browser
,
&
IID_IShellView
,
(
void
**
)
&
sv
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
child
=
(
const
ITEMIDLIST
*
)
ptr
;
if
(
i
==
0
)
IShellView_SelectItem
(
sv
,
child
,
sv_flags
|
SVSI_ENSUREVISIBLE
|
SVSI_FOCUSED
|
SVSI_DESELECTOTHERS
);
else
IShellView_SelectItem
(
sv
,
child
,
sv_flags
);
ptr
+=
ILGetSize
(
child
);
}
IShellView_Release
(
sv
);
return
TRUE
;
}
static
LRESULT
CALLBACK
explorer_wnd_proc
(
HWND
hwnd
,
UINT
uMsg
,
WPARAM
wParam
,
LPARAM
lParam
)
{
explorer_info
*
info
...
...
@@ -718,6 +755,8 @@ static LRESULT CALLBACK explorer_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, L
case
WM_SIZE
:
update_window_size
(
info
,
HIWORD
(
lParam
),
LOWORD
(
lParam
));
break
;
case
WM_COPYDATA
:
return
handle_copydata
(
info
,
(
const
COPYDATASTRUCT
*
)
lParam
);
default:
return
DefWindowProcW
(
hwnd
,
uMsg
,
wParam
,
lParam
);
}
...
...
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