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