[PATCH 4/5] explorerframe/nstc: Implement Set/GetControlStyle(2). (resend)
David Hedberg
david.hedberg at gmail.com
Mon Aug 2 20:43:09 CDT 2010
---
dlls/explorerframe/nstc.c | 81 +++++++++++--
dlls/explorerframe/tests/nstc.c | 255 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 327 insertions(+), 9 deletions(-)
diff --git a/dlls/explorerframe/nstc.c b/dlls/explorerframe/nstc.c
index 2c73471..70e7e1c 100644
--- a/dlls/explorerframe/nstc.c
+++ b/dlls/explorerframe/nstc.c
@@ -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
@@ -477,8 +481,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,
@@ -486,8 +536,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,
@@ -495,8 +548,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,
@@ -504,8 +566,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 = {
diff --git a/dlls/explorerframe/tests/nstc.c b/dlls/explorerframe/tests/nstc.c
index 6a72eb3..dc8f8f3 100644
--- a/dlls/explorerframe/tests/nstc.c
+++ b/dlls/explorerframe/tests/nstc.c
@@ -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();
--
1.7.2
More information about the wine-patches
mailing list