rpcrt4: Don't try to bind to a null handle.
[wine] / dlls / mshtml / view.c
1 /*
2  * Copyright 2005-2006 Jacek Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "commctrl.h"
30 #include "ole2.h"
31 #include "resource.h"
32
33 #include "wine/debug.h"
34
35 #include "mshtml_private.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38
39 #define TIMER_ID 0x1000
40
41 static const WCHAR wszInternetExplorer_Server[] =
42     {'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','_','S','e','r','v','e','r',0};
43
44 static const WCHAR wszTooltipData[] = {'t','o','o','l','t','i','p','_','d','a','t','a',0};
45
46 static ATOM serverwnd_class = 0;
47
48 typedef struct {
49     HTMLDocumentObj *doc;
50     WNDPROC proc;
51 } tooltip_data;
52
53 static void paint_document(HTMLDocumentObj *This)
54 {
55     PAINTSTRUCT ps;
56     RECT rect;
57     HDC hdc;
58
59     GetClientRect(This->hwnd, &rect);
60
61     hdc = BeginPaint(This->hwnd, &ps);
62
63     if(!(This->hostinfo.dwFlags & (DOCHOSTUIFLAG_NO3DOUTERBORDER|DOCHOSTUIFLAG_NO3DBORDER)))
64         DrawEdge(hdc, &rect, EDGE_SUNKEN, BF_RECT|BF_ADJUST);
65
66     if(!This->nscontainer) {
67         WCHAR wszHTMLDisabled[100];
68         HFONT font;
69
70         LoadStringW(hInst, IDS_HTMLDISABLED, wszHTMLDisabled, sizeof(wszHTMLDisabled)/sizeof(WCHAR));
71
72         font = CreateFontA(25,0,0,0,400,0,0,0,ANSI_CHARSET,0,0,DEFAULT_QUALITY,DEFAULT_PITCH,NULL);
73
74         SelectObject(hdc, font);
75         SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW));
76
77         Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
78         DrawTextW(hdc, wszHTMLDisabled,-1, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
79
80         DeleteObject(font);
81     }
82
83     EndPaint(This->hwnd, &ps);
84 }
85
86 static void activate_gecko(NSContainer *This)
87 {
88     TRACE("(%p) %p\n", This, This->window);
89
90     SetParent(This->hwnd, This->doc->hwnd);
91     ShowWindow(This->hwnd, SW_SHOW);
92
93     nsIBaseWindow_SetVisibility(This->window, TRUE);
94     nsIBaseWindow_SetEnabled(This->window, TRUE);
95 }
96
97 void update_doc(HTMLDocument *This, DWORD flags)
98 {
99     if(!This->doc_obj->update && This->doc_obj->hwnd)
100         SetTimer(This->doc_obj->hwnd, TIMER_ID, 100, NULL);
101
102     This->doc_obj->update |= flags;
103 }
104
105 void update_title(HTMLDocumentObj *This)
106 {
107     IOleCommandTarget *olecmd;
108     HRESULT hres;
109
110     if(!(This->update & UPDATE_TITLE))
111         return;
112
113     This->update &= ~UPDATE_TITLE;
114
115     if(!This->client)
116         return;
117
118     hres = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget, (void**)&olecmd);
119     if(SUCCEEDED(hres)) {
120         VARIANT title;
121         WCHAR empty[] = {0};
122
123         V_VT(&title) = VT_BSTR;
124         V_BSTR(&title) = SysAllocString(empty);
125         IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETTITLE, OLECMDEXECOPT_DONTPROMPTUSER,
126                                &title, NULL);
127         SysFreeString(V_BSTR(&title));
128
129         IOleCommandTarget_Release(olecmd);
130     }
131 }
132
133 static LRESULT on_timer(HTMLDocumentObj *This)
134 {
135     TRACE("(%p) %x\n", This, This->update);
136
137     KillTimer(This->hwnd, TIMER_ID);
138
139     if(!This->update)
140         return 0;
141
142     if(This->update & UPDATE_UI) {
143         if(This->hostui)
144             IDocHostUIHandler_UpdateUI(This->hostui);
145
146         if(This->client) {
147             IOleCommandTarget *cmdtrg;
148             HRESULT hres;
149
150             hres = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget,
151                                                  (void**)&cmdtrg);
152             if(SUCCEEDED(hres)) {
153                 IOleCommandTarget_Exec(cmdtrg, NULL, OLECMDID_UPDATECOMMANDS,
154                                        OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL);
155                 IOleCommandTarget_Release(cmdtrg);
156             }
157         }
158     }
159
160     update_title(This);
161     This->update = 0;
162     return 0;
163 }
164
165 void notif_focus(HTMLDocumentObj *This)
166 {
167     IOleControlSite *site;
168     HRESULT hres;
169
170     if(!This->client)
171         return;
172
173     hres = IOleClientSite_QueryInterface(This->client, &IID_IOleControlSite, (void**)&site);
174     if(FAILED(hres))
175         return;
176
177     IOleControlSite_OnFocus(site, This->focus);
178     IOleControlSite_Release(site);
179 }
180
181 static LRESULT WINAPI serverwnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
182 {
183     HTMLDocumentObj *This;
184
185     static const WCHAR wszTHIS[] = {'T','H','I','S',0};
186
187     if(msg == WM_CREATE) {
188         This = *(HTMLDocumentObj**)lParam;
189         SetPropW(hwnd, wszTHIS, This);
190     }else {
191         This = GetPropW(hwnd, wszTHIS);
192     }
193
194     switch(msg) {
195     case WM_CREATE:
196         This->hwnd = hwnd;
197         break;
198     case WM_PAINT:
199         paint_document(This);
200         break;
201     case WM_SIZE:
202         TRACE("(%p)->(WM_SIZE)\n", This);
203         if(This->nscontainer) {
204             INT ew=0, eh=0;
205
206             if(!(This->hostinfo.dwFlags & (DOCHOSTUIFLAG_NO3DOUTERBORDER|DOCHOSTUIFLAG_NO3DBORDER))) {
207                 ew = GetSystemMetrics(SM_CXEDGE);
208                 eh = GetSystemMetrics(SM_CYEDGE);
209             }
210
211             SetWindowPos(This->nscontainer->hwnd, NULL, ew, eh,
212                          LOWORD(lParam) - 2*ew, HIWORD(lParam) - 2*eh,
213                          SWP_NOZORDER | SWP_NOACTIVATE);
214         }
215         break;
216     case WM_TIMER:
217         return on_timer(This);
218     case WM_SETFOCUS:
219         TRACE("(%p) WM_SETFOCUS\n", This);
220         nsIWebBrowserFocus_Activate(This->nscontainer->focus);
221         break;
222     case WM_MOUSEACTIVATE:
223         return MA_ACTIVATE;
224     }
225         
226     return DefWindowProcW(hwnd, msg, wParam, lParam);
227 }
228
229 static void register_serverwnd_class(void)
230 {
231     static WNDCLASSEXW wndclass = {
232         sizeof(WNDCLASSEXW),
233         CS_DBLCLKS,
234         serverwnd_proc,
235         0, 0, NULL, NULL, NULL, NULL, NULL,
236         wszInternetExplorer_Server,
237         NULL,
238     };
239     wndclass.hInstance = hInst;
240     serverwnd_class = RegisterClassExW(&wndclass);
241 }
242
243 static HRESULT activate_window(HTMLDocumentObj *This)
244 {
245     IOleInPlaceFrame *pIPFrame;
246     IOleCommandTarget *cmdtrg;
247     IOleInPlaceSiteEx *ipsiteex;
248     RECT posrect, cliprect;
249     OLEINPLACEFRAMEINFO frameinfo;
250     HWND parent_hwnd;
251     HRESULT hres;
252
253     if(!serverwnd_class)
254         register_serverwnd_class();
255
256     hres = IOleInPlaceSite_CanInPlaceActivate(This->ipsite);
257     if(hres != S_OK) {
258         WARN("CanInPlaceActivate returned: %08x\n", hres);
259         return FAILED(hres) ? hres : E_FAIL;
260     }
261
262     frameinfo.cb = sizeof(OLEINPLACEFRAMEINFO);
263     hres = IOleInPlaceSite_GetWindowContext(This->ipsite, &pIPFrame, &This->ip_window,
264             &posrect, &cliprect, &frameinfo);
265     if(FAILED(hres)) {
266         WARN("GetWindowContext failed: %08x\n", hres);
267         return hres;
268     }
269
270     TRACE("got window context: %p %p {%d %d %d %d} {%d %d %d %d} {%d %x %p %p %d}\n",
271             pIPFrame, This->ip_window, posrect.left, posrect.top, posrect.right, posrect.bottom,
272             cliprect.left, cliprect.top, cliprect.right, cliprect.bottom,
273             frameinfo.cb, frameinfo.fMDIApp, frameinfo.hwndFrame, frameinfo.haccel, frameinfo.cAccelEntries);
274
275     hres = IOleInPlaceSite_GetWindow(This->ipsite, &parent_hwnd);
276     if(FAILED(hres)) {
277         WARN("GetWindow failed: %08x\n", hres);
278         return hres;
279     }
280
281     TRACE("got parent window %p\n", parent_hwnd);
282
283     if(This->hwnd) {
284         if(GetParent(This->hwnd) != parent_hwnd)
285             SetParent(This->hwnd, parent_hwnd);
286         SetWindowPos(This->hwnd, HWND_TOP,
287                 posrect.left, posrect.top, posrect.right-posrect.left, posrect.bottom-posrect.top,
288                 SWP_NOACTIVATE | SWP_SHOWWINDOW);
289     }else {
290         CreateWindowExW(0, wszInternetExplorer_Server, NULL,
291                 WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
292                 posrect.left, posrect.top, posrect.right-posrect.left, posrect.bottom-posrect.top,
293                 parent_hwnd, NULL, hInst, This);
294
295         TRACE("Created window %p\n", This->hwnd);
296
297         SetWindowPos(This->hwnd, NULL, 0, 0, 0, 0,
298                 SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_SHOWWINDOW);
299         RedrawWindow(This->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE | RDW_ALLCHILDREN);
300
301         /* NOTE:
302          * Windows implementation calls:
303          * RegisterWindowMessage("MSWHEEL_ROLLMSG");
304          */
305         SetTimer(This->hwnd, TIMER_ID, 100, NULL);
306     }
307
308     if(This->nscontainer)
309         activate_gecko(This->nscontainer);
310
311     This->in_place_active = TRUE;
312     hres = IOleInPlaceSite_QueryInterface(This->ipsite, &IID_IOleInPlaceSiteEx, (void**)&ipsiteex);
313     if(SUCCEEDED(hres)) {
314         BOOL redraw = FALSE;
315
316         hres = IOleInPlaceSiteEx_OnInPlaceActivateEx(ipsiteex, &redraw, 0);
317         IOleInPlaceSiteEx_Release(ipsiteex);
318         if(redraw)
319             FIXME("unsupported redraw\n");
320     }else{
321         hres = IOleInPlaceSite_OnInPlaceActivate(This->ipsite);
322     }
323     if(FAILED(hres)) {
324         WARN("OnInPlaceActivate failed: %08x\n", hres);
325         This->in_place_active = FALSE;
326         return hres;
327     }
328
329     hres = IOleClientSite_QueryInterface(This->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
330     if(SUCCEEDED(hres)) {
331         VARIANT var;
332
333         IOleInPlaceFrame_SetStatusText(pIPFrame, NULL);
334
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);
341
342         IOleCommandTarget_Release(cmdtrg);
343     }
344
345     if(This->frame)
346         IOleInPlaceFrame_Release(This->frame);
347     This->frame = pIPFrame;
348
349     if(!This->request_uiactivate) {
350         hres = IOleInPlaceSite_QueryInterface(This->ipsite, &IID_IOleInPlaceSiteEx, (void**)&ipsiteex);
351         if(SUCCEEDED(hres)) {
352             IOleInPlaceSiteEx_RequestUIActivate(ipsiteex);
353             IOleInPlaceSiteEx_Release(ipsiteex);
354         }
355     }
356
357     This->window_active = TRUE;
358
359     return S_OK;
360 }
361
362 static LRESULT WINAPI tooltips_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
363 {
364     tooltip_data *data = GetPropW(hwnd, wszTooltipData);
365
366     TRACE("%d %p\n", msg, data);
367
368     if(msg == TTM_WINDOWFROMPOINT) {
369         RECT rect;
370         POINT *pt = (POINT*)lParam;
371
372         TRACE("TTM_WINDOWFROMPOINT (%d,%d)\n", pt->x, pt->y);
373
374         GetWindowRect(data->doc->hwnd, &rect);
375
376         if(rect.left <= pt->x && pt->x <= rect.right
377            && rect.top <= pt->y && pt->y <= rect.bottom)
378             return (LPARAM)data->doc->hwnd;
379     }
380
381     return CallWindowProcW(data->proc, hwnd, msg, wParam, lParam);
382 }
383
384 static void create_tooltips_window(HTMLDocumentObj *This)
385 {
386     tooltip_data *data = heap_alloc(sizeof(*data));
387
388     This->tooltips_hwnd = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, TTS_NOPREFIX | WS_POPUP,
389             CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, This->hwnd, NULL, hInst, NULL);
390
391     data->doc = This;
392     data->proc = (WNDPROC)GetWindowLongPtrW(This->tooltips_hwnd, GWLP_WNDPROC);
393
394     SetPropW(This->tooltips_hwnd, wszTooltipData, data);
395
396     SetWindowLongPtrW(This->tooltips_hwnd, GWLP_WNDPROC, (LONG_PTR)tooltips_proc);
397
398     SetWindowPos(This->tooltips_hwnd, HWND_TOPMOST,0, 0, 0, 0,
399                  SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
400
401 }
402
403 void show_tooltip(HTMLDocumentObj *This, DWORD x, DWORD y, LPCWSTR text)
404 {
405     TTTOOLINFOW toolinfo = {
406         sizeof(TTTOOLINFOW), 0, This->hwnd, 0xdeadbeef,
407         {x>2 ? x-2 : 0, y>0 ? y-2 : 0, x+2, y+2}, /* FIXME */
408         NULL, (LPWSTR)text, 0};
409     MSG msg = {This->hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(x,y), 0, {x,y}};
410
411     TRACE("(%p)->(%d %d %s)\n", This, x, y, debugstr_w(text));
412
413     if(!This->tooltips_hwnd)
414         create_tooltips_window(This);
415
416     SendMessageW(This->tooltips_hwnd, TTM_ADDTOOLW, 0, (LPARAM)&toolinfo);
417     SendMessageW(This->tooltips_hwnd, TTM_ACTIVATE, TRUE, 0);
418     SendMessageW(This->tooltips_hwnd, TTM_RELAYEVENT, 0, (LPARAM)&msg);
419 }
420
421 void hide_tooltip(HTMLDocumentObj *This)
422 {
423     TTTOOLINFOW toolinfo = {
424         sizeof(TTTOOLINFOW), 0, This->hwnd, 0xdeadbeef,
425         {0,0,0,0}, NULL, NULL, 0};
426
427     TRACE("(%p)\n", This);
428
429     SendMessageW(This->tooltips_hwnd, TTM_DELTOOLW, 0, (LPARAM)&toolinfo);
430     SendMessageW(This->tooltips_hwnd, TTM_ACTIVATE, FALSE, 0);
431 }
432
433 HRESULT call_set_active_object(IOleInPlaceUIWindow *window, IOleInPlaceActiveObject *act_obj)
434 {
435     static WCHAR html_documentW[30];
436
437     if(act_obj && !html_documentW[0]) {
438         LoadStringW(hInst, IDS_HTMLDOCUMENT, html_documentW,
439                     sizeof(html_documentW)/sizeof(WCHAR));
440     }
441
442     return IOleInPlaceFrame_SetActiveObject(window, act_obj, act_obj ? html_documentW : NULL);
443 }
444
445 /**********************************************************
446  * IOleDocumentView implementation
447  */
448
449 static inline HTMLDocument *impl_from_IOleDocumentView(IOleDocumentView *iface)
450 {
451     return CONTAINING_RECORD(iface, HTMLDocument, IOleDocumentView_iface);
452 }
453
454 static HRESULT WINAPI OleDocumentView_QueryInterface(IOleDocumentView *iface, REFIID riid, void **ppvObject)
455 {
456     HTMLDocument *This = impl_from_IOleDocumentView(iface);
457     return htmldoc_query_interface(This, riid, ppvObject);
458 }
459
460 static ULONG WINAPI OleDocumentView_AddRef(IOleDocumentView *iface)
461 {
462     HTMLDocument *This = impl_from_IOleDocumentView(iface);
463     return htmldoc_addref(This);
464 }
465
466 static ULONG WINAPI OleDocumentView_Release(IOleDocumentView *iface)
467 {
468     HTMLDocument *This = impl_from_IOleDocumentView(iface);
469     return htmldoc_release(This);
470 }
471
472 static HRESULT WINAPI OleDocumentView_SetInPlaceSite(IOleDocumentView *iface, IOleInPlaceSite *pIPSite)
473 {
474     HTMLDocument *This = impl_from_IOleDocumentView(iface);
475     TRACE("(%p)->(%p)\n", This, pIPSite);
476
477     if(pIPSite)
478         IOleInPlaceSite_AddRef(pIPSite);
479
480     if(This->doc_obj->ipsite)
481         IOleInPlaceSite_Release(This->doc_obj->ipsite);
482
483     This->doc_obj->ipsite = pIPSite;
484     This->doc_obj->request_uiactivate = TRUE;
485     return S_OK;
486 }
487
488 static HRESULT WINAPI OleDocumentView_GetInPlaceSite(IOleDocumentView *iface, IOleInPlaceSite **ppIPSite)
489 {
490     HTMLDocument *This = impl_from_IOleDocumentView(iface);
491     TRACE("(%p)->(%p)\n", This, ppIPSite);
492
493     if(!ppIPSite)
494         return E_INVALIDARG;
495
496     if(This->doc_obj->ipsite)
497         IOleInPlaceSite_AddRef(This->doc_obj->ipsite);
498
499     *ppIPSite = This->doc_obj->ipsite;
500     return S_OK;
501 }
502
503 static HRESULT WINAPI OleDocumentView_GetDocument(IOleDocumentView *iface, IUnknown **ppunk)
504 {
505     HTMLDocument *This = impl_from_IOleDocumentView(iface);
506     TRACE("(%p)->(%p)\n", This, ppunk);
507
508     if(!ppunk)
509         return E_INVALIDARG;
510
511     htmldoc_addref(This);
512     *ppunk = (IUnknown*)&This->IHTMLDocument2_iface;
513     return S_OK;
514 }
515
516 static HRESULT WINAPI OleDocumentView_SetRect(IOleDocumentView *iface, LPRECT prcView)
517 {
518     HTMLDocument *This = impl_from_IOleDocumentView(iface);
519     RECT rect;
520
521     TRACE("(%p)->(%p)\n", This, prcView);
522
523     if(!prcView)
524         return E_INVALIDARG;
525
526     if(This->doc_obj->hwnd) {
527         GetClientRect(This->doc_obj->hwnd, &rect);
528         if(memcmp(prcView, &rect, sizeof(RECT))) {
529             InvalidateRect(This->doc_obj->hwnd, NULL, TRUE);
530             SetWindowPos(This->doc_obj->hwnd, NULL, prcView->left, prcView->top, prcView->right,
531                     prcView->bottom, SWP_NOZORDER | SWP_NOACTIVATE);
532         }
533     }
534     
535     return S_OK;
536 }
537
538 static HRESULT WINAPI OleDocumentView_GetRect(IOleDocumentView *iface, LPRECT prcView)
539 {
540     HTMLDocument *This = impl_from_IOleDocumentView(iface);
541
542     TRACE("(%p)->(%p)\n", This, prcView);
543
544     if(!prcView)
545         return E_INVALIDARG;
546
547     GetClientRect(This->doc_obj->hwnd, prcView);
548     return S_OK;
549 }
550
551 static HRESULT WINAPI OleDocumentView_SetRectComplex(IOleDocumentView *iface, LPRECT prcView,
552                         LPRECT prcHScroll, LPRECT prcVScroll, LPRECT prcSizeBox)
553 {
554     HTMLDocument *This = impl_from_IOleDocumentView(iface);
555     FIXME("(%p)->(%p %p %p %p)\n", This, prcView, prcHScroll, prcVScroll, prcSizeBox);
556     return E_NOTIMPL;
557 }
558
559 static HRESULT WINAPI OleDocumentView_Show(IOleDocumentView *iface, BOOL fShow)
560 {
561     HTMLDocument *This = impl_from_IOleDocumentView(iface);
562     HRESULT hres;
563
564     TRACE("(%p)->(%x)\n", This, fShow);
565
566     if(fShow) {
567         if(!This->doc_obj->ui_active) {
568             hres = activate_window(This->doc_obj);
569             if(FAILED(hres))
570                 return hres;
571         }
572         update_doc(This, UPDATE_UI);
573         ShowWindow(This->doc_obj->hwnd, SW_SHOW);
574     }else {
575         ShowWindow(This->doc_obj->hwnd, SW_HIDE);
576
577         if(This->doc_obj->in_place_active)
578             IOleInPlaceObjectWindowless_InPlaceDeactivate(&This->IOleInPlaceObjectWindowless_iface);
579
580         if(This->doc_obj->ip_window) {
581             IOleInPlaceUIWindow_Release(This->doc_obj->ip_window);
582             This->doc_obj->ip_window = NULL;
583         }
584     }
585
586     return S_OK;
587 }
588
589 static HRESULT WINAPI OleDocumentView_UIActivate(IOleDocumentView *iface, BOOL fUIActivate)
590 {
591     HTMLDocument *This = impl_from_IOleDocumentView(iface);
592     HRESULT hres;
593
594     TRACE("(%p)->(%x)\n", This, fUIActivate);
595
596     if(!This->doc_obj->ipsite) {
597         IOleClientSite *cs = This->doc_obj->client;
598         IOleInPlaceSite *ips;
599
600         if(!cs) {
601             WARN("this->ipsite = NULL\n");
602             return E_UNEXPECTED;
603         }
604
605         hres = IOleClientSite_QueryInterface(cs, &IID_IOleInPlaceSiteWindowless, (void**)&ips);
606         if(SUCCEEDED(hres))
607             This->doc_obj->ipsite = ips;
608         else {
609             hres = IOleClientSite_QueryInterface(cs, &IID_IOleInPlaceSiteEx, (void**)&ips);
610             if(SUCCEEDED(hres))
611                 This->doc_obj->ipsite = ips;
612             else {
613                 hres = IOleClientSite_QueryInterface(cs, &IID_IOleInPlaceSite, (void**)&ips);
614                 if(SUCCEEDED(hres))
615                     This->doc_obj->ipsite = ips;
616                 else {
617                     WARN("this->ipsite = NULL\n");
618                     return E_NOINTERFACE;
619                 }
620             }
621         }
622
623         IOleClientSite_AddRef(This->doc_obj->ipsite);
624         This->doc_obj->request_uiactivate = FALSE;
625         HTMLDocument_LockContainer(This->doc_obj, TRUE);
626     }
627
628     if(fUIActivate) {
629         RECT rcBorderWidths;
630
631         if(This->doc_obj->ui_active)
632             return S_OK;
633
634         if(!This->doc_obj->window_active) {
635             hres = activate_window(This->doc_obj);
636             if(FAILED(hres))
637                 return hres;
638         }
639
640         This->doc_obj->focus = TRUE;
641         if(This->doc_obj->nscontainer)
642             nsIWebBrowserFocus_Activate(This->doc_obj->nscontainer->focus);
643         notif_focus(This->doc_obj);
644
645         update_doc(This, UPDATE_UI);
646
647         hres = IOleInPlaceSite_OnUIActivate(This->doc_obj->ipsite);
648         if(SUCCEEDED(hres)) {
649             call_set_active_object((IOleInPlaceUIWindow*)This->doc_obj->frame,
650                     &This->IOleInPlaceActiveObject_iface);
651         }else {
652             FIXME("OnUIActivate failed: %08x\n", hres);
653             IOleInPlaceFrame_Release(This->doc_obj->frame);
654             This->doc_obj->frame = NULL;
655             This->doc_obj->ui_active = FALSE;
656             return hres;
657         }
658
659         if(This->doc_obj->hostui) {
660             hres = IDocHostUIHandler_ShowUI(This->doc_obj->hostui,
661                     This->doc_obj->usermode == EDITMODE ? DOCHOSTUITYPE_AUTHOR : DOCHOSTUITYPE_BROWSE,
662                     &This->IOleInPlaceActiveObject_iface, &This->IOleCommandTarget_iface,
663                     This->doc_obj->frame, This->doc_obj->ip_window);
664             if(FAILED(hres))
665                 IDocHostUIHandler_HideUI(This->doc_obj->hostui);
666         }
667
668         if(This->doc_obj->ip_window)
669             call_set_active_object(This->doc_obj->ip_window, &This->IOleInPlaceActiveObject_iface);
670
671         memset(&rcBorderWidths, 0, sizeof(rcBorderWidths));
672         IOleInPlaceFrame_SetBorderSpace(This->doc_obj->frame, &rcBorderWidths);
673
674         This->doc_obj->ui_active = TRUE;
675     }else {
676         This->doc_obj->focus = FALSE;
677         nsIWebBrowserFocus_Deactivate(This->doc_obj->nscontainer->focus);
678         if(This->doc_obj->ui_active) {
679             This->doc_obj->ui_active = FALSE;
680             if(This->doc_obj->ip_window)
681                 call_set_active_object(This->doc_obj->ip_window, NULL);
682             if(This->doc_obj->frame)
683                 call_set_active_object((IOleInPlaceUIWindow*)This->doc_obj->frame, NULL);
684             if(This->doc_obj->hostui)
685                 IDocHostUIHandler_HideUI(This->doc_obj->hostui);
686             if(This->doc_obj->ipsite)
687                 IOleInPlaceSite_OnUIDeactivate(This->doc_obj->ipsite, FALSE);
688         }
689     }
690     return S_OK;
691 }
692
693 static HRESULT WINAPI OleDocumentView_Open(IOleDocumentView *iface)
694 {
695     HTMLDocument *This = impl_from_IOleDocumentView(iface);
696     FIXME("(%p)\n", This);
697     return E_NOTIMPL;
698 }
699
700 static HRESULT WINAPI OleDocumentView_CloseView(IOleDocumentView *iface, DWORD dwReserved)
701 {
702     HTMLDocument *This = impl_from_IOleDocumentView(iface);
703     TRACE("(%p)->(%x)\n", This, dwReserved);
704
705     if(dwReserved)
706         WARN("dwReserved = %d\n", dwReserved);
707
708     /* NOTE:
709      * Windows implementation calls QueryInterface(IID_IOleCommandTarget),
710      * QueryInterface(IID_IOleControlSite) and KillTimer
711      */
712
713     IOleDocumentView_Show(iface, FALSE);
714
715     return S_OK;
716 }
717
718 static HRESULT WINAPI OleDocumentView_SaveViewState(IOleDocumentView *iface, LPSTREAM pstm)
719 {
720     HTMLDocument *This = impl_from_IOleDocumentView(iface);
721     FIXME("(%p)->(%p)\n", This, pstm);
722     return E_NOTIMPL;
723 }
724
725 static HRESULT WINAPI OleDocumentView_ApplyViewState(IOleDocumentView *iface, LPSTREAM pstm)
726 {
727     HTMLDocument *This = impl_from_IOleDocumentView(iface);
728     FIXME("(%p)->(%p)\n", This, pstm);
729     return E_NOTIMPL;
730 }
731
732 static HRESULT WINAPI OleDocumentView_Clone(IOleDocumentView *iface, IOleInPlaceSite *pIPSiteNew,
733                                         IOleDocumentView **ppViewNew)
734 {
735     HTMLDocument *This = impl_from_IOleDocumentView(iface);
736     FIXME("(%p)->(%p %p)\n", This, pIPSiteNew, ppViewNew);
737     return E_NOTIMPL;
738 }
739
740 static const IOleDocumentViewVtbl OleDocumentViewVtbl = {
741     OleDocumentView_QueryInterface,
742     OleDocumentView_AddRef,
743     OleDocumentView_Release,
744     OleDocumentView_SetInPlaceSite,
745     OleDocumentView_GetInPlaceSite,
746     OleDocumentView_GetDocument,
747     OleDocumentView_SetRect,
748     OleDocumentView_GetRect,
749     OleDocumentView_SetRectComplex,
750     OleDocumentView_Show,
751     OleDocumentView_UIActivate,
752     OleDocumentView_Open,
753     OleDocumentView_CloseView,
754     OleDocumentView_SaveViewState,
755     OleDocumentView_ApplyViewState,
756     OleDocumentView_Clone
757 };
758
759 /**********************************************************
760  * IViewObject implementation
761  */
762
763 static inline HTMLDocument *impl_from_IViewObjectEx(IViewObjectEx *iface)
764 {
765     return CONTAINING_RECORD(iface, HTMLDocument, IViewObjectEx_iface);
766 }
767
768 static HRESULT WINAPI ViewObject_QueryInterface(IViewObjectEx *iface, REFIID riid, void **ppv)
769 {
770     HTMLDocument *This = impl_from_IViewObjectEx(iface);
771     return htmldoc_query_interface(This, riid, ppv);
772 }
773
774 static ULONG WINAPI ViewObject_AddRef(IViewObjectEx *iface)
775 {
776     HTMLDocument *This = impl_from_IViewObjectEx(iface);
777     return htmldoc_addref(This);
778 }
779
780 static ULONG WINAPI ViewObject_Release(IViewObjectEx *iface)
781 {
782     HTMLDocument *This = impl_from_IViewObjectEx(iface);
783     return htmldoc_release(This);
784 }
785
786 static HRESULT WINAPI ViewObject_Draw(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect,
787         DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds,
788         LPCRECTL lprcWBounds, BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue), ULONG_PTR dwContinue)
789 {
790     HTMLDocument *This = impl_from_IViewObjectEx(iface);
791     FIXME("(%p)->(%d %d %p %p %p %p %p %p %p %ld)\n", This, dwDrawAspect, lindex, pvAspect,
792             ptd, hdcTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue, dwContinue);
793     return E_NOTIMPL;
794 }
795
796 static HRESULT WINAPI ViewObject_GetColorSet(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect,
797         DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet)
798 {
799     HTMLDocument *This = impl_from_IViewObjectEx(iface);
800     FIXME("(%p)->(%d %d %p %p %p %p)\n", This, dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, ppColorSet);
801     return E_NOTIMPL;
802 }
803
804 static HRESULT WINAPI ViewObject_Freeze(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex,
805         void *pvAspect, DWORD *pdwFreeze)
806 {
807     HTMLDocument *This = impl_from_IViewObjectEx(iface);
808     FIXME("(%p)->(%d %d %p %p)\n", This, dwDrawAspect, lindex, pvAspect, pdwFreeze);
809     return E_NOTIMPL;
810 }
811
812 static HRESULT WINAPI ViewObject_Unfreeze(IViewObjectEx *iface, DWORD dwFreeze)
813 {
814     HTMLDocument *This = impl_from_IViewObjectEx(iface);
815     FIXME("(%p)->(%d)\n", This, dwFreeze);
816     return E_NOTIMPL;
817 }
818
819 static HRESULT WINAPI ViewObject_SetAdvise(IViewObjectEx *iface, DWORD aspects, DWORD advf, IAdviseSink *pAdvSink)
820 {
821     HTMLDocument *This = impl_from_IViewObjectEx(iface);
822
823     TRACE("(%p)->(%d %d %p)\n", This, aspects, advf, pAdvSink);
824
825     if(aspects != DVASPECT_CONTENT || advf != ADVF_PRIMEFIRST)
826         FIXME("unsupported arguments\n");
827
828     if(This->doc_obj->view_sink)
829         IAdviseSink_Release(This->doc_obj->view_sink);
830     if(pAdvSink)
831         IAdviseSink_AddRef(pAdvSink);
832
833     This->doc_obj->view_sink = pAdvSink;
834     return S_OK;
835 }
836
837 static HRESULT WINAPI ViewObject_GetAdvise(IViewObjectEx *iface, DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink)
838 {
839     HTMLDocument *This = impl_from_IViewObjectEx(iface);
840     FIXME("(%p)->(%p %p %p)\n", This, pAspects, pAdvf, ppAdvSink);
841     return E_NOTIMPL;
842 }
843
844 static HRESULT WINAPI ViewObject_GetExtent(IViewObjectEx *iface, DWORD dwDrawAspect, LONG lindex,
845                                 DVTARGETDEVICE* ptd, LPSIZEL lpsizel)
846 {
847     HTMLDocument *This = impl_from_IViewObjectEx(iface);
848     FIXME("(%p)->(%d %d %p %p)\n", This, dwDrawAspect, lindex, ptd, lpsizel);
849     return E_NOTIMPL;
850 }
851
852 static HRESULT WINAPI ViewObject_GetRect(IViewObjectEx *iface, DWORD dwAspect, LPRECTL pRect)
853 {
854     HTMLDocument *This = impl_from_IViewObjectEx(iface);
855     FIXME("(%p)->(%d %p)\n", This, dwAspect, pRect);
856     return E_NOTIMPL;
857 }
858
859 static HRESULT WINAPI ViewObject_GetViewStatus(IViewObjectEx *iface, DWORD *pdwStatus)
860 {
861     HTMLDocument *This = impl_from_IViewObjectEx(iface);
862     FIXME("(%p)->(%p)\n", This, pdwStatus);
863     return E_NOTIMPL;
864 }
865
866 static HRESULT WINAPI ViewObject_QueryHitPoint(IViewObjectEx* iface, DWORD dwAspect,
867         LPCRECT pRectBounds, POINT ptlLoc, LONG lCloseHint, DWORD *pHitResult)
868 {
869     HTMLDocument *This = impl_from_IViewObjectEx(iface);
870     FIXME("(%p)->(%d %p (%d %d) %d %p)\n", This, dwAspect, pRectBounds, ptlLoc.x,
871          ptlLoc.y, lCloseHint, pHitResult);
872     return E_NOTIMPL;
873 }
874
875 static HRESULT WINAPI ViewObject_QueryHitRect(IViewObjectEx *iface, DWORD dwAspect,
876         LPCRECT pRectBounds, LPCRECT pRectLoc, LONG lCloseHint, DWORD *pHitResult)
877 {
878     HTMLDocument *This = impl_from_IViewObjectEx(iface);
879     FIXME("(%p)->(%d %p %p %d %p)\n", This, dwAspect, pRectBounds, pRectLoc, lCloseHint, pHitResult);
880     return E_NOTIMPL;
881 }
882
883 static HRESULT WINAPI ViewObject_GetNaturalExtent(IViewObjectEx *iface, DWORD dwAspect, LONG lindex,
884         DVTARGETDEVICE *ptd, HDC hicTargetDev, DVEXTENTINFO *pExtentInfo, LPSIZEL pSizel)
885 {
886     HTMLDocument *This = impl_from_IViewObjectEx(iface);
887     FIXME("(%p)->(%d %d %p %p %p %p\n", This, dwAspect,lindex, ptd,
888             hicTargetDev, pExtentInfo, pSizel);
889     return E_NOTIMPL;
890 }
891
892 static const IViewObjectExVtbl ViewObjectVtbl = {
893     ViewObject_QueryInterface,
894     ViewObject_AddRef,
895     ViewObject_Release,
896     ViewObject_Draw,
897     ViewObject_GetColorSet,
898     ViewObject_Freeze,
899     ViewObject_Unfreeze,
900     ViewObject_SetAdvise,
901     ViewObject_GetAdvise,
902     ViewObject_GetExtent,
903     ViewObject_GetRect,
904     ViewObject_GetViewStatus,
905     ViewObject_QueryHitPoint,
906     ViewObject_QueryHitRect,
907     ViewObject_GetNaturalExtent
908 };
909
910 void HTMLDocument_View_Init(HTMLDocument *This)
911 {
912     This->IOleDocumentView_iface.lpVtbl = &OleDocumentViewVtbl;
913     This->IViewObjectEx_iface.lpVtbl = &ViewObjectVtbl;
914 }