Reactos
at master 271 lines 8.1 kB view raw
1/* 2 * Copyright 2012 Piotr Caban for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18#define COBJMACROS 19#define CONST_VTABLE 20 21#include <stdio.h> 22#include <assert.h> 23 24#include "windows.h" 25#include "ole2.h" 26#include "mshtml.h" 27#include "mshtmdid.h" 28#include "initguid.h" 29#include "perhist.h" 30#include "docobj.h" 31#include "urlmon.h" 32#include "xmlparser.h" 33 34#include "wine/test.h" 35 36HRESULT (WINAPI *pCreateURLMoniker)(IMoniker*, LPCWSTR, IMoniker**); 37 38static const char xmlview_html[] = 39"\r\n" 40"<BODY><H2>Generated HTML</H2>\r\n" 41"<TABLE>\r\n" 42"<TBODY>\r\n" 43"<TR bgColor=green>\r\n" 44"<TH>Title</TH>\r\n" 45"<TH>Value</TH></TR>\r\n" 46"<TR>\r\n" 47"<TD>title1</TD>\r\n" 48"<TD>value1</TD></TR>\r\n" 49"<TR>\r\n" 50"<TD>title2</TD>\r\n" 51"<TD>value2</TD></TR></TBODY></TABLE></BODY>"; 52 53IHTMLDocument2 *html_doc; 54BOOL loaded; 55 56static int html_src_compare(LPCWSTR strw, const char *stra) 57{ 58 char buf[2048], *p1; 59 const char *p2; 60 61 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL); 62 63 p1 = buf; 64 p2 = stra; 65 while(1) { 66 while(*p1=='\r' || *p1=='\n' || *p1=='\"') p1++; 67 while(*p2=='\r' || *p2=='\n') p2++; 68 69 if(!*p1 || !*p2 || tolower(*p1)!=tolower(*p2)) 70 break; 71 72 p1++; 73 p2++; 74 } 75 76 return *p1 != *p2; 77} 78 79static HRESULT WINAPI HTMLEvents_QueryInterface(IDispatch *iface, REFIID riid, void **ppv) 80{ 81 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDispatch, riid)) { 82 *ppv = iface; 83 return S_OK; 84 } 85 86 ok(0, "Unexpected call\n"); 87 return E_NOINTERFACE; 88} 89 90static ULONG WINAPI HTMLEvents_AddRef(IDispatch *iface) 91{ 92 return 2; 93} 94 95static ULONG WINAPI HTMLEvents_Release(IDispatch *iface) 96{ 97 return 1; 98} 99 100static HRESULT WINAPI HTMLEvents_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo) 101{ 102 ok(0, "unexpected call\n"); 103 return E_NOTIMPL; 104} 105 106static HRESULT WINAPI HTMLEvents_GetTypeInfo(IDispatch *iface, UINT iTInfo, LCID lcid, 107 ITypeInfo **ppTInfo) 108{ 109 ok(0, "unexpected call\n"); 110 return E_NOTIMPL; 111} 112 113static HRESULT WINAPI HTMLEvents_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *rgszNames, 114 UINT cNames, LCID lcid, DISPID *rgDispId) 115{ 116 ok(0, "unexpected call\n"); 117 return E_NOTIMPL; 118} 119 120static HRESULT WINAPI HTMLEvents_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid, 121 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, 122 EXCEPINFO *pExcepInfo, UINT *puArgErr) 123{ 124 if (dispIdMember == DISPID_HTMLDOCUMENTEVENTS2_ONREADYSTATECHANGE) 125 { 126 static const WCHAR completeW[] = L"complete"; 127 HRESULT hr; 128 BSTR state; 129 130 hr = IHTMLDocument2_get_readyState(html_doc, &state); 131 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 132 if (!memcmp(state, completeW, sizeof(completeW))) 133 loaded = TRUE; 134 SysFreeString(state); 135 } 136 137 return S_OK; 138} 139 140static const IDispatchVtbl HTMLEventsVtbl = { 141 HTMLEvents_QueryInterface, 142 HTMLEvents_AddRef, 143 HTMLEvents_Release, 144 HTMLEvents_GetTypeInfoCount, 145 HTMLEvents_GetTypeInfo, 146 HTMLEvents_GetIDsOfNames, 147 HTMLEvents_Invoke 148}; 149 150static IDispatch HTMLEvents = { &HTMLEventsVtbl }; 151 152static void test_QueryInterface(void) 153{ 154 IUnknown *xmlview, *unk; 155 IHTMLDocument *htmldoc; 156 HRESULT hres; 157 158 hres = CoCreateInstance(&CLSID_XMLView, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, 159 &IID_IUnknown, (void**)&xmlview); 160 if(FAILED(hres)) { 161 win_skip("Failed to create XMLView instance\n"); 162 return; 163 } 164 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 165 166 hres = IUnknown_QueryInterface(xmlview, &IID_IPersistMoniker, (void**)&unk); 167 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 168 IUnknown_Release(unk); 169 170 hres = IUnknown_QueryInterface(xmlview, &IID_IPersistHistory, (void**)&unk); 171 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 172 IUnknown_Release(unk); 173 174 hres = IUnknown_QueryInterface(xmlview, &IID_IOleCommandTarget, (void**)&unk); 175 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 176 IUnknown_Release(unk); 177 178 hres = IUnknown_QueryInterface(xmlview, &IID_IOleObject, (void**)&unk); 179 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 180 IUnknown_Release(unk); 181 182 hres = IUnknown_QueryInterface(xmlview, &IID_IHTMLDocument, (void**)&htmldoc); 183 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 184 hres = IHTMLDocument_QueryInterface(htmldoc, &IID_IUnknown, (void**)&unk); 185 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 186 ok(unk == xmlview, "Aggregation is not working as expected\n"); 187 IUnknown_Release(unk); 188 IHTMLDocument_Release(htmldoc); 189 190 IUnknown_Release(xmlview); 191} 192 193static void test_Load(void) 194{ 195 WCHAR buf[1024]; 196 IPersistMoniker *pers_mon; 197 IConnectionPointContainer *cpc; 198 IConnectionPoint *cp; 199 IMoniker *mon; 200 IBindCtx *bctx; 201 IHTMLElement *elem; 202 HRESULT hres; 203 MSG msg; 204 BSTR source; 205 206 lstrcpyW(buf, L"res://"); 207 GetModuleFileNameW(NULL, buf+lstrlenW(buf), ARRAY_SIZE(buf)-ARRAY_SIZE(L"res://")); 208 lstrcatW(buf, L"/xml/xmlview.xml"); 209 210 if(!pCreateURLMoniker) { 211 win_skip("CreateURLMoniker not available\n"); 212 return; 213 } 214 215 hres = CoCreateInstance(&CLSID_XMLView, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, 216 &IID_IPersistMoniker, (void**)&pers_mon); 217 if(FAILED(hres)) { 218 win_skip("Failed to create XMLView instance\n"); 219 return; 220 } 221 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 222 223 hres = IPersistMoniker_QueryInterface(pers_mon, &IID_IHTMLDocument2, (void**)&html_doc); 224 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 225 hres = IPersistMoniker_QueryInterface(pers_mon, &IID_IConnectionPointContainer, (void**)&cpc); 226 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 227 hres = IConnectionPointContainer_FindConnectionPoint(cpc, &IID_IDispatch, &cp); 228 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 229 hres = IConnectionPoint_Advise(cp, (IUnknown*)&HTMLEvents, NULL); 230 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 231 IConnectionPoint_Release(cp); 232 IConnectionPointContainer_Release(cpc); 233 234 hres = CreateBindCtx(0, &bctx); 235 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 236 hres = pCreateURLMoniker(NULL, buf, &mon); 237 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 238 loaded = FALSE; 239 hres = IPersistMoniker_Load(pers_mon, TRUE, mon, bctx, 0); 240 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 241 IBindCtx_Release(bctx); 242 IMoniker_Release(mon); 243 244 while(!loaded && GetMessageA(&msg, NULL, 0, 0)) { 245 TranslateMessage(&msg); 246 DispatchMessageA(&msg); 247 } 248 249 hres = IHTMLDocument2_get_body(html_doc, &elem); 250 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 251 hres = IHTMLElement_get_outerHTML(elem, &source); 252 ok(hres == S_OK, "Unexpected hr %#lx.\n", hres); 253 ok(!html_src_compare(source, xmlview_html), "Incorrect HTML source: %s\n", wine_dbgstr_w(source)); 254 IHTMLElement_Release(elem); 255 SysFreeString(source); 256 257 IHTMLDocument2_Release(html_doc); 258 html_doc = NULL; 259 IPersistMoniker_Release(pers_mon); 260} 261 262START_TEST(xmlview) 263{ 264 HMODULE urlmon = LoadLibraryA("urlmon.dll"); 265 pCreateURLMoniker = (void*)GetProcAddress(urlmon, "CreateURLMoniker"); 266 267 CoInitialize(NULL); 268 test_QueryInterface(); 269 test_Load(); 270 CoUninitialize(); 271}