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
f87891c3
Commit
f87891c3
authored
Aug 04, 2010
by
David Hedberg
Committed by
Alexandre Julliard
Aug 04, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
explorerframe: Implement InsertRoot and AppendRoot.
parent
94dfbcaa
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
216 additions
and
5 deletions
+216
-5
Makefile.in
dlls/explorerframe/Makefile.in
+1
-1
nstc.c
dlls/explorerframe/nstc.c
+118
-4
nstc.c
dlls/explorerframe/tests/nstc.c
+97
-0
No files found.
dlls/explorerframe/Makefile.in
View file @
f87891c3
...
...
@@ -4,7 +4,7 @@ TOPOBJDIR = ../..
SRCDIR
=
@srcdir@
VPATH
=
@srcdir@
MODULE
=
explorerframe.dll
IMPORTS
=
uuid shell32 user32
IMPORTS
=
uuid
ole32
shell32 user32
C_SRCS
=
\
explorerframe_main.c
\
...
...
dlls/explorerframe/nstc.c
View file @
f87891c3
...
...
@@ -27,13 +27,25 @@
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "shellapi.h"
#include "wine/list.h"
#include "wine/debug.h"
#include "explorerframe_main.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
nstc
);
typedef
struct
nstc_root
{
IShellItem
*
psi
;
HTREEITEM
htreeitem
;
SHCONTF
enum_flags
;
NSTCROOTSTYLE
root_style
;
IShellItemFilter
*
pif
;
struct
list
entry
;
}
nstc_root
;
typedef
struct
{
const
INameSpaceTreeControl2Vtbl
*
lpVtbl
;
const
IOleWindowVtbl
*
lpowVtbl
;
...
...
@@ -44,6 +56,7 @@ typedef struct {
NSTCSTYLE
style
;
NSTCSTYLE2
style2
;
struct
list
roots
;
INameSpaceTreeControlEvents
*
pnstce
;
}
NSTC2Impl
;
...
...
@@ -57,6 +70,22 @@ static const DWORD unsupported_styles2 =
NSTCS2_DISPLAYPINNEDONLY
|
NTSCS2_NOSINGLETONAUTOEXPAND
|
NTSCS2_NEVERINSERTNONENUMERATED
;
/*************************************************************************
* NamespaceTree event wrappers
*/
static
HRESULT
events_OnItemAdded
(
NSTC2Impl
*
This
,
IShellItem
*
psi
,
BOOL
fIsRoot
)
{
HRESULT
ret
;
LONG
refcount
;
if
(
!
This
->
pnstce
)
return
S_OK
;
refcount
=
IShellItem_AddRef
(
psi
);
ret
=
INameSpaceTreeControlEvents_OnItemAdded
(
This
->
pnstce
,
psi
,
fIsRoot
);
if
(
IShellItem_Release
(
psi
)
<
refcount
-
1
)
ERR
(
"ShellItem was released by client - please file a bug.
\n
"
);
return
ret
;
}
/*************************************************************************
* NamespaceTree helper functions
*/
static
DWORD
treeview_style_from_nstcs
(
NSTC2Impl
*
This
,
NSTCSTYLE
nstcs
,
...
...
@@ -106,6 +135,34 @@ static DWORD treeview_style_from_nstcs(NSTC2Impl *This, NSTCSTYLE nstcs,
return
old_style
^*
new_style
;
}
/* Insert a shellitem into the given place in the tree and return the
resulting treeitem. */
static
HTREEITEM
insert_shellitem
(
NSTC2Impl
*
This
,
IShellItem
*
psi
,
HTREEITEM
hParent
,
HTREEITEM
hInsertAfter
)
{
TVINSERTSTRUCTW
tvins
;
TVITEMEXW
*
tvi
=
&
tvins
.
u
.
itemex
;
HTREEITEM
hinserted
;
TRACE
(
"%p (%p, %p)
\n
"
,
psi
,
hParent
,
hInsertAfter
);
tvi
->
mask
=
TVIF_PARAM
|
TVIF_CHILDREN
|
TVIF_IMAGE
|
TVIF_SELECTEDIMAGE
|
TVIF_TEXT
;
tvi
->
cChildren
=
I_CHILDRENCALLBACK
;
tvi
->
iImage
=
tvi
->
iSelectedImage
=
I_IMAGECALLBACK
;
tvi
->
pszText
=
LPSTR_TEXTCALLBACKW
;
/* Every treeitem contains a pointer to the corresponding ShellItem. */
tvi
->
lParam
=
(
LPARAM
)
psi
;
tvins
.
hParent
=
hParent
;
tvins
.
hInsertAfter
=
hInsertAfter
;
hinserted
=
(
HTREEITEM
)
SendMessageW
(
This
->
hwnd_tv
,
TVM_INSERTITEMW
,
0
,
(
LPARAM
)(
LPTVINSERTSTRUCTW
)
&
tvins
);
if
(
hinserted
)
IShellItem_AddRef
(
psi
);
return
hinserted
;
}
/*************************************************************************
* NamespaceTree window functions
*/
...
...
@@ -365,8 +422,59 @@ static HRESULT WINAPI NSTC2_fnInsertRoot(INameSpaceTreeControl2* iface,
IShellItemFilter
*
pif
)
{
NSTC2Impl
*
This
=
(
NSTC2Impl
*
)
iface
;
FIXME
(
"stub, %p, %p, %x, %x, %p
\n
"
,
This
,
psiRoot
,
grfEnumFlags
,
grfRootStyle
,
pif
);
return
E_NOTIMPL
;
nstc_root
*
new_root
;
struct
list
*
add_after_entry
;
HTREEITEM
add_after_hitem
;
UINT
i
;
TRACE
(
"%p, %d, %p, %x, %x, %p
\n
"
,
This
,
iIndex
,
psiRoot
,
grfEnumFlags
,
grfRootStyle
,
pif
);
new_root
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
nstc_root
));
if
(
!
new_root
)
return
E_OUTOFMEMORY
;
new_root
->
psi
=
psiRoot
;
new_root
->
enum_flags
=
grfEnumFlags
;
new_root
->
root_style
=
grfRootStyle
;
new_root
->
pif
=
pif
;
/* We want to keep the roots in the internal list and in the
* treeview in the same order. */
add_after_entry
=
&
This
->
roots
;
for
(
i
=
0
;
i
<
max
(
0
,
iIndex
)
&&
list_next
(
&
This
->
roots
,
add_after_entry
);
i
++
)
add_after_entry
=
list_next
(
&
This
->
roots
,
add_after_entry
);
if
(
add_after_entry
==
&
This
->
roots
)
add_after_hitem
=
TVI_FIRST
;
else
add_after_hitem
=
LIST_ENTRY
(
add_after_entry
,
nstc_root
,
entry
)
->
htreeitem
;
new_root
->
htreeitem
=
insert_shellitem
(
This
,
psiRoot
,
TVI_ROOT
,
add_after_hitem
);
if
(
!
new_root
->
htreeitem
)
{
WARN
(
"Failed to add the root.
\n
"
);
HeapFree
(
GetProcessHeap
(),
0
,
new_root
);
return
E_FAIL
;
}
list_add_after
(
add_after_entry
,
&
new_root
->
entry
);
events_OnItemAdded
(
This
,
psiRoot
,
TRUE
);
if
(
grfRootStyle
&
NSTCRS_HIDDEN
)
{
TVITEMEXW
tvi
;
tvi
.
mask
=
TVIF_STATEEX
;
tvi
.
uStateEx
=
TVIS_EX_FLAT
;
tvi
.
hItem
=
new_root
->
htreeitem
;
SendMessageW
(
This
->
hwnd_tv
,
TVM_SETITEMW
,
0
,
(
LPARAM
)
&
tvi
);
}
if
(
grfRootStyle
&
NSTCRS_EXPANDED
)
SendMessageW
(
This
->
hwnd_tv
,
TVM_EXPAND
,
TVE_EXPAND
,
(
LPARAM
)
new_root
->
htreeitem
);
return
S_OK
;
}
static
HRESULT
WINAPI
NSTC2_fnAppendRoot
(
INameSpaceTreeControl2
*
iface
,
...
...
@@ -376,9 +484,13 @@ static HRESULT WINAPI NSTC2_fnAppendRoot(INameSpaceTreeControl2* iface,
IShellItemFilter
*
pif
)
{
NSTC2Impl
*
This
=
(
NSTC2Impl
*
)
iface
;
FIXME
(
"stub, %p, %p, %x, %x, %p
\n
"
,
UINT
root_count
;
TRACE
(
"%p, %p, %x, %x, %p
\n
"
,
This
,
psiRoot
,
grfEnumFlags
,
grfRootStyle
,
pif
);
return
E_NOTIMPL
;
root_count
=
list_count
(
&
This
->
roots
);
return
NSTC2_fnInsertRoot
(
iface
,
root_count
,
psiRoot
,
grfEnumFlags
,
grfRootStyle
,
pif
);
}
static
HRESULT
WINAPI
NSTC2_fnRemoveRoot
(
INameSpaceTreeControl2
*
iface
,
...
...
@@ -702,6 +814,8 @@ HRESULT NamespaceTreeControl_Constructor(IUnknown *pUnkOuter, REFIID riid, void
nstc
->
lpVtbl
=
&
vt_INameSpaceTreeControl2
;
nstc
->
lpowVtbl
=
&
vt_IOleWindow
;
list_init
(
&
nstc
->
roots
);
ret
=
INameSpaceTreeControl_QueryInterface
((
INameSpaceTreeControl
*
)
nstc
,
riid
,
ppv
);
INameSpaceTreeControl_Release
((
INameSpaceTreeControl
*
)
nstc
);
...
...
dlls/explorerframe/tests/nstc.c
View file @
f87891c3
...
...
@@ -315,6 +315,35 @@ static INameSpaceTreeControlEventsImpl *create_nstc_events(void)
return
This
;
}
/* Process some messages */
static
void
process_msgs
(
void
)
{
MSG
msg
;
BOOL
got_msg
;
do
{
got_msg
=
FALSE
;
Sleep
(
100
);
while
(
PeekMessage
(
&
msg
,
NULL
,
0
,
0
,
PM_REMOVE
))
{
TranslateMessage
(
&
msg
);
DispatchMessage
(
&
msg
);
got_msg
=
TRUE
;
}
}
while
(
got_msg
);
/* There seem to be a timer that sometimes fires after about
500ms, we need to wait for it. Failing to wait can result in
seemingly sporadic selection change events. (Timer ID is 87,
sending WM_TIMER manually does not seem to help us.) */
Sleep
(
500
);
while
(
PeekMessage
(
&
msg
,
NULL
,
0
,
0
,
PM_REMOVE
))
{
TranslateMessage
(
&
msg
);
DispatchMessage
(
&
msg
);
}
}
/* Returns FALSE if the NamespaceTreeControl failed to be instantiated. */
static
BOOL
test_initialization
(
void
)
{
...
...
@@ -470,15 +499,52 @@ static void test_basics(void)
{
INameSpaceTreeControl
*
pnstc
;
INameSpaceTreeControl2
*
pnstc2
;
IShellFolder
*
psfdesktop
;
IShellItem
*
psidesktop
,
*
psidesktop2
;
IOleWindow
*
pow
;
LPITEMIDLIST
pidl_desktop
;
HRESULT
hr
;
UINT
i
,
res
;
RECT
rc
;
/* These should exist on platforms supporting the NSTC */
ok
(
pSHCreateShellItem
!=
NULL
,
"No SHCreateShellItem.
\n
"
);
ok
(
pSHGetIDListFromObject
!=
NULL
,
"No SHCreateShellItem.
\n
"
);
/* Create ShellItems for testing. */
SHGetDesktopFolder
(
&
psfdesktop
);
hr
=
pSHGetIDListFromObject
((
IUnknown
*
)
psfdesktop
,
&
pidl_desktop
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
pSHCreateShellItem
(
NULL
,
NULL
,
pidl_desktop
,
&
psidesktop
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
pSHCreateShellItem
(
NULL
,
NULL
,
pidl_desktop
,
&
psidesktop2
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
if
(
FAILED
(
hr
))
IShellItem_Release
(
psidesktop
);
}
ILFree
(
pidl_desktop
);
}
ok
(
psidesktop
!=
psidesktop2
,
"psidesktop == psidesktop2
\n
"
);
IShellFolder_Release
(
psfdesktop
);
if
(
FAILED
(
hr
))
{
win_skip
(
"Test setup failed.
\n
"
);
return
;
}
hr
=
CoCreateInstance
(
&
CLSID_NamespaceTreeControl
,
NULL
,
CLSCTX_INPROC_SERVER
,
&
IID_INameSpaceTreeControl
,
(
void
**
)
&
pnstc
);
ok
(
hr
==
S_OK
,
"Failed to initialize control (0x%08x)
\n
"
,
hr
);
/* Some tests on an uninitialized control */
hr
=
INameSpaceTreeControl_AppendRoot
(
pnstc
,
psidesktop
,
SHCONTF_NONFOLDERS
,
0
,
NULL
);
ok
(
hr
==
E_FAIL
,
"Got (0x%08x)
\n
"
,
hr
);
process_msgs
();
/* Initialize the control */
rc
.
top
=
rc
.
left
=
0
;
rc
.
right
=
rc
.
bottom
=
200
;
hr
=
INameSpaceTreeControl_Initialize
(
pnstc
,
hwnd
,
&
rc
,
0
);
...
...
@@ -697,6 +763,37 @@ static void test_basics(void)
skip
(
"INameSpaceTreeControl2 missing.
\n
"
);
}
/* Append / Insert root */
if
(
0
)
{
/* Crashes under Windows 7 */
hr
=
INameSpaceTreeControl_AppendRoot
(
pnstc
,
NULL
,
SHCONTF_FOLDERS
,
0
,
NULL
);
hr
=
INameSpaceTreeControl_InsertRoot
(
pnstc
,
0
,
NULL
,
SHCONTF_FOLDERS
,
0
,
NULL
);
}
/* Note the usage of psidesktop and psidesktop2 */
hr
=
INameSpaceTreeControl_AppendRoot
(
pnstc
,
psidesktop
,
SHCONTF_FOLDERS
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Got (0x%08x)
\n
"
,
hr
);
hr
=
INameSpaceTreeControl_AppendRoot
(
pnstc
,
psidesktop
,
SHCONTF_FOLDERS
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Got (0x%08x)
\n
"
,
hr
);
hr
=
INameSpaceTreeControl_AppendRoot
(
pnstc
,
psidesktop2
,
SHCONTF_FOLDERS
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Got (0x%08x)
\n
"
,
hr
);
process_msgs
();
hr
=
INameSpaceTreeControl_InsertRoot
(
pnstc
,
0
,
psidesktop
,
SHCONTF_FOLDERS
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Got (0x%08x)
\n
"
,
hr
);
hr
=
INameSpaceTreeControl_InsertRoot
(
pnstc
,
-
1
,
psidesktop
,
SHCONTF_FOLDERS
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Got (0x%08x)
\n
"
,
hr
);
hr
=
INameSpaceTreeControl_InsertRoot
(
pnstc
,
-
1
,
psidesktop
,
SHCONTF_FOLDERS
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Got (0x%08x)
\n
"
,
hr
);
hr
=
INameSpaceTreeControl_InsertRoot
(
pnstc
,
50
,
psidesktop
,
SHCONTF_FOLDERS
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Got (0x%08x)
\n
"
,
hr
);
hr
=
INameSpaceTreeControl_InsertRoot
(
pnstc
,
1
,
psidesktop
,
SHCONTF_FOLDERS
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Got (0x%08x)
\n
"
,
hr
);
IShellItem_Release
(
psidesktop
);
IShellItem_Release
(
psidesktop2
);
hr
=
INameSpaceTreeControl_QueryInterface
(
pnstc
,
&
IID_IOleWindow
,
(
void
**
)
&
pow
);
ok
(
hr
==
S_OK
,
"Got 0x%08x
\n
"
,
hr
);
if
(
SUCCEEDED
(
hr
))
...
...
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