Fix some gcc 4.0 warnings.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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(This->client)
74         IOleClientSite_Release(This->client);
75
76     if(This->hostui)
77         IDocHostUIHandler_Release(This->hostui);
78
79     if(!pClientSite) {
80         This->client = NULL;
81         return S_OK;
82     }
83
84     hres = IOleObject_QueryInterface(pClientSite, &IID_IDocHostUIHandler, (void**)&pDocHostUIHandler);
85     if(SUCCEEDED(hres)) {
86         DOCHOSTUIINFO hostinfo;
87         LPOLESTR key_path = NULL, override_key_path = NULL;
88         IDocHostUIHandler2 *pDocHostUIHandler2;
89
90         memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO));
91         hostinfo.cbSize = sizeof(DOCHOSTUIINFO);
92         hres = IDocHostUIHandler_GetHostInfo(pDocHostUIHandler, &hostinfo);
93         if(SUCCEEDED(hres))
94             /* FIXME: use hostinfo */
95             TRACE("hostinfo = {%lu %08lx %08lx %s %s}\n",
96                     hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick,
97                     debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS));
98
99         if(!This->has_key_path) {
100             hres = IDocHostUIHandler_GetOptionKeyPath(pDocHostUIHandler, &key_path, 0);
101             if(hres == S_OK && key_path) {
102                 if(key_path[0]) {
103                     /* FIXME: use key_path */
104                     TRACE("key_path = %s\n", debugstr_w(key_path));
105                 }
106                 CoTaskMemFree(key_path);
107             }
108
109             hres = IDocHostUIHandler_QueryInterface(pDocHostUIHandler, &IID_IDocHostUIHandler2,
110                     (void**)&pDocHostUIHandler2);
111             if(SUCCEEDED(hres)) {
112                 hres = IDocHostUIHandler2_GetOverrideKeyPath(pDocHostUIHandler2, &override_key_path, 0);
113                 if(hres == S_OK && override_key_path && override_key_path[0]) {
114                     if(override_key_path[0]) {
115                         /*FIXME: use override_key_path */
116                         TRACE("override_key_path = %s\n", debugstr_w(override_key_path));
117                     }
118                     CoTaskMemFree(override_key_path);
119                 }
120             }
121
122             This->has_key_path = TRUE;
123         }
124     }
125
126     /* Native calls here GetWindow. What is it for?
127      * We don't have anything to do with it here (yet). */
128     if(pClientSite) {
129         IOleWindow *pOleWindow = NULL;
130         HWND hwnd;
131
132         hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleWindow, (void**)&pOleWindow);
133         if(SUCCEEDED(hres)) {
134             IOleWindow_GetWindow(pOleWindow, &hwnd);
135             IOleWindow_Release(pOleWindow);
136         }
137     }
138
139     hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleCommandTarget, (void**)&cmdtrg);
140     if(SUCCEEDED(hres)) {
141         VARIANT var;
142         OLECMD cmd = {OLECMDID_SETPROGRESSTEXT, 0};
143
144         IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &cmd, NULL);
145
146         V_VT(&var) = VT_I4;
147         V_I4(&var) = 0;
148         IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSMAX, 0, &var, NULL);
149         IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSPOS, 0, &var, NULL);
150
151         IOleCommandTarget_Release(cmdtrg);
152     }
153
154     IOleClientSite_AddRef(pClientSite);
155     This->client = pClientSite;
156     This->hostui = pDocHostUIHandler;
157
158     IOleControl_OnAmbientPropertyChange(CONTROL(This), DISPID_AMBIENT_USERMODE);
159     IOleControl_OnAmbientPropertyChange(CONTROL(This), DISPID_AMBIENT_OFFLINEIFNOTCONNECTED); 
160     IOleControl_OnAmbientPropertyChange(CONTROL(This), DISPID_AMBIENT_SILENT);
161     IOleControl_OnAmbientPropertyChange(CONTROL(This), DISPID_AMBIENT_USERAGENT);
162     IOleControl_OnAmbientPropertyChange(CONTROL(This), DISPID_AMBIENT_PALETTE);
163
164     return S_OK;
165 }
166
167 static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **ppClientSite)
168 {
169     HTMLDocument *This = OLEOBJ_THIS(iface);
170
171     TRACE("(%p)->(%p)\n", This, ppClientSite);
172
173     if(!ppClientSite)
174         return E_INVALIDARG;
175
176     if(This->client)
177         IOleClientSite_AddRef(This->client);
178     *ppClientSite = This->client;
179
180     return S_OK;
181 }
182
183 static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
184 {
185     HTMLDocument *This = OLEOBJ_THIS(iface);
186     FIXME("(%p)->(%s %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));
187     return E_NOTIMPL;
188 }
189
190 static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
191 {
192     HTMLDocument *This = OLEOBJ_THIS(iface);
193     HRESULT hres;
194
195     TRACE("(%p)->(%08lx)\n", This, dwSaveOption);
196
197     if(dwSaveOption == OLECLOSE_PROMPTSAVE)
198         FIXME("OLECLOSE_PROMPTSAVE not implemented\n");
199
200     if(This->in_place_active)
201         IOleInPlaceObjectWindowless_InPlaceDeactivate(INPLACEWIN(This));
202
203     if(This->client) {
204         IOleContainer *container;
205         hres = IOleClientSite_GetContainer(This->client, &container);
206         if(SUCCEEDED(hres)) {
207             IOleContainer_LockContainer(container, FALSE);
208             IOleContainer_Release(container);
209         }
210     }
211     
212     return S_OK;
213 }
214
215 static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker *pmk)
216 {
217     HTMLDocument *This = OLEOBJ_THIS(iface);
218     FIXME("(%p %ld %p)->()\n", This, dwWhichMoniker, pmk);
219     return E_NOTIMPL;
220 }
221
222 static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
223 {
224     HTMLDocument *This = OLEOBJ_THIS(iface);
225     FIXME("(%p)->(%ld %ld %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
226     return E_NOTIMPL;
227 }
228
229 static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *pDataObject, BOOL fCreation,
230                                         DWORD dwReserved)
231 {
232     HTMLDocument *This = OLEOBJ_THIS(iface);
233     FIXME("(%p)->(%p %x %ld)\n", This, pDataObject, fCreation, dwReserved);
234     return E_NOTIMPL;
235 }
236
237 static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved, IDataObject **ppDataObject)
238 {
239     HTMLDocument *This = OLEOBJ_THIS(iface);
240     FIXME("(%p)->(%ld %p)\n", This, dwReserved, ppDataObject);
241     return E_NOTIMPL;
242 }
243
244 static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
245                                         LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
246 {
247     HTMLDocument *This = OLEOBJ_THIS(iface);
248     IOleDocumentSite *pDocSite;
249     HRESULT hres;
250
251     TRACE("(%p)->(%ld %p %p %ld %p %p)\n", This, iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect);
252
253     if(iVerb != OLEIVERB_SHOW && iVerb != OLEIVERB_UIACTIVATE && iVerb != OLEIVERB_INPLACEACTIVATE) { 
254         FIXME("iVerb = %ld not supported\n", iVerb);
255         return E_NOTIMPL;
256     }
257
258     if(!pActiveSite)
259         pActiveSite = This->client;
260
261     hres = IOleClientSite_QueryInterface(pActiveSite, &IID_IOleDocumentSite, (void**)&pDocSite);
262     if(SUCCEEDED(hres)) {
263         IOleContainer *pContainer;
264         hres = IOleClientSite_GetContainer(pActiveSite, &pContainer);
265         if(SUCCEEDED(hres)) {
266             IOleContainer_LockContainer(pContainer, TRUE);
267             IOleContainer_Release(pContainer);
268         }
269         /* FIXME: Create new IOleDocumentView. See CreateView for more info. */
270         hres = IOleDocumentSite_ActivateMe(pDocSite, DOCVIEW(This));
271         IOleDocumentSite_Release(pDocSite);
272     }else {
273         hres = IOleDocumentView_UIActivate(DOCVIEW(This), TRUE);
274         if(SUCCEEDED(hres)) {
275             if(lprcPosRect) {
276                 RECT rect; /* We need to pass rect as not const pointer */
277                 memcpy(&rect, lprcPosRect, sizeof(RECT));
278                 IOleDocumentView_SetRect(DOCVIEW(This), &rect);
279             }
280             IOleDocumentView_Show(DOCVIEW(This), TRUE);
281         }
282     }
283
284     return hres;
285 }
286
287 static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
288 {
289     HTMLDocument *This = OLEOBJ_THIS(iface);
290     FIXME("(%p)->(%p)\n", This, ppEnumOleVerb);
291     return E_NOTIMPL;
292 }
293
294 static HRESULT WINAPI OleObject_Update(IOleObject *iface)
295 {
296     HTMLDocument *This = OLEOBJ_THIS(iface);
297     FIXME("(%p)\n", This);
298     return E_NOTIMPL;
299 }
300
301 static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
302 {
303     HTMLDocument *This = OLEOBJ_THIS(iface);
304     FIXME("(%p)\n", This);
305     return E_NOTIMPL;
306 }
307
308 static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *pClsid)
309 {
310     HTMLDocument *This = OLEOBJ_THIS(iface);
311
312     TRACE("(%p)->(%p)\n", This, pClsid);
313
314     if(!pClsid)
315         return E_INVALIDARG;
316
317     memcpy(pClsid, &CLSID_HTMLDocument, sizeof(GUID));
318     return S_OK;
319 }
320
321 static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType, LPOLESTR *pszUserType)
322 {
323     HTMLDocument *This = OLEOBJ_THIS(iface);
324     FIXME("(%p)->(%ld %p)\n", This, dwFormOfType, pszUserType);
325     return E_NOTIMPL;
326 }
327
328 static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
329 {
330     HTMLDocument *This = OLEOBJ_THIS(iface);
331     FIXME("(%p)->(%ld %p)\n", This, dwDrawAspect, psizel);
332     return E_NOTIMPL;
333 }
334
335 static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
336 {
337     HTMLDocument *This = OLEOBJ_THIS(iface);
338     FIXME("(%p)->(%ld %p)\n", This, dwDrawAspect, psizel);
339     return E_NOTIMPL;
340 }
341
342 static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection)
343 {
344     HTMLDocument *This = OLEOBJ_THIS(iface);
345     FIXME("(%p)->(%p %p)\n", This, pAdvSink, pdwConnection);
346     return E_NOTIMPL;
347 }
348
349 static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
350 {
351     HTMLDocument *This = OLEOBJ_THIS(iface);
352     FIXME("(%p)->(%ld)\n", This, dwConnection);
353     return E_NOTIMPL;
354 }
355
356 static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
357 {
358     HTMLDocument *This = OLEOBJ_THIS(iface);
359     FIXME("(%p)->(%p)\n", This, ppenumAdvise);
360     return E_NOTIMPL;
361 }
362
363 static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
364 {
365     HTMLDocument *This = OLEOBJ_THIS(iface);
366     FIXME("(%p)->(%ld %p)\n", This, dwAspect, pdwStatus);
367     return E_NOTIMPL;
368 }
369
370 static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *pLogpal)
371 {
372     HTMLDocument *This = OLEOBJ_THIS(iface);
373     FIXME("(%p)->(%p)\n", This, pLogpal);
374     return E_NOTIMPL;
375 }
376
377 #undef OLEPBJ_THIS
378
379 static const IOleObjectVtbl OleObjectVtbl = {
380     OleObject_QueryInterface,
381     OleObject_AddRef,
382     OleObject_Release,
383     OleObject_SetClientSite,
384     OleObject_GetClientSite,
385     OleObject_SetHostNames,
386     OleObject_Close,
387     OleObject_SetMoniker,
388     OleObject_GetMoniker,
389     OleObject_InitFromData,
390     OleObject_GetClipboardData,
391     OleObject_DoVerb,
392     OleObject_EnumVerbs,
393     OleObject_Update,
394     OleObject_IsUpToDate,
395     OleObject_GetUserClassID,
396     OleObject_GetUserType,
397     OleObject_SetExtent,
398     OleObject_GetExtent,
399     OleObject_Advise,
400     OleObject_Unadvise,
401     OleObject_EnumAdvise,
402     OleObject_GetMiscStatus,
403     OleObject_SetColorScheme
404 };
405
406 /**********************************************************
407  * IOleDocument implementation
408  */
409
410 #define OLEDOC_THIS(iface) DEFINE_THIS(HTMLDocument, OleDocument, iface)
411
412 static HRESULT WINAPI OleDocument_QueryInterface(IOleDocument *iface, REFIID riid, void **ppvObject)
413 {
414     HTMLDocument *This = OLEDOC_THIS(iface);
415     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
416 }
417
418 static ULONG WINAPI OleDocument_AddRef(IOleDocument *iface)
419 {
420     HTMLDocument *This = OLEDOC_THIS(iface);
421     return IHTMLDocument2_AddRef(HTMLDOC(This));
422 }
423
424 static ULONG WINAPI OleDocument_Release(IOleDocument *iface)
425 {
426     HTMLDocument *This = OLEDOC_THIS(iface);
427     return IHTMLDocument2_Release(HTMLDOC(This));
428 }
429
430 static HRESULT WINAPI OleDocument_CreateView(IOleDocument *iface, IOleInPlaceSite *pIPSite, IStream *pstm,
431                                    DWORD dwReserved, IOleDocumentView **ppView)
432 {
433     HTMLDocument *This = OLEDOC_THIS(iface);
434     HRESULT hres;
435
436     TRACE("(%p)->(%p %p %ld %p)\n", This, pIPSite, pstm, dwReserved, ppView);
437
438     if(!ppView)
439         return E_INVALIDARG;
440
441     /* FIXME:
442      * Windows implementation creates new IOleDocumentView when function is called for the
443      * first time and returns E_FAIL when it is called for the second time, but it doesn't matter
444      * if the application uses returned interfaces, passed to ActivateMe or returned by
445      * QueryInterface, so there is no reason to create new interface. This needs more testing.
446      */
447
448     if(pIPSite) {
449         hres = IOleDocumentView_SetInPlaceSite(DOCVIEW(This), pIPSite);
450         if(FAILED(hres))
451             return hres;
452     }
453
454     if(pstm)
455         FIXME("pstm is not supported\n");
456
457     IOleDocumentView_AddRef(DOCVIEW(This));
458     *ppView = DOCVIEW(This);
459     return S_OK;
460 }
461
462 static HRESULT WINAPI OleDocument_GetDocMiscStatus(IOleDocument *iface, DWORD *pdwStatus)
463 {
464     HTMLDocument *This = OLEDOC_THIS(iface);
465     FIXME("(%p)->(%p)\n", This, pdwStatus);
466     return E_NOTIMPL;
467 }
468
469 static HRESULT WINAPI OleDocument_EnumViews(IOleDocument *iface, IEnumOleDocumentViews **ppEnum,
470                                    IOleDocumentView **ppView)
471 {
472     HTMLDocument *This = OLEDOC_THIS(iface);
473     FIXME("(%p)->(%p %p)\n", This, ppEnum, ppView);
474     return E_NOTIMPL;
475 }
476
477 #undef OLEDOC_THIS
478
479 static const IOleDocumentVtbl OleDocumentVtbl = {
480     OleDocument_QueryInterface,
481     OleDocument_AddRef,
482     OleDocument_Release,
483     OleDocument_CreateView,
484     OleDocument_GetDocMiscStatus,
485     OleDocument_EnumViews
486 };
487
488 /**********************************************************
489  * IOleCommandTarget implementation
490  */
491
492 #define CMDTARGET_THIS(iface) DEFINE_THIS(HTMLDocument, OleCommandTarget, iface)
493
494 static HRESULT exec_open(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
495 {
496     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
497     return E_NOTIMPL;
498 }
499
500 static HRESULT exec_new(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
501 {
502     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
503     return E_NOTIMPL;
504 }
505
506 static HRESULT exec_save(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
507 {
508     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
509     return E_NOTIMPL;
510 }
511
512 static HRESULT exec_save_as(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
513 {
514     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
515     return E_NOTIMPL;
516 }
517
518 static HRESULT exec_save_copy_as(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
519 {
520     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
521     return E_NOTIMPL;
522 }
523
524 static HRESULT exec_print(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
525 {
526     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
527     return E_NOTIMPL;
528 }
529
530 static HRESULT exec_print_preview(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
531 {
532     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
533     return E_NOTIMPL;
534 }
535
536 static HRESULT exec_page_setup(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
537 {
538     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
539     return E_NOTIMPL;
540 }
541
542 static HRESULT exec_spell(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
543 {
544     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
545     return E_NOTIMPL;
546 }
547
548 static HRESULT exec_properties(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
549 {
550     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
551     return E_NOTIMPL;
552 }
553
554 static HRESULT exec_cut(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
555 {
556     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
557     return E_NOTIMPL;
558 }
559
560 static HRESULT exec_copy(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
561 {
562     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
563     return E_NOTIMPL;
564 }
565
566 static HRESULT exec_paste(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
567 {
568     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
569     return E_NOTIMPL;
570 }
571
572 static HRESULT exec_paste_special(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
573 {
574     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
575     return E_NOTIMPL;
576 }
577
578 static HRESULT exec_undo(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
579 {
580     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
581     return E_NOTIMPL;
582 }
583
584 static HRESULT exec_rendo(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
585 {
586     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
587     return E_NOTIMPL;
588 }
589
590 static HRESULT exec_select_all(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
591 {
592     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
593     return E_NOTIMPL;
594 }
595
596 static HRESULT exec_clear_selection(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
597 {
598     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
599     return E_NOTIMPL;
600 }
601
602 static HRESULT exec_zoom(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
603 {
604     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
605     return E_NOTIMPL;
606 }
607
608 static HRESULT exec_get_zoom_range(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
609 {
610     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
611     return E_NOTIMPL;
612 }
613
614 static HRESULT exec_refresh(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
615 {
616     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
617     return E_NOTIMPL;
618 }
619
620 static HRESULT exec_stop(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
621 {
622     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
623     return E_NOTIMPL;
624 }
625
626 static HRESULT exec_stop_download(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
627 {
628     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
629     return E_NOTIMPL;
630 }
631
632 static HRESULT exec_delete(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
633 {
634     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
635     return E_NOTIMPL;
636 }
637
638 static HRESULT exec_enable_interaction(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
639 {
640     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
641     return E_NOTIMPL;
642 }
643
644 static HRESULT exec_on_unload(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
645 {
646     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
647     return E_NOTIMPL;
648 }
649
650 static HRESULT exec_show_page_setup(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
651 {
652     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
653     return E_NOTIMPL;
654 }
655
656 static HRESULT exec_show_print(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
657 {
658     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
659     return E_NOTIMPL;
660 }
661
662 static HRESULT exec_close(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
663 {
664     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
665     return E_NOTIMPL;
666 }
667
668 static HRESULT exec_set_print_template(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
669 {
670     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
671     return E_NOTIMPL;
672 }
673
674 static HRESULT exec_get_print_template(HTMLDocument *This, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
675 {
676     FIXME("(%p)->(%ld %p %p)\n", This, nCmdexecopt, pvaIn, pvaOut);
677     return E_NOTIMPL;
678 }
679
680 static const struct {
681     OLECMDF cmdf;
682     HRESULT (*func)(HTMLDocument*,DWORD,VARIANT*,VARIANT*);
683 } exec_table[OLECMDID_GETPRINTTEMPLATE+1] = {
684     {0},
685     { OLECMDF_SUPPORTED,                  exec_open                 }, /* OLECMDID_OPEN */
686     { OLECMDF_SUPPORTED,                  exec_new                  }, /* OLECMDID_NEW */
687     { OLECMDF_SUPPORTED,                  exec_save                 }, /* OLECMDID_SAVE */
688     { OLECMDF_SUPPORTED|OLECMDF_ENABLED,  exec_save_as              }, /* OLECMDID_SAVEAS */
689     { OLECMDF_SUPPORTED,                  exec_save_copy_as         }, /* OLECMDID_SAVECOPYAS */
690     { OLECMDF_SUPPORTED|OLECMDF_ENABLED,  exec_print                }, /* OLECMDID_PRINT */
691     { OLECMDF_SUPPORTED|OLECMDF_ENABLED,  exec_print_preview        }, /* OLECMDID_PRINTPREVIEW */
692     { OLECMDF_SUPPORTED|OLECMDF_ENABLED,  exec_page_setup           }, /* OLECMDID_PAGESETUP */
693     { OLECMDF_SUPPORTED,                  exec_spell                }, /* OLECMDID_SPELL */
694     { OLECMDF_SUPPORTED|OLECMDF_ENABLED,  exec_properties           }, /* OLECMDID_PROPERTIES */
695     { OLECMDF_SUPPORTED,                  exec_cut                  }, /* OLECMDID_CUT */
696     { OLECMDF_SUPPORTED,                  exec_copy                 }, /* OLECMDID_COPY */
697     { OLECMDF_SUPPORTED,                  exec_paste                }, /* OLECMDID_PASTE */
698     { OLECMDF_SUPPORTED,                  exec_paste_special        }, /* OLECMDID_PASTESPECIAL */
699     { OLECMDF_SUPPORTED,                  exec_undo                 }, /* OLECMDID_UNDO */
700     { OLECMDF_SUPPORTED,                  exec_rendo                }, /* OLECMDID_REDO */
701     { OLECMDF_SUPPORTED|OLECMDF_ENABLED,  exec_select_all           }, /* OLECMDID_SELECTALL */
702     { OLECMDF_SUPPORTED,                  exec_clear_selection      }, /* OLECMDID_CLEARSELECTION */
703     { OLECMDF_SUPPORTED,                  exec_zoom                 }, /* OLECMDID_ZOOM */
704     { OLECMDF_SUPPORTED,                  exec_get_zoom_range       }, /* OLECMDID_GETZOOMRANGE */
705     {0},
706     { OLECMDF_SUPPORTED|OLECMDF_ENABLED,  exec_refresh              }, /* OLECMDID_REFRESH */
707     { OLECMDF_SUPPORTED|OLECMDF_ENABLED,  exec_stop                 }, /* OLECMDID_STOP */
708     {0},{0},{0},{0},{0},{0},
709     { OLECMDF_SUPPORTED,                  exec_stop_download        }, /* OLECMDID_STOPDOWNLOAD */
710     {0},{0},
711     { OLECMDF_SUPPORTED,                  exec_delete               }, /* OLECMDID_DELETE */
712     {0},{0},
713     { OLECMDF_SUPPORTED,                  exec_enable_interaction   }, /* OLECMDID_ENABLE_INTERACTION */
714     { OLECMDF_SUPPORTED,                  exec_on_unload            }, /* OLECMDID_ONUNLOAD */
715     {0},{0},{0},{0},{0},
716     { OLECMDF_SUPPORTED,                  exec_show_page_setup      }, /* OLECMDID_SHOWPAGESETUP */
717     { OLECMDF_SUPPORTED,                  exec_show_print           }, /* OLECMDID_SHOWPRINT */
718     {0},{0},
719     { OLECMDF_SUPPORTED,                  exec_close                }, /* OLECMDID_CLOSE */
720     {0},{0},{0},
721     { OLECMDF_SUPPORTED,                  exec_set_print_template   }, /* OLECMDID_SETPRINTTEMPLATE */
722     { OLECMDF_SUPPORTED,                  exec_get_print_template   }  /* OLECMDID_GETPRINTTEMPLATE */
723 };
724
725 static HRESULT WINAPI OleCommandTarget_QueryInterface(IOleCommandTarget *iface, REFIID riid, void **ppv)
726 {
727     HTMLDocument *This = CMDTARGET_THIS(iface);
728     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppv);
729 }
730
731 static ULONG WINAPI OleCommandTarget_AddRef(IOleCommandTarget *iface)
732 {
733     HTMLDocument *This = CMDTARGET_THIS(iface);
734     return IHTMLDocument2_AddRef(HTMLDOC(This));
735 }
736
737 static ULONG WINAPI OleCommandTarget_Release(IOleCommandTarget *iface)
738 {
739     HTMLDocument *This = CMDTARGET_THIS(iface);
740     return IHTMLDocument_Release(HTMLDOC(This));
741 }
742
743 static HRESULT WINAPI OleCommandTarget_QueryStatus(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
744         ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
745 {
746     HTMLDocument *This = CMDTARGET_THIS(iface);
747     HRESULT hres = S_OK, hr;
748
749     TRACE("(%p)->(%s %ld %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
750
751     if(!pguidCmdGroup) {
752         ULONG i;
753
754         for(i=0; i<cCmds; i++) {
755             if(prgCmds[i].cmdID<OLECMDID_OPEN || prgCmds[i].cmdID>OLECMDID_GETPRINTTEMPLATE) {
756                 WARN("Unsupported cmdID = %ld\n", prgCmds[i].cmdID);
757                 prgCmds[i].cmdf = 0;
758                 hres = OLECMDERR_E_NOTSUPPORTED;
759             }else {
760                 if(prgCmds[i].cmdID == OLECMDID_OPEN || prgCmds[i].cmdID == OLECMDID_NEW) {
761                     IOleCommandTarget *cmdtrg = NULL;
762                     OLECMD olecmd;
763
764                     prgCmds[i].cmdf = OLECMDF_SUPPORTED;
765                     if(This->client) {
766                         hr = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget,
767                                 (void**)&cmdtrg);
768                         if(SUCCEEDED(hr)) {
769                             olecmd.cmdID = prgCmds[i].cmdID;
770                             olecmd.cmdf = 0;
771
772                             hr = IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &olecmd, NULL);
773                             if(SUCCEEDED(hr) && olecmd.cmdf)
774                                 prgCmds[i].cmdf = olecmd.cmdf;
775                         }
776                     }else {
777                         ERR("This->client == NULL, native would crash\n");
778                     }
779                 }else {
780                     prgCmds[i].cmdf = exec_table[prgCmds[i].cmdID].cmdf;
781                     TRACE("cmdID = %ld  returning %lx\n", prgCmds[i].cmdID, prgCmds[i].cmdf);
782                 }
783                 hres = S_OK;
784             }
785         }
786
787         if(pguidCmdGroup)
788             FIXME("Set pCmdText\n");
789     }else {
790         FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup));
791         hres = OLECMDERR_E_UNKNOWNGROUP;
792     }
793
794     return hres;
795 }
796
797 static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID *pguidCmdGroup,
798         DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
799 {
800     HTMLDocument *This = CMDTARGET_THIS(iface);
801
802     if(!pguidCmdGroup) {
803         if(nCmdID<OLECMDID_OPEN || nCmdID>OLECMDID_GETPRINTTEMPLATE || !exec_table[nCmdID].func) {
804             WARN("Unsupported cmdID = %ld\n", nCmdID);
805             return OLECMDERR_E_NOTSUPPORTED;
806         }
807
808         return exec_table[nCmdID].func(This, nCmdexecopt, pvaIn, pvaOut);
809     }else if(IsEqualGUID(&CGID_ShellDocView, pguidCmdGroup)) {
810         FIXME("unsupported nCmdID %ld of CGID_ShellDocView group\n", nCmdID);
811         return OLECMDERR_E_UNKNOWNGROUP;
812     }
813
814     FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup));
815     return OLECMDERR_E_UNKNOWNGROUP;
816 }
817
818 #undef CMDTARGET_THIS
819
820 static const IOleCommandTargetVtbl OleCommandTargetVtbl = {
821     OleCommandTarget_QueryInterface,
822     OleCommandTarget_AddRef,
823     OleCommandTarget_Release,
824     OleCommandTarget_QueryStatus,
825     OleCommandTarget_Exec
826 };
827
828 /**********************************************************
829  * IOleControl implementation
830  */
831
832 #define CONTROL_THIS(iface) DEFINE_THIS(HTMLDocument, OleControl, iface)
833
834 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
835 {
836     HTMLDocument *This = CONTROL_THIS(iface);
837     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppv);
838 }
839
840 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
841 {
842     HTMLDocument *This = CONTROL_THIS(iface);
843     return IHTMLDocument2_AddRef(HTMLDOC(This));
844 }
845
846 static ULONG WINAPI OleControl_Release(IOleControl *iface)
847 {
848     HTMLDocument *This = CONTROL_THIS(iface);
849     return IHTMLDocument_Release(HTMLDOC(This));
850 }
851
852 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *pCI)
853 {
854     HTMLDocument *This = CONTROL_THIS(iface);
855     FIXME("(%p)->(%p)\n", This, pCI);
856     return E_NOTIMPL;
857 }
858
859 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *pMsg)
860 {
861     HTMLDocument *This = CONTROL_THIS(iface);
862     FIXME("(%p)->(%p)\n", This, pMsg);
863     return E_NOTIMPL;
864 }
865
866 static HRESULT get_property(IOleClientSite *client, DISPID dispid, VARIANT *res)
867 {
868     IDispatch *disp = NULL;
869     DISPPARAMS dispparams = {NULL, 0};
870     UINT err;
871     HRESULT hres;
872
873     hres = IOleClientSite_QueryInterface(client, &IID_IDispatch, (void**)&disp);
874     if(FAILED(hres)) {
875         TRACE("Could not get IDispatch\n");
876         return hres;
877     }
878
879     VariantInit(res);
880
881     hres = IDispatch_Invoke(disp, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
882             DISPATCH_PROPERTYGET, &dispparams, res, NULL, &err);
883
884     IDispatch_Release(disp);
885
886     return hres;
887 }
888
889 static HRESULT on_change_dlcontrol(HTMLDocument *This)
890 {
891     VARIANT res;
892     HRESULT hres;
893     
894     hres = get_property(This->client, DISPID_AMBIENT_DLCONTROL, &res);
895     if(SUCCEEDED(hres))
896         FIXME("unsupported dlcontrol %08lx\n", V_I4(&res));
897
898     return S_OK;
899 }
900
901 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
902 {
903     HTMLDocument *This = CONTROL_THIS(iface);
904     VARIANT res;
905     HRESULT hres;
906
907     if(!This->client) {
908         TRACE("This->client = NULL\n");
909         return S_OK;
910     }
911
912     switch(dispID) {
913     case DISPID_AMBIENT_USERMODE:
914         TRACE("(%p)->(DISPID_AMBIENT_USERMODE)\n", This);
915         hres = get_property(This->client, DISPID_AMBIENT_USERMODE, &res);
916         if(FAILED(hres))
917             return S_OK;
918
919         if(V_VT(&res) == VT_BOOL) {
920             if(!V_BOOL(&res)) {
921                 FIXME("edit mode is not supported\n");
922                 hres = E_FAIL;
923             }
924         }else {
925             FIXME("V_VT(res)=%d\n", V_VT(&res));
926         }
927         return S_OK;
928     case DISPID_AMBIENT_DLCONTROL:
929         TRACE("(%p)->(DISPID_AMBIENT_DLCONTROL)\n", This);
930         return on_change_dlcontrol(This);
931     case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
932         TRACE("(%p)->(DISPID_AMBIENT_OFFLINEIFNOTCONNECTED)\n", This);
933         on_change_dlcontrol(This);
934         hres = get_property(This->client, DISPID_AMBIENT_OFFLINEIFNOTCONNECTED, &res);
935         if(FAILED(hres))
936             return S_OK;
937
938         if(V_VT(&res) == VT_BOOL) {
939             if(V_BOOL(&res)) {
940                 FIXME("offline connection is not supported\n");
941                 hres = E_FAIL;
942             }
943         }else {
944             FIXME("V_VT(res)=%d\n", V_VT(&res));
945         }
946         return S_OK;
947     case DISPID_AMBIENT_SILENT:
948         TRACE("(%p)->(DISPID_AMBIENT_SILENT)\n", This);
949         on_change_dlcontrol(This);
950         hres = get_property(This->client, DISPID_AMBIENT_SILENT, &res);
951         if(FAILED(hres))
952             return S_OK;
953
954         if(V_VT(&res) == VT_BOOL) {
955             if(V_BOOL(&res)) {
956                 FIXME("silent mode is not supported\n");
957                 hres = E_FAIL;
958             }
959         }else {
960             FIXME("V_VT(res)=%d\n", V_VT(&res));
961         }
962         return S_OK;
963     case DISPID_AMBIENT_USERAGENT:
964         TRACE("(%p)->(DISPID_AMBIENT_USERAGENT)\n", This);
965         hres = get_property(This->client, DISPID_AMBIENT_USERAGENT, &res);
966         if(FAILED(hres))
967             return S_OK;
968
969         FIXME("not supported AMBIENT_USERAGENT\n");
970         hres = E_FAIL;
971         return S_OK;
972     case DISPID_AMBIENT_PALETTE:
973         TRACE("(%p)->(DISPID_AMBIENT_PALETTE)\n", This);
974         hres = get_property(This->client, DISPID_AMBIENT_PALETTE, &res);
975         if(FAILED(hres))
976             return S_OK;
977
978         FIXME("not supported AMBIENT_PALETTE\n");
979         hres = E_FAIL;
980         return S_OK;
981     }
982
983     FIXME("(%p) unsupported dispID=%ld\n", This, dispID);
984     return E_FAIL;
985 }
986
987 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
988 {
989     HTMLDocument *This = CONTROL_THIS(iface);
990     FIXME("(%p)->(%x)\n", This, bFreeze);
991     return E_NOTIMPL;
992 }
993
994 #undef CONTROL_THIS
995
996 static const IOleControlVtbl OleControlVtbl = {
997     OleControl_QueryInterface,
998     OleControl_AddRef,
999     OleControl_Release,
1000     OleControl_GetControlInfo,
1001     OleControl_OnMnemonic,
1002     OleControl_OnAmbientPropertyChange,
1003     OleControl_FreezeEvents
1004 };
1005
1006 void HTMLDocument_OleObj_Init(HTMLDocument *This)
1007 {
1008     This->lpOleObjectVtbl = &OleObjectVtbl;
1009     This->lpOleDocumentVtbl = &OleDocumentVtbl;
1010     This->lpOleCommandTargetVtbl = &OleCommandTargetVtbl;
1011     This->lpOleControlVtbl = &OleControlVtbl;
1012
1013     This->client = NULL;
1014     This->hostui = NULL;
1015
1016     This->has_key_path = FALSE;
1017 }