include: Define more wuapi interfaces to avoid undefined forward declarations.
[wine] / dlls / 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 "config.h"
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
30 #include "shlguid.h"
31 #include "mshtmdid.h"
32 #include "idispids.h"
33
34 #include "wine/debug.h"
35
36 #include "mshtml_private.h"
37 #include "initguid.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
40
41 DEFINE_OLEGUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0);
42 #define DOCHOST_DOCCANNAVIGATE  0
43
44 /**********************************************************
45  * IOleObject implementation
46  */
47
48 #define OLEOBJ_THIS(iface) DEFINE_THIS(HTMLDocument, OleObject, iface)
49
50 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppvObject)
51 {
52     HTMLDocument *This = OLEOBJ_THIS(iface);
53     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
54 }
55
56 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
57 {
58     HTMLDocument *This = OLEOBJ_THIS(iface);
59     return IHTMLDocument2_AddRef(HTMLDOC(This));
60 }
61
62 static ULONG WINAPI OleObject_Release(IOleObject *iface)
63 {
64     HTMLDocument *This = OLEOBJ_THIS(iface);
65     return IHTMLDocument2_Release(HTMLDOC(This));
66 }
67
68 static void update_hostinfo(HTMLDocumentObj *This, DOCHOSTUIINFO *hostinfo)
69 {
70     nsIScrollable *scrollable;
71     nsresult nsres;
72
73     if(!This->nscontainer)
74         return;
75
76     nsres = nsIWebBrowser_QueryInterface(This->nscontainer->webbrowser, &IID_nsIScrollable, (void**)&scrollable);
77     if(NS_SUCCEEDED(nsres)) {
78         nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, ScrollOrientation_Y,
79                 (hostinfo->dwFlags & DOCHOSTUIFLAG_SCROLL_NO) ? Scrollbar_Never : Scrollbar_Always);
80         if(NS_FAILED(nsres))
81             ERR("Could not set default Y scrollbar prefs: %08x\n", nsres);
82
83         nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, ScrollOrientation_X,
84                 hostinfo->dwFlags & DOCHOSTUIFLAG_SCROLL_NO ? Scrollbar_Never : Scrollbar_Auto);
85         if(NS_FAILED(nsres))
86             ERR("Could not set default X scrollbar prefs: %08x\n", nsres);
87
88         nsIScrollable_Release(scrollable);
89     }else {
90         ERR("Could not get nsIScrollable: %08x\n", nsres);
91     }
92 }
93
94 static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *pClientSite)
95 {
96     HTMLDocument *This = OLEOBJ_THIS(iface);
97     IOleCommandTarget *cmdtrg = NULL;
98     IOleWindow *ole_window;
99     BOOL hostui_setup;
100     VARIANT silent;
101     HWND hwnd;
102     HRESULT hres;
103
104     TRACE("(%p)->(%p)\n", This, pClientSite);
105
106     if(pClientSite == This->doc_obj->client)
107         return S_OK;
108
109     if(This->doc_obj->client) {
110         IOleClientSite_Release(This->doc_obj->client);
111         This->doc_obj->client = NULL;
112         This->doc_obj->usermode = UNKNOWN_USERMODE;
113     }
114
115     if(This->doc_obj->hostui && !This->doc_obj->custom_hostui) {
116         IDocHostUIHandler_Release(This->doc_obj->hostui);
117         This->doc_obj->hostui = NULL;
118     }
119
120     memset(&This->doc_obj->hostinfo, 0, sizeof(DOCHOSTUIINFO));
121
122     if(!pClientSite)
123         return S_OK;
124
125     IOleClientSite_AddRef(pClientSite);
126     This->doc_obj->client = pClientSite;
127
128     hostui_setup = This->doc_obj->hostui_setup;
129
130     if(!This->doc_obj->hostui) {
131         IDocHostUIHandler *uihandler;
132
133         This->doc_obj->custom_hostui = FALSE;
134
135         hres = IOleObject_QueryInterface(pClientSite, &IID_IDocHostUIHandler, (void**)&uihandler);
136         if(SUCCEEDED(hres))
137             This->doc_obj->hostui = uihandler;
138     }
139
140     if(This->doc_obj->hostui) {
141         DOCHOSTUIINFO hostinfo;
142         LPOLESTR key_path = NULL, override_key_path = NULL;
143         IDocHostUIHandler2 *uihandler2;
144
145         memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO));
146         hostinfo.cbSize = sizeof(DOCHOSTUIINFO);
147         hres = IDocHostUIHandler_GetHostInfo(This->doc_obj->hostui, &hostinfo);
148         if(SUCCEEDED(hres)) {
149             TRACE("hostinfo = {%u %08x %08x %s %s}\n",
150                     hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick,
151                     debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS));
152             update_hostinfo(This->doc_obj, &hostinfo);
153             This->doc_obj->hostinfo = hostinfo;
154         }
155
156         if(!hostui_setup) {
157             hres = IDocHostUIHandler_GetOptionKeyPath(This->doc_obj->hostui, &key_path, 0);
158             if(hres == S_OK && key_path) {
159                 if(key_path[0]) {
160                     /* FIXME: use key_path */
161                     TRACE("key_path = %s\n", debugstr_w(key_path));
162                 }
163                 CoTaskMemFree(key_path);
164             }
165
166             hres = IDocHostUIHandler_QueryInterface(This->doc_obj->hostui, &IID_IDocHostUIHandler2,
167                     (void**)&uihandler2);
168             if(SUCCEEDED(hres)) {
169                 hres = IDocHostUIHandler2_GetOverrideKeyPath(uihandler2, &override_key_path, 0);
170                 if(hres == S_OK && override_key_path && override_key_path[0]) {
171                     if(override_key_path[0]) {
172                         /*FIXME: use override_key_path */
173                         TRACE("override_key_path = %s\n", debugstr_w(override_key_path));
174                     }
175                     CoTaskMemFree(override_key_path);
176                 }
177                 IDocHostUIHandler2_Release(uihandler2);
178             }
179
180             This->doc_obj->hostui_setup = TRUE;
181         }
182     }
183
184     /* Native calls here GetWindow. What is it for?
185      * We don't have anything to do with it here (yet). */
186     hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleWindow, (void**)&ole_window);
187     if(SUCCEEDED(hres)) {
188         IOleWindow_GetWindow(ole_window, &hwnd);
189         IOleWindow_Release(ole_window);
190     }
191
192     hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleCommandTarget, (void**)&cmdtrg);
193     if(SUCCEEDED(hres)) {
194         VARIANT var;
195         OLECMD cmd = {OLECMDID_SETPROGRESSTEXT, 0};
196
197         if(!hostui_setup) {
198             V_VT(&var) = VT_UNKNOWN;
199             V_UNKNOWN(&var) = (IUnknown*)HTMLWINDOW2(This->window);
200             IOleCommandTarget_Exec(cmdtrg, &CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, &var, NULL);
201         }
202
203         IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &cmd, NULL);
204
205         V_VT(&var) = VT_I4;
206         V_I4(&var) = 0;
207         IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSMAX,
208                 OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
209         IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSPOS, 
210                 OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
211
212         IOleCommandTarget_Release(cmdtrg);
213     }
214
215     if(This->doc_obj->usermode == UNKNOWN_USERMODE)
216         IOleControl_OnAmbientPropertyChange(CONTROL(This), DISPID_AMBIENT_USERMODE);
217
218     IOleControl_OnAmbientPropertyChange(CONTROL(This), DISPID_AMBIENT_OFFLINEIFNOTCONNECTED); 
219
220     hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_SILENT, &silent);
221     if(SUCCEEDED(hres)) {
222         if(V_VT(&silent) != VT_BOOL)
223             WARN("V_VT(silent) = %d\n", V_VT(&silent));
224         else if(V_BOOL(&silent))
225             FIXME("silent == true\n");
226     }
227
228     IOleControl_OnAmbientPropertyChange(CONTROL(This), DISPID_AMBIENT_USERAGENT);
229     IOleControl_OnAmbientPropertyChange(CONTROL(This), DISPID_AMBIENT_PALETTE);
230
231     return S_OK;
232 }
233
234 static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **ppClientSite)
235 {
236     HTMLDocument *This = OLEOBJ_THIS(iface);
237
238     TRACE("(%p)->(%p)\n", This, ppClientSite);
239
240     if(!ppClientSite)
241         return E_INVALIDARG;
242
243     if(This->doc_obj->client)
244         IOleClientSite_AddRef(This->doc_obj->client);
245     *ppClientSite = This->doc_obj->client;
246
247     return S_OK;
248 }
249
250 static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
251 {
252     HTMLDocument *This = OLEOBJ_THIS(iface);
253     FIXME("(%p)->(%s %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));
254     return E_NOTIMPL;
255 }
256
257 static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
258 {
259     HTMLDocument *This = OLEOBJ_THIS(iface);
260
261     TRACE("(%p)->(%08x)\n", This, dwSaveOption);
262
263     if(dwSaveOption == OLECLOSE_PROMPTSAVE)
264         FIXME("OLECLOSE_PROMPTSAVE not implemented\n");
265
266     if(This->doc_obj->in_place_active)
267         IOleInPlaceObjectWindowless_InPlaceDeactivate(INPLACEWIN(This));
268
269     HTMLDocument_LockContainer(This->doc_obj, FALSE);
270
271     if(This->advise_holder)
272         IOleAdviseHolder_SendOnClose(This->advise_holder);
273     
274     return S_OK;
275 }
276
277 static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker *pmk)
278 {
279     HTMLDocument *This = OLEOBJ_THIS(iface);
280     FIXME("(%p %d %p)->()\n", This, dwWhichMoniker, pmk);
281     return E_NOTIMPL;
282 }
283
284 static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
285 {
286     HTMLDocument *This = OLEOBJ_THIS(iface);
287     FIXME("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
288     return E_NOTIMPL;
289 }
290
291 static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *pDataObject, BOOL fCreation,
292                                         DWORD dwReserved)
293 {
294     HTMLDocument *This = OLEOBJ_THIS(iface);
295     FIXME("(%p)->(%p %x %d)\n", This, pDataObject, fCreation, dwReserved);
296     return E_NOTIMPL;
297 }
298
299 static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved, IDataObject **ppDataObject)
300 {
301     HTMLDocument *This = OLEOBJ_THIS(iface);
302     FIXME("(%p)->(%d %p)\n", This, dwReserved, ppDataObject);
303     return E_NOTIMPL;
304 }
305
306 static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
307                                         LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
308 {
309     HTMLDocument *This = OLEOBJ_THIS(iface);
310     IOleDocumentSite *pDocSite;
311     HRESULT hres;
312
313     TRACE("(%p)->(%d %p %p %d %p %p)\n", This, iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect);
314
315     if(iVerb != OLEIVERB_SHOW && iVerb != OLEIVERB_UIACTIVATE && iVerb != OLEIVERB_INPLACEACTIVATE) { 
316         FIXME("iVerb = %d not supported\n", iVerb);
317         return E_NOTIMPL;
318     }
319
320     if(!pActiveSite)
321         pActiveSite = This->doc_obj->client;
322
323     hres = IOleClientSite_QueryInterface(pActiveSite, &IID_IOleDocumentSite, (void**)&pDocSite);
324     if(SUCCEEDED(hres)) {
325         HTMLDocument_LockContainer(This->doc_obj, TRUE);
326
327         /* FIXME: Create new IOleDocumentView. See CreateView for more info. */
328         hres = IOleDocumentSite_ActivateMe(pDocSite, DOCVIEW(This));
329         IOleDocumentSite_Release(pDocSite);
330     }else {
331         hres = IOleDocumentView_UIActivate(DOCVIEW(This), TRUE);
332         if(SUCCEEDED(hres)) {
333             if(lprcPosRect) {
334                 RECT rect; /* We need to pass rect as not const pointer */
335                 rect = *lprcPosRect;
336                 IOleDocumentView_SetRect(DOCVIEW(This), &rect);
337             }
338             IOleDocumentView_Show(DOCVIEW(This), TRUE);
339         }
340     }
341
342     return hres;
343 }
344
345 static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
346 {
347     HTMLDocument *This = OLEOBJ_THIS(iface);
348     FIXME("(%p)->(%p)\n", This, ppEnumOleVerb);
349     return E_NOTIMPL;
350 }
351
352 static HRESULT WINAPI OleObject_Update(IOleObject *iface)
353 {
354     HTMLDocument *This = OLEOBJ_THIS(iface);
355     FIXME("(%p)\n", This);
356     return E_NOTIMPL;
357 }
358
359 static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
360 {
361     HTMLDocument *This = OLEOBJ_THIS(iface);
362     FIXME("(%p)\n", This);
363     return E_NOTIMPL;
364 }
365
366 static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *pClsid)
367 {
368     HTMLDocument *This = OLEOBJ_THIS(iface);
369
370     TRACE("(%p)->(%p)\n", This, pClsid);
371
372     if(!pClsid)
373         return E_INVALIDARG;
374
375     *pClsid = CLSID_HTMLDocument;
376     return S_OK;
377 }
378
379 static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType, LPOLESTR *pszUserType)
380 {
381     HTMLDocument *This = OLEOBJ_THIS(iface);
382     FIXME("(%p)->(%d %p)\n", This, dwFormOfType, pszUserType);
383     return E_NOTIMPL;
384 }
385
386 static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
387 {
388     HTMLDocument *This = OLEOBJ_THIS(iface);
389     FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
390     return E_NOTIMPL;
391 }
392
393 static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
394 {
395     HTMLDocument *This = OLEOBJ_THIS(iface);
396     FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
397     return E_NOTIMPL;
398 }
399
400 static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection)
401 {
402     HTMLDocument *This = OLEOBJ_THIS(iface);
403     TRACE("(%p)->(%p %p)\n", This, pAdvSink, pdwConnection);
404
405     if(!pdwConnection)
406         return E_INVALIDARG;
407
408     if(!pAdvSink) {
409         *pdwConnection = 0;
410         return E_INVALIDARG;
411     }
412
413     if(!This->advise_holder) {
414         CreateOleAdviseHolder(&This->advise_holder);
415         if(!This->advise_holder)
416             return E_OUTOFMEMORY;
417     }
418
419     return IOleAdviseHolder_Advise(This->advise_holder, pAdvSink, pdwConnection);
420 }
421
422 static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
423 {
424     HTMLDocument *This = OLEOBJ_THIS(iface);
425     TRACE("(%p)->(%d)\n", This, dwConnection);
426
427     if(!This->advise_holder)
428         return OLE_E_NOCONNECTION;
429
430     return IOleAdviseHolder_Unadvise(This->advise_holder, dwConnection);
431 }
432
433 static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
434 {
435     HTMLDocument *This = OLEOBJ_THIS(iface);
436
437     if(!This->advise_holder) {
438         *ppenumAdvise = NULL;
439         return S_OK;
440     }
441
442     return IOleAdviseHolder_EnumAdvise(This->advise_holder, ppenumAdvise);
443 }
444
445 static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
446 {
447     HTMLDocument *This = OLEOBJ_THIS(iface);
448     FIXME("(%p)->(%d %p)\n", This, dwAspect, pdwStatus);
449     return E_NOTIMPL;
450 }
451
452 static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *pLogpal)
453 {
454     HTMLDocument *This = OLEOBJ_THIS(iface);
455     FIXME("(%p)->(%p)\n", This, pLogpal);
456     return E_NOTIMPL;
457 }
458
459 #undef OLEPBJ_THIS
460
461 static const IOleObjectVtbl OleObjectVtbl = {
462     OleObject_QueryInterface,
463     OleObject_AddRef,
464     OleObject_Release,
465     OleObject_SetClientSite,
466     OleObject_GetClientSite,
467     OleObject_SetHostNames,
468     OleObject_Close,
469     OleObject_SetMoniker,
470     OleObject_GetMoniker,
471     OleObject_InitFromData,
472     OleObject_GetClipboardData,
473     OleObject_DoVerb,
474     OleObject_EnumVerbs,
475     OleObject_Update,
476     OleObject_IsUpToDate,
477     OleObject_GetUserClassID,
478     OleObject_GetUserType,
479     OleObject_SetExtent,
480     OleObject_GetExtent,
481     OleObject_Advise,
482     OleObject_Unadvise,
483     OleObject_EnumAdvise,
484     OleObject_GetMiscStatus,
485     OleObject_SetColorScheme
486 };
487
488 /**********************************************************
489  * IOleDocument implementation
490  */
491
492 #define OLEDOC_THIS(iface) DEFINE_THIS(HTMLDocument, OleDocument, iface)
493
494 static HRESULT WINAPI OleDocument_QueryInterface(IOleDocument *iface, REFIID riid, void **ppvObject)
495 {
496     HTMLDocument *This = OLEDOC_THIS(iface);
497     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
498 }
499
500 static ULONG WINAPI OleDocument_AddRef(IOleDocument *iface)
501 {
502     HTMLDocument *This = OLEDOC_THIS(iface);
503     return IHTMLDocument2_AddRef(HTMLDOC(This));
504 }
505
506 static ULONG WINAPI OleDocument_Release(IOleDocument *iface)
507 {
508     HTMLDocument *This = OLEDOC_THIS(iface);
509     return IHTMLDocument2_Release(HTMLDOC(This));
510 }
511
512 static HRESULT WINAPI OleDocument_CreateView(IOleDocument *iface, IOleInPlaceSite *pIPSite, IStream *pstm,
513                                    DWORD dwReserved, IOleDocumentView **ppView)
514 {
515     HTMLDocument *This = OLEDOC_THIS(iface);
516     HRESULT hres;
517
518     TRACE("(%p)->(%p %p %d %p)\n", This, pIPSite, pstm, dwReserved, ppView);
519
520     if(!ppView)
521         return E_INVALIDARG;
522
523     /* FIXME:
524      * Windows implementation creates new IOleDocumentView when function is called for the
525      * first time and returns E_FAIL when it is called for the second time, but it doesn't matter
526      * if the application uses returned interfaces, passed to ActivateMe or returned by
527      * QueryInterface, so there is no reason to create new interface. This needs more testing.
528      */
529
530     if(pIPSite) {
531         hres = IOleDocumentView_SetInPlaceSite(DOCVIEW(This), pIPSite);
532         if(FAILED(hres))
533             return hres;
534     }
535
536     if(pstm)
537         FIXME("pstm is not supported\n");
538
539     IOleDocumentView_AddRef(DOCVIEW(This));
540     *ppView = DOCVIEW(This);
541     return S_OK;
542 }
543
544 static HRESULT WINAPI OleDocument_GetDocMiscStatus(IOleDocument *iface, DWORD *pdwStatus)
545 {
546     HTMLDocument *This = OLEDOC_THIS(iface);
547     FIXME("(%p)->(%p)\n", This, pdwStatus);
548     return E_NOTIMPL;
549 }
550
551 static HRESULT WINAPI OleDocument_EnumViews(IOleDocument *iface, IEnumOleDocumentViews **ppEnum,
552                                    IOleDocumentView **ppView)
553 {
554     HTMLDocument *This = OLEDOC_THIS(iface);
555     FIXME("(%p)->(%p %p)\n", This, ppEnum, ppView);
556     return E_NOTIMPL;
557 }
558
559 #undef OLEDOC_THIS
560
561 static const IOleDocumentVtbl OleDocumentVtbl = {
562     OleDocument_QueryInterface,
563     OleDocument_AddRef,
564     OleDocument_Release,
565     OleDocument_CreateView,
566     OleDocument_GetDocMiscStatus,
567     OleDocument_EnumViews
568 };
569
570 /**********************************************************
571  * IOleControl implementation
572  */
573
574 #define CONTROL_THIS(iface) DEFINE_THIS(HTMLDocument, OleControl, iface)
575
576 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
577 {
578     HTMLDocument *This = CONTROL_THIS(iface);
579     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppv);
580 }
581
582 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
583 {
584     HTMLDocument *This = CONTROL_THIS(iface);
585     return IHTMLDocument2_AddRef(HTMLDOC(This));
586 }
587
588 static ULONG WINAPI OleControl_Release(IOleControl *iface)
589 {
590     HTMLDocument *This = CONTROL_THIS(iface);
591     return IHTMLDocument_Release(HTMLDOC(This));
592 }
593
594 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *pCI)
595 {
596     HTMLDocument *This = CONTROL_THIS(iface);
597     FIXME("(%p)->(%p)\n", This, pCI);
598     return E_NOTIMPL;
599 }
600
601 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *pMsg)
602 {
603     HTMLDocument *This = CONTROL_THIS(iface);
604     FIXME("(%p)->(%p)\n", This, pMsg);
605     return E_NOTIMPL;
606 }
607
608 HRESULT get_client_disp_property(IOleClientSite *client, DISPID dispid, VARIANT *res)
609 {
610     IDispatch *disp = NULL;
611     DISPPARAMS dispparams = {NULL, 0};
612     UINT err;
613     HRESULT hres;
614
615     hres = IOleClientSite_QueryInterface(client, &IID_IDispatch, (void**)&disp);
616     if(FAILED(hres)) {
617         TRACE("Could not get IDispatch\n");
618         return hres;
619     }
620
621     VariantInit(res);
622
623     hres = IDispatch_Invoke(disp, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
624             DISPATCH_PROPERTYGET, &dispparams, res, NULL, &err);
625
626     IDispatch_Release(disp);
627
628     return hres;
629 }
630
631 static HRESULT on_change_dlcontrol(HTMLDocument *This)
632 {
633     VARIANT res;
634     HRESULT hres;
635     
636     hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_DLCONTROL, &res);
637     if(SUCCEEDED(hres))
638         FIXME("unsupported dlcontrol %08x\n", V_I4(&res));
639
640     return S_OK;
641 }
642
643 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
644 {
645     HTMLDocument *This = CONTROL_THIS(iface);
646     IOleClientSite *client;
647     VARIANT res;
648     HRESULT hres;
649
650     client = This->doc_obj->client;
651     if(!client) {
652         TRACE("client = NULL\n");
653         return S_OK;
654     }
655
656     switch(dispID) {
657     case DISPID_AMBIENT_USERMODE:
658         TRACE("(%p)->(DISPID_AMBIENT_USERMODE)\n", This);
659         hres = get_client_disp_property(client, DISPID_AMBIENT_USERMODE, &res);
660         if(FAILED(hres))
661             return S_OK;
662
663         if(V_VT(&res) == VT_BOOL) {
664             if(V_BOOL(&res)) {
665                 This->doc_obj->usermode = BROWSEMODE;
666             }else {
667                 FIXME("edit mode is not supported\n");
668                 This->doc_obj->usermode = EDITMODE;
669             }
670         }else {
671             FIXME("V_VT(res)=%d\n", V_VT(&res));
672         }
673         return S_OK;
674     case DISPID_AMBIENT_DLCONTROL:
675         TRACE("(%p)->(DISPID_AMBIENT_DLCONTROL)\n", This);
676         return on_change_dlcontrol(This);
677     case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
678         TRACE("(%p)->(DISPID_AMBIENT_OFFLINEIFNOTCONNECTED)\n", This);
679         on_change_dlcontrol(This);
680         hres = get_client_disp_property(client, DISPID_AMBIENT_OFFLINEIFNOTCONNECTED, &res);
681         if(FAILED(hres))
682             return S_OK;
683
684         if(V_VT(&res) == VT_BOOL) {
685             if(V_BOOL(&res)) {
686                 FIXME("offline connection is not supported\n");
687                 hres = E_FAIL;
688             }
689         }else {
690             FIXME("V_VT(res)=%d\n", V_VT(&res));
691         }
692         return S_OK;
693     case DISPID_AMBIENT_SILENT:
694         TRACE("(%p)->(DISPID_AMBIENT_SILENT)\n", This);
695         on_change_dlcontrol(This);
696         hres = get_client_disp_property(client, DISPID_AMBIENT_SILENT, &res);
697         if(FAILED(hres))
698             return S_OK;
699
700         if(V_VT(&res) == VT_BOOL) {
701             if(V_BOOL(&res)) {
702                 FIXME("silent mode is not supported\n");
703                 hres = E_FAIL;
704             }
705         }else {
706             FIXME("V_VT(res)=%d\n", V_VT(&res));
707         }
708         return S_OK;
709     case DISPID_AMBIENT_USERAGENT:
710         TRACE("(%p)->(DISPID_AMBIENT_USERAGENT)\n", This);
711         hres = get_client_disp_property(client, DISPID_AMBIENT_USERAGENT, &res);
712         if(FAILED(hres))
713             return S_OK;
714
715         FIXME("not supported AMBIENT_USERAGENT\n");
716         hres = E_FAIL;
717         return S_OK;
718     case DISPID_AMBIENT_PALETTE:
719         TRACE("(%p)->(DISPID_AMBIENT_PALETTE)\n", This);
720         hres = get_client_disp_property(client, DISPID_AMBIENT_PALETTE, &res);
721         if(FAILED(hres))
722             return S_OK;
723
724         FIXME("not supported AMBIENT_PALETTE\n");
725         hres = E_FAIL;
726         return S_OK;
727     }
728
729     FIXME("(%p) unsupported dispID=%d\n", This, dispID);
730     return E_FAIL;
731 }
732
733 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
734 {
735     HTMLDocument *This = CONTROL_THIS(iface);
736     FIXME("(%p)->(%x)\n", This, bFreeze);
737     return E_NOTIMPL;
738 }
739
740 #undef CONTROL_THIS
741
742 static const IOleControlVtbl OleControlVtbl = {
743     OleControl_QueryInterface,
744     OleControl_AddRef,
745     OleControl_Release,
746     OleControl_GetControlInfo,
747     OleControl_OnMnemonic,
748     OleControl_OnAmbientPropertyChange,
749     OleControl_FreezeEvents
750 };
751
752 /**********************************************************
753  * IObjectWithSite implementation
754  */
755
756 #define OBJSITE_THIS(iface) DEFINE_THIS(HTMLDocument, ObjectWithSite, iface)
757
758 static HRESULT WINAPI ObjectWithSite_QueryInterface(IObjectWithSite *iface, REFIID riid, void **ppvObject)
759 {
760     HTMLDocument *This = OBJSITE_THIS(iface);
761     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
762 }
763
764 static ULONG WINAPI ObjectWithSite_AddRef(IObjectWithSite *iface)
765 {
766     HTMLDocument *This = OBJSITE_THIS(iface);
767     return IHTMLDocument2_AddRef(HTMLDOC(This));
768 }
769
770 static ULONG WINAPI ObjectWithSite_Release(IObjectWithSite *iface)
771 {
772     HTMLDocument *This = OBJSITE_THIS(iface);
773     return IHTMLDocument2_Release(HTMLDOC(This));
774 }
775
776 static HRESULT WINAPI ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *pUnkSite)
777 {
778     HTMLDocument *This = OBJSITE_THIS(iface);
779     FIXME("(%p)->(%p)\n", This, pUnkSite);
780     return E_NOTIMPL;
781 }
782
783 static HRESULT WINAPI ObjectWithSite_GetSite(IObjectWithSite* iface, REFIID riid, PVOID *ppvSite)
784 {
785     HTMLDocument *This = OBJSITE_THIS(iface);
786     FIXME("(%p)->(%p)\n", This, ppvSite);
787     return E_NOTIMPL;
788 }
789
790 #undef OBJSITE_THIS
791
792 static const IObjectWithSiteVtbl ObjectWithSiteVtbl = {
793     ObjectWithSite_QueryInterface,
794     ObjectWithSite_AddRef,
795     ObjectWithSite_Release,
796     ObjectWithSite_SetSite,
797     ObjectWithSite_GetSite
798 };
799
800 void HTMLDocument_LockContainer(HTMLDocumentObj *This, BOOL fLock)
801 {
802     IOleContainer *container;
803     HRESULT hres;
804
805     if(!This->client || This->container_locked == fLock)
806         return;
807
808     hres = IOleClientSite_GetContainer(This->client, &container);
809     if(SUCCEEDED(hres)) {
810         IOleContainer_LockContainer(container, fLock);
811         This->container_locked = fLock;
812         IOleContainer_Release(container);
813     }
814 }
815
816 void HTMLDocument_OleObj_Init(HTMLDocument *This)
817 {
818     This->lpOleObjectVtbl = &OleObjectVtbl;
819     This->lpOleDocumentVtbl = &OleDocumentVtbl;
820     This->lpOleControlVtbl = &OleControlVtbl;
821     This->lpObjectWithSiteVtbl = &ObjectWithSiteVtbl;
822 }