winex11: Store the DC bounds rectangle as a pointer.
[wine/multimedia.git] / dlls / mshtml / oleobj.c
blob7db44400a0365952d6233c39d22fbbce83d53bc9
1 /*
2 * Copyright 2005 Jacek Caban
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.
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.
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
19 #include "config.h"
21 #include <stdarg.h>
22 #include <stdio.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
30 #include "shlguid.h"
31 #include "shdeprecated.h"
32 #include "mshtmdid.h"
33 #include "idispids.h"
35 #include "wine/debug.h"
37 #include "mshtml_private.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
41 #define DOCHOST_DOCCANNAVIGATE 0
43 typedef struct {
44 IEnumUnknown IEnumUnknown_iface;
45 LONG ref;
46 } EnumUnknown;
48 static inline EnumUnknown *impl_from_IEnumUnknown(IEnumUnknown *iface)
50 return CONTAINING_RECORD(iface, EnumUnknown, IEnumUnknown_iface);
53 static HRESULT WINAPI EnumUnknown_QueryInterface(IEnumUnknown *iface, REFIID riid, void **ppv)
55 EnumUnknown *This = impl_from_IEnumUnknown(iface);
57 if(IsEqualGUID(&IID_IUnknown, riid)) {
58 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
59 *ppv = &This->IEnumUnknown_iface;
60 }else if(IsEqualGUID(&IID_IEnumUnknown, riid)) {
61 TRACE("(%p)->(IID_IEnumUnknown %p)\n", This, ppv);
62 *ppv = &This->IEnumUnknown_iface;
63 }else {
64 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
65 *ppv = NULL;
66 return E_NOINTERFACE;
69 IUnknown_AddRef((IUnknown*)*ppv);
70 return S_OK;
73 static ULONG WINAPI EnumUnknown_AddRef(IEnumUnknown *iface)
75 EnumUnknown *This = impl_from_IEnumUnknown(iface);
76 LONG ref = InterlockedIncrement(&This->ref);
78 TRACE("(%p) ref=%d\n", This, ref);
80 return ref;
83 static ULONG WINAPI EnumUnknown_Release(IEnumUnknown *iface)
85 EnumUnknown *This = impl_from_IEnumUnknown(iface);
86 LONG ref = InterlockedDecrement(&This->ref);
88 TRACE("(%p) ref=%d\n", This, ref);
90 if(!ref)
91 heap_free(This);
93 return ref;
96 static HRESULT WINAPI EnumUnknown_Next(IEnumUnknown *iface, ULONG celt, IUnknown **rgelt, ULONG *pceltFetched)
98 EnumUnknown *This = impl_from_IEnumUnknown(iface);
100 TRACE("(%p)->(%u %p %p)\n", This, celt, rgelt, pceltFetched);
102 /* FIXME: It's not clear if we should ever return something here */
103 if(pceltFetched)
104 *pceltFetched = 0;
105 return S_FALSE;
108 static HRESULT WINAPI EnumUnknown_Skip(IEnumUnknown *iface, ULONG celt)
110 EnumUnknown *This = impl_from_IEnumUnknown(iface);
111 FIXME("(%p)->(%u)\n", This, celt);
112 return E_NOTIMPL;
115 static HRESULT WINAPI EnumUnknown_Reset(IEnumUnknown *iface)
117 EnumUnknown *This = impl_from_IEnumUnknown(iface);
118 FIXME("(%p)\n", This);
119 return E_NOTIMPL;
122 static HRESULT WINAPI EnumUnknown_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
124 EnumUnknown *This = impl_from_IEnumUnknown(iface);
125 FIXME("(%p)->(%p)\n", This, ppenum);
126 return E_NOTIMPL;
129 static const IEnumUnknownVtbl EnumUnknownVtbl = {
130 EnumUnknown_QueryInterface,
131 EnumUnknown_AddRef,
132 EnumUnknown_Release,
133 EnumUnknown_Next,
134 EnumUnknown_Skip,
135 EnumUnknown_Reset,
136 EnumUnknown_Clone
139 /**********************************************************
140 * IOleObject implementation
143 static inline HTMLDocument *impl_from_IOleObject(IOleObject *iface)
145 return CONTAINING_RECORD(iface, HTMLDocument, IOleObject_iface);
148 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
150 HTMLDocument *This = impl_from_IOleObject(iface);
151 return htmldoc_query_interface(This, riid, ppv);
154 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
156 HTMLDocument *This = impl_from_IOleObject(iface);
157 return htmldoc_addref(This);
160 static ULONG WINAPI OleObject_Release(IOleObject *iface)
162 HTMLDocument *This = impl_from_IOleObject(iface);
163 return htmldoc_release(This);
166 static void update_hostinfo(HTMLDocumentObj *This, DOCHOSTUIINFO *hostinfo)
168 nsIScrollable *scrollable;
169 nsresult nsres;
171 if(!This->nscontainer)
172 return;
174 nsres = nsIWebBrowser_QueryInterface(This->nscontainer->webbrowser, &IID_nsIScrollable, (void**)&scrollable);
175 if(NS_SUCCEEDED(nsres)) {
176 nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, ScrollOrientation_Y,
177 (hostinfo->dwFlags & DOCHOSTUIFLAG_SCROLL_NO) ? Scrollbar_Never : Scrollbar_Always);
178 if(NS_FAILED(nsres))
179 ERR("Could not set default Y scrollbar prefs: %08x\n", nsres);
181 nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, ScrollOrientation_X,
182 hostinfo->dwFlags & DOCHOSTUIFLAG_SCROLL_NO ? Scrollbar_Never : Scrollbar_Auto);
183 if(NS_FAILED(nsres))
184 ERR("Could not set default X scrollbar prefs: %08x\n", nsres);
186 nsIScrollable_Release(scrollable);
187 }else {
188 ERR("Could not get nsIScrollable: %08x\n", nsres);
192 static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *pClientSite)
194 HTMLDocument *This = impl_from_IOleObject(iface);
195 IOleCommandTarget *cmdtrg = NULL;
196 IOleWindow *ole_window;
197 BOOL hostui_setup;
198 VARIANT silent;
199 HWND hwnd;
200 HRESULT hres;
202 TRACE("(%p)->(%p)\n", This, pClientSite);
204 if(pClientSite == This->doc_obj->client)
205 return S_OK;
207 if(This->doc_obj->client) {
208 IOleClientSite_Release(This->doc_obj->client);
209 This->doc_obj->client = NULL;
210 This->doc_obj->usermode = UNKNOWN_USERMODE;
213 if(This->doc_obj->hostui && !This->doc_obj->custom_hostui) {
214 IDocHostUIHandler_Release(This->doc_obj->hostui);
215 This->doc_obj->hostui = NULL;
218 if(This->doc_obj->doc_object_service) {
219 IDocObjectService_Release(This->doc_obj->doc_object_service);
220 This->doc_obj->doc_object_service = NULL;
223 memset(&This->doc_obj->hostinfo, 0, sizeof(DOCHOSTUIINFO));
224 This->doc_obj->is_webbrowser = FALSE;
226 if(!pClientSite)
227 return S_OK;
229 IOleClientSite_AddRef(pClientSite);
230 This->doc_obj->client = pClientSite;
232 hostui_setup = This->doc_obj->hostui_setup;
234 if(!This->doc_obj->hostui) {
235 IDocHostUIHandler *uihandler;
237 This->doc_obj->custom_hostui = FALSE;
239 hres = IOleObject_QueryInterface(pClientSite, &IID_IDocHostUIHandler, (void**)&uihandler);
240 if(SUCCEEDED(hres))
241 This->doc_obj->hostui = uihandler;
244 if(This->doc_obj->hostui) {
245 DOCHOSTUIINFO hostinfo;
246 LPOLESTR key_path = NULL, override_key_path = NULL;
247 IDocHostUIHandler2 *uihandler2;
249 memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO));
250 hostinfo.cbSize = sizeof(DOCHOSTUIINFO);
251 hres = IDocHostUIHandler_GetHostInfo(This->doc_obj->hostui, &hostinfo);
252 if(SUCCEEDED(hres)) {
253 TRACE("hostinfo = {%u %08x %08x %s %s}\n",
254 hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick,
255 debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS));
256 update_hostinfo(This->doc_obj, &hostinfo);
257 This->doc_obj->hostinfo = hostinfo;
260 if(!hostui_setup) {
261 hres = IDocHostUIHandler_GetOptionKeyPath(This->doc_obj->hostui, &key_path, 0);
262 if(hres == S_OK && key_path) {
263 if(key_path[0]) {
264 /* FIXME: use key_path */
265 TRACE("key_path = %s\n", debugstr_w(key_path));
267 CoTaskMemFree(key_path);
270 hres = IDocHostUIHandler_QueryInterface(This->doc_obj->hostui, &IID_IDocHostUIHandler2,
271 (void**)&uihandler2);
272 if(SUCCEEDED(hres)) {
273 hres = IDocHostUIHandler2_GetOverrideKeyPath(uihandler2, &override_key_path, 0);
274 if(hres == S_OK && override_key_path && override_key_path[0]) {
275 if(override_key_path[0]) {
276 /*FIXME: use override_key_path */
277 TRACE("override_key_path = %s\n", debugstr_w(override_key_path));
279 CoTaskMemFree(override_key_path);
281 IDocHostUIHandler2_Release(uihandler2);
284 This->doc_obj->hostui_setup = TRUE;
288 /* Native calls here GetWindow. What is it for?
289 * We don't have anything to do with it here (yet). */
290 hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleWindow, (void**)&ole_window);
291 if(SUCCEEDED(hres)) {
292 IOleWindow_GetWindow(ole_window, &hwnd);
293 IOleWindow_Release(ole_window);
296 hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleCommandTarget, (void**)&cmdtrg);
297 if(SUCCEEDED(hres)) {
298 VARIANT var;
299 OLECMD cmd = {OLECMDID_SETPROGRESSTEXT, 0};
301 if(!hostui_setup) {
302 IDocObjectService *doc_object_service;
303 IBrowserService *browser_service;
304 IWebBrowser2 *wb;
306 V_VT(&var) = VT_UNKNOWN;
307 V_UNKNOWN(&var) = (IUnknown*)&This->window->IHTMLWindow2_iface;
308 IOleCommandTarget_Exec(cmdtrg, &CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, &var, NULL);
310 hres = do_query_service((IUnknown*)pClientSite, &IID_IShellBrowser,
311 &IID_IBrowserService, (void**)&browser_service);
312 if(SUCCEEDED(hres)) {
313 hres = IBrowserService_QueryInterface(browser_service,
314 &IID_IDocObjectService, (void**)&doc_object_service);
315 if(SUCCEEDED(hres)) {
316 This->doc_obj->doc_object_service = doc_object_service;
319 * Some embedding routines, esp. in regards to use of IDocObjectService, differ if
320 * embedder supports IWebBrowserApp.
322 hres = do_query_service((IUnknown*)pClientSite, &IID_IWebBrowserApp, &IID_IWebBrowser2, (void**)&wb);
323 if(SUCCEEDED(hres)) {
324 This->doc_obj->is_webbrowser = TRUE;
325 IWebBrowser2_Release(wb);
328 IBrowserService_Release(browser_service);
333 IOleCommandTarget_QueryStatus(cmdtrg, NULL, 1, &cmd, NULL);
335 V_VT(&var) = VT_I4;
336 V_I4(&var) = 0;
337 IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSMAX,
338 OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
339 IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_SETPROGRESSPOS,
340 OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
342 IOleCommandTarget_Release(cmdtrg);
345 if(This->doc_obj->usermode == UNKNOWN_USERMODE)
346 IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_USERMODE);
348 IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface,
349 DISPID_AMBIENT_OFFLINEIFNOTCONNECTED);
351 hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_SILENT, &silent);
352 if(SUCCEEDED(hres)) {
353 if(V_VT(&silent) != VT_BOOL)
354 WARN("silent = %s\n", debugstr_variant(&silent));
355 else if(V_BOOL(&silent))
356 FIXME("silent == true\n");
359 IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_USERAGENT);
360 IOleControl_OnAmbientPropertyChange(&This->IOleControl_iface, DISPID_AMBIENT_PALETTE);
362 return S_OK;
365 static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **ppClientSite)
367 HTMLDocument *This = impl_from_IOleObject(iface);
369 TRACE("(%p)->(%p)\n", This, ppClientSite);
371 if(!ppClientSite)
372 return E_INVALIDARG;
374 if(This->doc_obj->client)
375 IOleClientSite_AddRef(This->doc_obj->client);
376 *ppClientSite = This->doc_obj->client;
378 return S_OK;
381 static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
383 HTMLDocument *This = impl_from_IOleObject(iface);
384 FIXME("(%p)->(%s %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));
385 return E_NOTIMPL;
388 static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
390 HTMLDocument *This = impl_from_IOleObject(iface);
392 TRACE("(%p)->(%08x)\n", This, dwSaveOption);
394 if(dwSaveOption == OLECLOSE_PROMPTSAVE)
395 FIXME("OLECLOSE_PROMPTSAVE not implemented\n");
397 if(This->doc_obj->in_place_active)
398 IOleInPlaceObjectWindowless_InPlaceDeactivate(&This->IOleInPlaceObjectWindowless_iface);
400 HTMLDocument_LockContainer(This->doc_obj, FALSE);
402 if(This->advise_holder)
403 IOleAdviseHolder_SendOnClose(This->advise_holder);
405 return S_OK;
408 static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker *pmk)
410 HTMLDocument *This = impl_from_IOleObject(iface);
411 FIXME("(%p %d %p)->()\n", This, dwWhichMoniker, pmk);
412 return E_NOTIMPL;
415 static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
417 HTMLDocument *This = impl_from_IOleObject(iface);
418 FIXME("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
419 return E_NOTIMPL;
422 static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *pDataObject, BOOL fCreation,
423 DWORD dwReserved)
425 HTMLDocument *This = impl_from_IOleObject(iface);
426 FIXME("(%p)->(%p %x %d)\n", This, pDataObject, fCreation, dwReserved);
427 return E_NOTIMPL;
430 static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved, IDataObject **ppDataObject)
432 HTMLDocument *This = impl_from_IOleObject(iface);
433 FIXME("(%p)->(%d %p)\n", This, dwReserved, ppDataObject);
434 return E_NOTIMPL;
437 static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
438 LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
440 HTMLDocument *This = impl_from_IOleObject(iface);
441 IOleDocumentSite *pDocSite;
442 HRESULT hres;
444 TRACE("(%p)->(%d %p %p %d %p %p)\n", This, iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect);
446 if(iVerb != OLEIVERB_SHOW && iVerb != OLEIVERB_UIACTIVATE && iVerb != OLEIVERB_INPLACEACTIVATE) {
447 FIXME("iVerb = %d not supported\n", iVerb);
448 return E_NOTIMPL;
451 if(!pActiveSite)
452 pActiveSite = This->doc_obj->client;
454 hres = IOleClientSite_QueryInterface(pActiveSite, &IID_IOleDocumentSite, (void**)&pDocSite);
455 if(SUCCEEDED(hres)) {
456 HTMLDocument_LockContainer(This->doc_obj, TRUE);
458 /* FIXME: Create new IOleDocumentView. See CreateView for more info. */
459 hres = IOleDocumentSite_ActivateMe(pDocSite, &This->IOleDocumentView_iface);
460 IOleDocumentSite_Release(pDocSite);
461 }else {
462 hres = IOleDocumentView_UIActivate(&This->IOleDocumentView_iface, TRUE);
463 if(SUCCEEDED(hres)) {
464 if(lprcPosRect) {
465 RECT rect; /* We need to pass rect as not const pointer */
466 rect = *lprcPosRect;
467 IOleDocumentView_SetRect(&This->IOleDocumentView_iface, &rect);
469 IOleDocumentView_Show(&This->IOleDocumentView_iface, TRUE);
473 return hres;
476 static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
478 HTMLDocument *This = impl_from_IOleObject(iface);
479 FIXME("(%p)->(%p)\n", This, ppEnumOleVerb);
480 return E_NOTIMPL;
483 static HRESULT WINAPI OleObject_Update(IOleObject *iface)
485 HTMLDocument *This = impl_from_IOleObject(iface);
486 FIXME("(%p)\n", This);
487 return E_NOTIMPL;
490 static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
492 HTMLDocument *This = impl_from_IOleObject(iface);
493 FIXME("(%p)\n", This);
494 return E_NOTIMPL;
497 static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *pClsid)
499 HTMLDocument *This = impl_from_IOleObject(iface);
501 TRACE("(%p)->(%p)\n", This, pClsid);
503 if(!pClsid)
504 return E_INVALIDARG;
506 *pClsid = CLSID_HTMLDocument;
507 return S_OK;
510 static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType, LPOLESTR *pszUserType)
512 HTMLDocument *This = impl_from_IOleObject(iface);
513 FIXME("(%p)->(%d %p)\n", This, dwFormOfType, pszUserType);
514 return E_NOTIMPL;
517 static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
519 HTMLDocument *This = impl_from_IOleObject(iface);
520 FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
521 return E_NOTIMPL;
524 static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
526 HTMLDocument *This = impl_from_IOleObject(iface);
527 FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
528 return E_NOTIMPL;
531 static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection)
533 HTMLDocument *This = impl_from_IOleObject(iface);
534 TRACE("(%p)->(%p %p)\n", This, pAdvSink, pdwConnection);
536 if(!pdwConnection)
537 return E_INVALIDARG;
539 if(!pAdvSink) {
540 *pdwConnection = 0;
541 return E_INVALIDARG;
544 if(!This->advise_holder) {
545 CreateOleAdviseHolder(&This->advise_holder);
546 if(!This->advise_holder)
547 return E_OUTOFMEMORY;
550 return IOleAdviseHolder_Advise(This->advise_holder, pAdvSink, pdwConnection);
553 static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
555 HTMLDocument *This = impl_from_IOleObject(iface);
556 TRACE("(%p)->(%d)\n", This, dwConnection);
558 if(!This->advise_holder)
559 return OLE_E_NOCONNECTION;
561 return IOleAdviseHolder_Unadvise(This->advise_holder, dwConnection);
564 static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
566 HTMLDocument *This = impl_from_IOleObject(iface);
568 if(!This->advise_holder) {
569 *ppenumAdvise = NULL;
570 return S_OK;
573 return IOleAdviseHolder_EnumAdvise(This->advise_holder, ppenumAdvise);
576 static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
578 HTMLDocument *This = impl_from_IOleObject(iface);
579 FIXME("(%p)->(%d %p)\n", This, dwAspect, pdwStatus);
580 return E_NOTIMPL;
583 static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *pLogpal)
585 HTMLDocument *This = impl_from_IOleObject(iface);
586 FIXME("(%p)->(%p)\n", This, pLogpal);
587 return E_NOTIMPL;
590 static const IOleObjectVtbl OleObjectVtbl = {
591 OleObject_QueryInterface,
592 OleObject_AddRef,
593 OleObject_Release,
594 OleObject_SetClientSite,
595 OleObject_GetClientSite,
596 OleObject_SetHostNames,
597 OleObject_Close,
598 OleObject_SetMoniker,
599 OleObject_GetMoniker,
600 OleObject_InitFromData,
601 OleObject_GetClipboardData,
602 OleObject_DoVerb,
603 OleObject_EnumVerbs,
604 OleObject_Update,
605 OleObject_IsUpToDate,
606 OleObject_GetUserClassID,
607 OleObject_GetUserType,
608 OleObject_SetExtent,
609 OleObject_GetExtent,
610 OleObject_Advise,
611 OleObject_Unadvise,
612 OleObject_EnumAdvise,
613 OleObject_GetMiscStatus,
614 OleObject_SetColorScheme
617 /**********************************************************
618 * IOleDocument implementation
621 static inline HTMLDocument *impl_from_IOleDocument(IOleDocument *iface)
623 return CONTAINING_RECORD(iface, HTMLDocument, IOleDocument_iface);
626 static HRESULT WINAPI OleDocument_QueryInterface(IOleDocument *iface, REFIID riid, void **ppv)
628 HTMLDocument *This = impl_from_IOleDocument(iface);
629 return htmldoc_query_interface(This, riid, ppv);
632 static ULONG WINAPI OleDocument_AddRef(IOleDocument *iface)
634 HTMLDocument *This = impl_from_IOleDocument(iface);
635 return htmldoc_addref(This);
638 static ULONG WINAPI OleDocument_Release(IOleDocument *iface)
640 HTMLDocument *This = impl_from_IOleDocument(iface);
641 return htmldoc_release(This);
644 static HRESULT WINAPI OleDocument_CreateView(IOleDocument *iface, IOleInPlaceSite *pIPSite, IStream *pstm,
645 DWORD dwReserved, IOleDocumentView **ppView)
647 HTMLDocument *This = impl_from_IOleDocument(iface);
648 HRESULT hres;
650 TRACE("(%p)->(%p %p %d %p)\n", This, pIPSite, pstm, dwReserved, ppView);
652 if(!ppView)
653 return E_INVALIDARG;
655 /* FIXME:
656 * Windows implementation creates new IOleDocumentView when function is called for the
657 * first time and returns E_FAIL when it is called for the second time, but it doesn't matter
658 * if the application uses returned interfaces, passed to ActivateMe or returned by
659 * QueryInterface, so there is no reason to create new interface. This needs more testing.
662 if(pIPSite) {
663 hres = IOleDocumentView_SetInPlaceSite(&This->IOleDocumentView_iface, pIPSite);
664 if(FAILED(hres))
665 return hres;
668 if(pstm)
669 FIXME("pstm is not supported\n");
671 IOleDocumentView_AddRef(&This->IOleDocumentView_iface);
672 *ppView = &This->IOleDocumentView_iface;
673 return S_OK;
676 static HRESULT WINAPI OleDocument_GetDocMiscStatus(IOleDocument *iface, DWORD *pdwStatus)
678 HTMLDocument *This = impl_from_IOleDocument(iface);
679 FIXME("(%p)->(%p)\n", This, pdwStatus);
680 return E_NOTIMPL;
683 static HRESULT WINAPI OleDocument_EnumViews(IOleDocument *iface, IEnumOleDocumentViews **ppEnum,
684 IOleDocumentView **ppView)
686 HTMLDocument *This = impl_from_IOleDocument(iface);
687 FIXME("(%p)->(%p %p)\n", This, ppEnum, ppView);
688 return E_NOTIMPL;
691 static const IOleDocumentVtbl OleDocumentVtbl = {
692 OleDocument_QueryInterface,
693 OleDocument_AddRef,
694 OleDocument_Release,
695 OleDocument_CreateView,
696 OleDocument_GetDocMiscStatus,
697 OleDocument_EnumViews
700 /**********************************************************
701 * IOleControl implementation
704 static inline HTMLDocument *impl_from_IOleControl(IOleControl *iface)
706 return CONTAINING_RECORD(iface, HTMLDocument, IOleControl_iface);
709 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
711 HTMLDocument *This = impl_from_IOleControl(iface);
712 return htmldoc_query_interface(This, riid, ppv);
715 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
717 HTMLDocument *This = impl_from_IOleControl(iface);
718 return htmldoc_addref(This);
721 static ULONG WINAPI OleControl_Release(IOleControl *iface)
723 HTMLDocument *This = impl_from_IOleControl(iface);
724 return htmldoc_release(This);
727 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *pCI)
729 HTMLDocument *This = impl_from_IOleControl(iface);
730 FIXME("(%p)->(%p)\n", This, pCI);
731 return E_NOTIMPL;
734 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *pMsg)
736 HTMLDocument *This = impl_from_IOleControl(iface);
737 FIXME("(%p)->(%p)\n", This, pMsg);
738 return E_NOTIMPL;
741 HRESULT get_client_disp_property(IOleClientSite *client, DISPID dispid, VARIANT *res)
743 IDispatch *disp = NULL;
744 DISPPARAMS dispparams = {NULL, 0};
745 UINT err;
746 HRESULT hres;
748 hres = IOleClientSite_QueryInterface(client, &IID_IDispatch, (void**)&disp);
749 if(FAILED(hres)) {
750 TRACE("Could not get IDispatch\n");
751 return hres;
754 VariantInit(res);
756 hres = IDispatch_Invoke(disp, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
757 DISPATCH_PROPERTYGET, &dispparams, res, NULL, &err);
759 IDispatch_Release(disp);
761 return hres;
764 static HRESULT on_change_dlcontrol(HTMLDocument *This)
766 VARIANT res;
767 HRESULT hres;
769 hres = get_client_disp_property(This->doc_obj->client, DISPID_AMBIENT_DLCONTROL, &res);
770 if(SUCCEEDED(hres))
771 FIXME("unsupported dlcontrol %08x\n", V_I4(&res));
773 return S_OK;
776 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
778 HTMLDocument *This = impl_from_IOleControl(iface);
779 IOleClientSite *client;
780 VARIANT res;
781 HRESULT hres;
783 client = This->doc_obj->client;
784 if(!client) {
785 TRACE("client = NULL\n");
786 return S_OK;
789 switch(dispID) {
790 case DISPID_AMBIENT_USERMODE:
791 TRACE("(%p)->(DISPID_AMBIENT_USERMODE)\n", This);
792 hres = get_client_disp_property(client, DISPID_AMBIENT_USERMODE, &res);
793 if(FAILED(hres))
794 return S_OK;
796 if(V_VT(&res) == VT_BOOL) {
797 if(V_BOOL(&res)) {
798 This->doc_obj->usermode = BROWSEMODE;
799 }else {
800 FIXME("edit mode is not supported\n");
801 This->doc_obj->usermode = EDITMODE;
803 }else {
804 FIXME("usermode=%s\n", debugstr_variant(&res));
806 return S_OK;
807 case DISPID_AMBIENT_DLCONTROL:
808 TRACE("(%p)->(DISPID_AMBIENT_DLCONTROL)\n", This);
809 return on_change_dlcontrol(This);
810 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
811 TRACE("(%p)->(DISPID_AMBIENT_OFFLINEIFNOTCONNECTED)\n", This);
812 on_change_dlcontrol(This);
813 hres = get_client_disp_property(client, DISPID_AMBIENT_OFFLINEIFNOTCONNECTED, &res);
814 if(FAILED(hres))
815 return S_OK;
817 if(V_VT(&res) == VT_BOOL) {
818 if(V_BOOL(&res)) {
819 FIXME("offline connection is not supported\n");
820 hres = E_FAIL;
822 }else {
823 FIXME("offlineconnected=%s\n", debugstr_variant(&res));
825 return S_OK;
826 case DISPID_AMBIENT_SILENT:
827 TRACE("(%p)->(DISPID_AMBIENT_SILENT)\n", This);
828 on_change_dlcontrol(This);
829 hres = get_client_disp_property(client, DISPID_AMBIENT_SILENT, &res);
830 if(FAILED(hres))
831 return S_OK;
833 if(V_VT(&res) == VT_BOOL) {
834 if(V_BOOL(&res)) {
835 FIXME("silent mode is not supported\n");
836 hres = E_FAIL;
838 }else {
839 FIXME("silent=%s\n", debugstr_variant(&res));
841 return S_OK;
842 case DISPID_AMBIENT_USERAGENT:
843 TRACE("(%p)->(DISPID_AMBIENT_USERAGENT)\n", This);
844 hres = get_client_disp_property(client, DISPID_AMBIENT_USERAGENT, &res);
845 if(FAILED(hres))
846 return S_OK;
848 FIXME("not supported AMBIENT_USERAGENT\n");
849 hres = E_FAIL;
850 return S_OK;
851 case DISPID_AMBIENT_PALETTE:
852 TRACE("(%p)->(DISPID_AMBIENT_PALETTE)\n", This);
853 hres = get_client_disp_property(client, DISPID_AMBIENT_PALETTE, &res);
854 if(FAILED(hres))
855 return S_OK;
857 FIXME("not supported AMBIENT_PALETTE\n");
858 hres = E_FAIL;
859 return S_OK;
862 FIXME("(%p) unsupported dispID=%d\n", This, dispID);
863 return E_FAIL;
866 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL bFreeze)
868 HTMLDocument *This = impl_from_IOleControl(iface);
869 FIXME("(%p)->(%x)\n", This, bFreeze);
870 return E_NOTIMPL;
873 static const IOleControlVtbl OleControlVtbl = {
874 OleControl_QueryInterface,
875 OleControl_AddRef,
876 OleControl_Release,
877 OleControl_GetControlInfo,
878 OleControl_OnMnemonic,
879 OleControl_OnAmbientPropertyChange,
880 OleControl_FreezeEvents
883 /**********************************************************
884 * IObjectWithSite implementation
887 static inline HTMLDocument *impl_from_IObjectWithSite(IObjectWithSite *iface)
889 return CONTAINING_RECORD(iface, HTMLDocument, IObjectWithSite_iface);
892 static HRESULT WINAPI ObjectWithSite_QueryInterface(IObjectWithSite *iface, REFIID riid, void **ppv)
894 HTMLDocument *This = impl_from_IObjectWithSite(iface);
895 return htmldoc_query_interface(This, riid, ppv);
898 static ULONG WINAPI ObjectWithSite_AddRef(IObjectWithSite *iface)
900 HTMLDocument *This = impl_from_IObjectWithSite(iface);
901 return htmldoc_addref(This);
904 static ULONG WINAPI ObjectWithSite_Release(IObjectWithSite *iface)
906 HTMLDocument *This = impl_from_IObjectWithSite(iface);
907 return htmldoc_release(This);
910 static HRESULT WINAPI ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *pUnkSite)
912 HTMLDocument *This = impl_from_IObjectWithSite(iface);
913 FIXME("(%p)->(%p)\n", This, pUnkSite);
914 return E_NOTIMPL;
917 static HRESULT WINAPI ObjectWithSite_GetSite(IObjectWithSite* iface, REFIID riid, PVOID *ppvSite)
919 HTMLDocument *This = impl_from_IObjectWithSite(iface);
920 FIXME("(%p)->(%p)\n", This, ppvSite);
921 return E_NOTIMPL;
924 static const IObjectWithSiteVtbl ObjectWithSiteVtbl = {
925 ObjectWithSite_QueryInterface,
926 ObjectWithSite_AddRef,
927 ObjectWithSite_Release,
928 ObjectWithSite_SetSite,
929 ObjectWithSite_GetSite
932 /**********************************************************
933 * IOleContainer implementation
936 static inline HTMLDocument *impl_from_IOleContainer(IOleContainer *iface)
938 return CONTAINING_RECORD(iface, HTMLDocument, IOleContainer_iface);
941 static HRESULT WINAPI OleContainer_QueryInterface(IOleContainer *iface, REFIID riid, void **ppv)
943 HTMLDocument *This = impl_from_IOleContainer(iface);
944 return htmldoc_query_interface(This, riid, ppv);
947 static ULONG WINAPI OleContainer_AddRef(IOleContainer *iface)
949 HTMLDocument *This = impl_from_IOleContainer(iface);
950 return htmldoc_addref(This);
953 static ULONG WINAPI OleContainer_Release(IOleContainer *iface)
955 HTMLDocument *This = impl_from_IOleContainer(iface);
956 return htmldoc_release(This);
959 static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer *iface, IBindCtx *pbc, LPOLESTR pszDisplayName,
960 ULONG *pchEaten, IMoniker **ppmkOut)
962 HTMLDocument *This = impl_from_IOleContainer(iface);
963 FIXME("(%p)->(%p %s %p %p)\n", This, pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
964 return E_NOTIMPL;
967 static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer *iface, DWORD grfFlags, IEnumUnknown **ppenum)
969 HTMLDocument *This = impl_from_IOleContainer(iface);
970 EnumUnknown *ret;
972 TRACE("(%p)->(%x %p)\n", This, grfFlags, ppenum);
974 ret = heap_alloc(sizeof(*ret));
975 if(!ret)
976 return E_OUTOFMEMORY;
978 ret->IEnumUnknown_iface.lpVtbl = &EnumUnknownVtbl;
979 ret->ref = 1;
981 *ppenum = &ret->IEnumUnknown_iface;
982 return S_OK;
985 static HRESULT WINAPI OleContainer_LockContainer(IOleContainer *iface, BOOL fLock)
987 HTMLDocument *This = impl_from_IOleContainer(iface);
988 FIXME("(%p)->(%x)\n", This, fLock);
989 return E_NOTIMPL;
992 static const IOleContainerVtbl OleContainerVtbl = {
993 OleContainer_QueryInterface,
994 OleContainer_AddRef,
995 OleContainer_Release,
996 OleContainer_ParseDisplayName,
997 OleContainer_EnumObjects,
998 OleContainer_LockContainer
1001 static inline HTMLDocumentObj *impl_from_ITargetContainer(ITargetContainer *iface)
1003 return CONTAINING_RECORD(iface, HTMLDocumentObj, ITargetContainer_iface);
1006 static HRESULT WINAPI TargetContainer_QueryInterface(ITargetContainer *iface, REFIID riid, void **ppv)
1008 HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1009 return ICustomDoc_QueryInterface(&This->ICustomDoc_iface, riid, ppv);
1012 static ULONG WINAPI TargetContainer_AddRef(ITargetContainer *iface)
1014 HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1015 return ICustomDoc_AddRef(&This->ICustomDoc_iface);
1018 static ULONG WINAPI TargetContainer_Release(ITargetContainer *iface)
1020 HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1021 return ICustomDoc_Release(&This->ICustomDoc_iface);
1024 static HRESULT WINAPI TargetContainer_GetFrameUrl(ITargetContainer *iface, LPWSTR *ppszFrameSrc)
1026 HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1027 FIXME("(%p)->(%p)\n", This, ppszFrameSrc);
1028 return E_NOTIMPL;
1031 static HRESULT WINAPI TargetContainer_GetFramesContainer(ITargetContainer *iface, IOleContainer **ppContainer)
1033 HTMLDocumentObj *This = impl_from_ITargetContainer(iface);
1035 TRACE("(%p)->(%p)\n", This, ppContainer);
1037 /* NOTE: we should return wrapped interface here */
1038 IOleContainer_AddRef(&This->basedoc.IOleContainer_iface);
1039 *ppContainer = &This->basedoc.IOleContainer_iface;
1040 return S_OK;
1043 static const ITargetContainerVtbl TargetContainerVtbl = {
1044 TargetContainer_QueryInterface,
1045 TargetContainer_AddRef,
1046 TargetContainer_Release,
1047 TargetContainer_GetFrameUrl,
1048 TargetContainer_GetFramesContainer
1051 void TargetContainer_Init(HTMLDocumentObj *This)
1053 This->ITargetContainer_iface.lpVtbl = &TargetContainerVtbl;
1056 /**********************************************************
1057 * IObjectSafety implementation
1060 static inline HTMLDocument *impl_from_IObjectSafety(IObjectSafety *iface)
1062 return CONTAINING_RECORD(iface, HTMLDocument, IObjectSafety_iface);
1065 static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
1067 HTMLDocument *This = impl_from_IObjectSafety(iface);
1068 return htmldoc_query_interface(This, riid, ppv);
1071 static ULONG WINAPI ObjectSafety_AddRef(IObjectSafety *iface)
1073 HTMLDocument *This = impl_from_IObjectSafety(iface);
1074 return htmldoc_addref(This);
1077 static ULONG WINAPI ObjectSafety_Release(IObjectSafety *iface)
1079 HTMLDocument *This = impl_from_IObjectSafety(iface);
1080 return htmldoc_release(This);
1083 static HRESULT WINAPI ObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface,
1084 REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
1086 HTMLDocument *This = impl_from_IObjectSafety(iface);
1087 FIXME("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
1088 return E_NOTIMPL;
1091 static HRESULT WINAPI ObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface,
1092 REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
1094 HTMLDocument *This = impl_from_IObjectSafety(iface);
1095 FIXME("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
1097 if(IsEqualGUID(&IID_IPersistMoniker, riid) &&
1098 dwOptionSetMask==INTERFACESAFE_FOR_UNTRUSTED_DATA &&
1099 dwEnabledOptions==INTERFACESAFE_FOR_UNTRUSTED_DATA)
1100 return S_OK;
1102 return E_NOTIMPL;
1105 static const IObjectSafetyVtbl ObjectSafetyVtbl = {
1106 ObjectSafety_QueryInterface,
1107 ObjectSafety_AddRef,
1108 ObjectSafety_Release,
1109 ObjectSafety_GetInterfaceSafetyOptions,
1110 ObjectSafety_SetInterfaceSafetyOptions
1113 void HTMLDocument_LockContainer(HTMLDocumentObj *This, BOOL fLock)
1115 IOleContainer *container;
1116 HRESULT hres;
1118 if(!This->client || This->container_locked == fLock)
1119 return;
1121 hres = IOleClientSite_GetContainer(This->client, &container);
1122 if(SUCCEEDED(hres)) {
1123 IOleContainer_LockContainer(container, fLock);
1124 This->container_locked = fLock;
1125 IOleContainer_Release(container);
1129 void HTMLDocument_OleObj_Init(HTMLDocument *This)
1131 This->IOleObject_iface.lpVtbl = &OleObjectVtbl;
1132 This->IOleDocument_iface.lpVtbl = &OleDocumentVtbl;
1133 This->IOleControl_iface.lpVtbl = &OleControlVtbl;
1134 This->IObjectWithSite_iface.lpVtbl = &ObjectWithSiteVtbl;
1135 This->IOleContainer_iface.lpVtbl = &OleContainerVtbl;
1136 This->IObjectSafety_iface.lpVtbl = &ObjectSafetyVtbl;