5851abdcde494eb95413cbcd89ac3cb21ab72399
[reactos.git] / reactos / dll / win32 / mshtml / oleobj.c
1 /*
2 * Copyright 2005 Jacek Caban
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
19 #include "mshtml_private.h"
20
21 #define DOCHOST_DOCCANNAVIGATE 0
22
23 typedef struct {
24 IEnumUnknown IEnumUnknown_iface;
25 LONG ref;
26 } EnumUnknown;
27
28 static inline EnumUnknown *impl_from_IEnumUnknown(IEnumUnknown *iface)
29 {
30 return CONTAINING_RECORD(iface, EnumUnknown, IEnumUnknown_iface);
31 }
32
33 static HRESULT WINAPI EnumUnknown_QueryInterface(IEnumUnknown *iface, REFIID riid, void **ppv)
34 {
35 EnumUnknown *This = impl_from_IEnumUnknown(iface);
36
37 if(IsEqualGUID(&IID_IUnknown, riid)) {
38 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
39 *ppv = &This->IEnumUnknown_iface;
40 }else if(IsEqualGUID(&IID_IEnumUnknown, riid)) {
41 TRACE("(%p)->(IID_IEnumUnknown %p)\n", This, ppv);
42 *ppv = &This->IEnumUnknown_iface;
43 }else {
44 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
45 *ppv = NULL;
46 return E_NOINTERFACE;
47 }
48
49 IUnknown_AddRef((IUnknown*)*ppv);
50 return S_OK;
51 }
52
53 static ULONG WINAPI EnumUnknown_AddRef(IEnumUnknown *iface)
54 {
55 EnumUnknown *This = impl_from_IEnumUnknown(iface);
56 LONG ref = InterlockedIncrement(&This->ref);
57
58 TRACE("(%p) ref=%d\n", This, ref);
59
60 return ref;
61 }
62
63 static ULONG WINAPI EnumUnknown_Release(IEnumUnknown *iface)
64 {
65 EnumUnknown *This = impl_from_IEnumUnknown(iface);
66 LONG ref = InterlockedDecrement(&This->ref);
67
68 TRACE("(%p) ref=%d\n", This, ref);
69
70 if(!ref)
71 heap_free(This);
72
73 return ref;
74 }
75
76 static HRESULT WINAPI EnumUnknown_Next(IEnumUnknown *iface, ULONG celt, IUnknown **rgelt, ULONG *pceltFetched)
77 {
78 EnumUnknown *This = impl_from_IEnumUnknown(iface);
79
80 TRACE("(%p)->(%u %p %p)\n", This, celt, rgelt, pceltFetched);
81
82 /* FIXME: It's not clear if we should ever return something here */
83 if(pceltFetched)
84 *pceltFetched = 0;
85 return S_FALSE;
86 }
87
88 static HRESULT WINAPI EnumUnknown_Skip(IEnumUnknown *iface, ULONG celt)
89 {
90 EnumUnknown *This = impl_from_IEnumUnknown(iface);
91 FIXME("(%p)->(%u)\n", This, celt);
92 return E_NOTIMPL;
93 }
94
95 static HRESULT WINAPI EnumUnknown_Reset(IEnumUnknown *iface)
96 {
97 EnumUnknown *This = impl_from_IEnumUnknown(iface);
98 FIXME("(%p)\n", This);
99 return E_NOTIMPL;
100 }
101
102 static HRESULT WINAPI EnumUnknown_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
103 {
104 EnumUnknown *This = impl_from_IEnumUnknown(iface);
105 FIXME("(%p)->(%p)\n", This, ppenum);
106 return E_NOTIMPL;
107 }
108
109 static const IEnumUnknownVtbl EnumUnknownVtbl = {
110 EnumUnknown_QueryInterface,
111 EnumUnknown_AddRef,
112 EnumUnknown_Release,
113 EnumUnknown_Next,
114 EnumUnknown_Skip,
115 EnumUnknown_Reset,
116 EnumUnknown_Clone
117 };
118
119 /**********************************************************
120 * IOleObject implementation
121 */
122
123 static inline HTMLDocument *impl_from_IOleObject(IOleObject *iface)
124 {
125 return CONTAINING_RECORD(iface, HTMLDocument, IOleObject_iface);
126 }
127
128 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
129 {
130 HTMLDocument *This = impl_from_IOleObject(iface);
131 return htmldoc_query_interface(This, riid, ppv);
132 }
133
134 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
135 {
136 HTMLDocument *This = impl_from_IOleObject(iface);
137 return htmldoc_addref(This);
138 }
139
140 static ULONG WINAPI OleObject_Release(IOleObject *iface)
141 {
142 HTMLDocument *This = impl_from_IOleObject(iface);
143 return htmldoc_release(This);
144 }
145
146 static void update_hostinfo(HTMLDocumentObj *This, DOCHOSTUIINFO *hostinfo)
147 {
148 nsIScrollable *scrollable;
149 nsresult nsres;
150
151 if(!This->nscontainer)
152 return;
153
154 nsres = nsIWebBrowser_QueryInterface(This->nscontainer->webbrowser, &IID_nsIScrollable, (void**)&scrollable);
155 if(NS_SUCCEEDED(nsres)) {
156 nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, ScrollOrientation_Y,
157 (hostinfo->dwFlags & DOCHOSTUIFLAG_SCROLL_NO) ? Scrollbar_Never : Scrollbar_Always);
158 if(NS_FAILED(nsres))
159 ERR("Could not set default Y scrollbar prefs: %08x\n", nsres);
160
161 nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, ScrollOrientation_X,
162 hostinfo->dwFlags & DOCHOSTUIFLAG_SCROLL_NO ? Scrollbar_Never : Scrollbar_Auto);
163 if(NS_FAILED(nsres))
164 ERR("Could not set default X scrollbar prefs: %08x\n", nsres);
165
166 nsIScrollable_Release(scrollable);
167 }else {
168 ERR("Could not get nsIScrollable: %08x\n", nsres);
169 }
170 }
171
172 /* Calls undocumented 84 cmd of CGID_ShellDocView */
173 void call_docview_84(HTMLDocumentObj *doc)
174 {
175 IOleCommandTarget *olecmd;
176 VARIANT var;
177 HRESULT hres;
178
179 if(!doc->client)
180 return;
181
182 hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
183 if(FAILED(hres))
184 return;
185
186 VariantInit(&var);
187 hres = IOleCommandTarget_Exec(olecmd, &CGID_ShellDocView, 84, 0, NULL, &var);
188 IOleCommandTarget_Release(olecmd);
189 if(SUCCEEDED(hres) && V_VT(&var) != VT_NULL)
190 FIXME("handle result\n");
191 }
192
193 static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *pClientSite)
194 {
195 HTMLDocument *This = impl_from_IOleObject(iface);
196 IOleCommandTarget *cmdtrg = NULL;
197 IOleWindow *ole_window;
198 IBrowserService *browser_service;
199 BOOL hostui_setup;
200 VARIANT silent;
201 HWND hwnd;
202 HRESULT hres;
203
204 TRACE("(%p)->(%p)\n", This, pClientSite);
205
206 if(pClientSite == This->doc_obj->client)
207 return S_OK;
208
209 if(This->doc_obj->client) {
210 IOleClientSite_Release(This->doc_obj->client);
211 This->doc_obj->client = NULL;
212 This->doc_obj->usermode = UNKNOWN_USERMODE;
213 }
214
215 if(This->doc_obj->client_cmdtrg) {
216 IOleCommandTarget_Release(This->doc_obj->client_cmdtrg);
217 This->doc_obj->client_cmdtrg = NULL;
218 }
219
220 if(This->doc_obj->hostui && !This->doc_obj->custom_hostui) {
221 IDocHostUIHandler_Release(This->doc_obj->hostui);
222 This->doc_obj->hostui = NULL;
223 }
224
225 if(This->doc_obj->doc_object_service) {
226 IDocObjectService_Release(This->doc_obj->doc_object_service);
227 This->doc_obj->doc_object_service = NULL;
228 }
229
230 if(This->doc_obj->webbrowser) {
231 IUnknown_Release(This->doc_obj->webbrowser);
232 This->doc_obj->webbrowser = NULL;
233 }
234
235 if(This->doc_obj->browser_service) {
236 IUnknown_Release(This->doc_obj->browser_service);
237 This->doc_obj->browser_service = NULL;
238 }
239
240 if(This->doc_obj->travel_log) {
241 ITravelLog_Release(This->doc_obj->travel_log);
242 This->doc_obj->travel_log = NULL;
243 }
244
245 memset(&This->doc_obj->hostinfo, 0, sizeof(DOCHOSTUIINFO));
246
247 if(!pClientSite)
248 return S_OK;
249
250 IOleClientSite_AddRef(pClientSite);
251 This->doc_obj->client = pClientSite;
252
253 hostui_setup = This->doc_obj->hostui_setup;
254
255 if(!This->doc_obj->hostui) {
256 IDocHostUIHandler *uihandler;
257
258 This->doc_obj->custom_hostui = FALSE;
259
260 hres = IOleClientSite_QueryInterface(pClientSite, &IID_IDocHostUIHandler, (void**)&uihandler);
261 if(SUCCEEDED(hres))
262 This->doc_obj->hostui = uihandler;
263 }
264
265 if(This->doc_obj->hostui) {
266 DOCHOSTUIINFO hostinfo;
267 LPOLESTR key_path = NULL, override_key_path = NULL;
268 IDocHostUIHandler2 *uihandler2;
269
270 memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO));
271 hostinfo.cbSize = sizeof(DOCHOSTUIINFO);
272 hres = IDocHostUIHandler_GetHostInfo(This->doc_obj->hostui, &hostinfo);
273 if(SUCCEEDED(hres)) {
274 TRACE("hostinfo = {%u %08x %08x %s %s}\n",
275 hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick,
276 debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS));
277 update_hostinfo(This->doc_obj, &hostinfo);
278 This->doc_obj->hostinfo = hostinfo;
279 }
280
281 if(!hostui_setup) {
282 hres = IDocHostUIHandler_GetOptionKeyPath(This->doc_obj->hostui, &key_path, 0);
283 if(hres == S_OK && key_path) {
284 if(key_path[0]) {
285 /* FIXME: use key_path */
286 TRACE("key_path = %s\n", debugstr_w(key_path));
287 }
288 CoTaskMemFree(key_path);
289 }
290
291 hres = IDocHostUIHandler_QueryInterface(This->doc_obj->hostui, &IID_IDocHostUIHandler2,
292 (void**)&uihandler2);
293 if(SUCCEEDED(hres)) {
294 hres = IDocHostUIHandler2_GetOverrideKeyPath(uihandler2, &override_key_path, 0);
295 if(hres == S_OK && override_key_path && override_key_path[0]) {
296 if(override_key_path[0]) {
297 /*FIXME: use override_key_path */
298 TRACE("override_key_path = %s\n", debugstr_w(override_key_path));
299 }
300 CoTaskMemFree(override_key_path);
301 }
302 IDocHostUIHandler2_Release(uihandler2);
303 }
304
305 This->doc_obj->hostui_setup = TRUE;
306 }
307 }
308
309 /* Native calls here GetWindow. What is it for?
310 * We don't have anything to do with it here (yet). */
311 hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleWindow, (void**)&ole_window);
312 if(SUCCEEDED(hres)) {
313 IOleWindow_GetWindow(ole_window, &hwnd);
314 IOleWindow_Release(ole_window);
315 }
316
317 hres = do_query_service((IUnknown*)pClientSite, &IID_IShellBrowser,
318 &IID_IBrowserService, (void**)&browser_service);
319 if(SUCCEEDED(hres)) {
320 ITravelLog *travel_log;
321
322 This->doc_obj->browser_service = (IUnknown*)browser_service;
323
324 hres = IBrowserService_GetTravelLog(browser_service, &travel_log);
325 if(SUCCEEDED(hres))
326 This->doc_obj->travel_log = travel_log;
327 }else {
328 browser_service = NULL;
329 }
330
331 hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleCommandTarget, (void**)&cmdtrg);
332 if(SUCCEEDED(hres)) {
333 VARIANT var;
334 OLECMD cmd = {OLECMDID_SETPROGRESSTEXT, 0};
335
336 This->doc_obj->client_cmdtrg = cmdtrg;
337
338 if(!hostui_setup) {
339 IDocObjectService *doc_object_service;
340 IWebBrowser2 *wb;
341
342 V_VT(&var) = VT_UNKNOWN;
343 V_UNKNOWN(&var) = (IUnknown*)&This->window->base.IHTMLWindow2_iface;
344 IOleCommandTarget_Exec(cmdtrg, &CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, &var, NULL);
345
346 if(browser_service) {
347 hres = IBrowserService_QueryInterface(browser_service,
348 &IID_IDocObjectService, (void**)&doc_object_service);
349 if(SUCCEEDED(hres)) {
350 This->doc_obj->doc_object_service = doc_object_service;
351
352 /*
353 * Some embedding routines, esp. in regards to use of IDocObjectService, differ if
354 * embedder supports IWebBrowserApp.
355 */
356 hres = do_query_service((IUnknown*)pClientSite, &IID_IWebBrowserApp, &IID_IWebBrowser2, (void**)&wb);
357 if(SUCCEEDED(hres))
358 This->doc_obj->webbrowser = (IUnknown*)wb;
359 }
360 }
361 }
362
363 call_docview_84(This->doc_obj);
364
365 IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &cmd, NULL);
366
367 V_VT(&var) = VT_I4;
368 V_I4(&var) = 0;
369 IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSMAX,
370 OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
371 IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSPOS,
372 OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
373 }
374
375 if(This->doc_obj->usermode == UNKNOWN_USERMODE)
376 IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_USERMODE);
377
378 IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface,
379 DISPID_AMBIENT_OFFLINEIFNOTCONNECTED);
380
381 hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_SILENT, &silent);
382 if(SUCCEEDED(hres)) {
383 if(V_VT(&silent) != VT_BOOL)
384 WARN("silent = %s\n", debugstr_variant(&silent));
385 else if(V_BOOL(&silent))
386 FIXME("silent == true\n");
387 }
388
389 IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_USERAGENT);
390 IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_PALETTE);
391
392 return S_OK;
393 }
394
395 static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **ppClientSite)
396 {
397 HTMLDocument *This = impl_from_IOleObject(iface);
398
399 TRACE("(%p)->(%p)\n", This, ppClientSite);
400
401 if(!ppClientSite)
402 return E_INVALIDARG;
403
404 if(This->doc_obj->client)
405 IOleClientSite_AddRef(This->doc_obj->client);
406 *ppClientSite = This->doc_obj->client;
407
408 return S_OK;
409 }
410
411 static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
412 {
413 HTMLDocument *This = impl_from_IOleObject(iface);
414 FIXME("(%p)->(%s %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));
415 return E_NOTIMPL;
416 }
417
418 static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
419 {
420 HTMLDocument *This = impl_from_IOleObject(iface);
421
422 TRACE("(%p)->(%08x)\n", This, dwSaveOption);
423
424 if(dwSaveOption == OLECLOSE_PROMPTSAVE)
425 FIXME("OLECLOSE_PROMPTSAVE not implemented\n");
426
427 if(This->doc_obj->in_place_active)
428 IOleInPlaceObjectWindowless_InPlaceDeactivate(&This->IOleInPlaceObjectWindowless_iface);
429
430 HTMLDocument_LockContainer(This->doc_obj, FALSE);
431
432 if(This->advise_holder)
433 IOleAdviseHolder_SendOnClose(This->advise_holder);
434
435 return S_OK;
436 }
437
438 static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker *pmk)
439 {
440 HTMLDocument *This = impl_from_IOleObject(iface);
441 FIXME("(%p %d %p)->()\n", This, dwWhichMoniker, pmk);
442 return E_NOTIMPL;
443 }
444
445 static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
446 {
447 HTMLDocument *This = impl_from_IOleObject(iface);
448 FIXME("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
449 return E_NOTIMPL;
450 }
451
452 static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *pDataObject, BOOL fCreation,
453 DWORD dwReserved)
454 {
455 HTMLDocument *This = impl_from_IOleObject(iface);
456 FIXME("(%p)->(%p %x %d)\n", This, pDataObject, fCreation, dwReserved);
457 return E_NOTIMPL;
458 }
459
460 static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved, IDataObject **ppDataObject)
461 {
462 HTMLDocument *This = impl_from_IOleObject(iface);
463 FIXME("(%p)->(%d %p)\n", This, dwReserved, ppDataObject);
464 return E_NOTIMPL;
465 }
466
467 static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
468 LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
469 {
470 HTMLDocument *This = impl_from_IOleObject(iface);
471 IOleDocumentSite *pDocSite;
472 HRESULT hres;
473
474 TRACE("(%p)->(%d %p %p %d %p %p)\n", This, iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect);
475
476 if(iVerb != OLEIVERB_SHOW && iVerb != OLEIVERB_UIACTIVATE && iVerb != OLEIVERB_INPLACEACTIVATE) {
477 FIXME("iVerb = %d not supported\n", iVerb);
478 return E_NOTIMPL;
479 }
480
481 if(!pActiveSite)
482 pActiveSite = This->doc_obj->client;
483
484 hres = IOleClientSite_QueryInterface(pActiveSite, &IID_IOleDocumentSite, (void**)&pDocSite);
485 if(SUCCEEDED(hres)) {
486 HTMLDocument_LockContainer(This->doc_obj, TRUE);
487
488 /* FIXME: Create new IOleDocumentView. See CreateView for more info. */
489 hres = IOleDocumentSite_ActivateMe(pDocSite, &This->IOleDocumentView_iface);
490 IOleDocumentSite_Release(pDocSite);
491 }else {
492 hres = IOleDocumentView_UIActivate(&This->IOleDocumentView_iface, TRUE);
493 if(SUCCEEDED(hres)) {
494 if(lprcPosRect) {
495 RECT rect; /* We need to pass rect as not const pointer */
496 rect = *lprcPosRect;
497 IOleDocumentView_SetRect(&This->IOleDocumentView_iface, &rect);
498 }
499 IOleDocumentView_Show(&This->IOleDocumentView_iface, TRUE);
500 }
501 }
502
503 return hres;
504 }
505
506 static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
507 {
508 HTMLDocument *This = impl_from_IOleObject(iface);
509 FIXME("(%p)->(%p)\n", This, ppEnumOleVerb);
510 return E_NOTIMPL;
511 }
512
513 static HRESULT WINAPI OleObject_Update(IOleObject *iface)
514 {
515 HTMLDocument *This = impl_from_IOleObject(iface);
516 FIXME("(%p)\n", This);
517 return E_NOTIMPL;
518 }
519
520 static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
521 {
522 HTMLDocument *This = impl_from_IOleObject(iface);
523 FIXME("(%p)\n", This);
524 return E_NOTIMPL;
525 }
526
527 static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *pClsid)
528 {
529 HTMLDocument *This = impl_from_IOleObject(iface);
530
531 TRACE("(%p)->(%p)\n", This, pClsid);
532
533 if(!pClsid)
534 return E_INVALIDARG;
535
536 *pClsid = CLSID_HTMLDocument;
537 return S_OK;
538 }
539
540 static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType, LPOLESTR *pszUserType)
541 {
542 HTMLDocument *This = impl_from_IOleObject(iface);
543 FIXME("(%p)->(%d %p)\n", This, dwFormOfType, pszUserType);
544 return E_NOTIMPL;
545 }
546
547 static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
548 {
549 HTMLDocument *This = impl_from_IOleObject(iface);
550 FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
551 return E_NOTIMPL;
552 }
553
554 static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
555 {
556 HTMLDocument *This = impl_from_IOleObject(iface);
557 FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
558 return E_NOTIMPL;
559 }
560
561 static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection)
562 {
563 HTMLDocument *This = impl_from_IOleObject(iface);
564 TRACE("(%p)->(%p %p)\n", This, pAdvSink, pdwConnection);
565
566 if(!pdwConnection)
567 return E_INVALIDARG;
568
569 if(!pAdvSink) {
570 *pdwConnection = 0;
571 return E_INVALIDARG;
572 }
573
574 if(!This->advise_holder) {
575 CreateOleAdviseHolder(&This->advise_holder);
576 if(!This->advise_holder)
577 return E_OUTOFMEMORY;
578 }
579
580 return IOleAdviseHolder_Advise(This->advise_holder, pAdvSink, pdwConnection);
581 }
582
583 static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
584 {
585 HTMLDocument *This = impl_from_IOleObject(iface);
586 TRACE("(%p)->(%d)\n", This, dwConnection);
587
588 if(!This->advise_holder)
589 return OLE_E_NOCONNECTION;
590
591 return IOleAdviseHolder_Unadvise(This->advise_holder, dwConnection);
592 }
593
594 static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
595 {
596 HTMLDocument *This = impl_from_IOleObject(iface);
597
598 if(!This->advise_holder) {
599 *ppenumAdvise = NULL;
600 return S_OK;
601 }
602
603 return IOleAdviseHolder_EnumAdvise(This->advise_holder, ppenumAdvise);
604 }
605
606 static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
607 {
608 HTMLDocument *This = impl_from_IOleObject(iface);
609 FIXME("(%p)->(%d %p)\n", This, dwAspect, pdwStatus);
610 return E_NOTIMPL;
611 }
612
613 static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *pLogpal)
614 {
615 HTMLDocument *This = impl_from_IOleObject(iface);
616 FIXME("(%p)->(%p)\n", This, pLogpal);
617 return E_NOTIMPL;
618 }
619
620 static const IOleObjectVtbl OleObjectVtbl = {
621 OleObject_QueryInterface,
622 OleObject_AddRef,
623 OleObject_Release,
624 OleObject_SetClientSite,
625 OleObject_GetClientSite,
626 OleObject_SetHostNames,
627 OleObject_Close,
628 OleObject_SetMoniker,
629 OleObject_GetMoniker,
630 OleObject_InitFromData,
631 OleObject_GetClipboardData,
632 OleObject_DoVerb,
633 OleObject_EnumVerbs,
634 OleObject_Update,
635 OleObject_IsUpToDate,
636 OleObject_GetUserClassID,
637 OleObject_GetUserType,
638 OleObject_SetExtent,
639 OleObject_GetExtent,
640 OleObject_Advise,
641 OleObject_Unadvise,
642 OleObject_EnumAdvise,
643 OleObject_GetMiscStatus,
644 OleObject_SetColorScheme
645 };
646
647 /**********************************************************
648 * IOleDocument implementation
649 */
650
651 static inline HTMLDocument *impl_from_IOleDocument(IOleDocument *iface)
652 {
653 return CONTAINING_RECORD(iface, HTMLDocument, IOleDocument_iface);
654 }
655
656 static HRESULT WINAPI OleDocument_QueryInterface(IOleDocument *iface, REFIID riid, void **ppv)
657 {
658 HTMLDocument *This = impl_from_IOleDocument(iface);
659 return htmldoc_query_interface(This, riid, ppv);
660 }
661
662 static ULONG WINAPI OleDocument_AddRef(IOleDocument *iface)
663 {
664 HTMLDocument *This = impl_from_IOleDocument(iface);
665 return htmldoc_addref(This);
666 }
667
668 static ULONG WINAPI OleDocument_Release(IOleDocument *iface)
669 {
670 HTMLDocument *This = impl_from_IOleDocument(iface);
671 return htmldoc_release(This);
672 }
673
674 static HRESULT WINAPI OleDocument_CreateView(IOleDocument *iface, IOleInPlaceSite *pIPSite, IStream *pstm,
675 DWORD dwReserved, IOleDocumentView **ppView)
676 {
677 HTMLDocument *This = impl_from_IOleDocument(iface);
678 HRESULT hres;
679
680 TRACE("(%p)->(%p %p %d %p)\n", This, pIPSite, pstm, dwReserved, ppView);
681
682 if(!ppView)
683 return E_INVALIDARG;
684
685 /* FIXME:
686 * Windows implementation creates new IOleDocumentView when function is called for the
687 * first time and returns E_FAIL when it is called for the second time, but it doesn't matter
688 * if the application uses returned interfaces, passed to ActivateMe or returned by
689 * QueryInterface, so there is no reason to create new interface. This needs more testing.
690 */
691
692 if(pIPSite) {
693 hres = IOleDocumentView_SetInPlaceSite(&This->IOleDocumentView_iface, pIPSite);
694 if(FAILED(hres))
695 return hres;
696 }
697
698 if(pstm)
699 FIXME("pstm is not supported\n");
700
701 IOleDocumentView_AddRef(&This->IOleDocumentView_iface);
702 *ppView = &This->IOleDocumentView_iface;
703 return S_OK;
704 }
705
706 static HRESULT WINAPI OleDocument_GetDocMiscStatus(IOleDocument *iface, DWORD *pdwStatus)
707 {
708 HTMLDocument *This = impl_from_IOleDocument(iface);
709 FIXME("(%p)->(%p)\n", This, pdwStatus);
710 return E_NOTIMPL;
711 }
712
713 static HRESULT WINAPI OleDocument_EnumViews(IOleDocument *iface, IEnumOleDocumentViews **ppEnum,
714 IOleDocumentView **ppView)
715 {
716 HTMLDocument *This = impl_from_IOleDocument(iface);
717 FIXME("(%p)->(%p %p)\n", This, ppEnum, ppView);
718 return E_NOTIMPL;
719 }
720
721 static const IOleDocumentVtbl OleDocumentVtbl = {
722 OleDocument_QueryInterface,
723 OleDocument_AddRef,
724 OleDocument_Release,
725 OleDocument_CreateView,
726 OleDocument_GetDocMiscStatus,
727 OleDocument_EnumViews
728 };
729
730 /**********************************************************
731 * IOleControl implementation
732 */
733
734 static inline HTMLDocument *impl_from_IOleControl(IOleControl *iface)
735 {
736 return CONTAINING_RECORD(iface, HTMLDocument, IOleControl_iface);
737 }
738
739 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
740 {
741 HTMLDocument *This = impl_from_IOleControl(iface);
742 return htmldoc_query_interface(This, riid, ppv);
743 }
744
745 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
746 {
747 HTMLDocument *This = impl_from_IOleControl(iface);
748 return htmldoc_addref(This);
749 }
750
751 static ULONG WINAPI OleControl_Release(IOleControl *iface)
752 {
753 HTMLDocument *This = impl_from_IOleControl(iface);
754 return htmldoc_release(This);
755 }
756
757 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *pCI)
758 {
759 HTMLDocument *This = impl_from_IOleControl(iface);
760 FIXME("(%p)->(%p)\n", This, pCI);
761 return E_NOTIMPL;
762 }
763
764 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *pMsg)
765 {
766 HTMLDocument *This = impl_from_IOleControl(iface);
767 FIXME("(%p)->(%p)\n", This, pMsg);
768 return E_NOTIMPL;
769 }
770
771 HRESULT get_client_disp_property(IOleClientSite *client, DISPID dispid, VARIANT *res)
772 {
773 IDispatch *disp = NULL;
774 DISPPARAMS dispparams = {NULL, 0};
775 UINT err;
776 HRESULT hres;
777
778 hres = IOleClientSite_QueryInterface(client, &IID_IDispatch, (void**)&disp);
779 if(FAILED(hres)) {
780 TRACE("Could not get IDispatch\n");
781 return hres;
782 }
783
784 VariantInit(res);
785
786 hres = IDispatch_Invoke(disp, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
787 DISPATCH_PROPERTYGET, &dispparams, res, NULL, &err);
788
789 IDispatch_Release(disp);
790
791 return hres;
792 }
793
794 static HRESULT on_change_dlcontrol(HTMLDocument *This)
795 {
796 VARIANT res;
797 HRESULT hres;
798
799 hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_DLCONTROL, &res);
800 if(SUCCEEDED(hres))
801 FIXME("unsupported dlcontrol %08x\n", V_I4(&res));
802
803 return S_OK;
804 }
805
806 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
807 {
808 HTMLDocument *This = impl_from_IOleControl(iface);
809 IOleClientSite *client;
810 VARIANT res;
811 HRESULT hres;
812
813 client = This->doc_obj->client;
814 if(!client) {
815 TRACE("client = NULL\n");
816 return S_OK;
817 }
818
819 switch(dispID) {
820 case DISPID_AMBIENT_USERMODE:
821 TRACE("(%p)->(DISPID_AMBIENT_USERMODE)\n", This);
822 hres = get_client_disp_property(client, DISPID_AMBIENT_USERMODE, &res);
823 if(FAILED(hres))
824 return S_OK;
825
826 if(V_VT(&res) == VT_BOOL) {
827 if(V_BOOL(&res)) {
828 This->doc_obj->usermode = BROWSEMODE;
829 }else {
830 FIXME("edit mode is not supported\n");
831 This->doc_obj->usermode = EDITMODE;
832 }
833 }else {
834 FIXME("usermode=%s\n", debugstr_variant(&res));
835 }
836 return S_OK;
837 case DISPID_AMBIENT_DLCONTROL:
838 TRACE("(%p)->(DISPID_AMBIENT_DLCONTROL)\n", This);
839 return on_change_dlcontrol(This);
840 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
841 TRACE("(%p)->(DISPID_AMBIENT_OFFLINEIFNOTCONNECTED)\n", This);
842 on_change_dlcontrol(This);
843 hres = get_client_disp_property(client, DISPID_AMBIENT_OFFLINEIFNOTCONNECTED, &res);
844 if(FAILED(hres))
845 return S_OK;
846
847 if(V_VT(&res) == VT_BOOL) {
848 if(V_BOOL(&res)) {
849 FIXME("offline connection is not supported\n");
850 hres = E_FAIL;
851 }
852 }else {
853 FIXME("offlineconnected=%s\n", debugstr_variant(&res));
854 }
855 return S_OK;
856 case DISPID_AMBIENT_SILENT:
857 TRACE("(%p)->(DISPID_AMBIENT_SILENT)\n", This);
858 on_change_dlcontrol(This);
859 hres = get_client_disp_property(client, DISPID_AMBIENT_SILENT, &res);
860 if(FAILED(hres))
861 return S_OK;
862
863 if(V_VT(&res) == VT_BOOL) {
864 if(V_BOOL(&res)) {
865 FIXME("silent mode is not supported\n");
866 hres = E_FAIL;
867 }
868 }else {
869 FIXME("silent=%s\n", debugstr_variant(&res));
870 }
871 return S_OK;
872 case DISPID_AMBIENT_USERAGENT:
873 TRACE("(%p)->(DISPID_AMBIENT_USERAGENT)\n", This);
874 hres = get_client_disp_property(client, DISPID_AMBIENT_USERAGENT, &res);
875 if(FAILED(hres))
876 return S_OK;
877
878 FIXME("not supported AMBIENT_USERAGENT\n");
879 hres = E_FAIL;
880 return S_OK;
881 case DISPID_AMBIENT_PALETTE:
882 TRACE("(%p)->(DISPID_AMBIENT_PALETTE)\n", This);
883 hres = get_client_disp_property(client, DISPID_AMBIENT_PALETTE, &res);
884 if(FAILED(hres))
885 return S_OK;
886
887 FIXME("not supported AMBIENT_PALETTE\n");
888 hres = E_FAIL;
889 return S_OK;
890 }
891
892 FIXME("(%p) unsupported dispID=%d\n", This, dispID);
893 return E_FAIL;
894 }
895
896 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
897 {
898 HTMLDocument *This = impl_from_IOleControl(iface);
899 FIXME("(%p)->(%x)\n", This, bFreeze);
900 return E_NOTIMPL;
901 }
902
903 static const IOleControlVtbl OleControlVtbl = {
904 OleControl_QueryInterface,
905 OleControl_AddRef,
906 OleControl_Release,
907 OleControl_GetControlInfo,
908 OleControl_OnMnemonic,
909 OleControl_OnAmbientPropertyChange,
910 OleControl_FreezeEvents
911 };
912
913 /**********************************************************
914 * IObjectWithSite implementation
915 */
916
917 static inline HTMLDocument *impl_from_IObjectWithSite(IObjectWithSite *iface)
918 {
919 return CONTAINING_RECORD(iface, HTMLDocument, IObjectWithSite_iface);
920 }
921
922 static HRESULT WINAPI ObjectWithSite_QueryInterface(IObjectWithSite *iface, REFIID riid, void **ppv)
923 {
924 HTMLDocument *This = impl_from_IObjectWithSite(iface);
925 return htmldoc_query_interface(This, riid, ppv);
926 }
927
928 static ULONG WINAPI ObjectWithSite_AddRef(IObjectWithSite *iface)
929 {
930 HTMLDocument *This = impl_from_IObjectWithSite(iface);
931 return htmldoc_addref(This);
932 }
933
934 static ULONG WINAPI ObjectWithSite_Release(IObjectWithSite *iface)
935 {
936 HTMLDocument *This = impl_from_IObjectWithSite(iface);
937 return htmldoc_release(This);
938 }
939
940 static HRESULT WINAPI ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *pUnkSite)
941 {
942 HTMLDocument *This = impl_from_IObjectWithSite(iface);
943 FIXME("(%p)->(%p)\n", This, pUnkSite);
944 return E_NOTIMPL;
945 }
946
947 static HRESULT WINAPI ObjectWithSite_GetSite(IObjectWithSite* iface, REFIID riid, PVOID *ppvSite)
948 {
949 HTMLDocument *This = impl_from_IObjectWithSite(iface);
950 FIXME("(%p)->(%p)\n", This, ppvSite);
951 return E_NOTIMPL;
952 }
953
954 static const IObjectWithSiteVtbl ObjectWithSiteVtbl = {
955 ObjectWithSite_QueryInterface,
956 ObjectWithSite_AddRef,
957 ObjectWithSite_Release,
958 ObjectWithSite_SetSite,
959 ObjectWithSite_GetSite
960 };
961
962 /**********************************************************
963 * IOleContainer implementation
964 */
965
966 static inline HTMLDocument *impl_from_IOleContainer(IOleContainer *iface)
967 {
968 return CONTAINING_RECORD(iface, HTMLDocument, IOleContainer_iface);
969 }
970
971 static HRESULT WINAPI OleContainer_QueryInterface(IOleContainer *iface, REFIID riid, void **ppv)
972 {
973 HTMLDocument *This = impl_from_IOleContainer(iface);
974 return htmldoc_query_interface(This, riid, ppv);
975 }
976
977 static ULONG WINAPI OleContainer_AddRef(IOleContainer *iface)
978 {
979 HTMLDocument *This = impl_from_IOleContainer(iface);
980 return htmldoc_addref(This);
981 }
982
983 static ULONG WINAPI OleContainer_Release(IOleContainer *iface)
984 {
985 HTMLDocument *This = impl_from_IOleContainer(iface);
986 return htmldoc_release(This);
987 }
988
989 static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer *iface, IBindCtx *pbc, LPOLESTR pszDisplayName,
990 ULONG *pchEaten, IMoniker **ppmkOut)
991 {
992 HTMLDocument *This = impl_from_IOleContainer(iface);
993 FIXME("(%p)->(%p %s %p %p)\n", This, pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
994 return E_NOTIMPL;
995 }
996
997 static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer *iface, DWORD grfFlags, IEnumUnknown **ppenum)
998 {
999 HTMLDocument *This = impl_from_IOleContainer(iface);
1000 EnumUnknown *ret;
1001
1002 TRACE("(%p)->(%x %p)\n", This, grfFlags, ppenum);
1003
1004 ret = heap_alloc(sizeof(*ret));
1005 if(!ret)
1006 return E_OUTOFMEMORY;
1007
1008 ret->IEnumUnknown_iface.lpVtbl = &EnumUnknownVtbl;
1009 ret->ref = 1;
1010
1011 *ppenum = &ret->IEnumUnknown_iface;
1012 return S_OK;
1013 }
1014
1015 static HRESULT WINAPI OleContainer_LockContainer(IOleContainer *iface, BOOL fLock)
1016 {
1017 HTMLDocument *This = impl_from_IOleContainer(iface);
1018 FIXME("(%p)->(%x)\n", This, fLock);
1019 return E_NOTIMPL;
1020 }
1021
1022 static const IOleContainerVtbl OleContainerVtbl = {
1023 OleContainer_QueryInterface,
1024 OleContainer_AddRef,
1025 OleContainer_Release,
1026 OleContainer_ParseDisplayName,
1027 OleContainer_EnumObjects,
1028 OleContainer_LockContainer
1029 };
1030
1031 static inline HTMLDocumentObj *impl_from_ITargetContainer(ITargetContainer *iface)
1032 {
1033 return CONTAINING_RECORD(iface, HTMLDocumentObj, ITargetContainer_iface);
1034 }
1035
1036 static HRESULT WINAPI TargetContainer_QueryInterface(ITargetContainer *iface, REFIID riid, void **ppv)
1037 {
1038 HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1039 return ICustomDoc_QueryInterface(&This->ICustomDoc_iface, riid, ppv);
1040 }
1041
1042 static ULONG WINAPI TargetContainer_AddRef(ITargetContainer *iface)
1043 {
1044 HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1045 return ICustomDoc_AddRef(&This->ICustomDoc_iface);
1046 }
1047
1048 static ULONG WINAPI TargetContainer_Release(ITargetContainer *iface)
1049 {
1050 HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1051 return ICustomDoc_Release(&This->ICustomDoc_iface);
1052 }
1053
1054 static HRESULT WINAPI TargetContainer_GetFrameUrl(ITargetContainer *iface, LPWSTR *ppszFrameSrc)
1055 {
1056 HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1057 FIXME("(%p)->(%p)\n", This, ppszFrameSrc);
1058 return E_NOTIMPL;
1059 }
1060
1061 static HRESULT WINAPI TargetContainer_GetFramesContainer(ITargetContainer *iface, IOleContainer **ppContainer)
1062 {
1063 HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1064
1065 TRACE("(%p)->(%p)\n", This, ppContainer);
1066
1067 /* NOTE: we should return wrapped interface here */
1068 IOleContainer_AddRef(&This->basedoc.IOleContainer_iface);
1069 *ppContainer = &This->basedoc.IOleContainer_iface;
1070 return S_OK;
1071 }
1072
1073 static const ITargetContainerVtbl TargetContainerVtbl = {
1074 TargetContainer_QueryInterface,
1075 TargetContainer_AddRef,
1076 TargetContainer_Release,
1077 TargetContainer_GetFrameUrl,
1078 TargetContainer_GetFramesContainer
1079 };
1080
1081 void TargetContainer_Init(HTMLDocumentObj *This)
1082 {
1083 This->ITargetContainer_iface.lpVtbl = &TargetContainerVtbl;
1084 }
1085
1086 /**********************************************************
1087 * IObjectSafety implementation
1088 */
1089
1090 static inline HTMLDocument *impl_from_IObjectSafety(IObjectSafety *iface)
1091 {
1092 return CONTAINING_RECORD(iface, HTMLDocument, IObjectSafety_iface);
1093 }
1094
1095 static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
1096 {
1097 HTMLDocument *This = impl_from_IObjectSafety(iface);
1098 return htmldoc_query_interface(This, riid, ppv);
1099 }
1100
1101 static ULONG WINAPI ObjectSafety_AddRef(IObjectSafety *iface)
1102 {
1103 HTMLDocument *This = impl_from_IObjectSafety(iface);
1104 return htmldoc_addref(This);
1105 }
1106
1107 static ULONG WINAPI ObjectSafety_Release(IObjectSafety *iface)
1108 {
1109 HTMLDocument *This = impl_from_IObjectSafety(iface);
1110 return htmldoc_release(This);
1111 }
1112
1113 static HRESULT WINAPI ObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface,
1114 REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
1115 {
1116 HTMLDocument *This = impl_from_IObjectSafety(iface);
1117 FIXME("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
1118 return E_NOTIMPL;
1119 }
1120
1121 static HRESULT WINAPI ObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface,
1122 REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
1123 {
1124 HTMLDocument *This = impl_from_IObjectSafety(iface);
1125 FIXME("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
1126
1127 if(IsEqualGUID(&IID_IPersistMoniker, riid) &&
1128 dwOptionSetMask==INTERFACESAFE_FOR_UNTRUSTED_DATA &&
1129 dwEnabledOptions==INTERFACESAFE_FOR_UNTRUSTED_DATA)
1130 return S_OK;
1131
1132 return E_NOTIMPL;
1133 }
1134
1135 static const IObjectSafetyVtbl ObjectSafetyVtbl = {
1136 ObjectSafety_QueryInterface,
1137 ObjectSafety_AddRef,
1138 ObjectSafety_Release,
1139 ObjectSafety_GetInterfaceSafetyOptions,
1140 ObjectSafety_SetInterfaceSafetyOptions
1141 };
1142
1143 void HTMLDocument_LockContainer(HTMLDocumentObj *This, BOOL fLock)
1144 {
1145 IOleContainer *container;
1146 HRESULT hres;
1147
1148 if(!This->client || This->container_locked == fLock)
1149 return;
1150
1151 hres = IOleClientSite_GetContainer(This->client, &container);
1152 if(SUCCEEDED(hres)) {
1153 IOleContainer_LockContainer(container, fLock);
1154 This->container_locked = fLock;
1155 IOleContainer_Release(container);
1156 }
1157 }
1158
1159 void HTMLDocument_OleObj_Init(HTMLDocument *This)
1160 {
1161 This->IOleObject_iface.lpVtbl = &OleObjectVtbl;
1162 This->IOleDocument_iface.lpVtbl = &OleDocumentVtbl;
1163 This->IOleControl_iface.lpVtbl = &OleControlVtbl;
1164 This->IObjectWithSite_iface.lpVtbl = &ObjectWithSiteVtbl;
1165 This->IOleContainer_iface.lpVtbl = &OleContainerVtbl;
1166 This->IObjectSafety_iface.lpVtbl = &ObjectSafetyVtbl;
1167 }