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