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