explorerframe: Implement Set/GetControlStyle(2).

This commit is contained in:
David Hedberg 2010-08-03 03:43:09 +02:00 committed by Alexandre Julliard
parent c32fa3485b
commit a5cb7652de
2 changed files with 327 additions and 9 deletions

View File

@ -43,12 +43,16 @@ typedef struct {
HWND hwnd_tv;
NSTCSTYLE style;
NSTCSTYLE2 style2;
} NSTC2Impl;
static const DWORD unsupported_styles =
NSTCS_SINGLECLICKEXPAND | NSTCS_NOREPLACEOPEN | NSTCS_NOORDERSTREAM | NSTCS_FAVORITESMODE |
NSTCS_EMPTYTEXT | NSTCS_ALLOWJUNCTIONS | NSTCS_SHOWTABSBUTTON | NSTCS_SHOWDELETEBUTTON |
NSTCS_SHOWREFRESHBUTTON | NSTCS_SPRINGEXPAND | NSTCS_RICHTOOLTIP | NSTCS_NOINDENTCHECKS;
static const DWORD unsupported_styles2 =
NSTCS2_INTERRUPTNOTIFICATIONS | NSTCS2_SHOWNULLSPACEMENU | NSTCS2_DISPLAYPADDING |
NSTCS2_DISPLAYPINNEDONLY | NTSCS2_NOSINGLETONAUTOEXPAND | NTSCS2_NEVERINSERTNONENUMERATED;
/*************************************************************************
* NamespaceTree helper functions
@ -476,8 +480,54 @@ static HRESULT WINAPI NSTC2_fnSetControlStyle(INameSpaceTreeControl2* iface,
NSTCSTYLE nstcsStyle)
{
NSTC2Impl *This = (NSTC2Impl*)iface;
FIXME("stub, %p (%x, %x)\n", This, nstcsMask, nstcsStyle);
return E_NOTIMPL;
static const DWORD tv_style_flags =
NSTCS_HASEXPANDOS | NSTCS_HASLINES | NSTCS_FULLROWSELECT |
NSTCS_HORIZONTALSCROLL | NSTCS_ROOTHASEXPANDO |
NSTCS_SHOWSELECTIONALWAYS | NSTCS_NOINFOTIP | NSTCS_EVENHEIGHT |
NSTCS_DISABLEDRAGDROP | NSTCS_NOEDITLABELS | NSTCS_CHECKBOXES;
static const DWORD host_style_flags = NSTCS_TABSTOP | NSTCS_BORDER;
static const DWORD nstc_flags =
NSTCS_SINGLECLICKEXPAND | NSTCS_NOREPLACEOPEN | NSTCS_NOORDERSTREAM |
NSTCS_FAVORITESMODE | NSTCS_EMPTYTEXT | NSTCS_ALLOWJUNCTIONS |
NSTCS_SHOWTABSBUTTON | NSTCS_SHOWDELETEBUTTON | NSTCS_SHOWREFRESHBUTTON;
TRACE("%p (%x, %x)\n", This, nstcsMask, nstcsStyle);
/* Fail if there is an attempt to set an unknown style. */
if(nstcsMask & ~(tv_style_flags | host_style_flags | nstc_flags))
return E_FAIL;
if(nstcsMask & tv_style_flags)
{
DWORD new_style;
treeview_style_from_nstcs(This, nstcsStyle, nstcsMask, &new_style);
SetWindowLongPtrW(This->hwnd_tv, GWL_STYLE, new_style);
}
/* Flags affecting the host window */
if(nstcsMask & NSTCS_BORDER)
{
DWORD new_style = GetWindowLongPtrW(This->hwnd_main, GWL_STYLE);
new_style &= ~WS_BORDER;
new_style |= nstcsStyle & NSTCS_BORDER ? WS_BORDER : 0;
SetWindowLongPtrW(This->hwnd_main, GWL_STYLE, new_style);
}
if(nstcsMask & NSTCS_TABSTOP)
{
DWORD new_style = GetWindowLongPtrW(This->hwnd_main, GWL_EXSTYLE);
new_style &= ~WS_EX_CONTROLPARENT;
new_style |= nstcsStyle & NSTCS_TABSTOP ? WS_EX_CONTROLPARENT : 0;
SetWindowLongPtrW(This->hwnd_main, GWL_EXSTYLE, new_style);
}
if((nstcsStyle & nstcsMask) & unsupported_styles)
FIXME("mask & style (0x%08x) contains unsupported style(s): 0x%08x\n",
(nstcsStyle & nstcsMask),
(nstcsStyle & nstcsMask) & unsupported_styles);
This->style &= ~nstcsMask;
This->style |= (nstcsStyle & nstcsMask);
return S_OK;
}
static HRESULT WINAPI NSTC2_fnGetControlStyle(INameSpaceTreeControl2* iface,
@ -485,8 +535,11 @@ static HRESULT WINAPI NSTC2_fnGetControlStyle(INameSpaceTreeControl2* iface,
NSTCSTYLE *pnstcsStyle)
{
NSTC2Impl *This = (NSTC2Impl*)iface;
FIXME("stub, %p (%x, %p)\n", This, nstcsMask, pnstcsStyle);
return E_NOTIMPL;
TRACE("%p (%x, %p)\n", This, nstcsMask, pnstcsStyle);
*pnstcsStyle = (This->style & nstcsMask);
return S_OK;
}
static HRESULT WINAPI NSTC2_fnSetControlStyle2(INameSpaceTreeControl2* iface,
@ -494,8 +547,17 @@ static HRESULT WINAPI NSTC2_fnSetControlStyle2(INameSpaceTreeControl2* iface,
NSTCSTYLE2 nstcsStyle)
{
NSTC2Impl *This = (NSTC2Impl*)iface;
FIXME("stub, %p (%x, %x)\n", This, nstcsMask, nstcsStyle);
return E_NOTIMPL;
TRACE("%p (%x, %x)\n", This, nstcsMask, nstcsStyle);
if((nstcsStyle & nstcsMask) & unsupported_styles2)
FIXME("mask & style (0x%08x) contains unsupported style(s): 0x%08x\n",
(nstcsStyle & nstcsMask),
(nstcsStyle & nstcsMask) & unsupported_styles2);
This->style2 &= ~nstcsMask;
This->style2 |= (nstcsStyle & nstcsMask);
return S_OK;
}
static HRESULT WINAPI NSTC2_fnGetControlStyle2(INameSpaceTreeControl2* iface,
@ -503,8 +565,11 @@ static HRESULT WINAPI NSTC2_fnGetControlStyle2(INameSpaceTreeControl2* iface,
NSTCSTYLE2 *pnstcsStyle)
{
NSTC2Impl *This = (NSTC2Impl*)iface;
FIXME("stub, %p (%x, %p)\n", This, nstcsMask, pnstcsStyle);
return E_NOTIMPL;
TRACE("%p (%x, %p)\n", This, nstcsMask, pnstcsStyle);
*pnstcsStyle = (This->style2 & nstcsMask);
return S_OK;
}
static const INameSpaceTreeControl2Vtbl vt_INameSpaceTreeControl2 = {

View File

@ -181,6 +181,252 @@ static BOOL test_initialization(void)
return TRUE;
}
static void test_basics(void)
{
INameSpaceTreeControl *pnstc;
INameSpaceTreeControl2 *pnstc2;
IOleWindow *pow;
HRESULT hr;
UINT i, res;
RECT rc;
hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
&IID_INameSpaceTreeControl, (void**)&pnstc);
ok(hr == S_OK, "Failed to initialize control (0x%08x)\n", hr);
/* Initialize the control */
rc.top = rc.left = 0; rc.right = rc.bottom = 200;
hr = INameSpaceTreeControl_Initialize(pnstc, hwnd, &rc, 0);
ok(hr == S_OK, "Got (0x%08x)\n", hr);
/* Set/GetControlStyle(2) */
hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_INameSpaceTreeControl2, (void**)&pnstc2);
ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Got 0x%08x\n", hr);
if(SUCCEEDED(hr))
{
DWORD tmp;
NSTCSTYLE style;
NSTCSTYLE2 style2;
static const NSTCSTYLE2 styles2[] =
{ NSTCS2_INTERRUPTNOTIFICATIONS,NSTCS2_SHOWNULLSPACEMENU,
NSTCS2_DISPLAYPADDING,NSTCS2_DISPLAYPINNEDONLY,
NTSCS2_NOSINGLETONAUTOEXPAND,NTSCS2_NEVERINSERTNONENUMERATED, 0};
/* We can use this to differentiate between two versions of
* this interface. Windows 7 returns hr == S_OK. */
hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0, 0);
ok(hr == S_OK || broken(hr == E_FAIL), "Got 0x%08x\n", hr);
if(hr == S_OK)
{
static const NSTCSTYLE styles_setable[] =
{ NSTCS_HASEXPANDOS,NSTCS_HASLINES,NSTCS_SINGLECLICKEXPAND,
NSTCS_FULLROWSELECT,NSTCS_HORIZONTALSCROLL,
NSTCS_ROOTHASEXPANDO,NSTCS_SHOWSELECTIONALWAYS,NSTCS_NOINFOTIP,
NSTCS_EVENHEIGHT,NSTCS_NOREPLACEOPEN,NSTCS_DISABLEDRAGDROP,
NSTCS_NOORDERSTREAM,NSTCS_BORDER,NSTCS_NOEDITLABELS,
NSTCS_TABSTOP,NSTCS_FAVORITESMODE,NSTCS_EMPTYTEXT,NSTCS_CHECKBOXES,
NSTCS_ALLOWJUNCTIONS,NSTCS_SHOWTABSBUTTON,NSTCS_SHOWDELETEBUTTON,
NSTCS_SHOWREFRESHBUTTON, 0};
static const NSTCSTYLE styles_nonsetable[] =
{ NSTCS_SPRINGEXPAND, NSTCS_RICHTOOLTIP, NSTCS_AUTOHSCROLL,
NSTCS_FADEINOUTEXPANDOS,
NSTCS_PARTIALCHECKBOXES, NSTCS_EXCLUSIONCHECKBOXES,
NSTCS_DIMMEDCHECKBOXES, NSTCS_NOINDENTCHECKS,0};
/* Set/GetControlStyle */
style = style2 = 0xdeadbeef;
hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style == 0, "Got style %x\n", style);
hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0, 0xFFFFFFF);
ok(hr == S_OK, "Got 0x%08x\n", hr);
hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0xFFFFFFFF, 0);
ok(hr == E_FAIL, "Got 0x%08x\n", hr);
hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, 0xFFFFFFFF, 0xFFFFFFFF);
ok(hr == E_FAIL, "Got 0x%08x\n", hr);
tmp = 0;
for(i = 0; styles_setable[i] != 0; i++)
{
hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_setable[i], styles_setable[i]);
ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles_setable[i]);
if(SUCCEEDED(hr)) tmp |= styles_setable[i];
}
for(i = 0; styles_nonsetable[i] != 0; i++)
{
hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_nonsetable[i], styles_nonsetable[i]);
ok(hr == E_FAIL, "Got 0x%08x (%x)\n", hr, styles_nonsetable[i]);
}
hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style == tmp, "Got style %x (expected %x)\n", style, tmp);
if(SUCCEEDED(hr))
{
DWORD tmp2;
for(i = 0; styles_setable[i] != 0; i++)
{
hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, styles_setable[i], &tmp2);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(tmp2 == (style & styles_setable[i]), "Got %x\n", tmp2);
}
}
for(i = 0; styles_setable[i] != 0; i++)
{
hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_setable[i], 0);
ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles_setable[i]);
}
for(i = 0; styles_nonsetable[i] != 0; i++)
{
hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles_nonsetable[i], 0);
ok(hr == E_FAIL, "Got 0x%08x (%x)\n", hr, styles_nonsetable[i]);
}
hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style == 0, "Got style %x\n", style);
/* Set/GetControlStyle2 */
hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style2 == 0, "Got style %x\n", style2);
hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0, 0);
ok(hr == S_OK, "Got 0x%08x\n", hr);
hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0, 0xFFFFFFFF);
ok(hr == S_OK, "Got 0x%08x\n", hr);
hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFFFFFFFF, 0);
ok(hr == S_OK, "Got 0x%08x\n", hr);
hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFFFFFFFF, 0xFFFFFFFF);
ok(hr == S_OK, "Got 0x%08x\n", hr);
hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, 0xFFFFFFFF, 0);
ok(hr == S_OK, "Got 0x%08x\n", hr);
hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style2 == 0x00000000, "Got style %x\n", style2);
hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFF, &style2);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style2 == 0, "Got style %x\n", style2);
tmp = 0;
for(i = 0; styles2[i] != 0; i++)
{
hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, styles2[i], styles2[i]);
ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles2[i]);
if(SUCCEEDED(hr)) tmp |= styles2[i];
}
hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFF, &style2);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style2 == tmp, "Got style %x (expected %x)\n", style2, tmp);
if(SUCCEEDED(hr))
{
DWORD tmp2;
for(i = 0; styles2[i] != 0; i++)
{
hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, styles2[i], &tmp2);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(tmp2 == (style2 & styles2[i]), "Got %x\n", tmp2);
}
}
for(i = 0; styles2[i] != 0; i++)
{
hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, styles2[i], 0);
ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles2[i]);
}
hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFF, &style2);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style2 == 0, "Got style %x (expected 0)\n", style2);
}
else
{
/* 64-bit Windows Vista (others?) seems to have a somewhat
* different idea of how the methods of this interface
* should behave. */
static const NSTCSTYLE styles[] =
{ NSTCS_HASEXPANDOS,NSTCS_HASLINES,NSTCS_SINGLECLICKEXPAND,
NSTCS_FULLROWSELECT,NSTCS_SPRINGEXPAND,NSTCS_HORIZONTALSCROLL,
NSTCS_RICHTOOLTIP, NSTCS_AUTOHSCROLL,
NSTCS_FADEINOUTEXPANDOS,
NSTCS_PARTIALCHECKBOXES,NSTCS_EXCLUSIONCHECKBOXES,
NSTCS_DIMMEDCHECKBOXES, NSTCS_NOINDENTCHECKS,
NSTCS_ROOTHASEXPANDO,NSTCS_SHOWSELECTIONALWAYS,NSTCS_NOINFOTIP,
NSTCS_EVENHEIGHT,NSTCS_NOREPLACEOPEN,NSTCS_DISABLEDRAGDROP,
NSTCS_NOORDERSTREAM,NSTCS_BORDER,NSTCS_NOEDITLABELS,
NSTCS_TABSTOP,NSTCS_FAVORITESMODE,NSTCS_EMPTYTEXT,NSTCS_CHECKBOXES,
NSTCS_ALLOWJUNCTIONS,NSTCS_SHOWTABSBUTTON,NSTCS_SHOWDELETEBUTTON,
NSTCS_SHOWREFRESHBUTTON, 0};
trace("Detected broken INameSpaceTreeControl2.\n");
style = 0xdeadbeef;
hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, 0xFFFFFFFF, &style);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style == 0xdeadbeef, "Got style %x\n", style);
hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style2 == 0, "Got style %x\n", style2);
tmp = 0;
for(i = 0; styles[i] != 0; i++)
{
hr = INameSpaceTreeControl2_SetControlStyle(pnstc2, styles[i], styles[i]);
ok(hr == E_FAIL || ((styles[i] & NSTCS_SPRINGEXPAND) && hr == S_OK),
"Got 0x%08x (%x)\n", hr, styles[i]);
if(SUCCEEDED(hr)) tmp |= styles[i];
}
style = 0xdeadbeef;
hr = INameSpaceTreeControl2_GetControlStyle(pnstc2, tmp, &style);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style == 0xdeadbeef, "Got style %x\n", style);
tmp = 0;
for(i = 0; styles2[i] != 0; i++)
{
hr = INameSpaceTreeControl2_SetControlStyle2(pnstc2, styles2[i], styles2[i]);
ok(hr == S_OK, "Got 0x%08x (%x)\n", hr, styles2[i]);
if(SUCCEEDED(hr)) tmp |= styles2[i];
}
style2 = 0xdeadbeef;
hr = INameSpaceTreeControl2_GetControlStyle2(pnstc2, 0xFFFFFFFF, &style2);
ok(hr == S_OK, "Got 0x%08x\n", hr);
ok(style2 == tmp, "Got style %x\n", style2);
}
INameSpaceTreeControl2_Release(pnstc2);
}
else
{
skip("INameSpaceTreeControl2 missing.\n");
}
hr = INameSpaceTreeControl_QueryInterface(pnstc, &IID_IOleWindow, (void**)&pow);
ok(hr == S_OK, "Got 0x%08x\n", hr);
if(SUCCEEDED(hr))
{
HWND hwnd_nstc;
hr = IOleWindow_GetWindow(pow, &hwnd_nstc);
ok(hr == S_OK, "Got 0x%08x\n", hr);
DestroyWindow(hwnd_nstc);
IOleWindow_Release(pow);
}
res = INameSpaceTreeControl_Release(pnstc);
ok(!res, "res was %d!\n", res);
}
static void setup_window(void)
{
WNDCLASSA wc;
@ -206,7 +452,14 @@ START_TEST(nstc)
OleInitialize(NULL);
setup_window();
test_initialization();
if(test_initialization())
{
test_basics();
}
else
{
win_skip("No NamespaceTreeControl (or instantiation failed).\n");
}
destroy_window();
OleUninitialize();