/* * Copyright 2006 Jacek Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COBJMACROS #include #include #include "windef.h" #include "winbase.h" #include "ole2.h" #include "exdisp.h" #include "htiframe.h" #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE #define SET_EXPECT(func) \ expect_ ## func = TRUE #define CHECK_EXPECT(func) \ do { \ ok(expect_ ##func, "unexpected call " #func "\n"); \ expect_ ## func = FALSE; \ called_ ## func = TRUE; \ }while(0) #define CHECK_EXPECT2(func) \ do { \ ok(expect_ ##func, "unexpected call " #func "\n"); \ called_ ## func = TRUE; \ }while(0) #define CHECK_CALLED(func) \ do { \ ok(called_ ## func, "expected " #func "\n"); \ expect_ ## func = called_ ## func = FALSE; \ }while(0) DEFINE_EXPECT(GetContainer); DEFINE_EXPECT(Site_GetWindow); DEFINE_EXPECT(ShowObject); DEFINE_EXPECT(CanInPlaceActivate); DEFINE_EXPECT(OnInPlaceActivate); DEFINE_EXPECT(OnUIActivate); static HWND container_hwnd; static HRESULT QueryInterface(REFIID,void**); static HRESULT WINAPI OleContainer_QueryInterface(IOleContainer *iface, REFIID riid, void **ppv) { if(IsEqualGUID(&IID_ITargetContainer, riid)) return E_NOINTERFACE; /* TODO */ ok(0, "unexpected call\n"); return E_NOINTERFACE; } static ULONG WINAPI OleContainer_AddRef(IOleContainer *iface) { return 2; } static ULONG WINAPI OleContainer_Release(IOleContainer *iface) { return 1; } static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer *iface, IBindCtx *pbc, LPOLESTR pszDiaplayName, ULONG *pchEaten, IMoniker **ppmkOut) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer *iface, DWORD grfFlags, IEnumUnknown **ppenum) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI OleContainer_LockContainer(IOleContainer *iface, BOOL fLock) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static const IOleContainerVtbl OleContainerVtbl = { OleContainer_QueryInterface, OleContainer_AddRef, OleContainer_Release, OleContainer_ParseDisplayName, OleContainer_EnumObjects, OleContainer_LockContainer }; static IOleContainer OleContainer = { &OleContainerVtbl }; static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv) { return QueryInterface(riid, ppv); } static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface) { return 2; } static ULONG WINAPI ClientSite_Release(IOleClientSite *iface) { return 1; } static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAsign, DWORD dwWhichMoniker, IMoniker **ppmon) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer) { CHECK_EXPECT(GetContainer); ok(ppContainer != NULL, "ppContainer == NULL\n"); if(ppContainer) *ppContainer = &OleContainer; return S_OK; } static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface) { CHECK_EXPECT(ShowObject); return S_OK; } static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static const IOleClientSiteVtbl ClientSiteVtbl = { ClientSite_QueryInterface, ClientSite_AddRef, ClientSite_Release, ClientSite_SaveObject, ClientSite_GetMoniker, ClientSite_GetContainer, ClientSite_ShowObject, ClientSite_OnShowWindow, ClientSite_RequestNewObjectLayout }; static IOleClientSite ClientSite = { &ClientSiteVtbl }; static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSiteEx *iface, REFIID riid, void **ppv) { return QueryInterface(riid, ppv); } static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSiteEx *iface) { return 2; } static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSiteEx *iface) { return 1; } static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwnd) { CHECK_EXPECT(Site_GetWindow); ok(phwnd != NULL, "phwnd == NULL\n"); if(phwnd) *phwnd = container_hwnd; return S_OK; } static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx *iface, BOOL fEnterMode) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx *iface) { CHECK_EXPECT(CanInPlaceActivate); return S_OK; } static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx *iface) { CHECK_EXPECT(OnInPlaceActivate); return S_OK; } static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSiteEx *iface) { CHECK_EXPECT(OnUIActivate); return S_OK; } static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface, IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSiteEx *iface, SIZE scrollExtant) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx *iface, BOOL fUndoable) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx *iface) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSiteEx *iface) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx *iface) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSiteEx *iface, LPCRECT lprcPosRect) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI InPlaceSite_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface, BOOL *pNoRedraw, DWORD dwFlags) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *iface, BOOL fNoRedraw) { ok(0, "unexpected call\n"); return E_NOTIMPL; } static HRESULT WINAPI InPlaceSite_RequestUIActivate(IOleInPlaceSiteEx *iface) { ok(0, "unexpected call\n"); return S_OK; } static const IOleInPlaceSiteExVtbl InPlaceSiteExVtbl = { InPlaceSite_QueryInterface, InPlaceSite_AddRef, InPlaceSite_Release, InPlaceSite_GetWindow, InPlaceSite_ContextSensitiveHelp, InPlaceSite_CanInPlaceActivate, InPlaceSite_OnInPlaceActivate, InPlaceSite_OnUIActivate, InPlaceSite_GetWindowContext, InPlaceSite_Scroll, InPlaceSite_OnUIDeactivate, InPlaceSite_OnInPlaceDeactivate, InPlaceSite_DiscardUndoState, InPlaceSite_DeactivateAndUndo, InPlaceSite_OnPosRectChange, InPlaceSite_OnInPlaceActivateEx, InPlaceSite_OnInPlaceDeactivateEx, InPlaceSite_RequestUIActivate }; static IOleInPlaceSiteEx InPlaceSite = { &InPlaceSiteExVtbl }; static HRESULT QueryInterface(REFIID riid, void **ppv) { *ppv = NULL; if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid)) *ppv = &ClientSite; else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid) || IsEqualGUID(&IID_IOleInPlaceSiteEx, riid)) *ppv = &InPlaceSite; if(*ppv) return S_OK; return E_NOINTERFACE; } static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { return DefWindowProcW(hwnd, msg, wParam, lParam); } static HWND create_container_window(void) { static const WCHAR wszWebBrowserContainer[] = {'W','e','b','B','r','o','w','s','e','r','C','o','n','t','a','i','n','e','r',0}; static WNDCLASSEXW wndclass = { sizeof(WNDCLASSEXW), 0, wnd_proc, 0, 0, NULL, NULL, NULL, NULL, NULL, wszWebBrowserContainer, NULL }; RegisterClassExW(&wndclass); return CreateWindowW(wszWebBrowserContainer, wszWebBrowserContainer, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); } static void test_ClientSite(IUnknown *unk, IOleClientSite *client) { IOleObject *oleobj; IOleInPlaceObject *inplace; HWND hwnd; HRESULT hres; hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj); ok(hres == S_OK, "QueryInterface(IID_OleObject) failed: %08lx\n", hres); if(FAILED(hres)) return; hres = IUnknown_QueryInterface(unk, &IID_IOleInPlaceObject, (void**)&inplace); ok(hres == S_OK, "QueryInterface(IID_OleInPlaceObject) failed: %08lx\n", hres); if(FAILED(hres)) { IOleObject_Release(oleobj); return; } hres = IOleInPlaceObject_GetWindow(inplace, &hwnd); ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); ok((hwnd == NULL) ^ (client == NULL), "unexpected hwnd %p\n", hwnd); if(client) { SET_EXPECT(GetContainer); SET_EXPECT(Site_GetWindow); } hres = IOleObject_SetClientSite(oleobj, client); ok(hres == S_OK, "SetClientSite failed: %08lx\n", hres); if(client) { CHECK_CALLED(GetContainer); CHECK_CALLED(Site_GetWindow); } hres = IOleInPlaceObject_GetWindow(inplace, &hwnd); ok(hres == S_OK, "GetWindow failed: %08lx\n", hres); ok((hwnd == NULL) == (client == NULL), "unexpected hwnd %p\n", hwnd); IOleInPlaceObject_Release(inplace); IOleObject_Release(oleobj); } static void test_ClassInfo(IUnknown *unk) { IProvideClassInfo2 *class_info; GUID guid; HRESULT hres; hres = IUnknown_QueryInterface(unk, &IID_IProvideClassInfo2, (void**)&class_info); ok(hres == S_OK, "QueryInterface(IID_IProvideClassInfo) failed: %08lx\n", hres); if(FAILED(hres)) return; hres = IProvideClassInfo2_GetGUID(class_info, GUIDKIND_DEFAULT_SOURCE_DISP_IID, &guid); ok(hres == S_OK, "GetGUID failed: %08lx\n", hres); ok(IsEqualGUID(&DIID_DWebBrowserEvents2, &guid), "wrong guid\n"); hres = IProvideClassInfo2_GetGUID(class_info, 0, &guid); ok(hres == E_FAIL, "GetGUID failed: %08lx, expected E_FAIL\n", hres); ok(IsEqualGUID(&IID_NULL, &guid), "wrong guid\n"); hres = IProvideClassInfo2_GetGUID(class_info, 2, &guid); ok(hres == E_FAIL, "GetGUID failed: %08lx, expected E_FAIL\n", hres); ok(IsEqualGUID(&IID_NULL, &guid), "wrong guid\n"); hres = IProvideClassInfo2_GetGUID(class_info, GUIDKIND_DEFAULT_SOURCE_DISP_IID, NULL); ok(hres == E_POINTER, "GetGUID failed: %08lx, expected E_POINTER\n", hres); hres = IProvideClassInfo2_GetGUID(class_info, 0, NULL); ok(hres == E_POINTER, "GetGUID failed: %08lx, expected E_POINTER\n", hres); IProvideClassInfo2_Release(class_info); } static void test_WebBrowser(void) { IUnknown *unk = NULL; ULONG ref; HRESULT hres; hres = CoCreateInstance(&CLSID_WebBrowser, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void**)&unk); ok(hres == S_OK, "CoCreateInterface failed: %08lx\n", hres); if(FAILED(hres)) return; test_ClassInfo(unk); test_ClientSite(unk, &ClientSite); test_ClientSite(unk, NULL); ref = IUnknown_Release(unk); ok(ref == 0, "ref=%ld, expected 0\n", ref); } START_TEST(webbrowser) { container_hwnd = create_container_window(); OleInitialize(NULL); test_WebBrowser(); OleUninitialize(); }