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