atl: Host component implementation: IOleInPlaceSiteWindowless.
[wine/wine64.git] / dlls / atl / atl_ax.c
blob2dcd891a29d2f1a96d78df4e2862fa5be4e7a7b9
1 /*
2 * Active Template Library ActiveX functions (atl.dll)
4 * Copyright 2006 Andrey Turkin
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <stdio.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winerror.h"
30 #include "winuser.h"
31 #include "wine/debug.h"
32 #include "objbase.h"
33 #include "objidl.h"
34 #include "ole2.h"
35 #include "exdisp.h"
36 #include "atlbase.h"
37 #include "atliface.h"
38 #include "atlwin.h"
40 #include "wine/unicode.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(atl);
44 typedef struct IOCS {
45 const IOleClientSiteVtbl *lpOleClientSiteVtbl;
46 const IOleContainerVtbl *lpOleContainerVtbl;
47 const IOleInPlaceSiteWindowlessVtbl *lpOleInPlaceSiteWindowlessVtbl;
49 LONG ref;
50 HWND hWnd;
51 IOleObject *control;
52 RECT size;
53 WNDPROC OrigWndProc;
54 BOOL fActive, fInPlace, fWindowless;
55 } IOCS;
57 /**********************************************************************
58 * AtlAxWin class window procedure
60 static LRESULT CALLBACK AtlAxWin_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam )
62 if ( wMsg == WM_CREATE )
64 DWORD len = GetWindowTextLengthW( hWnd ) + 1;
65 WCHAR *ptr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
66 if (!ptr)
67 return 1;
68 GetWindowTextW( hWnd, ptr, len );
69 AtlAxCreateControlEx( ptr, hWnd, NULL, NULL, NULL, NULL, NULL );
70 HeapFree( GetProcessHeap(), 0, ptr );
71 return 0;
73 return DefWindowProcW( hWnd, wMsg, wParam, lParam );
76 /***********************************************************************
77 * AtlAxWinInit [ATL.@]
78 * Initializes the control-hosting code: registering the AtlAxWin,
79 * AtlAxWin7 and AtlAxWinLic7 window classes and some messages.
81 * RETURNS
82 * TRUE or FALSE
85 BOOL WINAPI AtlAxWinInit(void)
87 WNDCLASSEXW wcex;
88 const WCHAR AtlAxWin[] = {'A','t','l','A','x','W','i','n',0};
90 FIXME("semi-stub\n");
92 if ( FAILED( OleInitialize(NULL) ) )
93 return FALSE;
95 wcex.cbSize = sizeof(wcex);
96 wcex.style = 0;
97 wcex.cbClsExtra = 0;
98 wcex.cbWndExtra = 0;
99 wcex.hInstance = GetModuleHandleW( NULL );
100 wcex.hIcon = NULL;
101 wcex.hCursor = NULL;
102 wcex.hbrBackground = NULL;
103 wcex.lpszMenuName = NULL;
104 wcex.hIconSm = 0;
106 wcex.lpfnWndProc = AtlAxWin_wndproc;
107 wcex.lpszClassName = AtlAxWin;
108 if ( !RegisterClassExW( &wcex ) )
109 return FALSE;
111 return TRUE;
114 /***********************************************************************
115 * Atl container component implementation
119 static ULONG WINAPI IOCS_AddRef(IOCS *This)
121 ULONG ref = InterlockedIncrement(&This->ref);
123 TRACE( "(%p) : AddRef from %d\n", This, ref - 1 );
125 return ref;
128 #define THIS2IOLECLIENTSITE(This) ((IOleClientSite*)&This->lpOleClientSiteVtbl)
129 #define THIS2IOLECONTAINER(This) ((IOleContainer*)&This->lpOleContainerVtbl)
130 #define THIS2IOLEINPLACESITEWINDOWLESS(This) ((IOleInPlaceSiteWindowless*)&This->lpOleInPlaceSiteWindowlessVtbl)
132 static HRESULT WINAPI IOCS_QueryInterface(IOCS *This, REFIID riid, void **ppv)
134 *ppv = NULL;
136 if ( IsEqualIID( &IID_IUnknown, riid )
137 || IsEqualIID( &IID_IOleClientSite, riid ) )
139 *ppv = THIS2IOLECLIENTSITE(This);
140 } else if ( IsEqualIID( &IID_IOleContainer, riid ) )
142 *ppv = THIS2IOLECONTAINER(This);
143 } else if ( IsEqualIID( &IID_IOleInPlaceSite, riid ) || IsEqualIID( &IID_IOleInPlaceSiteEx, riid ) || IsEqualIID( &IID_IOleInPlaceSiteWindowless, riid ) )
145 *ppv = THIS2IOLEINPLACESITEWINDOWLESS(This);
148 if (*ppv)
150 IOCS_AddRef( This );
151 return S_OK;
154 WARN("unsupported interface %s\n", debugstr_guid( riid ) );
155 *ppv = NULL;
156 return E_NOINTERFACE;
159 static HRESULT IOCS_Detach( IOCS *This );
160 static ULONG WINAPI IOCS_Release(IOCS *This)
162 ULONG ref = InterlockedDecrement(&This->ref);
164 TRACE( "(%p) : ReleaseRef to %d\n", This, ref );
166 if (!ref)
168 IOCS_Detach( This );
169 HeapFree( GetProcessHeap(), 0, This );
172 return ref;
175 #define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl)))
177 /****** IOleClientSite *****/
178 #undef IFACE2THIS
179 #define IFACE2THIS(iface) DEFINE_THIS(IOCS,OleClientSite, iface)
180 static HRESULT WINAPI OleClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
182 IOCS *This = IFACE2THIS(iface);
183 return IOCS_QueryInterface(This, riid, ppv);
185 static ULONG WINAPI OleClientSite_AddRef(IOleClientSite *iface)
187 IOCS *This = IFACE2THIS(iface);
188 return IOCS_AddRef(This);
190 static ULONG WINAPI OleClientSite_Release(IOleClientSite *iface)
192 IOCS *This = IFACE2THIS(iface);
193 return IOCS_Release(This);
195 static HRESULT WINAPI OleClientSite_SaveObject(IOleClientSite *iface)
197 IOCS *This = IFACE2THIS(iface);
198 FIXME( "(%p) - stub\n", This );
199 return E_NOTIMPL;
201 static HRESULT WINAPI OleClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
203 IOCS *This = IFACE2THIS(iface);
205 FIXME( "(%p, 0x%x, 0x%x, %p)\n", This, dwAssign, dwWhichMoniker, ppmk );
206 return E_NOTIMPL;
208 static HRESULT WINAPI OleClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
210 IOCS *This = IFACE2THIS(iface);
211 TRACE( "(%p, %p)\n", This, ppContainer );
212 return OleClientSite_QueryInterface( iface, &IID_IOleContainer, (void**)ppContainer );
214 static HRESULT WINAPI OleClientSite_ShowObject(IOleClientSite *iface)
216 IOCS *This = IFACE2THIS(iface);
217 FIXME( "(%p) - stub\n", This );
218 return S_OK;
220 static HRESULT WINAPI OleClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
222 IOCS *This = IFACE2THIS(iface);
223 FIXME( "(%p, %s) - stub\n", This, fShow ? "TRUE" : "FALSE" );
224 return E_NOTIMPL;
226 static HRESULT WINAPI OleClientSite_RequestNewObjectLayout(IOleClientSite *iface)
228 IOCS *This = IFACE2THIS(iface);
229 FIXME( "(%p) - stub\n", This );
230 return E_NOTIMPL;
232 #undef IFACE2THIS
235 /****** IOleContainer *****/
236 #define IFACE2THIS(iface) DEFINE_THIS(IOCS, OleContainer, iface)
237 static HRESULT WINAPI OleContainer_QueryInterface( IOleContainer* iface, REFIID riid, void** ppv)
239 IOCS *This = IFACE2THIS(iface);
240 return IOCS_QueryInterface( This, riid, ppv );
242 static ULONG WINAPI OleContainer_AddRef(IOleContainer* iface)
244 IOCS *This = IFACE2THIS(iface);
245 return IOCS_AddRef(This);
247 static ULONG WINAPI OleContainer_Release(IOleContainer* iface)
249 IOCS *This = IFACE2THIS(iface);
250 return IOCS_Release(This);
252 static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer* iface, IBindCtx* pbc,
253 LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
255 IOCS *This = IFACE2THIS(iface);
256 FIXME( "(%p,%p,%s,%p,%p) - stub\n", This, pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut );
257 return E_NOTIMPL;
259 static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer* iface, DWORD grfFlags, IEnumUnknown** ppenum)
261 IOCS *This = IFACE2THIS(iface);
262 FIXME( "(%p, %u, %p) - stub\n", This, grfFlags, ppenum );
263 return E_NOTIMPL;
265 static HRESULT WINAPI OleContainer_LockContainer(IOleContainer* iface, BOOL fLock)
267 IOCS *This = IFACE2THIS(iface);
268 FIXME( "(%p, %s) - stub\n", This, fLock?"TRUE":"FALSE" );
269 return E_NOTIMPL;
271 #undef IFACE2THIS
274 /****** IOleInPlaceSiteWindowless *******/
275 #define IFACE2THIS(iface) DEFINE_THIS(IOCS, OleInPlaceSiteWindowless, iface)
276 static HRESULT WINAPI OleInPlaceSiteWindowless_QueryInterface(IOleInPlaceSiteWindowless *iface, REFIID riid, void **ppv)
278 IOCS *This = IFACE2THIS(iface);
279 return IOCS_QueryInterface(This, riid, ppv);
281 static ULONG WINAPI OleInPlaceSiteWindowless_AddRef(IOleInPlaceSiteWindowless *iface)
283 IOCS *This = IFACE2THIS(iface);
284 return IOCS_AddRef(This);
286 static ULONG WINAPI OleInPlaceSiteWindowless_Release(IOleInPlaceSiteWindowless *iface)
288 IOCS *This = IFACE2THIS(iface);
289 return IOCS_Release(This);
291 static HRESULT WINAPI OleInPlaceSiteWindowless_GetWindow(IOleInPlaceSiteWindowless* iface, HWND* phwnd)
293 IOCS *This = IFACE2THIS(iface);
295 TRACE("(%p,%p)\n", This, phwnd);
296 *phwnd = This->hWnd;
297 return S_OK;
299 static HRESULT WINAPI OleInPlaceSiteWindowless_ContextSensitiveHelp(IOleInPlaceSiteWindowless* iface, BOOL fEnterMode)
301 IOCS *This = IFACE2THIS(iface);
302 FIXME("(%p,%d) - stub\n", This, fEnterMode);
303 return E_NOTIMPL;
305 static HRESULT WINAPI OleInPlaceSiteWindowless_CanInPlaceActivate(IOleInPlaceSiteWindowless *iface)
307 IOCS *This = IFACE2THIS(iface);
308 TRACE("(%p)\n", This);
309 return S_OK;
311 static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceActivate(IOleInPlaceSiteWindowless *iface)
313 IOCS *This = IFACE2THIS(iface);
315 TRACE("(%p)\n", This);
317 This->fInPlace = TRUE;
318 return S_OK;
320 static HRESULT WINAPI OleInPlaceSiteWindowless_OnUIActivate(IOleInPlaceSiteWindowless *iface)
322 IOCS *This = IFACE2THIS(iface);
324 TRACE("(%p)\n", This);
326 return S_OK;
328 static HRESULT WINAPI OleInPlaceSiteWindowless_GetWindowContext(IOleInPlaceSiteWindowless *iface,
329 IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
330 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
332 IOCS *This = IFACE2THIS(iface);
334 TRACE("(%p,%p,%p,%p,%p,%p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
336 if ( lprcClipRect )
337 memcpy(lprcClipRect, &This->size, sizeof(RECT));
338 if ( lprcPosRect )
339 memcpy(lprcPosRect, &This->size, sizeof(RECT));
341 if ( ppFrame )
343 *ppFrame = NULL;
346 if ( ppDoc )
347 *ppDoc = NULL;
349 if ( lpFrameInfo )
351 lpFrameInfo->fMDIApp = FALSE;
352 lpFrameInfo->hwndFrame = This->hWnd;
353 lpFrameInfo->haccel = NULL;
354 lpFrameInfo->cAccelEntries = 0;
357 return S_OK;
359 static HRESULT WINAPI OleInPlaceSiteWindowless_Scroll(IOleInPlaceSiteWindowless *iface, SIZE scrollExtent)
361 IOCS *This = IFACE2THIS(iface);
362 FIXME("(%p) - stub\n", This);
363 return E_NOTIMPL;
365 static HRESULT WINAPI OleInPlaceSiteWindowless_OnUIDeactivate(IOleInPlaceSiteWindowless *iface, BOOL fUndoable)
367 IOCS *This = IFACE2THIS(iface);
368 FIXME("(%p,%d) - stub\n", This, fUndoable);
369 return E_NOTIMPL;
371 static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceDeactivate(IOleInPlaceSiteWindowless *iface)
373 IOCS *This = IFACE2THIS(iface);
375 TRACE("(%p)\n", This);
377 This->fInPlace = This->fWindowless = FALSE;
378 return S_OK;
380 static HRESULT WINAPI OleInPlaceSiteWindowless_DiscardUndoState(IOleInPlaceSiteWindowless *iface)
382 IOCS *This = IFACE2THIS(iface);
383 FIXME("(%p) - stub\n", This);
384 return E_NOTIMPL;
386 static HRESULT WINAPI OleInPlaceSiteWindowless_DeactivateAndUndo(IOleInPlaceSiteWindowless *iface)
388 IOCS *This = IFACE2THIS(iface);
389 FIXME("(%p) - stub\n", This);
390 return E_NOTIMPL;
392 static HRESULT WINAPI OleInPlaceSiteWindowless_OnPosRectChange(IOleInPlaceSiteWindowless *iface, LPCRECT lprcPosRect)
394 IOCS *This = IFACE2THIS(iface);
395 FIXME("(%p,%p) - stub\n", This, lprcPosRect);
396 return E_NOTIMPL;
398 static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceActivateEx( IOleInPlaceSiteWindowless *iface, BOOL* pfNoRedraw, DWORD dwFlags)
400 IOCS *This = IFACE2THIS(iface);
402 TRACE("\n");
404 This->fActive = This->fInPlace = TRUE;
405 if ( dwFlags & ACTIVATE_WINDOWLESS )
406 This->fWindowless = TRUE;
407 return S_OK;
409 static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceDeactivateEx( IOleInPlaceSiteWindowless *iface, BOOL fNoRedraw)
411 IOCS *This = IFACE2THIS(iface);
413 TRACE("\n");
415 This->fActive = This->fInPlace = This->fWindowless = FALSE;
416 return S_OK;
418 static HRESULT WINAPI OleInPlaceSiteWindowless_RequestUIActivate( IOleInPlaceSiteWindowless *iface)
420 FIXME("\n");
421 return E_NOTIMPL;
423 static HRESULT WINAPI OleInPlaceSiteWindowless_CanWindowlessActivate( IOleInPlaceSiteWindowless *iface)
425 FIXME("\n");
426 return S_OK;
428 static HRESULT WINAPI OleInPlaceSiteWindowless_GetCapture( IOleInPlaceSiteWindowless *iface)
430 FIXME("\n");
431 return E_NOTIMPL;
433 static HRESULT WINAPI OleInPlaceSiteWindowless_SetCapture( IOleInPlaceSiteWindowless *iface, BOOL fCapture)
435 FIXME("\n");
436 return E_NOTIMPL;
438 static HRESULT WINAPI OleInPlaceSiteWindowless_GetFocus( IOleInPlaceSiteWindowless *iface)
440 FIXME("\n");
441 return E_NOTIMPL;
443 static HRESULT WINAPI OleInPlaceSiteWindowless_SetFocus( IOleInPlaceSiteWindowless *iface, BOOL fFocus)
445 FIXME("\n");
446 return E_NOTIMPL;
448 static HRESULT WINAPI OleInPlaceSiteWindowless_GetDC( IOleInPlaceSiteWindowless *iface, LPCRECT pRect, DWORD grfFlags, HDC* phDC)
450 FIXME("\n");
451 return E_NOTIMPL;
453 static HRESULT WINAPI OleInPlaceSiteWindowless_ReleaseDC( IOleInPlaceSiteWindowless *iface, HDC hDC)
455 FIXME("\n");
456 return E_NOTIMPL;
458 static HRESULT WINAPI OleInPlaceSiteWindowless_InvalidateRect( IOleInPlaceSiteWindowless *iface, LPCRECT pRect, BOOL fErase)
460 FIXME("\n");
461 return E_NOTIMPL;
463 static HRESULT WINAPI OleInPlaceSiteWindowless_InvalidateRgn( IOleInPlaceSiteWindowless *iface, HRGN hRGN, BOOL fErase)
465 FIXME("\n");
466 return E_NOTIMPL;
468 static HRESULT WINAPI OleInPlaceSiteWindowless_ScrollRect( IOleInPlaceSiteWindowless *iface, INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip)
470 FIXME("\n");
471 return E_NOTIMPL;
473 static HRESULT WINAPI OleInPlaceSiteWindowless_AdjustRect( IOleInPlaceSiteWindowless *iface, LPRECT prc)
475 FIXME("\n");
476 return E_NOTIMPL;
478 static HRESULT WINAPI OleInPlaceSiteWindowless_OnDefWindowMessage( IOleInPlaceSiteWindowless *iface, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult)
480 FIXME("\n");
481 return E_NOTIMPL;
485 static const IOleClientSiteVtbl OleClientSite_vtbl = {
486 OleClientSite_QueryInterface,
487 OleClientSite_AddRef,
488 OleClientSite_Release,
489 OleClientSite_SaveObject,
490 OleClientSite_GetMoniker,
491 OleClientSite_GetContainer,
492 OleClientSite_ShowObject,
493 OleClientSite_OnShowWindow,
494 OleClientSite_RequestNewObjectLayout
496 static const IOleContainerVtbl OleContainer_vtbl = {
497 OleContainer_QueryInterface,
498 OleContainer_AddRef,
499 OleContainer_Release,
500 OleContainer_ParseDisplayName,
501 OleContainer_EnumObjects,
502 OleContainer_LockContainer
504 static const IOleInPlaceSiteWindowlessVtbl OleInPlaceSiteWindowless_vtbl = {
505 OleInPlaceSiteWindowless_QueryInterface,
506 OleInPlaceSiteWindowless_AddRef,
507 OleInPlaceSiteWindowless_Release,
508 OleInPlaceSiteWindowless_GetWindow,
509 OleInPlaceSiteWindowless_ContextSensitiveHelp,
510 OleInPlaceSiteWindowless_CanInPlaceActivate,
511 OleInPlaceSiteWindowless_OnInPlaceActivate,
512 OleInPlaceSiteWindowless_OnUIActivate,
513 OleInPlaceSiteWindowless_GetWindowContext,
514 OleInPlaceSiteWindowless_Scroll,
515 OleInPlaceSiteWindowless_OnUIDeactivate,
516 OleInPlaceSiteWindowless_OnInPlaceDeactivate,
517 OleInPlaceSiteWindowless_DiscardUndoState,
518 OleInPlaceSiteWindowless_DeactivateAndUndo,
519 OleInPlaceSiteWindowless_OnPosRectChange,
520 OleInPlaceSiteWindowless_OnInPlaceActivateEx,
521 OleInPlaceSiteWindowless_OnInPlaceDeactivateEx,
522 OleInPlaceSiteWindowless_RequestUIActivate,
523 OleInPlaceSiteWindowless_CanWindowlessActivate,
524 OleInPlaceSiteWindowless_GetCapture,
525 OleInPlaceSiteWindowless_SetCapture,
526 OleInPlaceSiteWindowless_GetFocus,
527 OleInPlaceSiteWindowless_SetFocus,
528 OleInPlaceSiteWindowless_GetDC,
529 OleInPlaceSiteWindowless_ReleaseDC,
530 OleInPlaceSiteWindowless_InvalidateRect,
531 OleInPlaceSiteWindowless_InvalidateRgn,
532 OleInPlaceSiteWindowless_ScrollRect,
533 OleInPlaceSiteWindowless_AdjustRect,
534 OleInPlaceSiteWindowless_OnDefWindowMessage
537 static HRESULT IOCS_Detach( IOCS *This ) /* remove subclassing */
539 if ( This->hWnd )
541 SetWindowLongPtrW( This->hWnd, GWLP_WNDPROC, (ULONG_PTR) This->OrigWndProc );
542 SetWindowLongPtrW( This->hWnd, GWLP_USERDATA, (LONG_PTR) NULL );
543 This->hWnd = NULL;
545 if ( This->control )
547 IOleObject *control = This->control;
549 This->control = NULL;
550 IOleObject_SetClientSite( control, NULL );
551 IOleObject_Release( control );
553 return S_OK;
556 static void IOCS_OnSize( IOCS* This, LPCRECT rect )
558 SIZEL inPix, inHi;
560 This->size.left = rect->left; This->size.right = rect->right; This->size.top = rect->top; This->size.bottom = rect->bottom;
562 if ( !This->control )
563 return;
565 inPix.cx = rect->right - rect->left;
566 inPix.cy = rect->bottom - rect->top;
567 AtlPixelToHiMetric( &inPix, &inHi );
568 IOleObject_SetExtent( This->control, DVASPECT_CONTENT, &inHi );
570 if ( This->fInPlace )
572 IOleInPlaceObject *wl;
574 if ( SUCCEEDED( IOleObject_QueryInterface( This->control, &IID_IOleInPlaceObject, (void**)&wl ) ) )
576 IOleInPlaceObject_SetObjectRects( wl, rect, rect );
577 IOleInPlaceObject_Release( wl );
582 static void IOCS_OnShow( IOCS *This, BOOL fShow )
584 if (!This->control || This->fActive || !fShow )
585 return;
587 This->fActive = TRUE;
590 static void IOCS_OnDraw( IOCS *This )
592 IViewObject *view;
594 if ( !This->control || !This->fWindowless )
595 return;
597 if ( SUCCEEDED( IOleObject_QueryInterface( This->control, &IID_IViewObject, (void**)&view ) ) )
599 HDC dc = GetDC( This->hWnd );
600 RECTL rect;
602 rect.left = This->size.left; rect.top = This->size.top;
603 rect.bottom = This->size.bottom; rect.right = This->size.right;
605 IViewObject_Draw( view, DVASPECT_CONTENT, ~0, NULL, NULL, 0, dc, &rect, &rect, NULL, 0 );
606 IViewObject_Release( view );
607 ReleaseDC( This->hWnd, dc );
611 static LRESULT IOCS_OnWndProc( IOCS *This, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
613 WNDPROC OrigWndProc = This->OrigWndProc;
615 switch( uMsg )
617 case WM_DESTROY:
618 IOCS_Detach( This );
619 break;
620 case WM_SIZE:
622 RECT r;
623 r.left = r.top = 0;
624 r.right = LOWORD( lParam );
625 r.bottom = HIWORD( lParam );
626 IOCS_OnSize( This, &r );
628 break;
629 case WM_SHOWWINDOW:
630 IOCS_OnShow( This, (BOOL) wParam );
631 break;
632 case WM_PAINT:
633 IOCS_OnDraw( This );
634 break;
637 return OrigWndProc( hWnd, uMsg, wParam, lParam );
640 static LRESULT CALLBACK AtlHost_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam )
642 IOCS *This = (IOCS*) GetWindowLongPtrW( hWnd, GWLP_USERDATA );
643 return IOCS_OnWndProc( This, hWnd, wMsg, wParam, lParam );
646 static HRESULT IOCS_Attach( IOCS *This, HWND hWnd, IUnknown *pUnkControl ) /* subclass hWnd */
648 This->hWnd = hWnd;
649 IUnknown_QueryInterface( pUnkControl, &IID_IOleObject, (void**)&This->control );
650 IOleObject_SetClientSite( This->control, THIS2IOLECLIENTSITE( This ) );
651 This->OrigWndProc = (WNDPROC) GetWindowLongPtrW( This->hWnd, GWLP_WNDPROC );
652 SetWindowLongPtrW( hWnd, GWLP_USERDATA, (ULONG_PTR) This );
653 SetWindowLongPtrW( hWnd, GWLP_WNDPROC, (ULONG_PTR) AtlHost_wndproc );
655 return S_OK;
658 static HRESULT IOCS_Init( IOCS *This )
660 RECT rect;
661 static const WCHAR AXWIN[] = {'A','X','W','I','N',0};
663 IOleObject_SetHostNames( This->control, AXWIN, AXWIN );
665 GetClientRect( This->hWnd, &rect );
666 IOCS_OnSize( This, &rect );
667 IOleObject_DoVerb( This->control, OLEIVERB_INPLACEACTIVATE, NULL, THIS2IOLECLIENTSITE( This ), 0, This->hWnd, &rect );
669 return S_OK;
672 /**********************************************************************
673 * Create new instance of Atl host component and attach it to window *
675 static HRESULT IOCS_Create( HWND hWnd, IUnknown *pUnkControl, IOCS **ppSite )
677 HRESULT hr;
678 IOCS *This;
680 *ppSite = NULL;
681 This = HeapAlloc(GetProcessHeap(), 0, sizeof(IOCS));
683 if (!This)
684 return E_OUTOFMEMORY;
686 This->lpOleClientSiteVtbl = &OleClientSite_vtbl;
687 This->lpOleContainerVtbl = &OleContainer_vtbl;
688 This->lpOleInPlaceSiteWindowlessVtbl = &OleInPlaceSiteWindowless_vtbl;
689 This->ref = 1;
691 This->OrigWndProc = NULL;
692 This->hWnd = NULL;
693 This->fWindowless = This->fActive = This->fInPlace = FALSE;
695 hr = IOCS_Attach( This, hWnd, pUnkControl );
696 if ( SUCCEEDED( hr ) )
697 hr = IOCS_Init( This );
698 if ( SUCCEEDED( hr ) )
699 *ppSite = This;
700 else
701 IOCS_Release( This );
703 return hr;
707 /***********************************************************************
708 * AtlAxCreateControl [ATL.@]
710 HRESULT WINAPI AtlAxCreateControl(LPCOLESTR lpszName, HWND hWnd,
711 IStream *pStream, IUnknown **ppUnkContainer)
713 return AtlAxCreateControlEx( lpszName, hWnd, pStream, ppUnkContainer,
714 NULL, NULL, NULL );
717 /***********************************************************************
718 * AtlAxCreateControlEx [ATL.@]
720 * REMARKS
721 * See http://www.codeproject.com/com/cwebpage.asp for some background
724 HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd,
725 IStream *pStream, IUnknown **ppUnkContainer, IUnknown **ppUnkControl,
726 REFIID iidSink, IUnknown *punkSink)
728 CLSID controlId;
729 HRESULT hRes;
730 IOleObject *pControl;
731 IUnknown *pUnkControl;
732 IPersistStreamInit *pPSInit;
733 IUnknown *pContainer;
734 enum {IsGUID=0,IsHTML=1,IsURL=2} content;
736 TRACE("(%s %p %p %p %p %p %p)\n", debugstr_w(lpszName), hWnd, pStream,
737 ppUnkContainer, ppUnkControl, iidSink, punkSink);
739 hRes = CLSIDFromString( (LPOLESTR) lpszName, &controlId );
740 if ( FAILED(hRes) )
741 hRes = CLSIDFromProgID( lpszName, &controlId );
742 if ( SUCCEEDED( hRes ) )
743 content = IsGUID;
744 else {
745 /* FIXME - check for MSHTML: prefix! */
746 content = IsURL;
747 memcpy( &controlId, &CLSID_WebBrowser, sizeof(controlId) );
750 hRes = CoCreateInstance( &controlId, 0, CLSCTX_ALL, &IID_IOleObject,
751 (void**) &pControl );
752 if ( FAILED( hRes ) )
754 WARN( "cannot create ActiveX control %s instance - error 0x%08x\n",
755 debugstr_guid( &controlId ), hRes );
756 return hRes;
759 hRes = IOleObject_QueryInterface( pControl, &IID_IPersistStreamInit, (void**) &pPSInit );
760 if ( SUCCEEDED( hRes ) )
762 if (!pStream)
763 IPersistStreamInit_InitNew( pPSInit );
764 else
765 IPersistStreamInit_Load( pPSInit, pStream );
766 IPersistStreamInit_Release( pPSInit );
767 } else
768 WARN("cannot get IID_IPersistStreamInit out of control\n");
770 IOleObject_QueryInterface( pControl, &IID_IUnknown, (void**) &pUnkControl );
771 IOleObject_Release( pControl );
774 hRes = AtlAxAttachControl( pUnkControl, hWnd, &pContainer );
775 if ( FAILED( hRes ) )
776 WARN("cannot attach control to window\n");
778 if ( content == IsURL )
780 IWebBrowser2 *browser;
782 hRes = IOleObject_QueryInterface( pControl, &IID_IWebBrowser2, (void**) &browser );
783 if ( !browser )
784 WARN( "Cannot query IWebBrowser2 interface: %08x\n", hRes );
785 else {
786 VARIANT url;
788 IWebBrowser2_put_Visible( browser, VARIANT_TRUE ); /* it seems that native does this on URL (but do not on MSHTML:! why? */
790 V_VT(&url) = VT_BSTR;
791 V_BSTR(&url) = SysAllocString( lpszName );
793 hRes = IWebBrowser2_Navigate2( browser, &url, NULL, NULL, NULL, NULL );
794 if ( FAILED( hRes ) )
795 WARN( "IWebBrowser2::Navigate2 failed: %08x\n", hRes );
796 SysFreeString( V_BSTR(&url) );
798 IWebBrowser2_Release( browser );
802 if (ppUnkContainer)
804 *ppUnkContainer = pContainer;
805 if ( pContainer )
806 IUnknown_AddRef( pContainer );
808 if (ppUnkControl)
810 *ppUnkControl = pUnkControl;
811 if ( pUnkControl )
812 IUnknown_AddRef( pUnkControl );
815 IUnknown_Release( pUnkControl );
816 if ( pContainer )
817 IUnknown_Release( pContainer );
819 return S_OK;
822 /***********************************************************************
823 * AtlAxAttachControl [ATL.@]
825 HRESULT WINAPI AtlAxAttachControl(IUnknown* pControl, HWND hWnd, IUnknown** ppUnkContainer)
827 IOCS *pUnkContainer;
828 HRESULT hr;
830 TRACE( "%p %p %p\n", pControl, hWnd, ppUnkContainer );
832 *ppUnkContainer = NULL;
834 hr = IOCS_Create( hWnd, pControl, &pUnkContainer );
835 if ( SUCCEEDED( hr ) )
837 *ppUnkContainer = (IUnknown*) pUnkContainer;
840 return hr;
843 /**********************************************************************
844 * Helper function for AX_ConvertDialogTemplate
846 static inline BOOL advance_array(WORD **pptr, DWORD *palloc, DWORD *pfilled, const WORD *data, DWORD size)
848 if ( (*pfilled + size) > *palloc )
850 *palloc = ((*pfilled+size) + 0xFF) & ~0xFF;
851 *pptr = HeapReAlloc( GetProcessHeap(), 0, *pptr, *palloc * sizeof(WORD) );
852 if (!*pptr)
853 return FALSE;
855 RtlMoveMemory( *pptr+*pfilled, data, size * sizeof(WORD) );
856 *pfilled += size;
857 return TRUE;
860 /**********************************************************************
861 * Convert ActiveX control templates to AtlAxWin class instances
863 static LPDLGTEMPLATEW AX_ConvertDialogTemplate(LPCDLGTEMPLATEW src_tmpl)
865 #define GET_WORD(x) (*(const WORD *)(x))
866 #define GET_DWORD(x) (*(const DWORD *)(x))
867 #define PUT_BLOCK(x,y) do {if (!advance_array(&output, &allocated, &filled, (x), (y))) return NULL;} while (0)
868 #define PUT_WORD(x) do {WORD w = (x);PUT_BLOCK(&w, 1);} while(0)
869 #define PUT_DWORD(x) do {DWORD w = (x);PUT_BLOCK(&w, 2);} while(0)
870 const WORD *tmp, *src = (const WORD *)src_tmpl;
871 WORD *output;
872 DWORD allocated, filled; /* in WORDs */
873 BOOL ext;
874 WORD signature, dlgver, rescount;
875 DWORD style;
877 filled = 0; allocated = 256;
878 output = HeapAlloc( GetProcessHeap(), 0, allocated * sizeof(WORD) );
879 if (!output)
880 return NULL;
882 /* header */
883 tmp = src;
884 signature = GET_WORD(src);
885 dlgver = GET_WORD(src + 1);
886 if (signature == 1 && dlgver == 0xFFFF)
888 ext = TRUE;
889 src += 6;
890 style = GET_DWORD(src);
891 src += 2;
892 rescount = GET_WORD(src++);
893 src += 4;
894 if ( GET_WORD(src) == 0xFFFF ) /* menu */
895 src += 2;
896 else
897 src += strlenW(src) + 1;
898 if ( GET_WORD(src) == 0xFFFF ) /* class */
899 src += 2;
900 else
901 src += strlenW(src) + 1;
902 src += strlenW(src) + 1; /* title */
903 if ( style & (DS_SETFONT | DS_SHELLFONT) )
905 src += 3;
906 src += strlenW(src) + 1;
908 } else {
909 ext = FALSE;
910 style = GET_DWORD(src);
911 src += 4;
912 rescount = GET_WORD(src++);
913 src += 4;
914 if ( GET_WORD(src) == 0xFFFF ) /* menu */
915 src += 2;
916 else
917 src += strlenW(src) + 1;
918 if ( GET_WORD(src) == 0xFFFF ) /* class */
919 src += 2;
920 else
921 src += strlenW(src) + 1;
922 src += strlenW(src) + 1; /* title */
923 if ( style & DS_SETFONT )
925 src++;
926 src += strlenW(src) + 1;
929 PUT_BLOCK(tmp, src-tmp);
931 while(rescount--)
933 src = (const WORD *)( ( ((ULONG)src) + 3) & ~3); /* align on DWORD boundary */
934 filled = (filled + 1) & ~1; /* depends on DWORD-aligned allocation unit */
936 tmp = src;
937 if (ext)
938 src += 11;
939 else
940 src += 9;
941 PUT_BLOCK(tmp, src-tmp);
943 tmp = src;
944 if ( GET_WORD(src) == 0xFFFF ) /* class */
946 src += 2;
947 } else
949 src += strlenW(src) + 1;
951 src += strlenW(src) + 1; /* title */
952 if ( GET_WORD(tmp) == '{' ) /* all this mess created because of this line */
954 const WCHAR AtlAxWin[9]={'A','t','l','A','x','W','i','n',0};
955 PUT_BLOCK(AtlAxWin, sizeof(AtlAxWin)/sizeof(WORD));
956 PUT_BLOCK(tmp, strlenW(tmp)+1);
957 } else
958 PUT_BLOCK(tmp, src-tmp);
960 if ( GET_WORD(src) )
962 WORD size = (GET_WORD(src)+sizeof(WORD)-1) / sizeof(WORD); /* quite ugly :( Maybe use BYTE* instead of WORD* everywhere ? */
963 PUT_BLOCK(src, size);
964 src+=size;
966 else
968 PUT_WORD(0);
969 src++;
972 return (LPDLGTEMPLATEW) output;
975 /***********************************************************************
976 * AtlAxCreateDialogA [ATL.@]
978 * Creates a dialog window
980 * PARAMS
981 * hInst [I] Application instance
982 * name [I] Dialog box template name
983 * owner [I] Dialog box parent HWND
984 * dlgProc [I] Dialog box procedure
985 * param [I] This value will be passed to dlgProc as WM_INITDIALOG's message lParam
987 * RETURNS
988 * Window handle of dialog window.
990 HWND WINAPI AtlAxCreateDialogA(HINSTANCE hInst, LPCSTR name, HWND owner, DLGPROC dlgProc ,LPARAM param)
992 HWND res = NULL;
993 int length;
994 WCHAR *nameW;
996 if ( HIWORD(name) == 0 )
997 return AtlAxCreateDialogW( hInst, (LPCWSTR) name, owner, dlgProc, param );
999 length = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
1000 nameW = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) );
1001 if (nameW)
1003 MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, length );
1004 res = AtlAxCreateDialogW( hInst, nameW, owner, dlgProc, param );
1005 HeapFree( GetProcessHeap(), 0, nameW );
1007 return res;
1010 /***********************************************************************
1011 * AtlAxCreateDialogW [ATL.@]
1013 * See AtlAxCreateDialogA
1016 HWND WINAPI AtlAxCreateDialogW(HINSTANCE hInst, LPCWSTR name, HWND owner, DLGPROC dlgProc ,LPARAM param)
1018 HRSRC hrsrc;
1019 HGLOBAL hgl;
1020 LPCDLGTEMPLATEW ptr;
1021 LPDLGTEMPLATEW newptr;
1022 HWND res;
1024 FIXME("(%p %s %p %p %lx) - not tested\n", hInst, debugstr_w(name), owner, dlgProc, param);
1026 hrsrc = FindResourceW( hInst, name, (LPWSTR)RT_DIALOG );
1027 if ( !hrsrc )
1028 return NULL;
1029 hgl = LoadResource (hInst, hrsrc);
1030 if ( !hgl )
1031 return NULL;
1032 ptr = (LPCDLGTEMPLATEW)LockResource ( hgl );
1033 if (!ptr)
1035 FreeResource( hgl );
1036 return NULL;
1038 newptr = AX_ConvertDialogTemplate( ptr );
1039 if ( newptr )
1041 res = CreateDialogIndirectParamW( hInst, newptr, owner, dlgProc, param );
1042 HeapFree( GetProcessHeap(), 0, newptr );
1043 } else
1044 res = NULL;
1045 FreeResource ( hrsrc );
1046 return res;