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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
34 #include "wine/debug.h"
36 #include "mshtml_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
40 struct BindStatusCallback
{
41 const IBindStatusCallbackVtbl
*lpBindStatusCallbackVtbl
;
51 #define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface)
53 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallback
*iface
,
54 REFIID riid
, void **ppv
)
56 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
59 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
60 TRACE("(%p)->(IID_IUnknown, %p)\n", This
, ppv
);
61 *ppv
= STATUSCLB(This
);
62 }else if(IsEqualGUID(&IID_IBindStatusCallback
, riid
)) {
63 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This
, ppv
);
64 *ppv
= STATUSCLB(This
);
68 IBindStatusCallback_AddRef(STATUSCLB(This
));
72 TRACE("Unsupported riid = %s\n", debugstr_guid(riid
));
76 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallback
*iface
)
78 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
79 LONG ref
= InterlockedIncrement(&This
->ref
);
81 TRACE("(%p) ref = %ld\n", This
, ref
);
86 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallback
*iface
)
88 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
89 LONG ref
= InterlockedDecrement(&This
->ref
);
91 TRACE("(%p) ref = %ld\n", This
, ref
);
94 if(This
->doc
->status_callback
== This
)
95 This
->doc
->status_callback
= NULL
;
96 IHTMLDocument2_Release(HTMLDOC(This
->doc
));
98 IStream_Release(This
->stream
);
99 CoTaskMemFree(This
->url
);
100 HeapFree(GetProcessHeap(), 0, This
);
106 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
,
107 DWORD dwReserved
, IBinding
*pbind
)
109 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
111 TRACE("(%p)->(%ld %p)\n", This
, dwReserved
, pbind
);
113 This
->binding
= pbind
;
114 IBinding_AddRef(pbind
);
116 if(This
->doc
->nscontainer
&& This
->doc
->nscontainer
->stream
) {
117 nsACString
*strTextHtml
;
119 nsIURI
*uri
= get_nsIURI(This
->url
);
121 strTextHtml
= nsACString_Create();
122 /* FIXME: Set it correctly */
123 nsACString_SetData(strTextHtml
, "text/html");
125 nsres
= nsIWebBrowserStream_OpenStream(This
->doc
->nscontainer
->stream
, uri
, strTextHtml
);
127 ERR("OpenStream failed: %08lx\n", nsres
);
135 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallback
*iface
, LONG
*pnPriority
)
137 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
138 FIXME("(%p)->(%p)\n", This
, pnPriority
);
142 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallback
*iface
, DWORD reserved
)
144 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
145 FIXME("(%p)->(%ld)\n", This
, reserved
);
149 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallback
*iface
, ULONG ulProgress
,
150 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
152 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
153 TRACE("%p)->(%lu %lu %lu %s)\n", This
, ulProgress
, ulProgressMax
, ulStatusCode
,
154 debugstr_w(szStatusText
));
158 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
,
159 HRESULT hresult
, LPCWSTR szError
)
161 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
163 TRACE("(%p)->(%08lx %s)\n", This
, hresult
, debugstr_w(szError
));
165 if(This
->doc
->nscontainer
&& This
->doc
->nscontainer
->stream
)
166 nsIWebBrowserStream_CloseStream(This
->doc
->nscontainer
->stream
);
168 IBinding_Release(This
->binding
);
169 This
->binding
= NULL
;
173 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
,
174 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
176 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
179 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
181 *grfBINDF
= BINDF_ASYNCHRONOUS
| BINDF_ASYNCSTORAGE
| BINDF_PULLDATA
;
182 size
= pbindinfo
->cbSize
;
183 memset(pbindinfo
, 0, size
);
184 pbindinfo
->cbSize
= size
;
189 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
,
190 DWORD grfBSCF
, DWORD dwSize
, FORMATETC
*pformatetc
, STGMEDIUM
*pstgmed
)
192 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
194 TRACE("(%p)->(%08lx %ld %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
197 This
->stream
= pstgmed
->u
.pstm
;
198 IStream_AddRef(This
->stream
);
201 if(This
->doc
->nscontainer
&& This
->doc
->nscontainer
->stream
) {
208 hres
= IStream_Read(This
->stream
, buf
, size
, &size
);
209 nsIWebBrowserStream_AppendToStream(This
->doc
->nscontainer
->stream
, buf
, size
);
210 }while(hres
== S_OK
);
216 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
,
217 REFIID riid
, IUnknown
*punk
)
219 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
220 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), punk
);
224 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl
= {
225 BindStatusCallback_QueryInterface
,
226 BindStatusCallback_AddRef
,
227 BindStatusCallback_Release
,
228 BindStatusCallback_OnStartBinding
,
229 BindStatusCallback_GetPriority
,
230 BindStatusCallback_OnLowResource
,
231 BindStatusCallback_OnProgress
,
232 BindStatusCallback_OnStopBinding
,
233 BindStatusCallback_GetBindInfo
,
234 BindStatusCallback_OnDataAvailable
,
235 BindStatusCallback_OnObjectAvailable
238 static BindStatusCallback
*BindStatusCallback_Create(HTMLDocument
*doc
, LPOLESTR url
)
240 BindStatusCallback
*ret
= HeapAlloc(GetProcessHeap(), 0, sizeof(BindStatusCallback
));
241 ret
->lpBindStatusCallbackVtbl
= &BindStatusCallbackVtbl
;
246 IHTMLDocument2_AddRef(HTMLDOC(doc
));
250 /**********************************************************
251 * IPersistMoniker implementation
254 #define PERSISTMON_THIS(iface) DEFINE_THIS(HTMLDocument, PersistMoniker, iface)
256 static HRESULT WINAPI
PersistMoniker_QueryInterface(IPersistMoniker
*iface
, REFIID riid
,
259 HTMLDocument
*This
= PERSISTMON_THIS(iface
);
260 return IHTMLDocument2_QueryInterface(HTMLDOC(This
), riid
, ppvObject
);
263 static ULONG WINAPI
PersistMoniker_AddRef(IPersistMoniker
*iface
)
265 HTMLDocument
*This
= PERSISTMON_THIS(iface
);
266 return IHTMLDocument2_AddRef(HTMLDOC(This
));
269 static ULONG WINAPI
PersistMoniker_Release(IPersistMoniker
*iface
)
271 HTMLDocument
*This
= PERSISTMON_THIS(iface
);
272 return IHTMLDocument2_Release(HTMLDOC(This
));
275 static HRESULT WINAPI
PersistMoniker_GetClassID(IPersistMoniker
*iface
, CLSID
*pClassID
)
277 HTMLDocument
*This
= PERSISTMON_THIS(iface
);
278 return IPersist_GetClassID(PERSIST(This
), pClassID
);
281 static HRESULT WINAPI
PersistMoniker_IsDirty(IPersistMoniker
*iface
)
283 HTMLDocument
*This
= PERSISTMON_THIS(iface
);
284 FIXME("(%p)\n", This
);
288 static HRESULT WINAPI
PersistMoniker_Load(IPersistMoniker
*iface
, BOOL fFullyAvailable
,
289 IMoniker
*pimkName
, LPBC pibc
, DWORD grfMode
)
291 HTMLDocument
*This
= PERSISTMON_THIS(iface
);
293 BindStatusCallback
*callback
;
299 TRACE("(%p)->(%x %p %p %08lx)\n", This
, fFullyAvailable
, pimkName
, pibc
, grfMode
);
302 IUnknown
*unk
= NULL
;
304 static WCHAR wszClientSiteParam
[] = {'{','d','4','d','b','6','8','5','0','-',
305 '5','3','8','5','-','1','1','d','0','-','8','9','e','9','-','0','0','a',
306 '0','c','9','0','a','9','0','a','c','}',0};
310 * "__PrecreatedObject"
311 * "BIND_CONTEXT_PARAM"
312 * "__HTMLLOADOPTIONS"
316 * "_ITransData_Object_"
320 IBindCtx_GetObjectParam(pibc
, wszClientSiteParam
, &unk
);
322 IOleClientSite
*client
= NULL
;
324 hres
= IUnknown_QueryInterface(unk
, &IID_IOleClientSite
, (void**)&client
);
325 if(SUCCEEDED(hres
)) {
326 TRACE("Got client site %p\n", client
);
327 IOleObject_SetClientSite(OLEOBJ(This
), client
);
328 IOleClientSite_Release(client
);
331 IUnknown_Release(unk
);
335 HTMLDocument_LockContainer(This
, TRUE
);
337 hres
= IMoniker_GetDisplayName(pimkName
, pibc
, NULL
, &url
);
339 WARN("GetDiaplayName failed: %08lx\n", hres
);
343 TRACE("got url: %s\n", debugstr_w(url
));
346 IOleCommandTarget
*cmdtrg
= NULL
;
348 hres
= IOleClientSite_QueryInterface(This
->client
, &IID_IOleCommandTarget
,
350 if(SUCCEEDED(hres
)) {
355 IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 37, 0, &var
, NULL
);
359 if(This
->nscontainer
&& !This
->nscontainer
->stream
) {
361 * This is a workaround for older Gecko that doesn't support nsIWebBrowserStream.
362 * It uses Gecko's LoadURI instead of IMoniker's BindToStorage. Should we improve
363 * it (to do so we'd have to use not frozen interfaces)?
365 LPOLESTR old_url
= This
->nscontainer
->url
;
367 This
->nscontainer
->url
= url
;
368 nsres
= nsIWebNavigation_LoadURI(This
->nscontainer
->navigation
, url
,
369 LOAD_FLAGS_NONE
, NULL
, NULL
, NULL
);
370 if(NS_SUCCEEDED(nsres
)) {
371 CoTaskMemFree(old_url
);
374 WARN("LoadURI failed: %08lx\n", nsres
);
375 This
->nscontainer
->url
= old_url
;
379 /* FIXME: Use grfMode */
382 FIXME("not supported fFullyAvailable\n");
384 if(This
->status_callback
&& This
->status_callback
->binding
)
385 IBinding_Abort(This
->status_callback
->binding
);
387 callback
= This
->status_callback
= BindStatusCallback_Create(This
, url
);
391 RegisterBindStatusCallback(pbind
, STATUSCLB(callback
), NULL
, 0);
393 CreateAsyncBindCtx(0, STATUSCLB(callback
), NULL
, &pbind
);
396 hres
= IMoniker_BindToStorage(pimkName
, pbind
, NULL
, &IID_IStream
, (void**)&str
);
399 IBindCtx_Release(pbind
);
401 IStream_Release(str
);
403 WARN("BindToStorage failed: %08lx\n", hres
);
410 static HRESULT WINAPI
PersistMoniker_Save(IPersistMoniker
*iface
, IMoniker
*pimkName
,
411 LPBC pbc
, BOOL fRemember
)
413 HTMLDocument
*This
= PERSISTMON_THIS(iface
);
414 FIXME("(%p)->(%p %p %x)\n", This
, pimkName
, pbc
, fRemember
);
418 static HRESULT WINAPI
PersistMoniker_SaveCompleted(IPersistMoniker
*iface
, IMoniker
*pimkName
, LPBC pibc
)
420 HTMLDocument
*This
= PERSISTMON_THIS(iface
);
421 FIXME("(%p)->(%p %p)\n", This
, pimkName
, pibc
);
425 static HRESULT WINAPI
PersistMoniker_GetCurMoniker(IPersistMoniker
*iface
, IMoniker
**ppimkName
)
427 HTMLDocument
*This
= PERSISTMON_THIS(iface
);
428 FIXME("(%p)->(%p)\n", This
, ppimkName
);
432 static const IPersistMonikerVtbl PersistMonikerVtbl
= {
433 PersistMoniker_QueryInterface
,
434 PersistMoniker_AddRef
,
435 PersistMoniker_Release
,
436 PersistMoniker_GetClassID
,
437 PersistMoniker_IsDirty
,
440 PersistMoniker_SaveCompleted
,
441 PersistMoniker_GetCurMoniker
444 /**********************************************************
445 * IMonikerProp implementation
448 #define MONPROP_THIS(iface) DEFINE_THIS(HTMLDocument, MonikerProp, iface)
450 static HRESULT WINAPI
MonikerProp_QueryInterface(IMonikerProp
*iface
, REFIID riid
, void **ppvObject
)
452 HTMLDocument
*This
= MONPROP_THIS(iface
);
453 return IHTMLDocument2_QueryInterface(HTMLDOC(This
), riid
, ppvObject
);
456 static ULONG WINAPI
MonikerProp_AddRef(IMonikerProp
*iface
)
458 HTMLDocument
*This
= MONPROP_THIS(iface
);
459 return IHTMLDocument2_AddRef(HTMLDOC(This
));
462 static ULONG WINAPI
MonikerProp_Release(IMonikerProp
*iface
)
464 HTMLDocument
*This
= MONPROP_THIS(iface
);
465 return IHTMLDocument_Release(HTMLDOC(This
));
468 static HRESULT WINAPI
MonikerProp_PutProperty(IMonikerProp
*iface
, MONIKERPROPERTY mkp
, LPCWSTR val
)
470 HTMLDocument
*This
= MONPROP_THIS(iface
);
471 FIXME("(%p)->(%d %s)\n", This
, mkp
, debugstr_w(val
));
475 static const IMonikerPropVtbl MonikerPropVtbl
= {
476 MonikerProp_QueryInterface
,
479 MonikerProp_PutProperty
482 /**********************************************************
483 * IPersistFile implementation
486 #define PERSISTFILE_THIS(iface) DEFINE_THIS(HTMLDocument, PersistFile, iface)
488 static HRESULT WINAPI
PersistFile_QueryInterface(IPersistFile
*iface
, REFIID riid
, void **ppvObject
)
490 HTMLDocument
*This
= PERSISTFILE_THIS(iface
);
491 return IHTMLDocument2_QueryInterface(HTMLDOC(This
), riid
, ppvObject
);
494 static ULONG WINAPI
PersistFile_AddRef(IPersistFile
*iface
)
496 HTMLDocument
*This
= PERSISTFILE_THIS(iface
);
497 return IHTMLDocument2_AddRef(HTMLDOC(This
));
500 static ULONG WINAPI
PersistFile_Release(IPersistFile
*iface
)
502 HTMLDocument
*This
= PERSISTFILE_THIS(iface
);
503 return IHTMLDocument2_Release(HTMLDOC(This
));
506 static HRESULT WINAPI
PersistFile_GetClassID(IPersistFile
*iface
, CLSID
*pClassID
)
508 HTMLDocument
*This
= PERSISTFILE_THIS(iface
);
510 TRACE("(%p)->(%p)\n", This
, pClassID
);
515 memcpy(pClassID
, &CLSID_HTMLDocument
, sizeof(CLSID
));
519 static HRESULT WINAPI
PersistFile_IsDirty(IPersistFile
*iface
)
521 HTMLDocument
*This
= PERSISTFILE_THIS(iface
);
522 FIXME("(%p)\n", This
);
526 static HRESULT WINAPI
PersistFile_Load(IPersistFile
*iface
, LPCOLESTR pszFileName
, DWORD dwMode
)
528 HTMLDocument
*This
= PERSISTFILE_THIS(iface
);
529 FIXME("(%p)->(%s %08lx)\n", This
, debugstr_w(pszFileName
), dwMode
);
533 static HRESULT WINAPI
PersistFile_Save(IPersistFile
*iface
, LPCOLESTR pszFileName
, BOOL fRemember
)
535 HTMLDocument
*This
= PERSISTFILE_THIS(iface
);
536 FIXME("(%p)->(%s %x)\n", This
, debugstr_w(pszFileName
), fRemember
);
540 static HRESULT WINAPI
PersistFile_SaveCompleted(IPersistFile
*iface
, LPCOLESTR pszFileName
)
542 HTMLDocument
*This
= PERSISTFILE_THIS(iface
);
543 FIXME("(%p)->(%s)\n", This
, debugstr_w(pszFileName
));
547 static HRESULT WINAPI
PersistFile_GetCurFile(IPersistFile
*iface
, LPOLESTR
*pszFileName
)
549 HTMLDocument
*This
= PERSISTFILE_THIS(iface
);
550 FIXME("(%p)->(%p)\n", This
, pszFileName
);
554 static const IPersistFileVtbl PersistFileVtbl
= {
555 PersistFile_QueryInterface
,
558 PersistFile_GetClassID
,
562 PersistFile_SaveCompleted
,
563 PersistFile_GetCurFile
566 BOOL
HTMLDocument_OnLoad(HTMLDocument
*This
, LPCWSTR url
)
568 IOleCommandTarget
*cmdtrg
= NULL
;
571 TRACE("(%p)->(%s)\n", This
, debugstr_w(url
));
573 hres
= IOleClientSite_QueryInterface(This
->client
, &IID_IOleCommandTarget
, (void**)&cmdtrg
);
574 if(SUCCEEDED(hres
)) {
575 VARIANT varUrl
, varRes
;
577 V_VT(&varUrl
) = VT_BSTR
;
578 V_BSTR(&varUrl
) = SysAllocString(url
);
579 V_VT(&varRes
) = VT_BOOL
;
581 hres
= IOleCommandTarget_Exec(cmdtrg
, &CGID_ShellDocView
, 67, 0, &varUrl
, &varRes
);
582 SysFreeString(V_BSTR(&varUrl
));
584 if(SUCCEEDED(hres
) && !V_BOOL(&varRes
)) {
585 TRACE("got VARIANT_FALSE, do not load\n");
586 IOleCommandTarget_Release(cmdtrg
);
594 void HTMLDocument_Persist_Init(HTMLDocument
*This
)
596 This
->lpPersistMonikerVtbl
= &PersistMonikerVtbl
;
597 This
->lpPersistFileVtbl
= &PersistFileVtbl
;
598 This
->lpMonikerPropVtbl
= &MonikerPropVtbl
;
600 This
->status_callback
= NULL
;