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
49 static const WCHAR about_blankW
[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
56 } download_proc_task_t
;
58 static BOOL
use_gecko_script(HTMLOuterWindow
*window
)
63 hres
= IInternetSecurityManager_MapUrlToZone(window
->secmgr
, window
->url
, &zone
, 0);
65 WARN("Could not map %s to zone: %08x\n", debugstr_w(window
->url
), hres
);
69 TRACE("zone %d\n", zone
);
70 return zone
== URLZONE_UNTRUSTED
;
73 static void notify_travellog_update(HTMLDocumentObj
*doc
)
75 IOleCommandTarget
*cmdtrg
;
81 hres
= IOleClientSite_QueryInterface(doc
->client
, &IID_IOleCommandTarget
, (void**)&cmdtrg
);
88 IOleCommandTarget_Exec(cmdtrg
, &CGID_Explorer
, CMDID_EXPLORER_UPDATEHISTORY
, 0, &vin
, NULL
);
89 IOleCommandTarget_Release(cmdtrg
);
93 void set_current_uri(HTMLOuterWindow
*window
, IUri
*uri
)
96 IUri_Release(window
->uri
);
100 if(window
->uri_nofrag
) {
101 IUri_Release(window
->uri_nofrag
);
102 window
->uri_nofrag
= NULL
;
105 SysFreeString(window
->url
);
114 window
->uri_nofrag
= get_uri_nofrag(uri
);
115 if(!window
->uri_nofrag
) {
116 FIXME("get_uri_nofrag failed\n");
118 window
->uri_nofrag
= uri
;
121 IUri_GetDisplayUri(uri
, &window
->url
);
124 void set_current_mon(HTMLOuterWindow
*This
, IMoniker
*mon
, DWORD flags
)
126 IUriContainer
*uri_container
;
131 if(This
->doc_obj
&& !(flags
& (BINDING_REPLACE
|BINDING_REFRESH
))) {
132 if(This
== This
->doc_obj
->basedoc
.window
)
133 notify_travellog_update(This
->doc_obj
);
135 TRACE("Skipping travellog update for frame navigation.\n");
137 IMoniker_Release(This
->mon
);
141 This
->load_flags
= flags
;
145 IMoniker_AddRef(mon
);
148 hres
= IMoniker_QueryInterface(mon
, &IID_IUriContainer
, (void**)&uri_container
);
149 if(SUCCEEDED(hres
)) {
150 hres
= IUriContainer_GetIUri(uri_container
, &uri
);
151 IUriContainer_Release(uri_container
);
153 WARN("GetIUri failed: %08x\n", hres
);
161 hres
= IMoniker_GetDisplayName(mon
, NULL
, NULL
, &url
);
162 if(SUCCEEDED(hres
)) {
163 hres
= create_uri(url
, 0, &uri
);
165 WARN("CreateUri failed: %08x\n", hres
);
166 set_current_uri(This
, NULL
);
167 This
->url
= SysAllocString(url
);
173 WARN("GetDisplayName failed: %08x\n", hres
);
177 set_current_uri(This
, uri
);
180 set_script_mode(This
, use_gecko_script(This
) ? SCRIPTMODE_GECKO
: SCRIPTMODE_ACTIVESCRIPT
);
183 HRESULT
create_uri(const WCHAR
*uri_str
, DWORD flags
, IUri
**uri
)
185 return CreateUri(uri_str
, flags
| Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME
, 0, uri
);
188 HRESULT
create_relative_uri(HTMLOuterWindow
*window
, const WCHAR
*rel_uri
, IUri
**uri
)
191 ? CoInternetCombineUrlEx(window
->uri
, rel_uri
, URL_ESCAPE_SPACES_ONLY
|URL_DONT_ESCAPE_EXTRA_INFO
, uri
, 0)
192 : create_uri(rel_uri
, 0, uri
);
195 void set_download_state(HTMLDocumentObj
*doc
, int state
)
198 IOleCommandTarget
*olecmd
;
201 hres
= IOleClientSite_QueryInterface(doc
->client
, &IID_IOleCommandTarget
, (void**)&olecmd
);
202 if(SUCCEEDED(hres
)) {
208 IOleCommandTarget_Exec(olecmd
, NULL
, OLECMDID_SETDOWNLOADSTATE
,
209 OLECMDEXECOPT_DONTPROMPTUSER
, &var
, NULL
);
210 IOleCommandTarget_Release(olecmd
);
214 doc
->download_state
= state
;
217 static void set_progress_proc(task_t
*_task
)
219 docobj_task_t
*task
= (docobj_task_t
*)_task
;
220 IOleCommandTarget
*olecmd
= NULL
;
221 HTMLDocumentObj
*doc
= task
->doc
;
224 TRACE("(%p)\n", doc
);
227 IOleClientSite_QueryInterface(doc
->client
, &IID_IOleCommandTarget
, (void**)&olecmd
);
230 VARIANT progress_max
, progress
;
232 V_VT(&progress_max
) = VT_I4
;
233 V_I4(&progress_max
) = 0; /* FIXME */
234 IOleCommandTarget_Exec(olecmd
, NULL
, OLECMDID_SETPROGRESSMAX
, OLECMDEXECOPT_DONTPROMPTUSER
,
235 &progress_max
, NULL
);
237 V_VT(&progress
) = VT_I4
;
238 V_I4(&progress
) = 0; /* FIXME */
239 IOleCommandTarget_Exec(olecmd
, NULL
, OLECMDID_SETPROGRESSPOS
, OLECMDEXECOPT_DONTPROMPTUSER
,
241 IOleCommandTarget_Release(olecmd
);
244 if(doc
->usermode
== EDITMODE
&& doc
->hostui
) {
245 DOCHOSTUIINFO hostinfo
;
247 memset(&hostinfo
, 0, sizeof(DOCHOSTUIINFO
));
248 hostinfo
.cbSize
= sizeof(DOCHOSTUIINFO
);
249 hres
= IDocHostUIHandler_GetHostInfo(doc
->hostui
, &hostinfo
);
251 /* FIXME: use hostinfo */
252 TRACE("hostinfo = {%u %08x %08x %s %s}\n",
253 hostinfo
.cbSize
, hostinfo
.dwFlags
, hostinfo
.dwDoubleClick
,
254 debugstr_w(hostinfo
.pchHostCss
), debugstr_w(hostinfo
.pchHostNS
));
258 static void set_downloading_proc(task_t
*_task
)
260 download_proc_task_t
*task
= (download_proc_task_t
*)_task
;
261 HTMLDocumentObj
*doc
= task
->doc
;
264 TRACE("(%p)\n", doc
);
266 set_statustext(doc
, IDS_STATUS_DOWNLOADINGFROM
, task
->url
);
268 if(task
->set_download
)
269 set_download_state(doc
, 1);
275 IAdviseSink_OnViewChange(doc
->view_sink
, DVASPECT_CONTENT
, -1);
278 IDropTarget
*drop_target
= NULL
;
280 hres
= IDocHostUIHandler_GetDropTarget(doc
->hostui
, NULL
/* FIXME */, &drop_target
);
281 if(SUCCEEDED(hres
) && drop_target
) {
282 FIXME("Use IDropTarget\n");
283 IDropTarget_Release(drop_target
);
288 static void set_downloading_task_destr(task_t
*_task
)
290 download_proc_task_t
*task
= (download_proc_task_t
*)_task
;
292 CoTaskMemFree(task
->url
);
296 void prepare_for_binding(HTMLDocument
*This
, IMoniker
*mon
, DWORD flags
)
300 if(This
->doc_obj
->client
) {
301 VARIANT silent
, offline
;
303 hres
= get_client_disp_property(This
->doc_obj
->client
, DISPID_AMBIENT_SILENT
, &silent
);
304 if(SUCCEEDED(hres
)) {
305 if(V_VT(&silent
) != VT_BOOL
)
306 WARN("silent = %s\n", debugstr_variant(&silent
));
307 else if(V_BOOL(&silent
))
308 FIXME("silent == true\n");
311 hres
= get_client_disp_property(This
->doc_obj
->client
,
312 DISPID_AMBIENT_OFFLINEIFNOTCONNECTED
, &offline
);
313 if(SUCCEEDED(hres
)) {
314 if(V_VT(&offline
) != VT_BOOL
)
315 WARN("offline = %s\n", debugstr_variant(&offline
));
316 else if(V_BOOL(&offline
))
317 FIXME("offline == true\n");
321 if(This
->window
->mon
) {
322 update_doc(This
, UPDATE_TITLE
|UPDATE_UI
);
324 update_doc(This
, UPDATE_TITLE
);
325 set_current_mon(This
->window
, mon
, flags
);
328 if(This
->doc_obj
->client
) {
329 IOleCommandTarget
*cmdtrg
= NULL
;
331 hres
= IOleClientSite_QueryInterface(This
->doc_obj
->client
, &IID_IOleCommandTarget
,
333 if(SUCCEEDED(hres
)) {
336 if(flags
& BINDING_NAVIGATED
) {
337 V_VT(&var
) = VT_UNKNOWN
;
338 V_UNKNOWN(&var
) = (IUnknown
*)&This
->window
->base
.IHTMLWindow2_iface
;
339 V_VT(&out
) = VT_EMPTY
;
340 hres
= IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 63, 0, &var
, &out
);
343 }else if(!(flags
& BINDING_FROMHIST
)) {
346 IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 37, 0, &var
, NULL
);
349 IOleCommandTarget_Release(cmdtrg
);
354 HRESULT
set_moniker(HTMLOuterWindow
*window
, IMoniker
*mon
, IUri
*nav_uri
, IBindCtx
*pibc
, nsChannelBSC
*async_bsc
,
357 download_proc_task_t
*download_task
;
358 HTMLDocumentObj
*doc_obj
= NULL
;
359 nsChannelBSC
*bscallback
;
365 if(window
->doc_obj
&& window
->doc_obj
->basedoc
.window
== window
)
366 doc_obj
= window
->doc_obj
;
368 hres
= IMoniker_GetDisplayName(mon
, pibc
, NULL
, &url
);
370 WARN("GetDiaplayName failed: %08x\n", hres
);
377 hres
= create_uri(url
, 0, &uri
);
384 TRACE("got url: %s\n", debugstr_w(url
));
386 set_ready_state(window
, READYSTATE_LOADING
);
388 hres
= create_doc_uri(window
, uri
, &nsuri
);
391 if(SUCCEEDED(hres
)) {
393 bscallback
= async_bsc
;
395 hres
= create_channelbsc(mon
, NULL
, NULL
, 0, TRUE
, &bscallback
);
398 if(SUCCEEDED(hres
)) {
399 if(window
->base
.inner_window
->doc
)
400 remove_target_tasks(window
->base
.inner_window
->task_magic
);
401 abort_window_bindings(window
->base
.inner_window
);
403 hres
= load_nsuri(window
, nsuri
, NULL
, bscallback
, LOAD_FLAGS_BYPASS_CACHE
);
404 nsISupports_Release((nsISupports
*)nsuri
); /* FIXME */
405 if(SUCCEEDED(hres
)) {
406 hres
= create_pending_window(window
, bscallback
);
407 TRACE("pending window for %p %p %p\n", window
, bscallback
, window
->pending_window
);
409 if(bscallback
!= async_bsc
)
410 IBindStatusCallback_Release(&bscallback
->bsc
.IBindStatusCallback_iface
);
419 HTMLDocument_LockContainer(doc_obj
, TRUE
);
424 task
= heap_alloc(sizeof(docobj_task_t
));
426 hres
= push_task(&task
->header
, set_progress_proc
, NULL
, doc_obj
->basedoc
.task_magic
);
433 download_task
= heap_alloc(sizeof(download_proc_task_t
));
434 download_task
->doc
= doc_obj
;
435 download_task
->set_download
= set_download
;
436 download_task
->url
= url
;
437 return push_task(&download_task
->header
, set_downloading_proc
, set_downloading_task_destr
, doc_obj
->basedoc
.task_magic
);
443 static void notif_readystate(HTMLOuterWindow
*window
)
445 window
->readystate_pending
= FALSE
;
447 if(window
->doc_obj
&& window
->doc_obj
->basedoc
.window
== window
)
448 call_property_onchanged(&window
->doc_obj
->basedoc
.cp_container
, DISPID_READYSTATE
);
450 fire_event(window
->base
.inner_window
->doc
, EVENTID_READYSTATECHANGE
, FALSE
,
451 &window
->base
.inner_window
->doc
->node
, NULL
, NULL
);
453 if(window
->frame_element
)
454 fire_event(window
->frame_element
->element
.node
.doc
, EVENTID_READYSTATECHANGE
,
455 TRUE
, &window
->frame_element
->element
.node
, NULL
, NULL
);
460 HTMLOuterWindow
*window
;
463 static void notif_readystate_proc(task_t
*_task
)
465 readystate_task_t
*task
= (readystate_task_t
*)_task
;
466 notif_readystate(task
->window
);
469 static void notif_readystate_destr(task_t
*_task
)
471 readystate_task_t
*task
= (readystate_task_t
*)_task
;
472 IHTMLWindow2_Release(&task
->window
->base
.IHTMLWindow2_iface
);
475 void set_ready_state(HTMLOuterWindow
*window
, READYSTATE readystate
)
477 READYSTATE prev_state
= window
->readystate
;
479 window
->readystate
= readystate
;
481 if(window
->readystate_locked
) {
482 readystate_task_t
*task
;
485 if(window
->readystate_pending
|| prev_state
== readystate
)
488 task
= heap_alloc(sizeof(*task
));
492 IHTMLWindow2_AddRef(&window
->base
.IHTMLWindow2_iface
);
493 task
->window
= window
;
495 hres
= push_task(&task
->header
, notif_readystate_proc
, notif_readystate_destr
, window
->task_magic
);
497 window
->readystate_pending
= TRUE
;
501 notif_readystate(window
);
504 static HRESULT
get_doc_string(HTMLDocumentNode
*This
, char **str
)
513 WARN("NULL nsdoc\n");
517 nsres
= nsIDOMHTMLDocument_QueryInterface(This
->nsdoc
, &IID_nsIDOMNode
, (void**)&nsnode
);
518 if(NS_FAILED(nsres
)) {
519 ERR("Could not get nsIDOMNode failed: %08x\n", nsres
);
523 nsAString_Init(&nsstr
, NULL
);
524 hres
= nsnode_to_nsstring(nsnode
, &nsstr
);
525 nsIDOMNode_Release(nsnode
);
527 nsAString_Finish(&nsstr
);
531 nsAString_GetData(&nsstr
, &strw
);
532 TRACE("%s\n", debugstr_w(strw
));
534 *str
= heap_strdupWtoA(strw
);
536 nsAString_Finish(&nsstr
);
539 return E_OUTOFMEMORY
;
544 /**********************************************************
545 * IPersistMoniker implementation
548 static inline HTMLDocument
*impl_from_IPersistMoniker(IPersistMoniker
*iface
)
550 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistMoniker_iface
);
553 static HRESULT WINAPI
PersistMoniker_QueryInterface(IPersistMoniker
*iface
, REFIID riid
, void **ppv
)
555 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
556 return htmldoc_query_interface(This
, riid
, ppv
);
559 static ULONG WINAPI
PersistMoniker_AddRef(IPersistMoniker
*iface
)
561 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
562 return htmldoc_addref(This
);
565 static ULONG WINAPI
PersistMoniker_Release(IPersistMoniker
*iface
)
567 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
568 return htmldoc_release(This
);
571 static HRESULT WINAPI
PersistMoniker_GetClassID(IPersistMoniker
*iface
, CLSID
*pClassID
)
573 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
574 return IPersistFile_GetClassID(&This
->IPersistFile_iface
, pClassID
);
577 static HRESULT WINAPI
PersistMoniker_IsDirty(IPersistMoniker
*iface
)
579 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
581 TRACE("(%p)\n", This
);
583 return IPersistStreamInit_IsDirty(&This
->IPersistStreamInit_iface
);
586 static HRESULT WINAPI
PersistMoniker_Load(IPersistMoniker
*iface
, BOOL fFullyAvailable
,
587 IMoniker
*pimkName
, LPBC pibc
, DWORD grfMode
)
589 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
592 TRACE("(%p)->(%x %p %p %08x)\n", This
, fFullyAvailable
, pimkName
, pibc
, grfMode
);
595 IUnknown
*unk
= NULL
;
599 * "__PrecreatedObject"
600 * "BIND_CONTEXT_PARAM"
601 * "__HTMLLOADOPTIONS"
604 * "_ITransData_Object_"
608 hres
= IBindCtx_GetObjectParam(pibc
, (LPOLESTR
)SZ_HTML_CLIENTSITE_OBJECTPARAM
, &unk
);
609 if(SUCCEEDED(hres
) && unk
) {
610 IOleClientSite
*client
= NULL
;
612 hres
= IUnknown_QueryInterface(unk
, &IID_IOleClientSite
, (void**)&client
);
613 if(SUCCEEDED(hres
)) {
614 TRACE("Got client site %p\n", client
);
615 IOleObject_SetClientSite(&This
->IOleObject_iface
, client
);
616 IOleClientSite_Release(client
);
619 IUnknown_Release(unk
);
623 prepare_for_binding(This
, pimkName
, FALSE
);
624 call_docview_84(This
->doc_obj
);
625 hres
= set_moniker(This
->window
, pimkName
, NULL
, pibc
, NULL
, TRUE
);
629 return start_binding(This
->window
->pending_window
, (BSCallback
*)This
->window
->pending_window
->bscallback
, pibc
);
632 static HRESULT WINAPI
PersistMoniker_Save(IPersistMoniker
*iface
, IMoniker
*pimkName
,
633 LPBC pbc
, BOOL fRemember
)
635 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
636 FIXME("(%p)->(%p %p %x)\n", This
, pimkName
, pbc
, fRemember
);
640 static HRESULT WINAPI
PersistMoniker_SaveCompleted(IPersistMoniker
*iface
, IMoniker
*pimkName
, LPBC pibc
)
642 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
643 FIXME("(%p)->(%p %p)\n", This
, pimkName
, pibc
);
647 static HRESULT WINAPI
PersistMoniker_GetCurMoniker(IPersistMoniker
*iface
, IMoniker
**ppimkName
)
649 HTMLDocument
*This
= impl_from_IPersistMoniker(iface
);
651 TRACE("(%p)->(%p)\n", This
, ppimkName
);
653 if(!This
->window
|| !This
->window
->mon
)
656 IMoniker_AddRef(This
->window
->mon
);
657 *ppimkName
= This
->window
->mon
;
661 static const IPersistMonikerVtbl PersistMonikerVtbl
= {
662 PersistMoniker_QueryInterface
,
663 PersistMoniker_AddRef
,
664 PersistMoniker_Release
,
665 PersistMoniker_GetClassID
,
666 PersistMoniker_IsDirty
,
669 PersistMoniker_SaveCompleted
,
670 PersistMoniker_GetCurMoniker
673 /**********************************************************
674 * IMonikerProp implementation
677 static inline HTMLDocument
*impl_from_IMonikerProp(IMonikerProp
*iface
)
679 return CONTAINING_RECORD(iface
, HTMLDocument
, IMonikerProp_iface
);
682 static HRESULT WINAPI
MonikerProp_QueryInterface(IMonikerProp
*iface
, REFIID riid
, void **ppv
)
684 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
685 return htmldoc_query_interface(This
, riid
, ppv
);
688 static ULONG WINAPI
MonikerProp_AddRef(IMonikerProp
*iface
)
690 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
691 return htmldoc_addref(This
);
694 static ULONG WINAPI
MonikerProp_Release(IMonikerProp
*iface
)
696 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
697 return htmldoc_release(This
);
700 static HRESULT WINAPI
MonikerProp_PutProperty(IMonikerProp
*iface
, MONIKERPROPERTY mkp
, LPCWSTR val
)
702 HTMLDocument
*This
= impl_from_IMonikerProp(iface
);
704 TRACE("(%p)->(%d %s)\n", This
, mkp
, debugstr_w(val
));
708 heap_free(This
->doc_obj
->mime
);
709 This
->doc_obj
->mime
= heap_strdupW(val
);
716 FIXME("mkp %d\n", mkp
);
723 static const IMonikerPropVtbl MonikerPropVtbl
= {
724 MonikerProp_QueryInterface
,
727 MonikerProp_PutProperty
730 /**********************************************************
731 * IPersistFile implementation
734 static inline HTMLDocument
*impl_from_IPersistFile(IPersistFile
*iface
)
736 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistFile_iface
);
739 static HRESULT WINAPI
PersistFile_QueryInterface(IPersistFile
*iface
, REFIID riid
, void **ppv
)
741 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
742 return htmldoc_query_interface(This
, riid
, ppv
);
745 static ULONG WINAPI
PersistFile_AddRef(IPersistFile
*iface
)
747 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
748 return htmldoc_addref(This
);
751 static ULONG WINAPI
PersistFile_Release(IPersistFile
*iface
)
753 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
754 return htmldoc_release(This
);
757 static HRESULT WINAPI
PersistFile_GetClassID(IPersistFile
*iface
, CLSID
*pClassID
)
759 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
761 TRACE("(%p)->(%p)\n", This
, pClassID
);
766 *pClassID
= CLSID_HTMLDocument
;
770 static HRESULT WINAPI
PersistFile_IsDirty(IPersistFile
*iface
)
772 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
774 TRACE("(%p)\n", This
);
776 return IPersistStreamInit_IsDirty(&This
->IPersistStreamInit_iface
);
779 static HRESULT WINAPI
PersistFile_Load(IPersistFile
*iface
, LPCOLESTR pszFileName
, DWORD dwMode
)
781 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
782 FIXME("(%p)->(%s %08x)\n", This
, debugstr_w(pszFileName
), dwMode
);
786 static HRESULT WINAPI
PersistFile_Save(IPersistFile
*iface
, LPCOLESTR pszFileName
, BOOL fRemember
)
788 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
794 TRACE("(%p)->(%s %x)\n", This
, debugstr_w(pszFileName
), fRemember
);
796 file
= CreateFileW(pszFileName
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
797 FILE_ATTRIBUTE_NORMAL
, NULL
);
798 if(file
== INVALID_HANDLE_VALUE
) {
799 WARN("Could not create file: %u\n", GetLastError());
803 hres
= get_doc_string(This
->doc_node
, &str
);
805 WriteFile(file
, str
, strlen(str
), &written
, NULL
);
811 static HRESULT WINAPI
PersistFile_SaveCompleted(IPersistFile
*iface
, LPCOLESTR pszFileName
)
813 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
814 FIXME("(%p)->(%s)\n", This
, debugstr_w(pszFileName
));
818 static HRESULT WINAPI
PersistFile_GetCurFile(IPersistFile
*iface
, LPOLESTR
*pszFileName
)
820 HTMLDocument
*This
= impl_from_IPersistFile(iface
);
821 FIXME("(%p)->(%p)\n", This
, pszFileName
);
825 static const IPersistFileVtbl PersistFileVtbl
= {
826 PersistFile_QueryInterface
,
829 PersistFile_GetClassID
,
833 PersistFile_SaveCompleted
,
834 PersistFile_GetCurFile
837 static inline HTMLDocument
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
839 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistStreamInit_iface
);
842 static HRESULT WINAPI
PersistStreamInit_QueryInterface(IPersistStreamInit
*iface
,
843 REFIID riid
, void **ppv
)
845 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
846 return htmldoc_query_interface(This
, riid
, ppv
);
849 static ULONG WINAPI
PersistStreamInit_AddRef(IPersistStreamInit
*iface
)
851 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
852 return htmldoc_addref(This
);
855 static ULONG WINAPI
PersistStreamInit_Release(IPersistStreamInit
*iface
)
857 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
858 return htmldoc_release(This
);
861 static HRESULT WINAPI
PersistStreamInit_GetClassID(IPersistStreamInit
*iface
, CLSID
*pClassID
)
863 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
864 return IPersistFile_GetClassID(&This
->IPersistFile_iface
, pClassID
);
867 static HRESULT WINAPI
PersistStreamInit_IsDirty(IPersistStreamInit
*iface
)
869 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
871 TRACE("(%p)\n", This
);
873 if(This
->doc_obj
->usermode
== EDITMODE
)
874 return editor_is_dirty(This
);
879 static HRESULT WINAPI
PersistStreamInit_Load(IPersistStreamInit
*iface
, IStream
*pStm
)
881 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
885 TRACE("(%p)->(%p)\n", This
, pStm
);
887 hres
= CreateURLMoniker(NULL
, about_blankW
, &mon
);
889 WARN("CreateURLMoniker failed: %08x\n", hres
);
893 prepare_for_binding(This
, mon
, FALSE
);
894 hres
= set_moniker(This
->window
, mon
, NULL
, NULL
, NULL
, TRUE
);
898 hres
= channelbsc_load_stream(This
->window
->pending_window
, mon
, pStm
);
899 IMoniker_Release(mon
);
903 static HRESULT WINAPI
PersistStreamInit_Save(IPersistStreamInit
*iface
, IStream
*pStm
,
906 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
911 TRACE("(%p)->(%p %x)\n", This
, pStm
, fClearDirty
);
913 hres
= get_doc_string(This
->doc_node
, &str
);
917 hres
= IStream_Write(pStm
, str
, strlen(str
), &written
);
919 FIXME("Write failed: %08x\n", hres
);
924 set_dirty(This
, VARIANT_FALSE
);
929 static HRESULT WINAPI
PersistStreamInit_GetSizeMax(IPersistStreamInit
*iface
,
930 ULARGE_INTEGER
*pcbSize
)
932 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
933 FIXME("(%p)->(%p)\n", This
, pcbSize
);
937 static HRESULT WINAPI
PersistStreamInit_InitNew(IPersistStreamInit
*iface
)
939 HTMLDocument
*This
= impl_from_IPersistStreamInit(iface
);
943 TRACE("(%p)\n", This
);
945 hres
= CreateURLMoniker(NULL
, about_blankW
, &mon
);
947 WARN("CreateURLMoniker failed: %08x\n", hres
);
951 prepare_for_binding(This
, mon
, FALSE
);
952 hres
= set_moniker(This
->window
, mon
, NULL
, NULL
, NULL
, FALSE
);
956 hres
= channelbsc_load_stream(This
->window
->pending_window
, mon
, NULL
);
957 IMoniker_Release(mon
);
961 static const IPersistStreamInitVtbl PersistStreamInitVtbl
= {
962 PersistStreamInit_QueryInterface
,
963 PersistStreamInit_AddRef
,
964 PersistStreamInit_Release
,
965 PersistStreamInit_GetClassID
,
966 PersistStreamInit_IsDirty
,
967 PersistStreamInit_Load
,
968 PersistStreamInit_Save
,
969 PersistStreamInit_GetSizeMax
,
970 PersistStreamInit_InitNew
973 /**********************************************************
974 * IPersistHistory implementation
977 static inline HTMLDocument
*impl_from_IPersistHistory(IPersistHistory
*iface
)
979 return CONTAINING_RECORD(iface
, HTMLDocument
, IPersistHistory_iface
);
982 static HRESULT WINAPI
PersistHistory_QueryInterface(IPersistHistory
*iface
, REFIID riid
, void **ppv
)
984 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
985 return htmldoc_query_interface(This
, riid
, ppv
);
988 static ULONG WINAPI
PersistHistory_AddRef(IPersistHistory
*iface
)
990 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
991 return htmldoc_addref(This
);
994 static ULONG WINAPI
PersistHistory_Release(IPersistHistory
*iface
)
996 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
997 return htmldoc_release(This
);
1000 static HRESULT WINAPI
PersistHistory_GetClassID(IPersistHistory
*iface
, CLSID
*pClassID
)
1002 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1003 return IPersistFile_GetClassID(&This
->IPersistFile_iface
, pClassID
);
1006 static HRESULT WINAPI
PersistHistory_LoadHistory(IPersistHistory
*iface
, IStream
*pStream
, IBindCtx
*pbc
)
1008 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1009 ULONG str_len
, read
;
1014 TRACE("(%p)->(%p %p)\n", This
, pStream
, pbc
);
1017 FIXME("No current window\n");
1018 return E_UNEXPECTED
;
1022 FIXME("pbc not supported\n");
1024 if(This
->doc_obj
->client
) {
1025 IOleCommandTarget
*cmdtrg
= NULL
;
1027 hres
= IOleClientSite_QueryInterface(This
->doc_obj
->client
, &IID_IOleCommandTarget
,
1029 if(SUCCEEDED(hres
)) {
1030 IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 138, 0, NULL
, NULL
);
1031 IOleCommandTarget_Release(cmdtrg
);
1035 hres
= IStream_Read(pStream
, &str_len
, sizeof(str_len
), &read
);
1038 if(read
!= sizeof(str_len
))
1041 uri_str
= heap_alloc((str_len
+1)*sizeof(WCHAR
));
1043 return E_OUTOFMEMORY
;
1045 hres
= IStream_Read(pStream
, uri_str
, str_len
*sizeof(WCHAR
), &read
);
1046 if(SUCCEEDED(hres
) && read
!= str_len
*sizeof(WCHAR
))
1048 if(SUCCEEDED(hres
)) {
1049 uri_str
[str_len
] = 0;
1050 hres
= create_uri(uri_str
, 0, &uri
);
1056 hres
= load_uri(This
->window
, uri
, BINDING_FROMHIST
);
1061 static HRESULT WINAPI
PersistHistory_SaveHistory(IPersistHistory
*iface
, IStream
*pStream
)
1063 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1068 TRACE("(%p)->(%p)\n", This
, pStream
);
1070 if(!This
->window
|| !This
->window
->uri
) {
1071 FIXME("No current URI\n");
1075 /* NOTE: The format we store is *not* compatible with native MSHTML. We currently
1076 * store only URI of the page (as a length followed by a string) */
1077 hres
= IUri_GetDisplayUri(This
->window
->uri
, &display_uri
);
1081 len
= SysStringLen(display_uri
);
1082 hres
= IStream_Write(pStream
, &len
, sizeof(len
), &written
);
1084 hres
= IStream_Write(pStream
, display_uri
, len
*sizeof(WCHAR
), &written
);
1085 SysFreeString(display_uri
);
1089 static HRESULT WINAPI
PersistHistory_SetPositionCookie(IPersistHistory
*iface
, DWORD dwPositioncookie
)
1091 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1092 FIXME("(%p)->(%x)\n", This
, dwPositioncookie
);
1096 static HRESULT WINAPI
PersistHistory_GetPositionCookie(IPersistHistory
*iface
, DWORD
*pdwPositioncookie
)
1098 HTMLDocument
*This
= impl_from_IPersistHistory(iface
);
1099 FIXME("(%p)->(%p)\n", This
, pdwPositioncookie
);
1103 static const IPersistHistoryVtbl PersistHistoryVtbl
= {
1104 PersistHistory_QueryInterface
,
1105 PersistHistory_AddRef
,
1106 PersistHistory_Release
,
1107 PersistHistory_GetClassID
,
1108 PersistHistory_LoadHistory
,
1109 PersistHistory_SaveHistory
,
1110 PersistHistory_SetPositionCookie
,
1111 PersistHistory_GetPositionCookie
1114 void HTMLDocument_Persist_Init(HTMLDocument
*This
)
1116 This
->IPersistMoniker_iface
.lpVtbl
= &PersistMonikerVtbl
;
1117 This
->IPersistFile_iface
.lpVtbl
= &PersistFileVtbl
;
1118 This
->IMonikerProp_iface
.lpVtbl
= &MonikerPropVtbl
;
1119 This
->IPersistStreamInit_iface
.lpVtbl
= &PersistStreamInitVtbl
;
1120 This
->IPersistHistory_iface
.lpVtbl
= &PersistHistoryVtbl
;