msctf: Correct handling if NULL for pdimFocus in ITfThreadMgr::SetFocus.
[wine/multimedia.git] / dlls / mshtml / persist.c
blob6c1a0e5f3b739e24d0e990d3dc714c1c79af0634
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
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "ole2.h"
32 #include "shlguid.h"
33 #include "idispids.h"
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
38 #include "mshtml_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
42 static BOOL use_gecko_script(LPCWSTR url)
44 static const WCHAR fileW[] = {'f','i','l','e',':'};
45 return strncmpiW(fileW, url, sizeof(fileW)/sizeof(WCHAR));
48 void set_current_mon(HTMLDocument *This, IMoniker *mon)
50 HRESULT hres;
52 if(This->mon) {
53 IMoniker_Release(This->mon);
54 This->mon = NULL;
57 if(This->url) {
58 CoTaskMemFree(This->url);
59 This->url = NULL;
62 if(!mon)
63 return;
65 IMoniker_AddRef(mon);
66 This->mon = mon;
68 hres = IMoniker_GetDisplayName(mon, NULL, NULL, &This->url);
69 if(FAILED(hres))
70 WARN("GetDisplayName failed: %08x\n", hres);
72 set_script_mode(This, use_gecko_script(This->url) ? SCRIPTMODE_GECKO : SCRIPTMODE_ACTIVESCRIPT);
75 static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BOOL *bind_complete)
77 nsChannelBSC *bscallback;
78 LPOLESTR url = NULL;
79 task_t *task;
80 HRESULT hres;
81 nsresult nsres;
83 if(pibc) {
84 IUnknown *unk = NULL;
86 /* FIXME:
87 * Use params:
88 * "__PrecreatedObject"
89 * "BIND_CONTEXT_PARAM"
90 * "__HTMLLOADOPTIONS"
91 * "__DWNBINDINFO"
92 * "URL Context"
93 * "CBinding Context"
94 * "_ITransData_Object_"
95 * "_EnumFORMATETC_"
98 IBindCtx_GetObjectParam(pibc, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM, &unk);
99 if(unk) {
100 IOleClientSite *client = NULL;
102 hres = IUnknown_QueryInterface(unk, &IID_IOleClientSite, (void**)&client);
103 if(SUCCEEDED(hres)) {
104 TRACE("Got client site %p\n", client);
105 IOleObject_SetClientSite(OLEOBJ(This), client);
106 IOleClientSite_Release(client);
109 IUnknown_Release(unk);
113 This->readystate = READYSTATE_LOADING;
114 call_property_onchanged(&This->cp_propnotif, DISPID_READYSTATE);
115 update_doc(This, UPDATE_TITLE);
117 HTMLDocument_LockContainer(This, TRUE);
119 hres = IMoniker_GetDisplayName(mon, pibc, NULL, &url);
120 if(FAILED(hres)) {
121 WARN("GetDiaplayName failed: %08x\n", hres);
122 return hres;
125 TRACE("got url: %s\n", debugstr_w(url));
127 set_current_mon(This, mon);
129 if(This->client) {
130 VARIANT silent, offline;
131 IOleCommandTarget *cmdtrg = NULL;
133 hres = get_client_disp_property(This->client, DISPID_AMBIENT_SILENT, &silent);
134 if(SUCCEEDED(hres)) {
135 if(V_VT(&silent) != VT_BOOL)
136 WARN("V_VT(silent) = %d\n", V_VT(&silent));
137 else if(V_BOOL(&silent))
138 FIXME("silent == true\n");
141 hres = get_client_disp_property(This->client,
142 DISPID_AMBIENT_OFFLINEIFNOTCONNECTED, &offline);
143 if(SUCCEEDED(hres)) {
144 if(V_VT(&silent) != VT_BOOL)
145 WARN("V_VT(offline) = %d\n", V_VT(&silent));
146 else if(V_BOOL(&silent))
147 FIXME("offline == true\n");
150 hres = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget,
151 (void**)&cmdtrg);
152 if(SUCCEEDED(hres)) {
153 VARIANT var;
155 V_VT(&var) = VT_I4;
156 V_I4(&var) = 0;
157 IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 37, 0, &var, NULL);
159 IOleCommandTarget_Release(cmdtrg);
163 bscallback = create_channelbsc(mon);
165 if(This->frame) {
166 task = heap_alloc(sizeof(task_t));
168 task->doc = This;
169 task->task_id = TASK_SETPROGRESS;
170 task->next = NULL;
172 push_task(task);
175 task = heap_alloc(sizeof(task_t));
177 task->doc = This;
178 task->task_id = TASK_SETDOWNLOADSTATE;
179 task->next = NULL;
181 push_task(task);
183 if(This->nscontainer) {
184 This->nscontainer->bscallback = bscallback;
185 nsres = nsIWebNavigation_LoadURI(This->nscontainer->navigation, url,
186 LOAD_FLAGS_NONE, NULL, NULL, NULL);
187 This->nscontainer->bscallback = NULL;
188 if(NS_FAILED(nsres)) {
189 WARN("LoadURI failed: %08x\n", nsres);
190 IUnknown_Release((IUnknown*)bscallback);
191 CoTaskMemFree(url);
192 return E_FAIL;
196 set_document_bscallback(This, bscallback);
197 IUnknown_Release((IUnknown*)bscallback);
198 CoTaskMemFree(url);
200 if(bind_complete)
201 *bind_complete = FALSE;
202 return S_OK;
205 static HRESULT get_doc_string(HTMLDocument *This, char **str)
207 nsIDOMNode *nsnode;
208 LPCWSTR strw;
209 nsAString nsstr;
210 nsresult nsres;
212 if(!This->nsdoc) {
213 WARN("NULL nsdoc\n");
214 return E_UNEXPECTED;
217 nsres = nsIDOMHTMLDocument_QueryInterface(This->nsdoc, &IID_nsIDOMNode, (void**)&nsnode);
218 if(NS_FAILED(nsres)) {
219 ERR("Could not get nsIDOMNode failed: %08x\n", nsres);
220 return E_FAIL;
223 nsAString_Init(&nsstr, NULL);
224 nsnode_to_nsstring(nsnode, &nsstr);
225 nsIDOMNode_Release(nsnode);
227 nsAString_GetData(&nsstr, &strw);
228 TRACE("%s\n", debugstr_w(strw));
230 *str = heap_strdupWtoA(strw);
232 nsAString_Finish(&nsstr);
234 return S_OK;
238 /**********************************************************
239 * IPersistMoniker implementation
242 #define PERSISTMON_THIS(iface) DEFINE_THIS(HTMLDocument, PersistMoniker, iface)
244 static HRESULT WINAPI PersistMoniker_QueryInterface(IPersistMoniker *iface, REFIID riid,
245 void **ppvObject)
247 HTMLDocument *This = PERSISTMON_THIS(iface);
248 return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
251 static ULONG WINAPI PersistMoniker_AddRef(IPersistMoniker *iface)
253 HTMLDocument *This = PERSISTMON_THIS(iface);
254 return IHTMLDocument2_AddRef(HTMLDOC(This));
257 static ULONG WINAPI PersistMoniker_Release(IPersistMoniker *iface)
259 HTMLDocument *This = PERSISTMON_THIS(iface);
260 return IHTMLDocument2_Release(HTMLDOC(This));
263 static HRESULT WINAPI PersistMoniker_GetClassID(IPersistMoniker *iface, CLSID *pClassID)
265 HTMLDocument *This = PERSISTMON_THIS(iface);
266 return IPersist_GetClassID(PERSIST(This), pClassID);
269 static HRESULT WINAPI PersistMoniker_IsDirty(IPersistMoniker *iface)
271 HTMLDocument *This = PERSISTMON_THIS(iface);
273 TRACE("(%p)\n", This);
275 return IPersistStreamInit_IsDirty(PERSTRINIT(This));
278 static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAvailable,
279 IMoniker *pimkName, LPBC pibc, DWORD grfMode)
281 HTMLDocument *This = PERSISTMON_THIS(iface);
282 BOOL bind_complete = FALSE;
283 HRESULT hres;
285 TRACE("(%p)->(%x %p %p %08x)\n", This, fFullyAvailable, pimkName, pibc, grfMode);
287 hres = set_moniker(This, pimkName, pibc, &bind_complete);
288 if(FAILED(hres))
289 return hres;
291 if(!bind_complete)
292 return start_binding(This, (BSCallback*)This->bscallback, pibc);
294 return S_OK;
297 static HRESULT WINAPI PersistMoniker_Save(IPersistMoniker *iface, IMoniker *pimkName,
298 LPBC pbc, BOOL fRemember)
300 HTMLDocument *This = PERSISTMON_THIS(iface);
301 FIXME("(%p)->(%p %p %x)\n", This, pimkName, pbc, fRemember);
302 return E_NOTIMPL;
305 static HRESULT WINAPI PersistMoniker_SaveCompleted(IPersistMoniker *iface, IMoniker *pimkName, LPBC pibc)
307 HTMLDocument *This = PERSISTMON_THIS(iface);
308 FIXME("(%p)->(%p %p)\n", This, pimkName, pibc);
309 return E_NOTIMPL;
312 static HRESULT WINAPI PersistMoniker_GetCurMoniker(IPersistMoniker *iface, IMoniker **ppimkName)
314 HTMLDocument *This = PERSISTMON_THIS(iface);
316 TRACE("(%p)->(%p)\n", This, ppimkName);
318 if(!This->mon)
319 return E_UNEXPECTED;
321 IMoniker_AddRef(This->mon);
322 *ppimkName = This->mon;
323 return S_OK;
326 static const IPersistMonikerVtbl PersistMonikerVtbl = {
327 PersistMoniker_QueryInterface,
328 PersistMoniker_AddRef,
329 PersistMoniker_Release,
330 PersistMoniker_GetClassID,
331 PersistMoniker_IsDirty,
332 PersistMoniker_Load,
333 PersistMoniker_Save,
334 PersistMoniker_SaveCompleted,
335 PersistMoniker_GetCurMoniker
338 /**********************************************************
339 * IMonikerProp implementation
342 #define MONPROP_THIS(iface) DEFINE_THIS(HTMLDocument, MonikerProp, iface)
344 static HRESULT WINAPI MonikerProp_QueryInterface(IMonikerProp *iface, REFIID riid, void **ppvObject)
346 HTMLDocument *This = MONPROP_THIS(iface);
347 return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
350 static ULONG WINAPI MonikerProp_AddRef(IMonikerProp *iface)
352 HTMLDocument *This = MONPROP_THIS(iface);
353 return IHTMLDocument2_AddRef(HTMLDOC(This));
356 static ULONG WINAPI MonikerProp_Release(IMonikerProp *iface)
358 HTMLDocument *This = MONPROP_THIS(iface);
359 return IHTMLDocument_Release(HTMLDOC(This));
362 static HRESULT WINAPI MonikerProp_PutProperty(IMonikerProp *iface, MONIKERPROPERTY mkp, LPCWSTR val)
364 HTMLDocument *This = MONPROP_THIS(iface);
366 TRACE("(%p)->(%d %s)\n", This, mkp, debugstr_w(val));
368 switch(mkp) {
369 case MIMETYPEPROP:
370 heap_free(This->mime);
371 This->mime = heap_strdupW(val);
372 break;
374 case CLASSIDPROP:
375 break;
377 default:
378 FIXME("mkp %d\n", mkp);
379 return E_NOTIMPL;
382 return S_OK;
385 static const IMonikerPropVtbl MonikerPropVtbl = {
386 MonikerProp_QueryInterface,
387 MonikerProp_AddRef,
388 MonikerProp_Release,
389 MonikerProp_PutProperty
392 /**********************************************************
393 * IPersistFile implementation
396 #define PERSISTFILE_THIS(iface) DEFINE_THIS(HTMLDocument, PersistFile, iface)
398 static HRESULT WINAPI PersistFile_QueryInterface(IPersistFile *iface, REFIID riid, void **ppvObject)
400 HTMLDocument *This = PERSISTFILE_THIS(iface);
401 return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
404 static ULONG WINAPI PersistFile_AddRef(IPersistFile *iface)
406 HTMLDocument *This = PERSISTFILE_THIS(iface);
407 return IHTMLDocument2_AddRef(HTMLDOC(This));
410 static ULONG WINAPI PersistFile_Release(IPersistFile *iface)
412 HTMLDocument *This = PERSISTFILE_THIS(iface);
413 return IHTMLDocument2_Release(HTMLDOC(This));
416 static HRESULT WINAPI PersistFile_GetClassID(IPersistFile *iface, CLSID *pClassID)
418 HTMLDocument *This = PERSISTFILE_THIS(iface);
420 TRACE("(%p)->(%p)\n", This, pClassID);
422 if(!pClassID)
423 return E_INVALIDARG;
425 *pClassID = CLSID_HTMLDocument;
426 return S_OK;
429 static HRESULT WINAPI PersistFile_IsDirty(IPersistFile *iface)
431 HTMLDocument *This = PERSISTFILE_THIS(iface);
433 TRACE("(%p)\n", This);
435 return IPersistStreamInit_IsDirty(PERSTRINIT(This));
438 static HRESULT WINAPI PersistFile_Load(IPersistFile *iface, LPCOLESTR pszFileName, DWORD dwMode)
440 HTMLDocument *This = PERSISTFILE_THIS(iface);
441 FIXME("(%p)->(%s %08x)\n", This, debugstr_w(pszFileName), dwMode);
442 return E_NOTIMPL;
445 static HRESULT WINAPI PersistFile_Save(IPersistFile *iface, LPCOLESTR pszFileName, BOOL fRemember)
447 HTMLDocument *This = PERSISTFILE_THIS(iface);
448 char *str;
449 DWORD written=0;
450 HANDLE file;
451 HRESULT hres;
453 TRACE("(%p)->(%s %x)\n", This, debugstr_w(pszFileName), fRemember);
455 file = CreateFileW(pszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
456 FILE_ATTRIBUTE_NORMAL, NULL);
457 if(file == INVALID_HANDLE_VALUE) {
458 WARN("Could not create file: %u\n", GetLastError());
459 return E_FAIL;
462 hres = get_doc_string(This, &str);
463 if(SUCCEEDED(hres))
464 WriteFile(file, str, strlen(str), &written, NULL);
466 CloseHandle(file);
467 return hres;
470 static HRESULT WINAPI PersistFile_SaveCompleted(IPersistFile *iface, LPCOLESTR pszFileName)
472 HTMLDocument *This = PERSISTFILE_THIS(iface);
473 FIXME("(%p)->(%s)\n", This, debugstr_w(pszFileName));
474 return E_NOTIMPL;
477 static HRESULT WINAPI PersistFile_GetCurFile(IPersistFile *iface, LPOLESTR *pszFileName)
479 HTMLDocument *This = PERSISTFILE_THIS(iface);
480 FIXME("(%p)->(%p)\n", This, pszFileName);
481 return E_NOTIMPL;
484 static const IPersistFileVtbl PersistFileVtbl = {
485 PersistFile_QueryInterface,
486 PersistFile_AddRef,
487 PersistFile_Release,
488 PersistFile_GetClassID,
489 PersistFile_IsDirty,
490 PersistFile_Load,
491 PersistFile_Save,
492 PersistFile_SaveCompleted,
493 PersistFile_GetCurFile
496 #define PERSTRINIT_THIS(iface) DEFINE_THIS(HTMLDocument, PersistStreamInit, iface)
498 static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface,
499 REFIID riid, void **ppv)
501 HTMLDocument *This = PERSTRINIT_THIS(iface);
502 return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppv);
505 static ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface)
507 HTMLDocument *This = PERSTRINIT_THIS(iface);
508 return IHTMLDocument2_AddRef(HTMLDOC(This));
511 static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface)
513 HTMLDocument *This = PERSTRINIT_THIS(iface);
514 return IHTMLDocument2_Release(HTMLDOC(This));
517 static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *pClassID)
519 HTMLDocument *This = PERSTRINIT_THIS(iface);
520 return IPersist_GetClassID(PERSIST(This), pClassID);
523 static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface)
525 HTMLDocument *This = PERSTRINIT_THIS(iface);
527 TRACE("(%p)\n", This);
529 if(This->usermode == EDITMODE)
530 return editor_is_dirty(This);
532 return S_FALSE;
535 static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, LPSTREAM pStm)
537 HTMLDocument *This = PERSTRINIT_THIS(iface);
538 IMoniker *mon;
539 HRESULT hres;
541 static const WCHAR about_blankW[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
543 TRACE("(%p)->(%p)\n", This, pStm);
545 hres = CreateURLMoniker(NULL, about_blankW, &mon);
546 if(FAILED(hres)) {
547 WARN("CreateURLMoniker failed: %08x\n", hres);
548 return hres;
551 hres = set_moniker(This, mon, NULL, NULL);
552 IMoniker_Release(mon);
553 if(FAILED(hres))
554 return hres;
556 return channelbsc_load_stream(This->bscallback, pStm);
559 static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM pStm,
560 BOOL fClearDirty)
562 HTMLDocument *This = PERSTRINIT_THIS(iface);
563 char *str;
564 DWORD written=0;
565 HRESULT hres;
567 TRACE("(%p)->(%p %x)\n", This, pStm, fClearDirty);
569 hres = get_doc_string(This, &str);
570 if(FAILED(hres))
571 return hres;
573 hres = IStream_Write(pStm, str, strlen(str), &written);
574 if(FAILED(hres))
575 FIXME("Write failed: %08x\n", hres);
577 heap_free(str);
579 if(fClearDirty)
580 set_dirty(This, VARIANT_FALSE);
582 return S_OK;
585 static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface,
586 ULARGE_INTEGER *pcbSize)
588 HTMLDocument *This = PERSTRINIT_THIS(iface);
589 FIXME("(%p)->(%p)\n", This, pcbSize);
590 return E_NOTIMPL;
593 static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface)
595 HTMLDocument *This = PERSTRINIT_THIS(iface);
596 FIXME("(%p)\n", This);
597 return E_NOTIMPL;
600 #undef PERSTRINIT_THIS
602 static const IPersistStreamInitVtbl PersistStreamInitVtbl = {
603 PersistStreamInit_QueryInterface,
604 PersistStreamInit_AddRef,
605 PersistStreamInit_Release,
606 PersistStreamInit_GetClassID,
607 PersistStreamInit_IsDirty,
608 PersistStreamInit_Load,
609 PersistStreamInit_Save,
610 PersistStreamInit_GetSizeMax,
611 PersistStreamInit_InitNew
614 /**********************************************************
615 * IPersistHistory implementation
618 #define PERSISTHIST_THIS(iface) DEFINE_THIS(HTMLDocument, PersistHistory, iface)
620 static HRESULT WINAPI PersistHistory_QueryInterface(IPersistHistory *iface, REFIID riid, void **ppvObject)
622 HTMLDocument *This = PERSISTHIST_THIS(iface);
623 return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
626 static ULONG WINAPI PersistHistory_AddRef(IPersistHistory *iface)
628 HTMLDocument *This = PERSISTHIST_THIS(iface);
629 return IHTMLDocument2_AddRef(HTMLDOC(This));
632 static ULONG WINAPI PersistHistory_Release(IPersistHistory *iface)
634 HTMLDocument *This = PERSISTHIST_THIS(iface);
635 return IHTMLDocument2_Release(HTMLDOC(This));
638 static HRESULT WINAPI PersistHistory_GetClassID(IPersistHistory *iface, CLSID *pClassID)
640 HTMLDocument *This = PERSISTHIST_THIS(iface);
641 return IPersist_GetClassID(PERSIST(This), pClassID);
644 static HRESULT WINAPI PersistHistory_LoadHistory(IPersistHistory *iface, IStream *pStream, IBindCtx *pbc)
646 HTMLDocument *This = PERSISTHIST_THIS(iface);
647 FIXME("(%p)->(%p %p)\n", This, pStream, pbc);
648 return E_NOTIMPL;
651 static HRESULT WINAPI PersistHistory_SaveHistory(IPersistHistory *iface, IStream *pStream)
653 HTMLDocument *This = PERSISTHIST_THIS(iface);
654 FIXME("(%p)->(%p)\n", This, pStream);
655 return E_NOTIMPL;
658 static HRESULT WINAPI PersistHistory_SetPositionCookie(IPersistHistory *iface, DWORD dwPositioncookie)
660 HTMLDocument *This = PERSISTHIST_THIS(iface);
661 FIXME("(%p)->(%x)\n", This, dwPositioncookie);
662 return E_NOTIMPL;
665 static HRESULT WINAPI PersistHistory_GetPositionCookie(IPersistHistory *iface, DWORD *pdwPositioncookie)
667 HTMLDocument *This = PERSISTHIST_THIS(iface);
668 FIXME("(%p)->(%p)\n", This, pdwPositioncookie);
669 return E_NOTIMPL;
672 #undef PERSISTHIST_THIS
674 static const IPersistHistoryVtbl PersistHistoryVtbl = {
675 PersistHistory_QueryInterface,
676 PersistHistory_AddRef,
677 PersistHistory_Release,
678 PersistHistory_GetClassID,
679 PersistHistory_LoadHistory,
680 PersistHistory_SaveHistory,
681 PersistHistory_SetPositionCookie,
682 PersistHistory_GetPositionCookie
685 void HTMLDocument_Persist_Init(HTMLDocument *This)
687 This->lpPersistMonikerVtbl = &PersistMonikerVtbl;
688 This->lpPersistFileVtbl = &PersistFileVtbl;
689 This->lpMonikerPropVtbl = &MonikerPropVtbl;
690 This->lpPersistStreamInitVtbl = &PersistStreamInitVtbl;
691 This->lpPersistHistoryVtbl = &PersistHistoryVtbl;
693 This->bscallback = NULL;
694 This->mon = NULL;
695 This->url = NULL;
696 This->mime = NULL;