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