Unicodify wineesd.
[wine] / dlls / mshtml / view.c
1 /*
2  * Copyright 2005 Jacek Caban
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "wingdi.h"
30 #include "ole2.h"
31 #include "docobj.h"
32
33 #include "mshtml.h"
34 #include "mshtmhst.h"
35
36 #include "wine/debug.h"
37
38 #include "mshtml_private.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
41
42 static const WCHAR wszInternetExplorer_Server[] =
43     {'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','_','S','e','r','v','e','r',0};
44 static const WCHAR wszHTML_Document[] =
45     {'H','T','M','L',' ','D','o','c','u','m','e','n','t',0};
46
47 static ATOM serverwnd_class = 0;
48
49 static void paint_disabled(HWND hwnd) {
50     HDC hdc;
51     PAINTSTRUCT ps;
52     HBRUSH brush;
53     RECT rect;
54     HFONT font;
55
56     font = CreateFontA(25,0,0,0,400,0,0,0,ANSI_CHARSET,0,0,DEFAULT_QUALITY,DEFAULT_PITCH,NULL);
57     brush = CreateSolidBrush(RGB(255,255,255));
58     GetClientRect(hwnd, &rect);
59
60     hdc = BeginPaint(hwnd, &ps);
61     SelectObject(hdc, font);
62     SelectObject(hdc, brush);
63     Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
64     DrawTextA(hdc, "HTML rendering is currently disabled.",-1, &rect,
65             DT_CENTER | DT_SINGLELINE | DT_VCENTER);
66     EndPaint(hwnd, &ps);
67
68     DeleteObject(font);
69     DeleteObject(brush);
70 }
71
72 static void activate_gecko(HTMLDocument *This)
73 {
74     TRACE("(%p) %p\n", This, This->nscontainer->window);
75
76     SetParent(This->nscontainer->hwnd, This->hwnd);
77     ShowWindow(This->nscontainer->hwnd, SW_SHOW);
78
79     nsIBaseWindow_SetVisibility(This->nscontainer->window, TRUE);
80     nsIBaseWindow_SetEnabled(This->nscontainer->window, TRUE);
81 }
82
83 static LRESULT WINAPI serverwnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
84 {
85     HTMLDocument *This;
86
87     static const WCHAR wszTHIS[] = {'T','H','I','S',0};
88
89     if(msg == WM_CREATE) {
90         This = *(HTMLDocument**)lParam;
91         SetPropW(hwnd, wszTHIS, This);
92     }else {
93         This = (HTMLDocument*)GetPropW(hwnd, wszTHIS);
94     }
95
96     switch(msg) {
97     case WM_CREATE:
98         This->hwnd = hwnd;
99         if(This->nscontainer)
100             activate_gecko(This);
101         break;
102     case WM_PAINT:
103         if(!This->nscontainer)
104             paint_disabled(hwnd);
105         break;
106     case WM_SIZE:
107         TRACE("(%p)->(WM_SIZE)\n", This);
108         if(This->nscontainer)
109             SetWindowPos(This->nscontainer->hwnd, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
110                     SWP_NOZORDER | SWP_NOACTIVATE);
111     }
112         
113     return DefWindowProcW(hwnd, msg, wParam, lParam);
114 }
115
116 static void register_serverwnd_class(void)
117 {
118     static WNDCLASSEXW wndclass = {
119         sizeof(WNDCLASSEXW),
120         CS_DBLCLKS,
121         serverwnd_proc,
122         0, 0, NULL, NULL, NULL, NULL, NULL,
123         wszInternetExplorer_Server,
124         NULL,
125     };
126     wndclass.hInstance = hInst;
127     serverwnd_class = RegisterClassExW(&wndclass);
128 }
129
130 /**********************************************************
131  * IOleDocumentView implementation
132  */
133
134 #define DOCVIEW_THIS(iface) DEFINE_THIS(HTMLDocument, OleDocumentView, iface)
135
136 static HRESULT WINAPI OleDocumentView_QueryInterface(IOleDocumentView *iface, REFIID riid, void **ppvObject)
137 {
138     HTMLDocument *This = DOCVIEW_THIS(iface);
139     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
140 }
141
142 static ULONG WINAPI OleDocumentView_AddRef(IOleDocumentView *iface)
143 {
144     HTMLDocument *This = DOCVIEW_THIS(iface);
145     return IHTMLDocument2_AddRef(HTMLDOC(This));
146 }
147
148 static ULONG WINAPI OleDocumentView_Release(IOleDocumentView *iface)
149 {
150     HTMLDocument *This = DOCVIEW_THIS(iface);
151     return IHTMLDocument2_Release(HTMLDOC(This));
152 }
153
154 static HRESULT WINAPI OleDocumentView_SetInPlaceSite(IOleDocumentView *iface, IOleInPlaceSite *pIPSite)
155 {
156     HTMLDocument *This = DOCVIEW_THIS(iface);
157     TRACE("(%p)->(%p)\n", This, pIPSite);
158
159     if(pIPSite)
160         IOleInPlaceSite_AddRef(pIPSite);
161
162     if(This->ipsite)
163         IOleInPlaceSite_Release(This->ipsite);
164
165     This->ipsite = pIPSite;
166     return S_OK;
167 }
168
169 static HRESULT WINAPI OleDocumentView_GetInPlaceSite(IOleDocumentView *iface, IOleInPlaceSite **ppIPSite)
170 {
171     HTMLDocument *This = DOCVIEW_THIS(iface);
172     TRACE("(%p)->(%p)\n", This, ppIPSite);
173
174     if(!ppIPSite)
175         return E_INVALIDARG;
176
177     if(This->ipsite)
178         IOleInPlaceSite_AddRef(This->ipsite);
179
180     *ppIPSite = This->ipsite;
181     return S_OK;
182 }
183
184 static HRESULT WINAPI OleDocumentView_GetDocument(IOleDocumentView *iface, IUnknown **ppunk)
185 {
186     HTMLDocument *This = DOCVIEW_THIS(iface);
187     TRACE("(%p)->(%p)\n", This, ppunk);
188
189     if(!ppunk)
190         return E_INVALIDARG;
191
192     IHTMLDocument2_AddRef(HTMLDOC(This));
193     *ppunk = (IUnknown*)HTMLDOC(This);
194     return S_OK;
195 }
196
197 static HRESULT WINAPI OleDocumentView_SetRect(IOleDocumentView *iface, LPRECT prcView)
198 {
199     HTMLDocument *This = DOCVIEW_THIS(iface);
200     RECT rect;
201
202     TRACE("(%p)->(%p)\n", This, prcView);
203
204     if(!prcView)
205         return E_INVALIDARG;
206
207     if(This->hwnd) {
208         GetClientRect(This->hwnd, &rect);
209         if(memcmp(prcView, &rect, sizeof(RECT))) {
210             InvalidateRect(This->hwnd,NULL,TRUE);
211             SetWindowPos(This->hwnd, NULL, prcView->left, prcView->top, prcView->right,
212                     prcView->bottom, SWP_NOZORDER | SWP_NOACTIVATE);
213         }
214     }
215     
216     return S_OK;
217 }
218
219 static HRESULT WINAPI OleDocumentView_GetRect(IOleDocumentView *iface, LPRECT prcView)
220 {
221     HTMLDocument *This = DOCVIEW_THIS(iface);
222
223     TRACE("(%p)->(%p)\n", This, prcView);
224
225     if(!prcView)
226         return E_INVALIDARG;
227
228     GetClientRect(This->hwnd, prcView);
229     return S_OK;
230 }
231
232 static HRESULT WINAPI OleDocumentView_SetRectComplex(IOleDocumentView *iface, LPRECT prcView,
233                         LPRECT prcHScroll, LPRECT prcVScroll, LPRECT prcSizeBox)
234 {
235     HTMLDocument *This = DOCVIEW_THIS(iface);
236     FIXME("(%p)->(%p %p %p %p)\n", This, prcView, prcHScroll, prcVScroll, prcSizeBox);
237     return E_NOTIMPL;
238 }
239
240 static HRESULT WINAPI OleDocumentView_Show(IOleDocumentView *iface, BOOL fShow)
241 {
242     HTMLDocument *This = DOCVIEW_THIS(iface);
243     TRACE("(%p)->(%x)\n", This, fShow);
244
245     if(This->hwnd)
246         ShowWindow(This->hwnd, fShow);
247
248     return S_OK;
249 }
250
251 static HRESULT WINAPI OleDocumentView_UIActivate(IOleDocumentView *iface, BOOL fUIActivate)
252 {
253     HTMLDocument *This = DOCVIEW_THIS(iface);
254     HRESULT hres;
255     IOleInPlaceUIWindow *pIPWnd;
256     IOleInPlaceFrame *pIPFrame;
257     RECT posrect, cliprect;
258     OLEINPLACEFRAMEINFO frameinfo;
259     HWND parent_hwnd;
260
261     TRACE("(%p)->(%x)\n", This, fUIActivate);
262
263     if(!This->ipsite) {
264         FIXME("This->ipsite = NULL\n");
265         return E_FAIL;
266     }
267
268     if(fUIActivate) {
269         if(This->ui_active)
270             return S_OK;
271         if(!serverwnd_class)
272             register_serverwnd_class();
273
274         hres = IOleInPlaceSite_CanInPlaceActivate(This->ipsite);
275         if(hres != S_OK) {
276             WARN("CanInPlaceActivate returned: %08lx\n", hres);
277             return FAILED(hres) ? hres : E_FAIL;
278         }
279
280         hres = IOleInPlaceSite_GetWindowContext(This->ipsite, &pIPFrame, &pIPWnd, &posrect, &cliprect, &frameinfo);
281         if(FAILED(hres)) {
282             WARN("GetWindowContext failed: %08lx\n", hres);
283             return hres;
284         }
285         if(pIPWnd)
286             IOleInPlaceUIWindow_Release(pIPWnd);
287         TRACE("got window context: %p %p {%ld %ld %ld %ld} {%ld %ld %ld %ld} {%d %x %p %p %d}\n",
288                 pIPFrame, pIPWnd, posrect.left, posrect.top, posrect.right, posrect.bottom,
289                 cliprect.left, cliprect.top, cliprect.right, cliprect.bottom,
290                 frameinfo.cb, frameinfo.fMDIApp, frameinfo.hwndFrame, frameinfo.haccel, frameinfo.cAccelEntries);
291
292         hres = IOleInPlaceSite_GetWindow(This->ipsite, &parent_hwnd);
293         if(FAILED(hres)) {
294             WARN("GetWindow failed: %08lx\n", hres);
295             return hres;
296         }
297
298         TRACE("got parent window %p\n", parent_hwnd);
299
300         if(This->hwnd) {
301             if(GetParent(This->hwnd) != parent_hwnd)
302                 SetParent(This->hwnd, parent_hwnd);
303             SetWindowPos(This->hwnd, HWND_TOP,
304                     posrect.left, posrect.top, posrect.right-posrect.left, posrect.bottom-posrect.top,
305                     SWP_NOACTIVATE | SWP_SHOWWINDOW);
306         }else {
307             CreateWindowExW(0, wszInternetExplorer_Server, NULL,
308                     WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
309                     posrect.left, posrect.top, posrect.right-posrect.left, posrect.bottom-posrect.top,
310                     parent_hwnd, NULL, hInst, This);
311
312             TRACE("Created window %p\n", This->hwnd);
313
314             SetWindowPos(This->hwnd, NULL, 0, 0, 0, 0,
315                     SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_SHOWWINDOW);
316             RedrawWindow(This->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_NOERASE | RDW_ALLCHILDREN);
317             SetFocus(This->hwnd);
318         }
319
320         This->in_place_active = TRUE;
321         hres = IOleInPlaceSite_OnInPlaceActivate(This->ipsite);
322         if(FAILED(hres)) {
323             WARN("OnInPlaceActivate failed: %08lx\n", hres);
324             This->in_place_active = FALSE;
325             return hres;
326         }
327
328         /* NOTE:
329          * Windows implementation calls:
330          * RegisterWindowMessage("MSWHEEL_ROLLMSG");
331          * SetTimer(This->hwnd, TIMER_ID, 100, NULL);
332          */
333
334         This->ui_active = TRUE;
335         hres = IOleInPlaceSite_OnUIActivate(This->ipsite);
336         if(SUCCEEDED(hres)) {
337             IOleInPlaceFrame_SetActiveObject(pIPFrame, ACTOBJ(This), wszHTML_Document);
338         }else {
339             FIXME("OnUIActivate failed: %08lx\n", hres);
340             This->ui_active = FALSE;
341             return hres;
342         }
343         if(This->frame)
344             IOleInPlaceFrame_Release(This->frame);
345         This->frame = pIPFrame;
346
347         hres = IDocHostUIHandler_ShowUI(This->hostui, 0, ACTOBJ(This), CMDTARGET(This),
348                 pIPFrame, NULL);
349         if(FAILED(hres))
350             IDocHostUIHandler_HideUI(This->hostui);
351     }else {
352         This->ui_active = FALSE;
353         if(This->frame)
354             IOleInPlaceFrame_SetActiveObject(This->frame, NULL, NULL);
355         if(This->hostui)
356             IDocHostUIHandler_HideUI(This->hostui);
357         if(This->ipsite)
358             IOleInPlaceSite_OnUIDeactivate(This->ipsite, FALSE);
359     }
360     return S_OK;
361 }
362
363 static HRESULT WINAPI OleDocumentView_Open(IOleDocumentView *iface)
364 {
365     HTMLDocument *This = DOCVIEW_THIS(iface);
366     FIXME("(%p)\n", This);
367     return E_NOTIMPL;
368 }
369
370 static HRESULT WINAPI OleDocumentView_CloseView(IOleDocumentView *iface, DWORD dwReserved)
371 {
372     HTMLDocument *This = DOCVIEW_THIS(iface);
373     TRACE("(%p)->(%lx)\n", This, dwReserved);
374
375     if(dwReserved)
376         WARN("dwReserved = %ld\n", dwReserved);
377
378     /* NOTE:
379      * Windows implementation calls QueryInterface(IID_IOleCommandTarget),
380      * QueryInterface(IID_IOleControlSite) and KillTimer
381      */
382
383     IOleDocumentView_Show(iface, FALSE);
384
385     return S_OK;
386 }
387
388 static HRESULT WINAPI OleDocumentView_SaveViewState(IOleDocumentView *iface, LPSTREAM pstm)
389 {
390     HTMLDocument *This = DOCVIEW_THIS(iface);
391     FIXME("(%p)->(%p)\n", This, pstm);
392     return E_NOTIMPL;
393 }
394
395 static HRESULT WINAPI OleDocumentView_ApplyViewState(IOleDocumentView *iface, LPSTREAM pstm)
396 {
397     HTMLDocument *This = DOCVIEW_THIS(iface);
398     FIXME("(%p)->(%p)\n", This, pstm);
399     return E_NOTIMPL;
400 }
401
402 static HRESULT WINAPI OleDocumentView_Clone(IOleDocumentView *iface, IOleInPlaceSite *pIPSiteNew,
403                                         IOleDocumentView **ppViewNew)
404 {
405     HTMLDocument *This = DOCVIEW_THIS(iface);
406     FIXME("(%p)->(%p %p)\n", This, pIPSiteNew, ppViewNew);
407     return E_NOTIMPL;
408 }
409
410 #undef DOCVIEW_THIS
411
412 static const IOleDocumentViewVtbl OleDocumentViewVtbl = {
413     OleDocumentView_QueryInterface,
414     OleDocumentView_AddRef,
415     OleDocumentView_Release,
416     OleDocumentView_SetInPlaceSite,
417     OleDocumentView_GetInPlaceSite,
418     OleDocumentView_GetDocument,
419     OleDocumentView_SetRect,
420     OleDocumentView_GetRect,
421     OleDocumentView_SetRectComplex,
422     OleDocumentView_Show,
423     OleDocumentView_UIActivate,
424     OleDocumentView_Open,
425     OleDocumentView_CloseView,
426     OleDocumentView_SaveViewState,
427     OleDocumentView_ApplyViewState,
428     OleDocumentView_Clone
429 };
430
431 /**********************************************************
432  * IViewObject implementation
433  */
434
435 #define VIEWOBJ_THIS(iface) DEFINE_THIS(HTMLDocument, ViewObject2, iface)
436
437 static HRESULT WINAPI ViewObject_QueryInterface(IViewObject2 *iface, REFIID riid, void **ppvObject)
438 {
439     HTMLDocument *This = VIEWOBJ_THIS(iface);
440     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
441 }
442
443 static ULONG WINAPI ViewObject_AddRef(IViewObject2 *iface)
444 {
445     HTMLDocument *This = VIEWOBJ_THIS(iface);
446     return IHTMLDocument2_AddRef(HTMLDOC(This));
447 }
448
449 static ULONG WINAPI ViewObject_Release(IViewObject2 *iface)
450 {
451     HTMLDocument *This = VIEWOBJ_THIS(iface);
452     return IHTMLDocument2_Release(HTMLDOC(This));
453 }
454
455 static HRESULT WINAPI ViewObject_Draw(IViewObject2 *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect,
456         DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds,
457         LPCRECTL lprcWBounds, BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue), ULONG_PTR dwContinue)
458 {
459     HTMLDocument *This = VIEWOBJ_THIS(iface);
460     FIXME("(%p)->(%ld %ld %p %p %p %p %p %p %p %ld)\n", This, dwDrawAspect, lindex, pvAspect,
461             ptd, hdcTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue, dwContinue);
462     return E_NOTIMPL;
463 }
464
465 static HRESULT WINAPI ViewObject_GetColorSet(IViewObject2 *iface, DWORD dwDrawAspect, LONG lindex, void *pvAspect,
466         DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet)
467 {
468     HTMLDocument *This = VIEWOBJ_THIS(iface);
469     FIXME("(%p)->(%ld %ld %p %p %p %p)\n", This, dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, ppColorSet);
470     return E_NOTIMPL;
471 }
472
473 static HRESULT WINAPI ViewObject_Freeze(IViewObject2 *iface, DWORD dwDrawAspect, LONG lindex,
474         void *pvAspect, DWORD *pdwFreeze)
475 {
476     HTMLDocument *This = VIEWOBJ_THIS(iface);
477     FIXME("(%p)->(%ld %ld %p %p)\n", This, dwDrawAspect, lindex, pvAspect, pdwFreeze);
478     return E_NOTIMPL;
479 }
480
481 static HRESULT WINAPI ViewObject_Unfreeze(IViewObject2 *iface, DWORD dwFreeze)
482 {
483     HTMLDocument *This = VIEWOBJ_THIS(iface);
484     FIXME("(%p)->(%ld)\n", This, dwFreeze);
485     return E_NOTIMPL;
486 }
487
488 static HRESULT WINAPI ViewObject_SetAdvise(IViewObject2 *iface, DWORD aspects, DWORD advf, IAdviseSink *pAdvSink)
489 {
490     HTMLDocument *This = VIEWOBJ_THIS(iface);
491     FIXME("(%p)->(%ld %ld %p)\n", This, aspects, advf, pAdvSink);
492     return E_NOTIMPL;
493 }
494
495 static HRESULT WINAPI ViewObject_GetAdvise(IViewObject2 *iface, DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink)
496 {
497     HTMLDocument *This = VIEWOBJ_THIS(iface);
498     FIXME("(%p)->(%p %p %p)\n", This, pAspects, pAdvf, ppAdvSink);
499     return E_NOTIMPL;
500 }
501
502 static HRESULT WINAPI ViewObject_GetExtent(IViewObject2 *iface, DWORD dwDrawAspect, LONG lindex,
503                                 DVTARGETDEVICE* ptd, LPSIZEL lpsizel)
504 {
505     HTMLDocument *This = VIEWOBJ_THIS(iface);
506     FIXME("(%p)->(%ld %ld %p %p)\n", This, dwDrawAspect, lindex, ptd, lpsizel);
507     return E_NOTIMPL;
508 }
509
510 #undef VIEWOBJ_THIS
511
512 static const IViewObject2Vtbl ViewObjectVtbl = {
513     ViewObject_QueryInterface,
514     ViewObject_AddRef,
515     ViewObject_Release,
516     ViewObject_Draw,
517     ViewObject_GetColorSet,
518     ViewObject_Freeze,
519     ViewObject_Unfreeze,
520     ViewObject_SetAdvise,
521     ViewObject_GetAdvise,
522     ViewObject_GetExtent
523 };
524
525 void HTMLDocument_View_Init(HTMLDocument *This)
526 {
527     This->lpOleDocumentViewVtbl = &OleDocumentViewVtbl;
528     This->lpViewObject2Vtbl = &ViewObjectVtbl;
529
530     This->ipsite = NULL;
531     This->frame = NULL;
532     This->hwnd = NULL;
533
534     This->in_place_active = FALSE;
535     This->ui_active = FALSE;
536 }