progman: Add close button and sysmenu to dialogs.
[wine/gsoc_dplay.git] / dlls / shdocvw / iexplore.c
blob20ef7962c52852e70c189d525ad165506a32de4b
1 /*
2 * SHDOCVW - Internet Explorer main frame window
4 * Copyright 2006 Mike McCormack (for CodeWeavers)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define COBJMACROS
23 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "wingdi.h"
28 #include "winnls.h"
29 #include "ole2.h"
30 #include "exdisp.h"
31 #include "oleidl.h"
33 #include "shdocvw.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
39 typedef struct tag_ieoc {
40 const IOleContainerVtbl *lpVtbl;
41 LONG ref;
42 } ieoc;
44 static ieoc *ieoc_from_IOleContainer(IOleContainer *iface)
46 return (ieoc*) iface;
49 static HRESULT WINAPI
50 ic_QueryInterface(IOleContainer *iface, REFIID riid, void **ppv)
52 if (IsEqualGUID(riid, &IID_IUnknown) ||
53 IsEqualGUID(riid, &IID_IOleClientSite))
55 IUnknown_AddRef(iface);
56 *ppv = iface;
57 return S_OK;
59 return E_NOINTERFACE;
62 static ULONG WINAPI ic_AddRef(IOleContainer *iface)
64 ieoc *This = ieoc_from_IOleContainer(iface);
65 return InterlockedIncrement(&This->ref);
68 static ULONG WINAPI ic_Release(IOleContainer *iface)
70 ieoc *This = ieoc_from_IOleContainer(iface);
71 LONG ref = InterlockedDecrement(&This->ref);
72 if (!ref)
74 HeapFree(GetProcessHeap(), 0, This);
75 SHDOCVW_UnlockModule();
77 TRACE("refcount = %ld\n", ref);
78 return ref;
81 static HRESULT WINAPI
82 ic_ParseDisplayName(IOleContainer *iface, IBindCtx *pbc, LPOLESTR pszDisplayName,
83 ULONG *pchEaten, IMoniker **ppmkOut)
85 FIXME("\n");
86 return E_NOTIMPL;
89 static HRESULT WINAPI
90 ic_EnumObjects(IOleContainer *iface, DWORD grfFlags, IEnumUnknown **ppenum)
92 FIXME("\n");
93 return E_NOTIMPL;
96 static HRESULT WINAPI ic_LockContainer(IOleContainer *iface, BOOL fLock)
98 FIXME("\n");
99 return E_NOTIMPL;
102 static const IOleContainerVtbl ocVtbl =
104 ic_QueryInterface,
105 ic_AddRef,
106 ic_Release,
107 ic_ParseDisplayName,
108 ic_EnumObjects,
109 ic_LockContainer,
112 static IOleContainer * get_container(void)
114 IOleContainer *This;
115 ieoc *oc;
117 oc = HeapAlloc(GetProcessHeap(), 0, sizeof *oc);
118 oc->lpVtbl = &ocVtbl;
119 oc->ref = 0;
121 This = (IOleContainer*) oc;
122 IOleContainer_AddRef(This);
123 SHDOCVW_LockModule();
125 return This;
128 /**********************/
130 typedef struct tag_iecs {
131 const IOleClientSiteVtbl *lpVtbl;
132 const IOleInPlaceSiteVtbl *lpInPlaceVtbl;
133 LONG ref;
134 IOleContainer *container;
135 HWND hwnd;
136 IOleObject *oo;
137 } iecs;
139 static iecs *iecs_from_IOleClientSite(IOleClientSite *iface)
141 return (iecs*) iface;
144 static iecs *iecs_from_IOleInPlaceSite(IOleInPlaceSite *iface)
146 return (iecs*) (((char*)iface) - FIELD_OFFSET(iecs,lpInPlaceVtbl));
149 static ULONG WINAPI iecs_AddRef(iecs *This)
151 return InterlockedIncrement(&This->ref);
154 static ULONG WINAPI iecs_Release(iecs *This)
156 LONG ref = InterlockedDecrement(&This->ref);
157 if (!ref)
159 if (This->hwnd)
160 DestroyWindow(This->hwnd);
161 IOleContainer_Release(This->container);
162 HeapFree(GetProcessHeap(), 0, This);
163 SHDOCVW_UnlockModule();
165 return ref;
168 static HRESULT WINAPI
169 iecs_QueryInterface(iecs *This, REFIID riid, void **ppv)
171 if (IsEqualGUID(riid, &IID_IUnknown) ||
172 IsEqualGUID(riid, &IID_IOleClientSite))
174 iecs_AddRef(This);
175 *ppv = &This->lpVtbl;
176 return S_OK;
178 if (IsEqualGUID(riid, &IID_IOleInPlaceSite) ||
179 IsEqualGUID(riid, &IID_IOleWindow))
181 iecs_AddRef(This);
182 *ppv = &This->lpInPlaceVtbl;
183 return S_OK;
185 FIXME("unknown interface %s\n", debugstr_guid(riid));
186 return E_NOINTERFACE;
189 static HRESULT WINAPI
190 cs_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
192 iecs *This = iecs_from_IOleClientSite(iface);
193 return iecs_QueryInterface(This, riid, ppv);
196 static ULONG WINAPI cs_AddRef(IOleClientSite *iface)
198 iecs *This = iecs_from_IOleClientSite(iface);
199 return iecs_AddRef(This);
202 static ULONG WINAPI cs_Release(IOleClientSite *iface)
204 iecs *This = iecs_from_IOleClientSite(iface);
205 return iecs_Release(This);
208 static HRESULT WINAPI cs_SaveObject(IOleClientSite *iface)
210 FIXME("\n");
211 return E_NOTIMPL;
214 static HRESULT WINAPI cs_GetMoniker(IOleClientSite *iface, DWORD dwAssign,
215 DWORD dwWhichMoniker, IMoniker **ppmk)
217 FIXME("\n");
218 return E_NOTIMPL;
221 static HRESULT WINAPI
222 cs_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
224 iecs *This = iecs_from_IOleClientSite(iface);
226 TRACE("\n");
228 IOleContainer_AddRef(This->container);
229 *ppContainer = This->container;
230 return S_OK;
233 static HRESULT WINAPI cs_ShowObject(IOleClientSite *iface)
235 FIXME("\n");
236 return E_NOTIMPL;
239 static HRESULT WINAPI cs_OnShowWindow(IOleClientSite *iface, BOOL fShow)
241 FIXME("\n");
242 return E_NOTIMPL;
245 static HRESULT WINAPI cs_RequestNewObjectLayout(IOleClientSite *iface)
247 FIXME("\n");
248 return E_NOTIMPL;
251 static const IOleClientSiteVtbl csVtbl =
253 cs_QueryInterface,
254 cs_AddRef,
255 cs_Release,
256 cs_SaveObject,
257 cs_GetMoniker,
258 cs_GetContainer,
259 cs_ShowObject,
260 cs_OnShowWindow,
261 cs_RequestNewObjectLayout,
264 static HRESULT WINAPI
265 is_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv)
267 iecs *This = iecs_from_IOleInPlaceSite(iface);
268 return iecs_QueryInterface(This, riid, ppv);
271 static ULONG WINAPI is_AddRef(IOleInPlaceSite *iface)
273 iecs *This = iecs_from_IOleInPlaceSite(iface);
274 return iecs_AddRef(This);
277 static ULONG WINAPI is_Release(IOleInPlaceSite *iface)
279 iecs *This = iecs_from_IOleInPlaceSite(iface);
280 return iecs_Release(This);
283 static HRESULT WINAPI is_getWindow(IOleInPlaceSite *iface, HWND *phwnd)
285 iecs *This = iecs_from_IOleInPlaceSite(iface);
287 TRACE("\n");
289 *phwnd = This->hwnd;
290 return S_OK;
293 static HRESULT WINAPI
294 is_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
296 FIXME("\n");
297 return E_NOTIMPL;
300 static HRESULT WINAPI is_CanInPlaceActivate(IOleInPlaceSite *iface)
302 FIXME("\n");
303 return S_OK;
306 static HRESULT WINAPI is_OnInPlaceActivate(IOleInPlaceSite *iface)
308 TRACE("\n");
309 return S_OK;
312 static HRESULT WINAPI is_OnUIActivate(IOleInPlaceSite *iface)
314 FIXME("\n");
315 return E_NOTIMPL;
318 static HRESULT WINAPI
319 is_GetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame,
320 IOleInPlaceUIWindow ** ppDoc, LPRECT lprcPosRect,
321 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
323 iecs *This = iecs_from_IOleInPlaceSite(iface);
325 TRACE("%p\n", This);
327 *ppFrame = NULL;
328 *ppDoc = NULL;
329 GetClientRect(This->hwnd, lprcPosRect);
330 GetClientRect(This->hwnd, lprcClipRect);
331 if (lpFrameInfo->cb != sizeof *lpFrameInfo)
332 ERR("frame info wrong size\n");
333 lpFrameInfo->cAccelEntries = 0;
334 lpFrameInfo->fMDIApp = FALSE;
335 lpFrameInfo->haccel = 0;
336 lpFrameInfo->hwndFrame = This->hwnd;
338 return S_OK;
341 static HRESULT WINAPI is_Scroll(IOleInPlaceSite *iface, SIZE scrollExtent)
343 FIXME("\n");
344 return E_NOTIMPL;
347 static HRESULT WINAPI is_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
349 FIXME("\n");
350 return E_NOTIMPL;
353 static HRESULT WINAPI is_OnInPlaceDeactivate(IOleInPlaceSite *iface)
355 FIXME("\n");
356 return E_NOTIMPL;
359 static HRESULT WINAPI is_DiscardUndoState(IOleInPlaceSite *iface)
361 FIXME("\n");
362 return E_NOTIMPL;
365 static const IOleInPlaceSiteVtbl isVtbl =
367 is_QueryInterface,
368 is_AddRef,
369 is_Release,
370 is_getWindow,
371 is_ContextSensitiveHelp,
372 is_CanInPlaceActivate,
373 is_OnInPlaceActivate,
374 is_OnUIActivate,
375 is_GetWindowContext,
376 is_Scroll,
377 is_OnUIDeactivate,
378 is_OnInPlaceDeactivate,
379 is_DiscardUndoState,
382 static const WCHAR szIEWinFrame[] = { 'I','E','F','r','a','m','e',0 };
384 static LRESULT iewnd_OnCreate(HWND hwnd, LPCREATESTRUCTW lpcs)
386 SetWindowLongPtrW(hwnd, 0, (LONG_PTR) lpcs->lpCreateParams);
387 return 0;
390 static LRESULT iewnd_OnSize(iecs *This, INT width, INT height)
392 SIZEL sz;
394 TRACE("%p %d %d\n", This, width, height);
396 sz.cx = width;
397 sz.cy = height;
398 IOleObject_SetExtent(This->oo, DVASPECT_CONTENT, &sz);
399 return 0;
402 static LRESULT iewnd_OnDestroy(iecs *This)
404 TRACE("%p\n", This);
406 This->hwnd = NULL;
407 IOleObject_Close(This->oo, OLECLOSE_NOSAVE);
408 IOleObject_Release(This->oo);
409 This->oo = NULL;
410 PostQuitMessage(0);
412 return 0;
415 static LRESULT CALLBACK
416 ie_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
418 iecs *This = (iecs*) GetWindowLongPtrW(hwnd, 0);
420 switch (msg)
422 case WM_CREATE:
423 return iewnd_OnCreate(hwnd, (LPCREATESTRUCTW)lparam);
424 case WM_DESTROY:
425 return iewnd_OnDestroy(This);
426 case WM_SIZE:
427 return iewnd_OnSize(This, LOWORD(lparam), HIWORD(lparam));
429 return DefWindowProcW(hwnd, msg, wparam, lparam);
432 static IOleClientSite * get_client_site(IOleObject *oo, HWND *phwnd)
434 static const WCHAR winname[] = {
435 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',0};
436 IOleClientSite *This;
437 HWND hwnd;
438 iecs *cs;
440 cs = HeapAlloc(GetProcessHeap(), 0, sizeof *cs);
441 if (!cs)
442 return NULL;
444 cs->ref = 0;
445 cs->lpVtbl = &csVtbl;
446 cs->lpInPlaceVtbl = &isVtbl;
447 cs->container = get_container();
448 cs->oo = oo;
450 hwnd = CreateWindowW(szIEWinFrame, winname, WS_VISIBLE|WS_OVERLAPPEDWINDOW,
451 CW_USEDEFAULT, CW_USEDEFAULT,
452 CW_USEDEFAULT, CW_USEDEFAULT,
453 NULL, NULL, shdocvw_hinstance, cs);
454 if (!hwnd)
456 HeapFree(GetProcessHeap(), 0, cs);
457 return NULL;
460 IOleObject_AddRef(oo);
461 cs->hwnd = hwnd;
462 *phwnd = hwnd;
464 This = (IOleClientSite*) cs;
465 IOleClientSite_AddRef(This);
466 SHDOCVW_LockModule();
468 return This;
471 void register_iewindow_class(void)
473 WNDCLASSW wc;
475 memset(&wc, 0, sizeof wc);
476 wc.style = 0;
477 wc.lpfnWndProc = ie_window_proc;
478 wc.cbClsExtra = 0;
479 wc.cbWndExtra = sizeof(iecs *);
480 wc.hInstance = shdocvw_hinstance;
481 wc.hIcon = 0;
482 wc.hCursor = LoadCursorW(0, MAKEINTRESOURCEW(IDI_APPLICATION));
483 wc.hbrBackground = 0;
484 wc.lpszClassName = szIEWinFrame;
485 wc.lpszMenuName = NULL;
487 RegisterClassW(&wc);
490 void unregister_iewindow_class(void)
492 UnregisterClassW(szIEWinFrame, shdocvw_hinstance);
495 BOOL create_ie_window(LPCWSTR url)
497 IWebBrowser2 *wb = NULL;
498 IOleObject *oo = NULL;
499 IOleClientSite *cs = NULL;
500 HRESULT r;
501 MSG msg;
502 RECT rcClient = { 0,0,100,100 };
503 BSTR bstrUrl;
504 HWND hwnd = NULL;
506 /* create the web browser */
507 r = CoCreateInstance(&CLSID_WebBrowser, NULL, CLSCTX_INPROC_SERVER,
508 &IID_IWebBrowser2, (LPVOID)&wb);
509 if (FAILED(r))
510 goto error;
512 /* get its IOleObject interface */
513 r = IWebBrowser2_QueryInterface(wb, &IID_IOleObject, (void**) &oo);
514 if (FAILED(r))
515 goto error;
517 /* create the window frame for the browser object */
518 cs = get_client_site(oo, &hwnd);
519 if (!cs)
520 goto error;
522 /* attach the browser to the window frame */
523 r = IOleObject_SetClientSite(oo, cs);
524 if (FAILED(r))
525 goto error;
527 /* activate the browser */
528 r = IOleObject_DoVerb(oo, OLEIVERB_INPLACEACTIVATE, &msg, cs, 0, hwnd, &rcClient);
529 if (FAILED(r))
530 goto error;
532 /* navigate to the first page */
533 bstrUrl = SysAllocString(url);
534 IWebBrowser2_Navigate(wb, bstrUrl, NULL, NULL, NULL, NULL);
536 /* run the message loop for this thread */
537 while (GetMessageW(&msg, 0, 0, 0))
539 TranslateMessage(&msg);
540 DispatchMessageW(&msg);
543 r = S_OK;
545 /* clean up */
546 error:
547 if (cs)
548 IOleClientSite_Release(cs);
549 if (oo)
550 IOleObject_Release(oo);
551 if (wb)
552 IOleObject_Release(wb);
554 return r;
557 HRESULT InternetExplorer_Create(IUnknown *pOuter, REFIID riid, void **ppv)
559 InternetExplorer *ret;
560 HRESULT hres;
562 TRACE("(%p %s %p)\n", pOuter, debugstr_guid(riid), ppv);
564 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(InternetExplorer));
565 ret->ref = 0;
567 ret->doc_host.disp = (IDispatch*)WEBBROWSER2(ret);
568 DocHost_Init(&ret->doc_host, (IDispatch*)WEBBROWSER2(ret));
570 InternetExplorer_WebBrowser_Init(ret);
572 /* create_frame_hwnd(ret); */
573 ret->doc_host.frame_hwnd = ret->frame_hwnd = NULL;
575 hres = IWebBrowser2_QueryInterface(WEBBROWSER2(ret), riid, ppv);
576 if(FAILED(hres)) {
577 HeapFree(GetProcessHeap(), 0, ret);
578 return hres;
581 return hres;
584 /******************************************************************
585 * IEWinMain (SHDOCVW.101)
587 * Only returns on error.
589 DWORD WINAPI IEWinMain(LPSTR szCommandLine, int nShowWindow)
591 LPWSTR url;
592 DWORD len;
593 HRESULT hres;
595 FIXME("%s %d\n", debugstr_a(szCommandLine), nShowWindow);
597 CoInitialize(NULL);
599 hres = register_class_object(TRUE);
600 if(FAILED(hres)) {
601 CoUninitialize();
602 ExitProcess(1);
605 /* FIXME: parse the command line properly, handle -Embedding */
607 len = MultiByteToWideChar(CP_ACP, 0, szCommandLine, -1, NULL, 0);
608 url = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
609 MultiByteToWideChar(CP_ACP, 0, szCommandLine, -1, url, len);
611 create_ie_window(url);
613 HeapFree(GetProcessHeap(), 0, url);
615 register_class_object(FALSE);
617 CoUninitialize();
619 ExitProcess(0);
620 return 0;