From: Jacek Caban Subject: [PATCH 2/2] ieframe: Return some verbs in IEnumOLEVERB:Next. Message-Id: <5432989D.1050601@codeweavers.com> Date: Mon, 06 Oct 2014 15:26:53 +0200 --- dlls/ieframe/oleobject.c | 16 +++++++++++++- dlls/ieframe/tests/webbrowser.c | 49 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/dlls/ieframe/oleobject.c b/dlls/ieframe/oleobject.c index 0bcf163..d611231 100644 --- a/dlls/ieframe/oleobject.c +++ b/dlls/ieframe/oleobject.c @@ -292,8 +292,8 @@ static void release_client_site(WebBrowser *This) typedef struct { IEnumOLEVERB IEnumOLEVERB_iface; - LONG ref; + LONG iter; } EnumOLEVERB; static inline EnumOLEVERB *impl_from_IEnumOLEVERB(IEnumOLEVERB *iface) @@ -348,10 +348,20 @@ static HRESULT WINAPI EnumOLEVERB_Next(IEnumOLEVERB *iface, ULONG celt, OLEVERB { EnumOLEVERB *This = impl_from_IEnumOLEVERB(iface); + static const OLEVERB verbs[] = + {{OLEIVERB_PRIMARY},{OLEIVERB_INPLACEACTIVATE},{OLEIVERB_UIACTIVATE},{OLEIVERB_SHOW},{OLEIVERB_HIDE}}; + TRACE("(%p)->(%u %p %p)\n", This, celt, rgelt, pceltFetched); + /* There are a few problems with this implementation, but that's how it seems to work in native. See tests. */ if(pceltFetched) *pceltFetched = 0; + + if(This->iter == sizeof(verbs)/sizeof(*verbs)) + return S_FALSE; + + if(celt) + *rgelt = verbs[This->iter++]; return S_OK; } @@ -365,7 +375,10 @@ static HRESULT WINAPI EnumOLEVERB_Skip(IEnumOLEVERB *iface, ULONG celt) static HRESULT WINAPI EnumOLEVERB_Reset(IEnumOLEVERB *iface) { EnumOLEVERB *This = impl_from_IEnumOLEVERB(iface); + TRACE("(%p)\n", This); + + This->iter = 0; return S_OK; } @@ -599,6 +612,7 @@ static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEn ret->IEnumOLEVERB_iface.lpVtbl = &EnumOLEVERBVtbl; ret->ref = 1; + ret->iter = 0; *ppEnumOleVerb = &ret->IEnumOLEVERB_iface; return S_OK; diff --git a/dlls/ieframe/tests/webbrowser.c b/dlls/ieframe/tests/webbrowser.c index 27598cf..5973900 100644 --- a/dlls/ieframe/tests/webbrowser.c +++ b/dlls/ieframe/tests/webbrowser.c @@ -1997,6 +1997,30 @@ static void test_ClassInfo(IWebBrowser2 *unk) IProvideClassInfo2_Release(class_info); } +#define expect_oleverb(a,b) _expect_oleverb(__LINE__,a,b) +static void _expect_oleverb(unsigned line, const OLEVERB *verb, LONG exverb) +{ + ok_(__FILE__,line)(verb->lVerb == exverb, "verb->lVerb = %d, expected %d\n", verb->lVerb, exverb); + ok_(__FILE__,line)(!verb->lpszVerbName, "verb->lpszVerbName = %s\n", wine_dbgstr_w(verb->lpszVerbName)); + ok_(__FILE__,line)(!verb->fuFlags, "verb->fuFlags = %x\n", verb->fuFlags); + ok_(__FILE__,line)(!verb->grfAttribs, "verb->grfAttribs = %x\n", verb->grfAttribs); +} + +#define test_next_oleverb(a,b) _test_next_oleverb(__LINE__,a,b) +static void _test_next_oleverb(unsigned line, IEnumOLEVERB *enum_verbs, LONG exverb) +{ + ULONG fetched = 0xdeadbeef; + OLEVERB verb; + HRESULT hres; + + fetched = 0xdeadbeef; + memset(&verb, 0xa, sizeof(verb)); + hres = IEnumOLEVERB_Next(enum_verbs, 1, &verb, &fetched); + ok_(__FILE__,line)(hres == S_OK, "Next failed: %08x\n", hres); + ok_(__FILE__,line)(!fetched, "fetched = %d\n", fetched); + _expect_oleverb(line, &verb, exverb); +} + static void test_EnumVerbs(IWebBrowser2 *wb) { IEnumOLEVERB *enum_verbs; @@ -2014,13 +2038,32 @@ static void test_EnumVerbs(IWebBrowser2 *wb) ok(enum_verbs != NULL, "enum_verbs == NULL\n"); fetched = 0xdeadbeef; + memset(verbs, 0xa, sizeof(verbs)); + verbs[1].lVerb = 0xdeadbeef; hres = IEnumOLEVERB_Next(enum_verbs, sizeof(verbs)/sizeof(*verbs), verbs, &fetched); ok(hres == S_OK, "Next failed: %08x\n", hres); ok(!fetched, "fetched = %d\n", fetched); + /* Although fetched==0, an element is returned. */ + expect_oleverb(verbs, OLEIVERB_PRIMARY); + /* The first argument is ignorred and always one element is returned. */ + ok(verbs[1].lVerb == 0xdeadbeef, "verbs[1].lVerb = %x\n", verbs[1].lVerb); + + test_next_oleverb(enum_verbs, OLEIVERB_INPLACEACTIVATE); + test_next_oleverb(enum_verbs, OLEIVERB_UIACTIVATE); + test_next_oleverb(enum_verbs, OLEIVERB_SHOW); + test_next_oleverb(enum_verbs, OLEIVERB_HIDE); + /* There is anouther verb, returned correctly. */ fetched = 0xdeadbeef; - hres = IEnumOLEVERB_Next(enum_verbs, 1, verbs, &fetched); - ok(hres == S_OK, "Next failed: %08x\n", hres); + memset(verbs, 0xa, sizeof(verbs)); + verbs[0].lVerb = 0xdeadbeef; + hres = IEnumOLEVERB_Next(enum_verbs, sizeof(verbs)/sizeof(*verbs), verbs, &fetched); + todo_wine ok(hres == S_OK, "Next failed: %08x\n", hres); + todo_wine ok(fetched == 1, "fetched = %d\n", fetched); + todo_wine ok(verbs[0].lVerb != 0xdeadbeef, "verbs[0].lVerb = %x\n", verbs[0].lVerb); + + hres = IEnumOLEVERB_Next(enum_verbs, sizeof(verbs)/sizeof(*verbs), verbs, &fetched); + ok(hres == S_FALSE, "Next failed: %08x\n", hres); ok(!fetched, "fetched = %d\n", fetched); hres = IEnumOLEVERB_Reset(enum_verbs); @@ -2042,6 +2085,8 @@ static void test_EnumVerbs(IWebBrowser2 *wb) ok(hres == S_OK, "Next failed: %08x\n", hres); ok(!fetched, "fetched = %d\n", fetched); + test_next_oleverb(enum_verbs, OLEIVERB_SHOW); + IEnumOLEVERB_Release(enum_verbs); }