Changelog: - Added IOleCommandTerget interface to the test - Make Wine pass the test - Fix bug reported by Saulius Krasuckas Index: dlls/mshtml/oleobj.c =================================================================== RCS file: /home/wine/wine/dlls/mshtml/oleobj.c,v retrieving revision 1.15 diff -u -p -r1.15 oleobj.c --- dlls/mshtml/oleobj.c 12 Aug 2005 15:51:55 -0000 1.15 +++ dlls/mshtml/oleobj.c 17 Aug 2005 19:16:09 -0000 @@ -27,6 +27,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "shlguid.h" #include "wine/debug.h" @@ -62,6 +63,7 @@ static HRESULT WINAPI OleObject_SetClien { HTMLDocument *This = OLEOBJ_THIS(iface); IDocHostUIHandler *pDocHostUIHandler = NULL; + IOleCommandTarget *cmdtrg = NULL; HRESULT hres; TRACE("(%p)->(%p)\n", This, pClientSite); @@ -132,6 +134,21 @@ static HRESULT WINAPI OleObject_SetClien } } + hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleCommandTarget, (void**)&cmdtrg); + if(SUCCEEDED(hres)) { + VARIANT var; + OLECMD cmd = {OLECMDID_SETPROGRESSTEXT, 0}; + + IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &cmd, NULL); + + V_VT(&var) = VT_I4; + V_I4(&var) = 0; + IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSMAX, 0, &var, NULL); + IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSPOS, 0, &var, NULL); + + IOleCommandTarget_Release(cmdtrg); + } + IOleClientSite_AddRef(pClientSite); This->client = pClientSite; This->hostui = pDocHostUIHandler; @@ -719,7 +736,7 @@ static HRESULT WINAPI OleCommandTarget_Q ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) { HTMLDocument *This = CMDTARGET_THIS(iface); - HRESULT hres = S_OK; + HRESULT hres = S_OK, hr; TRACE("(%p)->(%s %ld %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText); @@ -732,8 +749,29 @@ static HRESULT WINAPI OleCommandTarget_Q prgCmds[i].cmdf = 0; hres = OLECMDERR_E_NOTSUPPORTED; }else { - prgCmds[i].cmdf = exec_table[prgCmds[i].cmdID].cmdf; - TRACE("cmdID = %ld returning %lx\n", prgCmds[i].cmdID, prgCmds[i].cmdf); + if(prgCmds[i].cmdID == OLECMDID_OPEN || prgCmds[i].cmdID == OLECMDID_NEW) { + IOleCommandTarget *cmdtrg = NULL; + OLECMD olecmd; + + prgCmds[i].cmdf = OLECMDF_SUPPORTED; + if(This->client) { + hr = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget, + (void**)&cmdtrg); + if(SUCCEEDED(hr)) { + olecmd.cmdID = prgCmds[i].cmdID; + olecmd.cmdf = 0; + + hr = IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &olecmd, NULL); + if(SUCCEEDED(hr) && olecmd.cmdf) + prgCmds[i].cmdf = olecmd.cmdf; + } + }else { + ERR("This->client == NULL, native would crash\n"); + } + }else { + prgCmds[i].cmdf = exec_table[prgCmds[i].cmdID].cmdf; + TRACE("cmdID = %ld returning %lx\n", prgCmds[i].cmdID, prgCmds[i].cmdf); + } hres = S_OK; } } @@ -760,6 +798,9 @@ static HRESULT WINAPI OleCommandTarget_E } return exec_table[nCmdID].func(This, nCmdexecopt, pvaIn, pvaOut); + }else if(IsEqualGUID(&CGID_ShellDocView, pguidCmdGroup)) { + FIXME("unsupported nCmdID %ld of CGID_ShellDocView group\n", nCmdID); + return OLECMDERR_E_UNKNOWNGROUP; } FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup)); Index: dlls/mshtml/view.c =================================================================== RCS file: /home/wine/wine/dlls/mshtml/view.c,v retrieving revision 1.14 diff -u -p -r1.14 view.c --- dlls/mshtml/view.c 15 Aug 2005 09:41:30 -0000 1.14 +++ dlls/mshtml/view.c 17 Aug 2005 19:16:09 -0000 @@ -127,6 +127,7 @@ static HRESULT activate_window(HTMLDocum { IOleInPlaceUIWindow *pIPWnd; IOleInPlaceFrame *pIPFrame; + IOleCommandTarget *cmdtrg; RECT posrect, cliprect; OLEINPLACEFRAMEINFO frameinfo; HWND parent_hwnd; @@ -193,6 +194,20 @@ static HRESULT activate_window(HTMLDocum WARN("OnInPlaceActivate failed: %08lx\n", hres); This->in_place_active = FALSE; return hres; + } + + hres = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget, (void**)&cmdtrg); + if(SUCCEEDED(hres)) { + VARIANT var; + + IOleInPlaceFrame_SetStatusText(pIPFrame, NULL); + + V_VT(&var) = VT_I4; + V_I4(&var) = 0; + IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSMAX, 0, &var, NULL); + IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSPOS, 0, &var, NULL); + + IOleCommandTarget_Release(cmdtrg); } if(This->frame) Index: dlls/mshtml/tests/htmldoc.c =================================================================== RCS file: /home/wine/wine/dlls/mshtml/tests/htmldoc.c,v retrieving revision 1.9 diff -u -p -r1.9 htmldoc.c --- dlls/mshtml/tests/htmldoc.c 15 Aug 2005 20:50:41 -0000 1.9 +++ dlls/mshtml/tests/htmldoc.c 17 Aug 2005 19:16:10 -0000 @@ -27,6 +27,10 @@ #include "mshtml.h" #include "docobj.h" #include "mshtmhst.h" +#include "shlguid.h" + +#include "initguid.h" +DEFINE_SHLGUID(CGID_Undocumented, 0x000214D4L, 0, 0); #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE @@ -62,6 +66,12 @@ DEFINE_EXPECT(GetHostInfo); DEFINE_EXPECT(HideUI); DEFINE_EXPECT(GetOptionKeyPath); DEFINE_EXPECT(GetOverrideKeyPath); +DEFINE_EXPECT(SetStatusText); +DEFINE_EXPECT(QueryStatus_SETPROGRESSTEXT); +DEFINE_EXPECT(QueryStatus_OPEN); +DEFINE_EXPECT(QueryStatus_NEW); +DEFINE_EXPECT(Exec_SETPROGRESSMAX); +DEFINE_EXPECT(Exec_SETPROGRESSPOS); static BOOL expect_LockContainer_fLock; static BOOL expect_SetActiveObject_active; @@ -204,8 +214,9 @@ static HRESULT WINAPI InPlaceFrame_Remov static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText) { - ok(0, "unexpected call\n"); - return E_NOTIMPL; + CHECK_EXPECT(SetStatusText); + ok(pszStatusText == NULL, "pszStatusText=%p, expected NULL\n", pszStatusText); + return S_OK; } static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable) @@ -508,6 +519,9 @@ static HRESULT WINAPI DocumentSite_Activ SET_EXPECT(GetWindowContext); SET_EXPECT(GetWindow); SET_EXPECT(OnInPlaceActivate); + SET_EXPECT(SetStatusText); + SET_EXPECT(Exec_SETPROGRESSMAX); + SET_EXPECT(Exec_SETPROGRESSPOS); SET_EXPECT(OnUIActivate); SET_EXPECT(SetActiveObject); SET_EXPECT(ShowUI); @@ -525,12 +539,15 @@ static HRESULT WINAPI DocumentSite_Activ CHECK_CALLED(GetWindowContext); CHECK_CALLED(GetWindow); CHECK_CALLED(OnInPlaceActivate); + CHECK_CALLED(SetStatusText); + CHECK_CALLED(Exec_SETPROGRESSMAX); + CHECK_CALLED(Exec_SETPROGRESSPOS); CHECK_CALLED(OnUIActivate); CHECK_CALLED(SetActiveObject); CHECK_CALLED(ShowUI); if(activeobj) { - IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd); + hres = IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd); ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); ok(hwnd != NULL, "hwnd == NULL\n"); if(last_hwnd) @@ -541,7 +558,7 @@ static HRESULT WINAPI DocumentSite_Activ ok(hres == S_OK, "UIActivate failed: %08lx\n", hres); if(activeobj) { - IOleInPlaceActiveObject_GetWindow(activeobj, &tmp_hwnd); + hres = IOleInPlaceActiveObject_GetWindow(activeobj, &tmp_hwnd); ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); ok(tmp_hwnd == hwnd, "tmp_hwnd=%p, expected %p\n", tmp_hwnd, hwnd); } @@ -558,15 +575,22 @@ static HRESULT WINAPI DocumentSite_Activ SET_EXPECT(GetWindowContext); SET_EXPECT(GetWindow); SET_EXPECT(OnInPlaceActivate); + SET_EXPECT(SetStatusText); + SET_EXPECT(Exec_SETPROGRESSMAX); + SET_EXPECT(Exec_SETPROGRESSPOS); + SET_EXPECT(OnUIActivate); hres = IOleDocumentView_Show(view, TRUE); ok(hres == S_OK, "Show failed: %08lx\n", hres); CHECK_CALLED(CanInPlaceActivate); CHECK_CALLED(GetWindowContext); CHECK_CALLED(GetWindow); CHECK_CALLED(OnInPlaceActivate); + CHECK_CALLED(SetStatusText); + CHECK_CALLED(Exec_SETPROGRESSMAX); + CHECK_CALLED(Exec_SETPROGRESSPOS); if(activeobj) { - IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd); + hres = IOleInPlaceActiveObject_GetWindow(activeobj, &hwnd); ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); ok(hwnd != NULL, "hwnd == NULL\n"); if(last_hwnd) @@ -765,6 +789,96 @@ static const IDocHostUIHandler2Vtbl DocH static IDocHostUIHandler2 DocHostUIHandler = { &DocHostUIHandlerVtbl }; +static HRESULT WINAPI OleCommandTarget_QueryInterface(IOleCommandTarget *iface, + REFIID riid, void **ppv) +{ + return QueryInterface(riid, ppv); +} + +static ULONG WINAPI OleCommandTarget_AddRef(IOleCommandTarget *iface) +{ + return 2; +} + +static ULONG WINAPI OleCommandTarget_Release(IOleCommandTarget *iface) +{ + return 1; +} + +static HRESULT WINAPI OleCommandTarget_QueryStatus(IOleCommandTarget *iface, const GUID *pguidCmdGroup, + ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) +{ + ok(!pguidCmdGroup, "pguidCmdGroup != MULL\n"); + ok(cCmds == 1, "cCmds=%ld, expected 1\n", cCmds); + ok(!pCmdText, "pCmdText != NULL\n"); + + switch(prgCmds[0].cmdID) { + case OLECMDID_SETPROGRESSTEXT: + CHECK_EXPECT(QueryStatus_SETPROGRESSTEXT); + prgCmds[0].cmdf = OLECMDF_ENABLED; + return S_OK; + case OLECMDID_OPEN: + CHECK_EXPECT(QueryStatus_OPEN); + prgCmds[0].cmdf = 0; + return S_OK; + case OLECMDID_NEW: + CHECK_EXPECT(QueryStatus_NEW); + prgCmds[0].cmdf = 0; + return S_OK; + default: + ok(0, "unexpected command %ld\n", prgCmds[0].cmdID); + }; + + return E_FAIL; +} + +static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID *pguidCmdGroup, + DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) +{ + if(!pguidCmdGroup) { + switch(nCmdID) { + case OLECMDID_SETPROGRESSMAX: + CHECK_EXPECT(Exec_SETPROGRESSMAX); + ok(pvaIn != NULL, "pvaIn == NULL\n"); + if(pvaIn) { + ok(V_VT(pvaIn) == VT_I4, "V_VT(pvaIn)=%d, expected VT_I4\n", V_VT(pvaIn)); + ok(V_I4(pvaIn) == 0, "V_I4(pvaIn)=%ld, expected 0\n", V_I4(pvaIn)); + } + ok(pvaOut == NULL, "pvaOut=%p, expected NULL\n", pvaOut); + return S_OK; + case OLECMDID_SETPROGRESSPOS: + CHECK_EXPECT(Exec_SETPROGRESSPOS); + ok(pvaIn != NULL, "pvaIn == NULL\n"); + if(pvaIn) { + ok(V_VT(pvaIn) == VT_I4, "V_VT(pvaIn)=%d, expected VT_I4\n", V_VT(pvaIn)); + ok(V_I4(pvaIn) == 0, "V_I4(pvaIn)=%ld, expected 0\n", V_I4(pvaIn)); + } + ok(pvaOut == NULL, "pvaOut=%p, expected NULL\n", pvaOut); + return S_OK; + default: + ok(0, "unexpected command %ld\n", nCmdID); + return E_FAIL; + }; + } + + if(IsEqualGUID(&CGID_Undocumented, pguidCmdGroup)) + return E_FAIL; /* TODO */ + + ok(0, "unexpected call"); + + return E_NOTIMPL; +} + +static IOleCommandTargetVtbl OleCommandTargetVtbl = { + OleCommandTarget_QueryInterface, + OleCommandTarget_AddRef, + OleCommandTarget_Release, + OleCommandTarget_QueryStatus, + OleCommandTarget_Exec +}; + +static IOleCommandTarget OleCommandTarget = { &OleCommandTargetVtbl }; + static HRESULT QueryInterface(REFIID riid, void **ppv) { *ppv = NULL; @@ -773,20 +887,20 @@ static HRESULT QueryInterface(REFIID rii *ppv = &ClientSite; else if(IsEqualGUID(&IID_IOleDocumentSite, riid)) *ppv = &DocumentSite; - else if(IsEqualGUID(&IID_IDocHostUIHandler, riid) || IsEqualGUID(&IID_IDocHostUIHandler2, riid)) { + else if(IsEqualGUID(&IID_IDocHostUIHandler, riid) || IsEqualGUID(&IID_IDocHostUIHandler2, riid)) *ppv = &DocHostUIHandler; - } else if(IsEqualGUID(&IID_IOleContainer, riid)) *ppv = &OleContainer; else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid)) *ppv = &InPlaceSite; else if(IsEqualGUID(&IID_IOleInPlaceUIWindow, riid) || IsEqualGUID(&IID_IOleInPlaceFrame, riid)) *ppv = &InPlaceFrame; + else if(IsEqualGUID(&IID_IOleCommandTarget , riid)) + *ppv = &OleCommandTarget; /* TODO: * IDispatch * IServiceProvider - * IOleCommandTarget * {D48A6EC6-6A4A-11CF-94A7-444553540000} * {7BB0B520-B1A7-11D2-BB23-00C04F79ABCD} * {000670BA-0000-0000-C000-000000000046} @@ -895,8 +1009,12 @@ static void test_OleCommandTarget(IUnkno cmds[i].cmdf = 0xf0f0; } + SET_EXPECT(QueryStatus_OPEN); + SET_EXPECT(QueryStatus_NEW); hres = IOleCommandTarget_QueryStatus(cmdtrg, NULL, sizeof(cmds)/sizeof(cmds[0]), cmds, NULL); ok(hres == S_OK, "QueryStatus failed: %08lx\n", hres); + CHECK_CALLED(QueryStatus_OPEN); + CHECK_CALLED(QueryStatus_NEW); for(i=0; i