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
33 #define NO_SHLWAPI_REG
36 #include "wine/debug.h"
38 #include "mshtml_private.h"
39 #include "htmlscript.h"
40 #include "htmlevent.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
46 /* Undocumented notification, see tests */
47 #define CMDID_EXPLORER_UPDATEHISTORY 38
54 } download_proc_task_t
;
56 static void notify_travellog_update(HTMLDocumentObj
*doc
)
58 IOleCommandTarget
*cmdtrg
;
64 hres
= IOleClientSite_QueryInterface(doc
->client
, &IID_IOleCommandTarget
, (void**)&cmdtrg
);
71 IOleCommandTarget_Exec(cmdtrg
, &CGID_Explorer
, CMDID_EXPLORER_UPDATEHISTORY
, 0, &vin
, NULL
);
72 IOleCommandTarget_Release(cmdtrg
);
76 void set_current_uri(HTMLOuterWindow
*window
, IUri
*uri
)
79 IUri_Release(window
->uri
);
83 if(window
->uri_nofrag
) {
84 IUri_Release(window
->uri_nofrag
);
85 window
->uri_nofrag
= NULL
;
88 SysFreeString(window
->url
);
97 window
->uri_nofrag
= get_uri_nofrag(uri
);
98 if(!window
->uri_nofrag
) {
99 FIXME("get_uri_nofrag failed\n");
101 window
->uri_nofrag
= uri
;
104 IUri_GetDisplayUri(uri
, &window
->url
);
107 void set_current_mon(HTMLOuterWindow
*This
, IMoniker
*mon
, DWORD flags
)
109 IUriContainer
*uri_container
;
114 if(This
->browser
&& !(flags
& (BINDING_REPLACE
|BINDING_REFRESH
))) {
115 if(is_main_content_window(This
))
116 notify_travellog_update(This
->browser
->doc
);
118 TRACE("Skipping travellog update for frame navigation.\n");
120 IMoniker_Release(This
->mon
);
124 This
->load_flags
= flags
;
128 IMoniker_AddRef(mon
);
131 hres
= IMoniker_QueryInterface(mon
, &IID_IUriContainer
, (void**)&uri_container
);
132 if(SUCCEEDED(hres
)) {
133 hres
= IUriContainer_GetIUri(uri_container
, &uri
);
134 IUriContainer_Release(uri_container
);
136 WARN("GetIUri failed: %08lx\n", hres
);
144 hres
= IMoniker_GetDisplayName(mon
, NULL
, NULL
, &url
);
145 if(SUCCEEDED(hres
)) {
146 hres
= create_uri(url
, 0, &uri
);
148 WARN("CreateUri failed: %08lx\n", hres
);
149 set_current_uri(This
, NULL
);
150 This
->url
= SysAllocString(url
);
156 WARN("GetDisplayName failed: %08lx\n", hres
);
160 set_current_uri(This
, uri
);
164 if(is_main_content_window(This
))
165 update_browser_script_mode(This
->browser
, uri
);
168 HRESULT
create_uri(const WCHAR
*uri_str
, DWORD flags
, IUri
**uri
)
170 return CreateUri(uri_str
, flags
| Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME
, 0, uri
);
173 HRESULT
create_relative_uri(HTMLOuterWindow
*window
, const WCHAR
*rel_uri
, IUri
**uri
)
176 ? CoInternetCombineUrlEx(window
->uri
, rel_uri
, URL_ESCAPE_SPACES_ONLY
|URL_DONT_ESCAPE_EXTRA_INFO
, uri
, 0)
177 : create_uri(rel_uri
, 0, uri
);
180 void set_download_state(HTMLDocumentObj
*doc
, int state
)
183 IOleCommandTarget
*olecmd
;
186 hres
= IOleClientSite_QueryInterface(doc
->client
, &IID_IOleCommandTarget
, (void**)&olecmd
);
187 if(SUCCEEDED(hres
)) {
193 IOleCommandTarget_Exec(olecmd
, NULL
, OLECMDID_SETDOWNLOADSTATE
,
194 OLECMDEXECOPT_DONTPROMPTUSER
, &var
, NULL
);
195 IOleCommandTarget_Release(olecmd
);
199 doc
->download_state
= state
;
202 static void set_progress_proc(task_t
*_task
)
204 docobj_task_t
*task
= (docobj_task_t
*)_task
;
205 IOleCommandTarget
*olecmd
= NULL
;
206 HTMLDocumentObj
*doc
= task
->doc
;
209 TRACE("(%p)\n", doc
);
212 IOleClientSite_QueryInterface(doc
->client
, &IID_IOleCommandTarget
, (void**)&olecmd
);
215 VARIANT progress_max
, progress
;
217 V_VT(&progress_max
) = VT_I4
;
218 V_I4(&progress_max
) = 0; /* FIXME */
219 IOleCommandTarget_Exec(olecmd
, NULL
, OLECMDID_SETPROGRESSMAX
, OLECMDEXECOPT_DONTPROMPTUSER
,
220 &progress_max
, NULL
);
222 V_VT(&progress
) = VT_I4
;
223 V_I4(&progress
) = 0; /* FIXME */
224 IOleCommandTarget_Exec(olecmd
, NULL
, OLECMDID_SETPROGRESSPOS
, OLECMDEXECOPT_DONTPROMPTUSER
,
226 IOleCommandTarget_Release(olecmd
);
229 if(doc
->nscontainer
->usermode
== EDITMODE
&& doc
->hostui
) {
230 DOCHOSTUIINFO hostinfo
;
232 memset(&hostinfo
, 0, sizeof(DOCHOSTUIINFO
));
233 hostinfo
.cbSize
= sizeof(DOCHOSTUIINFO
);
234 hres
= IDocHostUIHandler_GetHostInfo(doc
->hostui
, &hostinfo
);
236 /* FIXME: use hostinfo */
237 TRACE("hostinfo = {%lu %08lx %08lx %s %s}\n",
238 hostinfo
.cbSize
, hostinfo
.dwFlags
, hostinfo
.dwDoubleClick
,
239 debugstr_w(hostinfo
.pchHostCss
), debugstr_w(hostinfo
.pchHostNS
));
243 static void set_downloading_proc(task_t
*_task
)
245 download_proc_task_t
*task
= (download_proc_task_t
*)_task
;
246 HTMLDocumentObj
*doc
= task
->doc
;
249 TRACE("(%p)\n", doc
);
251 set_statustext(doc
, IDS_STATUS_DOWNLOADINGFROM
, task
->url
);
253 if(task
->set_download
)
254 set_download_state(doc
, 1);
260 IAdviseSink_OnViewChange(doc
->view_sink
, DVASPECT_CONTENT
, -1);
263 IDropTarget
*drop_target
= NULL
;
265 hres
= IDocHostUIHandler_GetDropTarget(doc
->hostui
, NULL
/* FIXME */, &drop_target
);
266 if(SUCCEEDED(hres
) && drop_target
) {
267 FIXME("Use IDropTarget\n");
268 IDropTarget_Release(drop_target
);
273 static void set_downloading_task_destr(task_t
*_task
)
275 download_proc_task_t
*task
= (download_proc_task_t
*)_task
;
277 CoTaskMemFree(task
->url
);
281 void prepare_for_binding(HTMLDocument
*This
, IMoniker
*mon
, DWORD flags
)
285 if(This
->doc_obj
->client
) {
286 VARIANT silent
, offline
;
288 hres
= get_client_disp_property(This
->doc_obj
->client
, DISPID_AMBIENT_SILENT
, &silent
);
289 if(SUCCEEDED(hres
)) {
290 if(V_VT(&silent
) != VT_BOOL
)
291 WARN("silent = %s\n", debugstr_variant(&silent
));
292 else if(V_BOOL(&silent
))
293 FIXME("silent == true\n");
296 hres
= get_client_disp_property(This
->doc_obj
->client
,
297 DISPID_AMBIENT_OFFLINEIFNOTCONNECTED
, &offline
);
298 if(SUCCEEDED(hres
)) {
299 if(V_VT(&offline
) != VT_BOOL
)
300 WARN("offline = %s\n", debugstr_variant(&offline
));
301 else if(V_BOOL(&offline
))
302 FIXME("offline == true\n");
306 if(This
->window
->mon
) {
307 update_doc(This
->doc_obj
, UPDATE_TITLE
|UPDATE_UI
);
309 update_doc(This
->doc_obj
, UPDATE_TITLE
);
310 set_current_mon(This
->window
, mon
, flags
);
313 if(This
->doc_obj
->client
) {
314 IOleCommandTarget
*cmdtrg
= NULL
;
316 hres
= IOleClientSite_QueryInterface(This
->doc_obj
->client
, &IID_IOleCommandTarget
,
318 if(SUCCEEDED(hres
)) {
321 if(flags
& BINDING_NAVIGATED
) {
322 V_VT(&var
) = VT_UNKNOWN
;
323 V_UNKNOWN(&var
) = (IUnknown
*)&This
->window
->base
.IHTMLWindow2_iface
;
324 V_VT(&out
) = VT_EMPTY
;
325 hres
= IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 63, 0, &var
, &out
);
328 }else if(!(flags
& BINDING_FROMHIST
)) {
331 IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 37, 0, &var
, NULL
);
334 IOleCommandTarget_Release(cmdtrg
);
339 HRESULT
set_moniker(HTMLOuterWindow
*window
, IMoniker
*mon
, IUri
*nav_uri
, IBindCtx
*pibc
, nsChannelBSC
*async_bsc
,
342 download_proc_task_t
*download_task
;
343 HTMLDocumentObj
*doc_obj
= NULL
;
344 nsChannelBSC
*bscallback
;
350 if(is_main_content_window(window
))
351 doc_obj
= window
->browser
->doc
;
353 hres
= IMoniker_GetDisplayName(mon
, pibc
, NULL
, &url
);
355 WARN("GetDisplayName failed: %08lx\n", hres
);
362 hres
= create_uri(url
, 0, &uri
);
369 TRACE("got url: %s\n", debugstr_w(url
));
371 set_ready_state(window
, READYSTATE_LOADING
);
373 hres
= create_doc_uri(uri
, &nsuri
);
376 if(SUCCEEDED(hres
)) {
378 bscallback
= async_bsc
;
380 hres
= create_channelbsc(mon
, NULL
, NULL
, 0, TRUE
, &bscallback
);
383 if(SUCCEEDED(hres
)) {
384 if(window
->base
.inner_window
->doc
)
385 remove_target_tasks(window
->base
.inner_window
->task_magic
);
386 abort_window_bindings(window
->base
.inner_window
);
388 hres
= load_nsuri(window
, nsuri
, NULL
, bscallback
, LOAD_FLAGS_BYPASS_CACHE
);
389 nsISupports_Release((nsISupports
*)nsuri
); /* FIXME */
390 if(SUCCEEDED(hres
)) {
391 hres
= create_pending_window(window
, bscallback
);
392 TRACE("pending window for %p %p %p\n", window
, bscallback
, window
->pending_window
);
394 if(bscallback
!= async_bsc
)
395 IBindStatusCallback_Release(&bscallback
->bsc
.IBindStatusCallback_iface
);
404 HTMLDocument_LockContainer(doc_obj
, TRUE
);
409 task
= heap_alloc(sizeof(docobj_task_t
));
411 hres
= push_task(&task
->header
, set_progress_proc
, NULL
, doc_obj
->task_magic
);
418 download_task
= heap_alloc(sizeof(download_proc_task_t
));
419 download_task
->doc
= doc_obj
;
420 download_task
->set_download
= set_download
;
421 download_task
->url
= url
;
422 return push_task(&download_task
->header
, set_downloading_proc
, set_downloading_task_destr
, doc_obj
->task_magic
);
428 static void notif_readystate(HTMLOuterWindow
*window
)
433 window
->readystate_pending
= FALSE
;
435 if(is_main_content_window(window
))
436 call_property_onchanged(&window
->browser
->doc
->basedoc
.cp_container
, DISPID_READYSTATE
);
438 hres
= create_document_event(window
->base
.inner_window
->doc
, EVENTID_READYSTATECHANGE
, &event
);
439 if(SUCCEEDED(hres
)) {
440 event
->no_event_obj
= TRUE
;
441 dispatch_event(&window
->base
.inner_window
->doc
->node
.event_target
, event
);
442 IDOMEvent_Release(&event
->IDOMEvent_iface
);
445 if(window
->frame_element
) {
446 hres
= create_document_event(window
->frame_element
->element
.node
.doc
, EVENTID_READYSTATECHANGE
, &event
);
447 if(SUCCEEDED(hres
)) {
448 dispatch_event(&window
->frame_element
->element
.node
.event_target
, event
);
449 IDOMEvent_Release(&event
->IDOMEvent_iface
);
456 HTMLOuterWindow
*window
;
459 static void notif_readystate_proc(task_t
*_task
)
461 readystate_task_t
*task
= (readystate_task_t
*)_task
;
462 notif_readystate(task
->window
);
465 static void notif_readystate_destr(task_t
*_task
)
467 readystate_task_t
*task
= (readystate_task_t
*)_task
;
468 IHTMLWindow2_Release(&task
->window
->base
.IHTMLWindow2_iface
);
471 void set_ready_state(HTMLOuterWindow
*window
, READYSTATE readystate
)
473 READYSTATE prev_state
= window
->readystate
;
475 window
->readystate
= readystate
;
477 if(window
->readystate_locked
) {
478 readystate_task_t
*task
;
481 if(window
->readystate_pending
|| prev_state
== readystate
)
484 task
= heap_alloc(sizeof(*task
));
488 IHTMLWindow2_AddRef(&window
->base
.IHTMLWindow2_iface
);
489 task
->window
= window
;
491 hres
= push_task(&task
->header
, notif_readystate_proc
, notif_readystate_destr
, window
->task_magic
);
493 window
->readystate_pending
= TRUE
;
497 notif_readystate(window
);
500 static HRESULT
get_doc_string(HTMLDocumentNode
*This
, char **str
)
509 WARN("NULL nsdoc\n");
513 nsres
= nsIDOMHTMLDocument_QueryInterface(This
->nsdoc
, &IID_nsIDOMNode
, (void**)&nsnode
);
514 if(NS_FAILED(nsres
)) {
515 ERR("Could not get nsIDOMNode failed: %08lx\n", nsres
);
519 nsAString_Init(&nsstr
, NULL
);
520 hres
= nsnode_to_nsstring(nsnode
, &nsstr
);
521 nsIDOMNode_Release(nsnode
);
523 nsAString_Finish(&nsstr
);
527 nsAString_GetData(&nsstr
, &strw
);
528 TRACE("%s\n", debugstr_w(strw
));
530 *str
= heap_strdupWtoA(strw
);
532 nsAString_Finish(&nsstr
);
535 return E_OUTOFMEMORY
;
540 /**********************************************************
541 * IPersistMoniker implementation
544 static inline HTMLDocument
*impl_from_IPersistMoniker(IPersistMoniker
*iface
)
546 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistMoniker_iface
);
549 static HRESULT WINAPI
PersistMoniker_QueryInterface(IPersistMoniker
*iface
, REFIID riid
, void **ppv
)
551 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
552 return htmldoc_query_interface(This
, riid
, ppv
);
555 static ULONG WINAPI
PersistMoniker_AddRef(IPersistMoniker
*iface
)
557 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
558 return htmldoc_addref(This
);
561 static ULONG WINAPI
PersistMoniker_Release(IPersistMoniker
*iface
)
563 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
564 return htmldoc_release(This
);
567 static HRESULT WINAPI
PersistMoniker_GetClassID(IPersistMoniker
*iface
, CLSID
*pClassID
)
569 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
570 return IPersistFile_GetClassID(&This
->IPersistFile_iface
, pClassID
);
573 static HRESULT WINAPI
PersistMoniker_IsDirty(IPersistMoniker
*iface
)
575 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
577 TRACE("(%p)\n", This
);
579 return IPersistStreamInit_IsDirty(&This
->IPersistStreamInit_iface
);
582 static HRESULT WINAPI
PersistMoniker_Load(IPersistMoniker
*iface
, BOOL fFullyAvailable
,
583 IMoniker
*pimkName
, LPBC pibc
, DWORD grfMode
)
585 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
589 TRACE("(%p)->(%x %p %p %08lx)\n", This
, fFullyAvailable
, pimkName
, pibc
, grfMode
);
592 IUnknown
*unk
= NULL
;
596 * "__PrecreatedObject"
597 * "BIND_CONTEXT_PARAM"
598 * "__HTMLLOADOPTIONS"
601 * "_ITransData_Object_"
605 hres
= IBindCtx_GetObjectParam(pibc
, (LPOLESTR
)SZ_HTML_CLIENTSITE_OBJECTPARAM
, &unk
);
606 if(SUCCEEDED(hres
) && unk
) {
607 IOleClientSite
*client
= NULL
;
609 hres
= IUnknown_QueryInterface(unk
, &IID_IOleClientSite
, (void**)&client
);
610 if(SUCCEEDED(hres
)) {
611 TRACE("Got client site %p\n", client
);
612 IOleObject_SetClientSite(&This
->IOleObject_iface
, client
);
613 IOleClientSite_Release(client
);
616 IUnknown_Release(unk
);
620 if(This
->doc_obj
->is_mhtml
) {
623 hres
= MimeOleObjectFromMoniker(0, pimkName
, pibc
, &IID_IUnknown
, (void**)&unk
, &mon
);
626 IUnknown_Release(unk
);
629 IMoniker_AddRef(mon
= pimkName
);
632 prepare_for_binding(This
, mon
, FALSE
);
633 call_docview_84(This
->doc_obj
);
634 hres
= set_moniker(This
->window
, mon
, NULL
, pibc
, NULL
, TRUE
);
635 IMoniker_Release(mon
);
639 return start_binding(This
->window
->pending_window
, (BSCallback
*)This
->window
->pending_window
->bscallback
, pibc
);
642 static HRESULT WINAPI
PersistMoniker_Save(IPersistMoniker
*iface
, IMoniker
*pimkName
,
643 LPBC pbc
, BOOL fRemember
)
645 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
646 FIXME("(%p)->(%p %p %x)\n", This
, pimkName
, pbc
, fRemember
);
650 static HRESULT WINAPI
PersistMoniker_SaveCompleted(IPersistMoniker
*iface
, IMoniker
*pimkName
, LPBC pibc
)
652 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
653 FIXME("(%p)->(%p %p)\n", This
, pimkName
, pibc
);
657 static HRESULT WINAPI
PersistMoniker_GetCurMoniker(IPersistMoniker
*iface
, IMoniker
**ppimkName
)
659 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
661 TRACE("(%p)->(%p)\n", This
, ppimkName
);
663 if(!This
->window
|| !This
->window
->mon
)
666 IMoniker_AddRef(This
->window
->mon
);
667 *ppimkName
= This
->window
->mon
;
671 static const IPersistMonikerVtbl PersistMonikerVtbl
= {
672 PersistMoniker_QueryInterface
,
673 PersistMoniker_AddRef
,
674 PersistMoniker_Release
,
675 PersistMoniker_GetClassID
,
676 PersistMoniker_IsDirty
,
679 PersistMoniker_SaveCompleted
,
680 PersistMoniker_GetCurMoniker
683 /**********************************************************
684 * IMonikerProp implementation
687 static inline HTMLDocument
*impl_from_IMonikerProp(IMonikerProp
*iface
)
689 return CONTAINING_RECORD(iface
, HTMLDocument
, IMonikerProp_iface
);
692 static HRESULT WINAPI
MonikerProp_QueryInterface(IMonikerProp
*iface
, REFIID riid
, void **ppv
)
694 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
695 return htmldoc_query_interface(This
, riid
, ppv
);
698 static ULONG WINAPI
MonikerProp_AddRef(IMonikerProp
*iface
)
700 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
701 return htmldoc_addref(This
);
704 static ULONG WINAPI
MonikerProp_Release(IMonikerProp
*iface
)
706 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
707 return htmldoc_release(This
);
710 static HRESULT WINAPI
MonikerProp_PutProperty(IMonikerProp
*iface
, MONIKERPROPERTY mkp
, LPCWSTR val
)
712 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
714 TRACE("(%p)->(%d %s)\n", This
, mkp
, debugstr_w(val
));
718 heap_free(This
->doc_obj
->mime
);
719 This
->doc_obj
->mime
= heap_strdupW(val
);
726 FIXME("mkp %d\n", mkp
);
733 static const IMonikerPropVtbl MonikerPropVtbl
= {
734 MonikerProp_QueryInterface
,
737 MonikerProp_PutProperty
740 /**********************************************************
741 * IPersistFile implementation
744 static inline HTMLDocument
*impl_from_IPersistFile(IPersistFile
*iface
)
746 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistFile_iface
);
749 static HRESULT WINAPI
PersistFile_QueryInterface(IPersistFile
*iface
, REFIID riid
, void **ppv
)
751 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
752 return htmldoc_query_interface(This
, riid
, ppv
);
755 static ULONG WINAPI
PersistFile_AddRef(IPersistFile
*iface
)
757 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
758 return htmldoc_addref(This
);
761 static ULONG WINAPI
PersistFile_Release(IPersistFile
*iface
)
763 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
764 return htmldoc_release(This
);
767 static HRESULT WINAPI
PersistFile_GetClassID(IPersistFile
*iface
, CLSID
*pClassID
)
769 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
771 TRACE("(%p)->(%p)\n", This
, pClassID
);
776 *pClassID
= CLSID_HTMLDocument
;
780 static HRESULT WINAPI
PersistFile_IsDirty(IPersistFile
*iface
)
782 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
784 TRACE("(%p)\n", This
);
786 return IPersistStreamInit_IsDirty(&This
->IPersistStreamInit_iface
);
789 static HRESULT WINAPI
PersistFile_Load(IPersistFile
*iface
, LPCOLESTR pszFileName
, DWORD dwMode
)
791 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
792 FIXME("(%p)->(%s %08lx)\n", This
, debugstr_w(pszFileName
), dwMode
);
796 static HRESULT WINAPI
PersistFile_Save(IPersistFile
*iface
, LPCOLESTR pszFileName
, BOOL fRemember
)
798 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
804 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(pszFileName
), fRemember
);
806 file
= CreateFileW(pszFileName
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
807 FILE_ATTRIBUTE_NORMAL
, NULL
);
808 if(file
== INVALID_HANDLE_VALUE
) {
809 WARN("Could not create file: %lu\n", GetLastError());
813 hres
= get_doc_string(This
->doc_node
, &str
);
815 WriteFile(file
, str
, strlen(str
), &written
, NULL
);
821 static HRESULT WINAPI
PersistFile_SaveCompleted(IPersistFile
*iface
, LPCOLESTR pszFileName
)
823 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
824 FIXME("(%p)->(%s)\n", This
, debugstr_w(pszFileName
));
828 static HRESULT WINAPI
PersistFile_GetCurFile(IPersistFile
*iface
, LPOLESTR
*pszFileName
)
830 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
831 FIXME("(%p)->(%p)\n", This
, pszFileName
);
835 static const IPersistFileVtbl PersistFileVtbl
= {
836 PersistFile_QueryInterface
,
839 PersistFile_GetClassID
,
843 PersistFile_SaveCompleted
,
844 PersistFile_GetCurFile
847 static inline HTMLDocument
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
849 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistStreamInit_iface
);
852 static HRESULT WINAPI
PersistStreamInit_QueryInterface(IPersistStreamInit
*iface
,
853 REFIID riid
, void **ppv
)
855 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
856 return htmldoc_query_interface(This
, riid
, ppv
);
859 static ULONG WINAPI
PersistStreamInit_AddRef(IPersistStreamInit
*iface
)
861 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
862 return htmldoc_addref(This
);
865 static ULONG WINAPI
PersistStreamInit_Release(IPersistStreamInit
*iface
)
867 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
868 return htmldoc_release(This
);
871 static HRESULT WINAPI
PersistStreamInit_GetClassID(IPersistStreamInit
*iface
, CLSID
*pClassID
)
873 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
874 return IPersistFile_GetClassID(&This
->IPersistFile_iface
, pClassID
);
877 static HRESULT WINAPI
PersistStreamInit_IsDirty(IPersistStreamInit
*iface
)
879 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
881 TRACE("(%p)\n", This
);
883 return browser_is_dirty(This
->doc_obj
->nscontainer
);
886 static HRESULT WINAPI
PersistStreamInit_Load(IPersistStreamInit
*iface
, IStream
*pStm
)
888 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
892 TRACE("(%p)->(%p)\n", This
, pStm
);
894 hres
= CreateURLMoniker(NULL
, L
"about:blank", &mon
);
896 WARN("CreateURLMoniker failed: %08lx\n", hres
);
900 prepare_for_binding(This
, mon
, FALSE
);
901 hres
= set_moniker(This
->window
, mon
, NULL
, NULL
, NULL
, TRUE
);
903 hres
= channelbsc_load_stream(This
->window
->pending_window
, mon
, pStm
);
905 IMoniker_Release(mon
);
909 static HRESULT WINAPI
PersistStreamInit_Save(IPersistStreamInit
*iface
, IStream
*pStm
,
912 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
917 TRACE("(%p)->(%p %x)\n", This
, pStm
, fClearDirty
);
919 hres
= get_doc_string(This
->doc_node
, &str
);
923 hres
= IStream_Write(pStm
, str
, strlen(str
), &written
);
925 FIXME("Write failed: %08lx\n", hres
);
930 set_dirty(This
->doc_obj
->nscontainer
, VARIANT_FALSE
);
935 static HRESULT WINAPI
PersistStreamInit_GetSizeMax(IPersistStreamInit
*iface
,
936 ULARGE_INTEGER
*pcbSize
)
938 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
939 FIXME("(%p)->(%p)\n", This
, pcbSize
);
943 static HRESULT WINAPI
PersistStreamInit_InitNew(IPersistStreamInit
*iface
)
945 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
949 TRACE("(%p)\n", This
);
951 hres
= CreateURLMoniker(NULL
, L
"about:blank", &mon
);
953 WARN("CreateURLMoniker failed: %08lx\n", hres
);
957 prepare_for_binding(This
, mon
, FALSE
);
958 hres
= set_moniker(This
->window
, mon
, NULL
, NULL
, NULL
, FALSE
);
960 hres
= channelbsc_load_stream(This
->window
->pending_window
, mon
, NULL
);
962 IMoniker_Release(mon
);
966 static const IPersistStreamInitVtbl PersistStreamInitVtbl
= {
967 PersistStreamInit_QueryInterface
,
968 PersistStreamInit_AddRef
,
969 PersistStreamInit_Release
,
970 PersistStreamInit_GetClassID
,
971 PersistStreamInit_IsDirty
,
972 PersistStreamInit_Load
,
973 PersistStreamInit_Save
,
974 PersistStreamInit_GetSizeMax
,
975 PersistStreamInit_InitNew
978 /**********************************************************
979 * IPersistHistory implementation
982 static inline HTMLDocument
*impl_from_IPersistHistory(IPersistHistory
*iface
)
984 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistHistory_iface
);
987 static HRESULT WINAPI
PersistHistory_QueryInterface(IPersistHistory
*iface
, REFIID riid
, void **ppv
)
989 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
990 return htmldoc_query_interface(This
, riid
, ppv
);
993 static ULONG WINAPI
PersistHistory_AddRef(IPersistHistory
*iface
)
995 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
996 return htmldoc_addref(This
);
999 static ULONG WINAPI
PersistHistory_Release(IPersistHistory
*iface
)
1001 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1002 return htmldoc_release(This
);
1005 static HRESULT WINAPI
PersistHistory_GetClassID(IPersistHistory
*iface
, CLSID
*pClassID
)
1007 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1008 return IPersistFile_GetClassID(&This
->IPersistFile_iface
, pClassID
);
1011 static HRESULT WINAPI
PersistHistory_LoadHistory(IPersistHistory
*iface
, IStream
*pStream
, IBindCtx
*pbc
)
1013 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1014 ULONG str_len
, read
;
1019 TRACE("(%p)->(%p %p)\n", This
, pStream
, pbc
);
1022 FIXME("No current window\n");
1023 return E_UNEXPECTED
;
1027 FIXME("pbc not supported\n");
1029 if(This
->doc_obj
->client
) {
1030 IOleCommandTarget
*cmdtrg
= NULL
;
1032 hres
= IOleClientSite_QueryInterface(This
->doc_obj
->client
, &IID_IOleCommandTarget
,
1034 if(SUCCEEDED(hres
)) {
1035 IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 138, 0, NULL
, NULL
);
1036 IOleCommandTarget_Release(cmdtrg
);
1040 hres
= IStream_Read(pStream
, &str_len
, sizeof(str_len
), &read
);
1043 if(read
!= sizeof(str_len
))
1046 uri_str
= heap_alloc((str_len
+1)*sizeof(WCHAR
));
1048 return E_OUTOFMEMORY
;
1050 hres
= IStream_Read(pStream
, uri_str
, str_len
*sizeof(WCHAR
), &read
);
1051 if(SUCCEEDED(hres
) && read
!= str_len
*sizeof(WCHAR
))
1053 if(SUCCEEDED(hres
)) {
1054 uri_str
[str_len
] = 0;
1055 hres
= create_uri(uri_str
, 0, &uri
);
1061 hres
= load_uri(This
->window
, uri
, BINDING_FROMHIST
);
1066 static HRESULT WINAPI
PersistHistory_SaveHistory(IPersistHistory
*iface
, IStream
*pStream
)
1068 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1073 TRACE("(%p)->(%p)\n", This
, pStream
);
1075 if(!This
->window
|| !This
->window
->uri
) {
1076 FIXME("No current URI\n");
1080 /* NOTE: The format we store is *not* compatible with native MSHTML. We currently
1081 * store only URI of the page (as a length followed by a string) */
1082 hres
= IUri_GetDisplayUri(This
->window
->uri
, &display_uri
);
1086 len
= SysStringLen(display_uri
);
1087 hres
= IStream_Write(pStream
, &len
, sizeof(len
), &written
);
1089 hres
= IStream_Write(pStream
, display_uri
, len
*sizeof(WCHAR
), &written
);
1090 SysFreeString(display_uri
);
1094 static HRESULT WINAPI
PersistHistory_SetPositionCookie(IPersistHistory
*iface
, DWORD dwPositioncookie
)
1096 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1097 FIXME("(%p)->(%lx)\n", This
, dwPositioncookie
);
1101 static HRESULT WINAPI
PersistHistory_GetPositionCookie(IPersistHistory
*iface
, DWORD
*pdwPositioncookie
)
1103 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1104 FIXME("(%p)->(%p)\n", This
, pdwPositioncookie
);
1108 static const IPersistHistoryVtbl PersistHistoryVtbl
= {
1109 PersistHistory_QueryInterface
,
1110 PersistHistory_AddRef
,
1111 PersistHistory_Release
,
1112 PersistHistory_GetClassID
,
1113 PersistHistory_LoadHistory
,
1114 PersistHistory_SaveHistory
,
1115 PersistHistory_SetPositionCookie
,
1116 PersistHistory_GetPositionCookie
1119 /**********************************************************
1120 * IHlinkTarget implementation
1123 static inline HTMLDocument
*impl_from_IHlinkTarget(IHlinkTarget
*iface
)
1125 return CONTAINING_RECORD(iface
, HTMLDocument
, IHlinkTarget_iface
);
1128 static HRESULT WINAPI
HlinkTarget_QueryInterface(IHlinkTarget
*iface
, REFIID riid
, void **ppv
)
1130 HTMLDocument
*This
= impl_from_IHlinkTarget(iface
);
1131 return htmldoc_query_interface(This
, riid
, ppv
);
1134 static ULONG WINAPI
HlinkTarget_AddRef(IHlinkTarget
*iface
)
1136 HTMLDocument
*This
= impl_from_IHlinkTarget(iface
);
1137 return htmldoc_addref(This
);
1140 static ULONG WINAPI
HlinkTarget_Release(IHlinkTarget
*iface
)
1142 HTMLDocument
*This
= impl_from_IHlinkTarget(iface
);
1143 return htmldoc_release(This
);
1146 static HRESULT WINAPI
HlinkTarget_SetBrowseContext(IHlinkTarget
*iface
, IHlinkBrowseContext
*pihlbc
)
1148 HTMLDocument
*This
= impl_from_IHlinkTarget(iface
);
1149 FIXME("(%p)->(%p)\n", This
, pihlbc
);
1153 static HRESULT WINAPI
HlinkTarget_GetBrowseContext(IHlinkTarget
*iface
, IHlinkBrowseContext
**ppihlbc
)
1155 HTMLDocument
*This
= impl_from_IHlinkTarget(iface
);
1156 FIXME("(%p)->(%p)\n", This
, ppihlbc
);
1160 static HRESULT WINAPI
HlinkTarget_Navigate(IHlinkTarget
*iface
, DWORD grfHLNF
, LPCWSTR pwzJumpLocation
)
1162 HTMLDocument
*This
= impl_from_IHlinkTarget(iface
);
1164 TRACE("(%p)->(%08lx %s)\n", This
, grfHLNF
, debugstr_w(pwzJumpLocation
));
1167 FIXME("Unsupported grfHLNF=%08lx\n", grfHLNF
);
1169 FIXME("JumpLocation not supported\n");
1171 if(!This
->doc_obj
->client
) {
1175 hres
= IUri_GetAbsoluteUri(This
->window
->uri
, &uri
);
1179 ShellExecuteW(NULL
, L
"open", uri
, NULL
, NULL
, SW_SHOW
);
1184 return IOleObject_DoVerb(&This
->IOleObject_iface
, OLEIVERB_SHOW
, NULL
, NULL
, -1, NULL
, NULL
);
1187 static HRESULT WINAPI
HlinkTarget_GetMoniker(IHlinkTarget
*iface
, LPCWSTR pwzLocation
, DWORD dwAssign
,
1188 IMoniker
**ppimkLocation
)
1190 HTMLDocument
*This
= impl_from_IHlinkTarget(iface
);
1191 FIXME("(%p)->(%s %08lx %p)\n", This
, debugstr_w(pwzLocation
), dwAssign
, ppimkLocation
);
1195 static HRESULT WINAPI
HlinkTarget_GetFriendlyName(IHlinkTarget
*iface
, LPCWSTR pwzLocation
,
1196 LPWSTR
*ppwzFriendlyName
)
1198 HTMLDocument
*This
= impl_from_IHlinkTarget(iface
);
1199 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(pwzLocation
), ppwzFriendlyName
);
1203 static const IHlinkTargetVtbl HlinkTargetVtbl
= {
1204 HlinkTarget_QueryInterface
,
1206 HlinkTarget_Release
,
1207 HlinkTarget_SetBrowseContext
,
1208 HlinkTarget_GetBrowseContext
,
1209 HlinkTarget_Navigate
,
1210 HlinkTarget_GetMoniker
,
1211 HlinkTarget_GetFriendlyName
1214 void HTMLDocument_Persist_Init(HTMLDocument
*This
)
1216 This
->IPersistMoniker_iface
.lpVtbl
= &PersistMonikerVtbl
;
1217 This
->IPersistFile_iface
.lpVtbl
= &PersistFileVtbl
;
1218 This
->IMonikerProp_iface
.lpVtbl
= &MonikerPropVtbl
;
1219 This
->IPersistStreamInit_iface
.lpVtbl
= &PersistStreamInitVtbl
;
1220 This
->IPersistHistory_iface
.lpVtbl
= &PersistHistoryVtbl
;
1221 This
->IHlinkTarget_iface
.lpVtbl
= &HlinkTargetVtbl
;