| /* |
| * 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 <wine/test.h> |
| #include <stdarg.h> |
| |
| #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(); |
| } |