ole32: Release the global interface table in the tests when it is no longer needed.
[wine] / dlls / atl / atl_ax.c
1 /*
2  * Active Template Library ActiveX functions (atl.dll)
3  *
4  * Copyright 2006 Andrey Turkin
5  *
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.
10  *
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.
15  *
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
19  */
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 "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"
39
40 #include "wine/unicode.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(atl);
43
44 typedef struct IOCS {
45     const IOleClientSiteVtbl *lpOleClientSiteVtbl;
46     const IOleContainerVtbl *lpOleContainerVtbl;
47     const IOleInPlaceSiteWindowlessVtbl *lpOleInPlaceSiteWindowlessVtbl;
48     const IOleInPlaceFrameVtbl *lpOleInPlaceFrameVtbl;
49     const IOleControlSiteVtbl *lpOleControlSiteVtbl;
50
51     LONG ref;
52     HWND hWnd;
53     IOleObject *control;
54     RECT size;
55     WNDPROC OrigWndProc;
56     BOOL fActive, fInPlace, fWindowless;
57 } IOCS;
58
59 /**********************************************************************
60  * AtlAxWin class window procedure
61  */
62 static LRESULT CALLBACK AtlAxWin_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam )
63 {
64     if ( wMsg == WM_CREATE )
65     {
66             DWORD len = GetWindowTextLengthW( hWnd ) + 1;
67             WCHAR *ptr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
68             if (!ptr)
69                 return 1;
70             GetWindowTextW( hWnd, ptr, len );
71             AtlAxCreateControlEx( ptr, hWnd, NULL, NULL, NULL, NULL, NULL );
72             HeapFree( GetProcessHeap(), 0, ptr );
73             return 0;
74     }
75     return DefWindowProcW( hWnd, wMsg, wParam, lParam );
76 }
77
78 /***********************************************************************
79  *           AtlAxWinInit          [ATL.@]
80  * Initializes the control-hosting code: registering the AtlAxWin,
81  * AtlAxWin7 and AtlAxWinLic7 window classes and some messages.
82  *
83  * RETURNS
84  *  TRUE or FALSE
85  */
86
87 BOOL WINAPI AtlAxWinInit(void)
88 {
89     WNDCLASSEXW wcex;
90     const WCHAR AtlAxWin[] = {'A','t','l','A','x','W','i','n',0};
91
92     FIXME("semi-stub\n");
93
94     if ( FAILED( OleInitialize(NULL) ) )
95         return FALSE;
96
97     wcex.cbSize        = sizeof(wcex);
98     wcex.style         = 0;
99     wcex.cbClsExtra    = 0;
100     wcex.cbWndExtra    = 0;
101     wcex.hInstance     = GetModuleHandleW( NULL );
102     wcex.hIcon         = NULL;
103     wcex.hCursor       = NULL;
104     wcex.hbrBackground = NULL;
105     wcex.lpszMenuName  = NULL;
106     wcex.hIconSm       = 0;
107
108     wcex.lpfnWndProc   = AtlAxWin_wndproc;
109     wcex.lpszClassName = AtlAxWin;
110     if ( !RegisterClassExW( &wcex ) )
111         return FALSE;
112
113     return TRUE;
114 }
115
116 /***********************************************************************
117  *  Atl container component implementation
118  */
119
120
121 static ULONG WINAPI IOCS_AddRef(IOCS *This)
122 {
123     ULONG ref = InterlockedIncrement(&This->ref);
124
125     TRACE( "(%p) : AddRef from %d\n", This, ref - 1 );
126
127     return ref;
128 }
129
130 #define THIS2IOLECLIENTSITE(This) ((IOleClientSite*)&This->lpOleClientSiteVtbl)
131 #define THIS2IOLECONTAINER(This) ((IOleContainer*)&This->lpOleContainerVtbl)
132 #define THIS2IOLEINPLACESITEWINDOWLESS(This) ((IOleInPlaceSiteWindowless*)&This->lpOleInPlaceSiteWindowlessVtbl)
133 #define THIS2IOLEINPLACEFRAME(This) ((IOleInPlaceFrame*)&This->lpOleInPlaceFrameVtbl)
134 #define THIS2IOLECONTROLSITE(This) ((IOleControlSite*)&This->lpOleControlSiteVtbl)
135
136 static HRESULT WINAPI IOCS_QueryInterface(IOCS *This, REFIID riid, void **ppv)
137 {
138     *ppv = NULL;
139
140     if ( IsEqualIID( &IID_IUnknown, riid )
141       || IsEqualIID( &IID_IOleClientSite, riid ) )
142     {
143         *ppv = THIS2IOLECLIENTSITE(This);
144     } else if ( IsEqualIID( &IID_IOleContainer, riid ) )
145     {
146         *ppv = THIS2IOLECONTAINER(This);
147     } else if ( IsEqualIID( &IID_IOleInPlaceSite, riid ) || IsEqualIID( &IID_IOleInPlaceSiteEx, riid ) || IsEqualIID( &IID_IOleInPlaceSiteWindowless, riid ) )
148     {
149         *ppv = THIS2IOLEINPLACESITEWINDOWLESS(This);
150     } else if ( IsEqualIID( &IID_IOleInPlaceFrame, riid ) )
151     {
152         *ppv = THIS2IOLEINPLACEFRAME(This);
153     } else if ( IsEqualIID( &IID_IOleControlSite, riid ) )
154     {
155         *ppv = THIS2IOLECONTROLSITE(This);
156     }
157
158     if (*ppv)
159     {
160         IOCS_AddRef( This );
161         return S_OK;
162     }
163
164     WARN("unsupported interface %s\n", debugstr_guid( riid ) );
165     *ppv = NULL;
166     return E_NOINTERFACE;
167 }
168
169 static HRESULT IOCS_Detach( IOCS *This );
170 static ULONG WINAPI IOCS_Release(IOCS *This)
171 {
172     ULONG ref = InterlockedDecrement(&This->ref);
173
174     TRACE( "(%p) : ReleaseRef to %d\n", This, ref );
175
176     if (!ref)
177     {
178         IOCS_Detach( This );
179         HeapFree( GetProcessHeap(), 0, This );
180     }
181
182     return ref;
183 }
184
185 #define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl)))
186
187 /******      IOleClientSite    *****/
188 #undef  IFACE2THIS
189 #define IFACE2THIS(iface) DEFINE_THIS(IOCS,OleClientSite, iface)
190 static HRESULT WINAPI OleClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
191 {
192     IOCS *This = IFACE2THIS(iface);
193     return IOCS_QueryInterface(This, riid, ppv);
194 }
195 static ULONG WINAPI OleClientSite_AddRef(IOleClientSite *iface)
196 {
197     IOCS *This = IFACE2THIS(iface);
198     return IOCS_AddRef(This);
199 }
200 static ULONG WINAPI OleClientSite_Release(IOleClientSite *iface)
201 {
202     IOCS *This = IFACE2THIS(iface);
203     return IOCS_Release(This);
204 }
205 static HRESULT WINAPI OleClientSite_SaveObject(IOleClientSite *iface)
206 {
207     IOCS *This = IFACE2THIS(iface);
208     FIXME( "(%p) - stub\n", This );
209     return E_NOTIMPL;
210 }
211 static HRESULT WINAPI OleClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
212 {
213     IOCS *This = IFACE2THIS(iface);
214
215     FIXME( "(%p, 0x%x, 0x%x, %p)\n", This, dwAssign, dwWhichMoniker, ppmk );
216     return E_NOTIMPL;
217 }
218 static HRESULT WINAPI OleClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
219 {
220     IOCS *This = IFACE2THIS(iface);
221     TRACE( "(%p, %p)\n", This, ppContainer );
222     return OleClientSite_QueryInterface( iface, &IID_IOleContainer, (void**)ppContainer );
223 }
224 static HRESULT WINAPI OleClientSite_ShowObject(IOleClientSite *iface)
225 {
226     IOCS *This = IFACE2THIS(iface);
227     FIXME( "(%p) - stub\n", This );
228     return S_OK;
229 }
230 static HRESULT WINAPI OleClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
231 {
232     IOCS *This = IFACE2THIS(iface);
233     FIXME( "(%p, %s) - stub\n", This, fShow ? "TRUE" : "FALSE" );
234     return E_NOTIMPL;
235 }
236 static HRESULT WINAPI OleClientSite_RequestNewObjectLayout(IOleClientSite *iface)
237 {
238     IOCS *This = IFACE2THIS(iface);
239     FIXME( "(%p) - stub\n", This );
240     return E_NOTIMPL;
241 }
242 #undef IFACE2THIS
243
244
245 /******      IOleContainer     *****/
246 #define IFACE2THIS(iface) DEFINE_THIS(IOCS, OleContainer, iface)
247 static HRESULT WINAPI OleContainer_QueryInterface( IOleContainer* iface, REFIID riid, void** ppv)
248 {
249     IOCS *This = IFACE2THIS(iface);
250     return IOCS_QueryInterface( This, riid, ppv );
251 }
252 static ULONG WINAPI OleContainer_AddRef(IOleContainer* iface)
253 {
254     IOCS *This = IFACE2THIS(iface);
255     return IOCS_AddRef(This);
256 }
257 static ULONG WINAPI OleContainer_Release(IOleContainer* iface)
258 {
259     IOCS *This = IFACE2THIS(iface);
260     return IOCS_Release(This);
261 }
262 static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer* iface, IBindCtx* pbc,
263         LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
264 {
265     IOCS *This = IFACE2THIS(iface);
266     FIXME( "(%p,%p,%s,%p,%p) - stub\n", This, pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut );
267     return E_NOTIMPL;
268 }
269 static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer* iface, DWORD grfFlags, IEnumUnknown** ppenum)
270 {
271     IOCS *This = IFACE2THIS(iface);
272     FIXME( "(%p, %u, %p) - stub\n", This, grfFlags, ppenum );
273     return E_NOTIMPL;
274 }
275 static HRESULT WINAPI OleContainer_LockContainer(IOleContainer* iface, BOOL fLock)
276 {
277     IOCS *This = IFACE2THIS(iface);
278     FIXME( "(%p, %s) - stub\n", This, fLock?"TRUE":"FALSE" );
279     return E_NOTIMPL;
280 }
281 #undef  IFACE2THIS
282
283
284 /******    IOleInPlaceSiteWindowless   *******/
285 #define IFACE2THIS(iface) DEFINE_THIS(IOCS, OleInPlaceSiteWindowless, iface)
286 static HRESULT WINAPI OleInPlaceSiteWindowless_QueryInterface(IOleInPlaceSiteWindowless *iface, REFIID riid, void **ppv)
287 {
288     IOCS *This = IFACE2THIS(iface);
289     return IOCS_QueryInterface(This, riid, ppv);
290 }
291 static ULONG WINAPI OleInPlaceSiteWindowless_AddRef(IOleInPlaceSiteWindowless *iface)
292 {
293     IOCS *This = IFACE2THIS(iface);
294     return IOCS_AddRef(This);
295 }
296 static ULONG WINAPI OleInPlaceSiteWindowless_Release(IOleInPlaceSiteWindowless *iface)
297 {
298     IOCS *This = IFACE2THIS(iface);
299     return IOCS_Release(This);
300 }
301 static HRESULT WINAPI OleInPlaceSiteWindowless_GetWindow(IOleInPlaceSiteWindowless* iface, HWND* phwnd)
302 {
303     IOCS *This = IFACE2THIS(iface);
304
305     TRACE("(%p,%p)\n", This, phwnd);
306     *phwnd = This->hWnd;
307     return S_OK;
308 }
309 static HRESULT WINAPI OleInPlaceSiteWindowless_ContextSensitiveHelp(IOleInPlaceSiteWindowless* iface, BOOL fEnterMode)
310 {
311     IOCS *This = IFACE2THIS(iface);
312     FIXME("(%p,%d) - stub\n", This, fEnterMode);
313     return E_NOTIMPL;
314 }
315 static HRESULT WINAPI OleInPlaceSiteWindowless_CanInPlaceActivate(IOleInPlaceSiteWindowless *iface)
316 {
317     IOCS *This = IFACE2THIS(iface);
318     TRACE("(%p)\n", This);
319     return S_OK;
320 }
321 static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceActivate(IOleInPlaceSiteWindowless *iface)
322 {
323     IOCS *This = IFACE2THIS(iface);
324
325     TRACE("(%p)\n", This);
326
327     This->fInPlace = TRUE;
328     return S_OK;
329 }
330 static HRESULT WINAPI OleInPlaceSiteWindowless_OnUIActivate(IOleInPlaceSiteWindowless *iface)
331 {
332     IOCS *This = IFACE2THIS(iface);
333
334     TRACE("(%p)\n", This);
335
336     return S_OK;
337 }
338 static HRESULT WINAPI OleInPlaceSiteWindowless_GetWindowContext(IOleInPlaceSiteWindowless *iface,
339         IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
340         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
341 {
342     IOCS *This = IFACE2THIS(iface);
343
344     TRACE("(%p,%p,%p,%p,%p,%p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
345
346     if ( lprcClipRect )
347         memcpy(lprcClipRect, &This->size, sizeof(RECT));
348     if ( lprcPosRect )
349         memcpy(lprcPosRect, &This->size, sizeof(RECT));
350
351     if ( ppFrame )
352     {
353         IOCS_QueryInterface( This, &IID_IOleInPlaceFrame, (void**) ppFrame );
354     }
355
356     if ( ppDoc )
357         *ppDoc = NULL;
358
359     if ( lpFrameInfo )
360     {
361         lpFrameInfo->fMDIApp = FALSE;
362         lpFrameInfo->hwndFrame = This->hWnd;
363         lpFrameInfo->haccel = NULL;
364         lpFrameInfo->cAccelEntries = 0;
365     }
366
367     return S_OK;
368 }
369 static HRESULT WINAPI OleInPlaceSiteWindowless_Scroll(IOleInPlaceSiteWindowless *iface, SIZE scrollExtent)
370 {
371     IOCS *This = IFACE2THIS(iface);
372     FIXME("(%p) - stub\n", This);
373     return E_NOTIMPL;
374 }
375 static HRESULT WINAPI OleInPlaceSiteWindowless_OnUIDeactivate(IOleInPlaceSiteWindowless *iface, BOOL fUndoable)
376 {
377     IOCS *This = IFACE2THIS(iface);
378     FIXME("(%p,%d) - stub\n", This, fUndoable);
379     return E_NOTIMPL;
380 }
381 static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceDeactivate(IOleInPlaceSiteWindowless *iface)
382 {
383     IOCS *This = IFACE2THIS(iface);
384
385     TRACE("(%p)\n", This);
386
387     This->fInPlace = This->fWindowless = FALSE;
388     return S_OK;
389 }
390 static HRESULT WINAPI OleInPlaceSiteWindowless_DiscardUndoState(IOleInPlaceSiteWindowless *iface)
391 {
392     IOCS *This = IFACE2THIS(iface);
393     FIXME("(%p) - stub\n", This);
394     return E_NOTIMPL;
395 }
396 static HRESULT WINAPI OleInPlaceSiteWindowless_DeactivateAndUndo(IOleInPlaceSiteWindowless *iface)
397 {
398     IOCS *This = IFACE2THIS(iface);
399     FIXME("(%p) - stub\n", This);
400     return E_NOTIMPL;
401 }
402 static HRESULT WINAPI OleInPlaceSiteWindowless_OnPosRectChange(IOleInPlaceSiteWindowless *iface, LPCRECT lprcPosRect)
403 {
404     IOCS *This = IFACE2THIS(iface);
405     FIXME("(%p,%p) - stub\n", This, lprcPosRect);
406     return E_NOTIMPL;
407 }
408 static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceActivateEx( IOleInPlaceSiteWindowless *iface, BOOL* pfNoRedraw, DWORD dwFlags)
409 {
410     IOCS *This = IFACE2THIS(iface);
411
412     TRACE("\n");
413
414     This->fActive = This->fInPlace = TRUE;
415     if ( dwFlags & ACTIVATE_WINDOWLESS )
416         This->fWindowless = TRUE;
417     return S_OK;
418 }
419 static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceDeactivateEx( IOleInPlaceSiteWindowless *iface, BOOL fNoRedraw)
420 {
421     IOCS *This = IFACE2THIS(iface);
422
423     TRACE("\n");
424
425     This->fActive = This->fInPlace = This->fWindowless = FALSE;
426     return S_OK;
427 }
428 static HRESULT WINAPI OleInPlaceSiteWindowless_RequestUIActivate( IOleInPlaceSiteWindowless *iface)
429 {
430     FIXME("\n");
431     return E_NOTIMPL;
432 }
433 static HRESULT WINAPI OleInPlaceSiteWindowless_CanWindowlessActivate( IOleInPlaceSiteWindowless *iface)
434 {
435     FIXME("\n");
436     return S_OK;
437 }
438 static HRESULT WINAPI OleInPlaceSiteWindowless_GetCapture( IOleInPlaceSiteWindowless *iface)
439 {
440     FIXME("\n");
441     return E_NOTIMPL;
442 }
443 static HRESULT WINAPI OleInPlaceSiteWindowless_SetCapture( IOleInPlaceSiteWindowless *iface, BOOL fCapture)
444 {
445     FIXME("\n");
446     return E_NOTIMPL;
447 }
448 static HRESULT WINAPI OleInPlaceSiteWindowless_GetFocus( IOleInPlaceSiteWindowless *iface)
449 {
450     FIXME("\n");
451     return E_NOTIMPL;
452 }
453 static HRESULT WINAPI OleInPlaceSiteWindowless_SetFocus( IOleInPlaceSiteWindowless *iface, BOOL fFocus)
454 {
455     FIXME("\n");
456     return E_NOTIMPL;
457 }
458 static HRESULT WINAPI OleInPlaceSiteWindowless_GetDC( IOleInPlaceSiteWindowless *iface, LPCRECT pRect, DWORD grfFlags, HDC* phDC)
459 {
460     FIXME("\n");
461     return E_NOTIMPL;
462 }
463 static HRESULT WINAPI OleInPlaceSiteWindowless_ReleaseDC( IOleInPlaceSiteWindowless *iface, HDC hDC)
464 {
465     FIXME("\n");
466     return E_NOTIMPL;
467 }
468 static HRESULT WINAPI OleInPlaceSiteWindowless_InvalidateRect( IOleInPlaceSiteWindowless *iface, LPCRECT pRect, BOOL fErase)
469 {
470     FIXME("\n");
471     return E_NOTIMPL;
472 }
473 static HRESULT WINAPI OleInPlaceSiteWindowless_InvalidateRgn( IOleInPlaceSiteWindowless *iface, HRGN hRGN, BOOL fErase)
474 {
475     FIXME("\n");
476     return E_NOTIMPL;
477 }
478 static HRESULT WINAPI OleInPlaceSiteWindowless_ScrollRect( IOleInPlaceSiteWindowless *iface, INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip)
479 {
480     FIXME("\n");
481     return E_NOTIMPL;
482 }
483 static HRESULT WINAPI OleInPlaceSiteWindowless_AdjustRect( IOleInPlaceSiteWindowless *iface, LPRECT prc)
484 {
485     FIXME("\n");
486     return E_NOTIMPL;
487 }
488 static HRESULT WINAPI OleInPlaceSiteWindowless_OnDefWindowMessage( IOleInPlaceSiteWindowless *iface, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult)
489 {
490     FIXME("\n");
491     return E_NOTIMPL;
492 }
493 #undef IFACE2THIS
494
495
496 /******    IOleInPlaceFrame   *******/
497 #define IFACE2THIS(iface) DEFINE_THIS(IOCS, OleInPlaceFrame, iface)
498 static HRESULT WINAPI OleInPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
499 {
500     IOCS *This = IFACE2THIS(iface);
501     return IOCS_QueryInterface(This, riid, ppv);
502 }
503 static ULONG WINAPI OleInPlaceFrame_AddRef(IOleInPlaceFrame *iface)
504 {
505     IOCS *This = IFACE2THIS(iface);
506     return IOCS_AddRef(This);
507 }
508 static ULONG WINAPI OleInPlaceFrame_Release(IOleInPlaceFrame *iface)
509 {
510     IOCS *This = IFACE2THIS(iface);
511     return IOCS_Release(This);
512 }
513 static HRESULT WINAPI OleInPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phWnd)
514 {
515     IOCS *This = IFACE2THIS(iface);
516
517     TRACE( "(%p,%p)\n", This, phWnd );
518
519     *phWnd = This->hWnd;
520     return S_OK;
521 }
522
523 static HRESULT WINAPI OleInPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
524 {
525     IOCS *This = IFACE2THIS(iface);
526
527     FIXME( "(%p,%d) - stub\n", This, fEnterMode );
528     return E_NOTIMPL;
529 }
530
531 static HRESULT WINAPI OleInPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
532 {
533     IOCS *This = IFACE2THIS(iface);
534
535     FIXME( "(%p,%p) - stub\n", This, lprectBorder );
536     return E_NOTIMPL;
537 }
538
539 static HRESULT WINAPI OleInPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface, LPCBORDERWIDTHS pborderwidths)
540 {
541     IOCS *This = IFACE2THIS(iface);
542
543     FIXME( "(%p,%p) - stub\n", This, pborderwidths );
544     return E_NOTIMPL;
545 }
546
547 static HRESULT WINAPI OleInPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface, LPCBORDERWIDTHS pborderwidths)
548 {
549     IOCS *This = IFACE2THIS(iface);
550
551     FIXME( "(%p,%p) - stub\n", This, pborderwidths );
552     return E_NOTIMPL;
553 }
554
555 static HRESULT WINAPI OleInPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
556 {
557     IOCS *This = IFACE2THIS(iface);
558
559     FIXME( "(%p,%p,%s) - stub\n", This, pActiveObject, debugstr_w(pszObjName) );
560     return S_OK;
561 }
562
563 static HRESULT WINAPI OleInPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
564 {
565     IOCS *This = IFACE2THIS(iface);
566
567     FIXME( "(%p,%p,%p) - stub\n", This, hmenuShared, lpMenuWidths );
568     return E_NOTIMPL;
569 }
570
571 static HRESULT WINAPI OleInPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
572 {
573     IOCS *This = IFACE2THIS(iface);
574
575     FIXME( "(%p,%p,%p,%p) - stub\n", This, hmenuShared, holemenu, hwndActiveObject );
576     return E_NOTIMPL;
577 }
578 static HRESULT WINAPI OleInPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
579 {
580     IOCS *This = IFACE2THIS(iface);
581
582     FIXME( "(%p, %p) - stub\n", This, hmenuShared );
583     return E_NOTIMPL;
584 }
585
586 static HRESULT WINAPI OleInPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
587 {
588     IOCS *This = IFACE2THIS(iface);
589
590     FIXME( "(%p, %s) - stub\n", This, debugstr_w( pszStatusText ) );
591     return E_NOTIMPL;
592 }
593
594 static HRESULT WINAPI OleInPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
595 {
596     IOCS *This = IFACE2THIS(iface);
597
598     FIXME( "(%p, %d) - stub\n", This, fEnable );
599     return E_NOTIMPL;
600 }
601
602 static HRESULT WINAPI OleInPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
603 {
604     IOCS *This = IFACE2THIS(iface);
605
606     FIXME( "(%p, %p, %x) - stub\n", This, lpmsg, wID );
607     return E_NOTIMPL;
608 }
609 #undef IFACE2THIS
610
611
612 /******    IOleControlSite    *******/
613 #define IFACE2THIS(iface) DEFINE_THIS(IOCS, OleControlSite, iface)
614 static HRESULT WINAPI OleControlSite_QueryInterface(IOleControlSite *iface, REFIID riid, void **ppv)
615 {
616     IOCS *This = IFACE2THIS(iface);
617     return IOCS_QueryInterface(This, riid, ppv);
618 }
619 static ULONG WINAPI OleControlSite_AddRef(IOleControlSite *iface)
620 {
621     IOCS *This = IFACE2THIS(iface);
622     return IOCS_AddRef(This);
623 }
624 static ULONG WINAPI OleControlSite_Release(IOleControlSite *iface)
625 {
626     IOCS *This = IFACE2THIS(iface);
627     return IOCS_Release(This);
628 }
629 static HRESULT WINAPI OleControlSite_OnControlInfoChanged( IOleControlSite* This)
630 {
631     FIXME( "\n" );
632     return E_NOTIMPL;
633 }
634 static HRESULT WINAPI OleControlSite_LockInPlaceActive( IOleControlSite* This, BOOL fLock)
635 {
636     FIXME( "\n" );
637     return E_NOTIMPL;
638 }
639 static HRESULT WINAPI OleControlSite_GetExtendedControl( IOleControlSite* This, IDispatch** ppDisp)
640 {
641     FIXME( "\n" );
642     return E_NOTIMPL;
643 }
644 static HRESULT WINAPI OleControlSite_TransformCoords( IOleControlSite* This, POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags)
645 {
646     FIXME( "\n" );
647     return E_NOTIMPL;
648 }
649 static HRESULT WINAPI OleControlSite_TranslateAccelerator( IOleControlSite* This, MSG* pMsg, DWORD grfModifiers)
650 {
651     FIXME( "\n" );
652     return E_NOTIMPL;
653 }
654 static HRESULT WINAPI OleControlSite_OnFocus( IOleControlSite* This, BOOL fGotFocus)
655 {
656     FIXME( "\n" );
657     return E_NOTIMPL;
658 }
659 static HRESULT WINAPI OleControlSite_ShowPropertyFrame( IOleControlSite* This)
660 {
661     FIXME( "\n" );
662     return E_NOTIMPL;
663 }
664 #undef IFACE2THIS
665
666
667
668 static const IOleClientSiteVtbl OleClientSite_vtbl = {
669     OleClientSite_QueryInterface,
670     OleClientSite_AddRef,
671     OleClientSite_Release,
672     OleClientSite_SaveObject,
673     OleClientSite_GetMoniker,
674     OleClientSite_GetContainer,
675     OleClientSite_ShowObject,
676     OleClientSite_OnShowWindow,
677     OleClientSite_RequestNewObjectLayout
678 };
679 static const IOleContainerVtbl OleContainer_vtbl = {
680     OleContainer_QueryInterface,
681     OleContainer_AddRef,
682     OleContainer_Release,
683     OleContainer_ParseDisplayName,
684     OleContainer_EnumObjects,
685     OleContainer_LockContainer
686 };
687 static const IOleInPlaceSiteWindowlessVtbl OleInPlaceSiteWindowless_vtbl = {
688     OleInPlaceSiteWindowless_QueryInterface,
689     OleInPlaceSiteWindowless_AddRef,
690     OleInPlaceSiteWindowless_Release,
691     OleInPlaceSiteWindowless_GetWindow,
692     OleInPlaceSiteWindowless_ContextSensitiveHelp,
693     OleInPlaceSiteWindowless_CanInPlaceActivate,
694     OleInPlaceSiteWindowless_OnInPlaceActivate,
695     OleInPlaceSiteWindowless_OnUIActivate,
696     OleInPlaceSiteWindowless_GetWindowContext,
697     OleInPlaceSiteWindowless_Scroll,
698     OleInPlaceSiteWindowless_OnUIDeactivate,
699     OleInPlaceSiteWindowless_OnInPlaceDeactivate,
700     OleInPlaceSiteWindowless_DiscardUndoState,
701     OleInPlaceSiteWindowless_DeactivateAndUndo,
702     OleInPlaceSiteWindowless_OnPosRectChange,
703     OleInPlaceSiteWindowless_OnInPlaceActivateEx,
704     OleInPlaceSiteWindowless_OnInPlaceDeactivateEx,
705     OleInPlaceSiteWindowless_RequestUIActivate,
706     OleInPlaceSiteWindowless_CanWindowlessActivate,
707     OleInPlaceSiteWindowless_GetCapture,
708     OleInPlaceSiteWindowless_SetCapture,
709     OleInPlaceSiteWindowless_GetFocus,
710     OleInPlaceSiteWindowless_SetFocus,
711     OleInPlaceSiteWindowless_GetDC,
712     OleInPlaceSiteWindowless_ReleaseDC,
713     OleInPlaceSiteWindowless_InvalidateRect,
714     OleInPlaceSiteWindowless_InvalidateRgn,
715     OleInPlaceSiteWindowless_ScrollRect,
716     OleInPlaceSiteWindowless_AdjustRect,
717     OleInPlaceSiteWindowless_OnDefWindowMessage
718 };
719 static const IOleInPlaceFrameVtbl OleInPlaceFrame_vtbl =
720 {
721     OleInPlaceFrame_QueryInterface,
722     OleInPlaceFrame_AddRef,
723     OleInPlaceFrame_Release,
724     OleInPlaceFrame_GetWindow,
725     OleInPlaceFrame_ContextSensitiveHelp,
726     OleInPlaceFrame_GetBorder,
727     OleInPlaceFrame_RequestBorderSpace,
728     OleInPlaceFrame_SetBorderSpace,
729     OleInPlaceFrame_SetActiveObject,
730     OleInPlaceFrame_InsertMenus,
731     OleInPlaceFrame_SetMenu,
732     OleInPlaceFrame_RemoveMenus,
733     OleInPlaceFrame_SetStatusText,
734     OleInPlaceFrame_EnableModeless,
735     OleInPlaceFrame_TranslateAccelerator
736 };
737 static const IOleControlSiteVtbl OleControlSite_vtbl =
738 {
739     OleControlSite_QueryInterface,
740     OleControlSite_AddRef,
741     OleControlSite_Release,
742     OleControlSite_OnControlInfoChanged,
743     OleControlSite_LockInPlaceActive,
744     OleControlSite_GetExtendedControl,
745     OleControlSite_TransformCoords,
746     OleControlSite_TranslateAccelerator,
747     OleControlSite_OnFocus,
748     OleControlSite_ShowPropertyFrame
749 };
750
751 static HRESULT IOCS_Detach( IOCS *This ) /* remove subclassing */
752 {
753     if ( This->hWnd )
754     {
755         SetWindowLongPtrW( This->hWnd, GWLP_WNDPROC, (ULONG_PTR) This->OrigWndProc );
756         SetWindowLongPtrW( This->hWnd, GWLP_USERDATA, (LONG_PTR) NULL );
757         This->hWnd = NULL;
758     }
759     if ( This->control )
760     {
761         IOleObject *control = This->control;
762
763         This->control = NULL;
764         IOleObject_SetClientSite( control, NULL );
765         IOleObject_Release( control );
766     }
767     return S_OK;
768 }
769
770 static void IOCS_OnSize( IOCS* This, LPCRECT rect )
771 {
772     SIZEL inPix, inHi;
773
774     This->size.left = rect->left; This->size.right = rect->right; This->size.top = rect->top; This->size.bottom = rect->bottom;
775
776     if ( !This->control )
777         return;
778
779     inPix.cx = rect->right - rect->left;
780     inPix.cy = rect->bottom - rect->top;
781     AtlPixelToHiMetric( &inPix, &inHi );
782     IOleObject_SetExtent( This->control, DVASPECT_CONTENT, &inHi );
783
784     if ( This->fInPlace )
785     {
786         IOleInPlaceObject *wl;
787
788         if ( SUCCEEDED( IOleObject_QueryInterface( This->control, &IID_IOleInPlaceObject, (void**)&wl ) ) )
789         {
790             IOleInPlaceObject_SetObjectRects( wl, rect, rect );
791             IOleInPlaceObject_Release( wl );
792         }
793     }
794 }
795
796 static void IOCS_OnShow( IOCS *This, BOOL fShow )
797 {
798     if (!This->control || This->fActive || !fShow )
799         return;
800
801     This->fActive = TRUE;
802 }
803
804 static void IOCS_OnDraw( IOCS *This )
805 {
806     IViewObject *view;
807
808     if ( !This->control || !This->fWindowless )
809         return;
810
811     if ( SUCCEEDED( IOleObject_QueryInterface( This->control, &IID_IViewObject, (void**)&view ) ) )
812     {
813         HDC dc = GetDC( This->hWnd );
814         RECTL rect;
815
816         rect.left = This->size.left; rect.top = This->size.top;
817         rect.bottom = This->size.bottom; rect.right = This->size.right;
818
819         IViewObject_Draw( view, DVASPECT_CONTENT, ~0, NULL, NULL, 0, dc, &rect, &rect, NULL, 0 );
820         IViewObject_Release( view );
821         ReleaseDC( This->hWnd, dc );
822     }
823 }
824
825 static LRESULT IOCS_OnWndProc( IOCS *This, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
826 {
827     WNDPROC OrigWndProc = This->OrigWndProc;
828
829     switch( uMsg )
830     {
831         case WM_DESTROY:
832             IOCS_Detach( This );
833             break;
834         case WM_SIZE:
835             {
836                 RECT r;
837                 r.left = r.top = 0;
838                 r.right = LOWORD( lParam );
839                 r.bottom = HIWORD( lParam );
840                 IOCS_OnSize( This, &r );
841             }
842             break;
843         case WM_SHOWWINDOW:
844             IOCS_OnShow( This, (BOOL) wParam );
845             break;
846         case WM_PAINT:
847             IOCS_OnDraw( This );
848             break;
849     }
850
851     return OrigWndProc( hWnd, uMsg, wParam, lParam );
852 }
853
854 static LRESULT CALLBACK AtlHost_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam )
855 {
856     IOCS *This = (IOCS*) GetWindowLongPtrW( hWnd, GWLP_USERDATA );
857     return IOCS_OnWndProc( This, hWnd, wMsg, wParam, lParam );
858 }
859
860 static HRESULT IOCS_Attach( IOCS *This, HWND hWnd, IUnknown *pUnkControl ) /* subclass hWnd */
861 {
862     This->hWnd = hWnd;
863     IUnknown_QueryInterface( pUnkControl, &IID_IOleObject, (void**)&This->control );
864     IOleObject_SetClientSite( This->control, THIS2IOLECLIENTSITE( This ) );
865     This->OrigWndProc = (WNDPROC) GetWindowLongPtrW( This->hWnd, GWLP_WNDPROC );
866     SetWindowLongPtrW( hWnd, GWLP_USERDATA, (ULONG_PTR) This );
867     SetWindowLongPtrW( hWnd, GWLP_WNDPROC, (ULONG_PTR) AtlHost_wndproc );
868
869     return S_OK;
870 }
871
872 static HRESULT IOCS_Init( IOCS *This )
873 {
874     RECT rect;
875     static const WCHAR AXWIN[] = {'A','X','W','I','N',0};
876
877     IOleObject_SetHostNames( This->control, AXWIN, AXWIN );
878
879     GetClientRect( This->hWnd, &rect );
880     IOCS_OnSize( This, &rect );
881     IOleObject_DoVerb( This->control, OLEIVERB_INPLACEACTIVATE, NULL, THIS2IOLECLIENTSITE( This ), 0, This->hWnd, &rect );
882
883     return S_OK;
884 }
885
886 /**********************************************************************
887  * Create new instance of Atl host component and attach it to window  *
888  */
889 static HRESULT IOCS_Create( HWND hWnd, IUnknown *pUnkControl, IOCS **ppSite )
890 {
891     HRESULT hr;
892     IOCS *This;
893
894     *ppSite = NULL;
895     This = HeapAlloc(GetProcessHeap(), 0, sizeof(IOCS));
896
897     if (!This)
898         return E_OUTOFMEMORY;
899
900     This->lpOleClientSiteVtbl = &OleClientSite_vtbl;
901     This->lpOleContainerVtbl = &OleContainer_vtbl;
902     This->lpOleInPlaceSiteWindowlessVtbl = &OleInPlaceSiteWindowless_vtbl;
903     This->lpOleInPlaceFrameVtbl = &OleInPlaceFrame_vtbl;
904     This->lpOleControlSiteVtbl = &OleControlSite_vtbl;
905     This->ref = 1;
906
907     This->OrigWndProc = NULL;
908     This->hWnd = NULL;
909     This->fWindowless = This->fActive = This->fInPlace = FALSE;
910
911     hr = IOCS_Attach( This, hWnd, pUnkControl );
912     if ( SUCCEEDED( hr ) )
913         hr = IOCS_Init( This );
914     if ( SUCCEEDED( hr ) )
915         *ppSite = This;
916     else
917         IOCS_Release( This );
918
919     return hr;
920 }
921
922
923 /***********************************************************************
924  *           AtlAxCreateControl           [ATL.@]
925  */
926 HRESULT WINAPI AtlAxCreateControl(LPCOLESTR lpszName, HWND hWnd,
927         IStream *pStream, IUnknown **ppUnkContainer)
928 {
929     return AtlAxCreateControlEx( lpszName, hWnd, pStream, ppUnkContainer,
930             NULL, NULL, NULL );
931 }
932
933 /***********************************************************************
934  *           AtlAxCreateControlEx            [ATL.@]
935  *
936  * REMARKS
937  *   See http://www.codeproject.com/com/cwebpage.asp for some background
938  *
939  */
940 HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd,
941         IStream *pStream, IUnknown **ppUnkContainer, IUnknown **ppUnkControl,
942         REFIID iidSink, IUnknown *punkSink)
943 {
944     CLSID controlId;
945     HRESULT hRes;
946     IOleObject *pControl;
947     IUnknown *pUnkControl;
948     IPersistStreamInit *pPSInit;
949     IUnknown *pContainer;
950     enum {IsGUID=0,IsHTML=1,IsURL=2} content;
951
952     TRACE("(%s %p %p %p %p %p %p)\n", debugstr_w(lpszName), hWnd, pStream, 
953             ppUnkContainer, ppUnkControl, iidSink, punkSink);
954
955     hRes = CLSIDFromString( (LPOLESTR) lpszName, &controlId );
956     if ( FAILED(hRes) )
957         hRes = CLSIDFromProgID( lpszName, &controlId );
958     if ( SUCCEEDED( hRes ) )
959         content = IsGUID;
960     else {
961         /* FIXME - check for MSHTML: prefix! */
962         content = IsURL;
963         memcpy( &controlId, &CLSID_WebBrowser, sizeof(controlId) );
964     }
965
966     hRes = CoCreateInstance( &controlId, 0, CLSCTX_ALL, &IID_IOleObject, 
967             (void**) &pControl );
968     if ( FAILED( hRes ) )
969     {
970         WARN( "cannot create ActiveX control %s instance - error 0x%08x\n",
971                 debugstr_guid( &controlId ), hRes );
972         return hRes;
973     }
974
975     hRes = IOleObject_QueryInterface( pControl, &IID_IPersistStreamInit, (void**) &pPSInit );
976     if ( SUCCEEDED( hRes ) )
977     {
978         if (!pStream)
979             IPersistStreamInit_InitNew( pPSInit );
980         else
981             IPersistStreamInit_Load( pPSInit, pStream );
982         IPersistStreamInit_Release( pPSInit );
983     } else
984         WARN("cannot get IID_IPersistStreamInit out of control\n");
985
986     IOleObject_QueryInterface( pControl, &IID_IUnknown, (void**) &pUnkControl );
987     IOleObject_Release( pControl );
988      
989
990     hRes = AtlAxAttachControl( pUnkControl, hWnd, &pContainer );
991     if ( FAILED( hRes ) )
992         WARN("cannot attach control to window\n");
993
994     if ( content == IsURL )
995     {
996         IWebBrowser2 *browser;
997
998         hRes = IOleObject_QueryInterface( pControl, &IID_IWebBrowser2, (void**) &browser );
999         if ( !browser )
1000             WARN( "Cannot query IWebBrowser2 interface: %08x\n", hRes );
1001         else {
1002             VARIANT url;
1003             
1004             IWebBrowser2_put_Visible( browser, VARIANT_TRUE ); /* it seems that native does this on URL (but do not on MSHTML:! why? */
1005
1006             V_VT(&url) = VT_BSTR;
1007             V_BSTR(&url) = SysAllocString( lpszName );
1008
1009             hRes = IWebBrowser2_Navigate2( browser, &url, NULL, NULL, NULL, NULL );
1010             if ( FAILED( hRes ) )
1011                 WARN( "IWebBrowser2::Navigate2 failed: %08x\n", hRes );
1012             SysFreeString( V_BSTR(&url) );
1013
1014             IWebBrowser2_Release( browser );
1015         }
1016     }
1017
1018     if (ppUnkContainer)
1019     {
1020         *ppUnkContainer = pContainer;
1021         if ( pContainer )
1022             IUnknown_AddRef( pContainer );
1023     }
1024     if (ppUnkControl)
1025     {
1026         *ppUnkControl = pUnkControl;
1027         if ( pUnkControl )
1028             IUnknown_AddRef( pUnkControl );
1029     }
1030
1031     IUnknown_Release( pUnkControl );
1032     if ( pContainer )
1033         IUnknown_Release( pContainer );
1034
1035     return S_OK;
1036 }
1037
1038 /***********************************************************************
1039  *           AtlAxAttachControl           [ATL.@]
1040  */
1041 HRESULT WINAPI AtlAxAttachControl(IUnknown* pControl, HWND hWnd, IUnknown** ppUnkContainer)
1042 {
1043     IOCS *pUnkContainer;
1044     HRESULT hr;
1045
1046     TRACE( "%p %p %p\n", pControl, hWnd, ppUnkContainer );
1047
1048     *ppUnkContainer = NULL;
1049
1050     hr = IOCS_Create( hWnd, pControl, &pUnkContainer );
1051     if ( SUCCEEDED( hr ) )
1052     {
1053         *ppUnkContainer = (IUnknown*) pUnkContainer;
1054     }
1055
1056     return hr;
1057 }
1058
1059 /**********************************************************************
1060  * Helper function for AX_ConvertDialogTemplate
1061  */
1062 static inline BOOL advance_array(WORD **pptr, DWORD *palloc, DWORD *pfilled, const WORD *data, DWORD size)
1063 {
1064     if ( (*pfilled + size) > *palloc )
1065     {
1066         *palloc = ((*pfilled+size) + 0xFF) & ~0xFF;
1067         *pptr = HeapReAlloc( GetProcessHeap(), 0, *pptr, *palloc * sizeof(WORD) );
1068         if (!*pptr)
1069             return FALSE;
1070     }
1071     RtlMoveMemory( *pptr+*pfilled, data, size * sizeof(WORD) );
1072     *pfilled += size;
1073     return TRUE;
1074 }
1075
1076 /**********************************************************************
1077  * Convert ActiveX control templates to AtlAxWin class instances
1078  */
1079 static LPDLGTEMPLATEW AX_ConvertDialogTemplate(LPCDLGTEMPLATEW src_tmpl)
1080 {
1081 #define GET_WORD(x)  (*(const  WORD *)(x))
1082 #define GET_DWORD(x) (*(const DWORD *)(x))
1083 #define PUT_BLOCK(x,y) do {if (!advance_array(&output, &allocated, &filled, (x), (y))) return NULL;} while (0)
1084 #define PUT_WORD(x)  do {WORD w = (x);PUT_BLOCK(&w, 1);} while(0)
1085 #define PUT_DWORD(x)  do {DWORD w = (x);PUT_BLOCK(&w, 2);} while(0)
1086     const WORD *tmp, *src = (const WORD *)src_tmpl;
1087     WORD *output; 
1088     DWORD allocated, filled; /* in WORDs */
1089     BOOL ext;
1090     WORD signature, dlgver, rescount;
1091     DWORD style;
1092
1093     filled = 0; allocated = 256;
1094     output = HeapAlloc( GetProcessHeap(), 0, allocated * sizeof(WORD) );
1095     if (!output)
1096         return NULL;
1097     
1098     /* header */
1099     tmp = src;
1100     signature = GET_WORD(src);
1101     dlgver = GET_WORD(src + 1);
1102     if (signature == 1 && dlgver == 0xFFFF)
1103     {
1104         ext = TRUE;
1105         src += 6;
1106         style = GET_DWORD(src);
1107         src += 2;
1108         rescount = GET_WORD(src++);
1109         src += 4;
1110         if ( GET_WORD(src) == 0xFFFF ) /* menu */
1111             src += 2;
1112         else
1113             src += strlenW(src) + 1;
1114         if ( GET_WORD(src) == 0xFFFF ) /* class */
1115             src += 2;
1116         else
1117             src += strlenW(src) + 1;
1118         src += strlenW(src) + 1; /* title */
1119         if ( style & (DS_SETFONT | DS_SHELLFONT) )
1120         {
1121             src += 3;
1122             src += strlenW(src) + 1;
1123         }
1124     } else {
1125         ext = FALSE;
1126         style = GET_DWORD(src);
1127         src += 4;
1128         rescount = GET_WORD(src++);
1129         src += 4;
1130         if ( GET_WORD(src) == 0xFFFF ) /* menu */
1131             src += 2;
1132         else
1133             src += strlenW(src) + 1;
1134         if ( GET_WORD(src) == 0xFFFF ) /* class */
1135             src += 2;
1136         else
1137             src += strlenW(src) + 1;
1138         src += strlenW(src) + 1; /* title */
1139         if ( style & DS_SETFONT )
1140         {
1141             src++;
1142             src += strlenW(src) + 1;
1143         }
1144     }
1145     PUT_BLOCK(tmp, src-tmp);
1146
1147     while(rescount--)
1148     {
1149         src = (const WORD *)( ( ((ULONG)src) + 3) & ~3); /* align on DWORD boundary */
1150                 filled = (filled + 1) & ~1; /* depends on DWORD-aligned allocation unit */
1151
1152         tmp = src;
1153         if (ext)
1154             src += 11;
1155         else
1156             src += 9;
1157         PUT_BLOCK(tmp, src-tmp);
1158
1159         tmp = src;
1160         if ( GET_WORD(src) == 0xFFFF ) /* class */
1161         {
1162             src += 2;
1163         } else
1164         {
1165             src += strlenW(src) + 1;
1166         }
1167         src += strlenW(src) + 1; /* title */
1168         if ( GET_WORD(tmp) == '{' ) /* all this mess created because of this line */
1169         {
1170             const WCHAR AtlAxWin[9]={'A','t','l','A','x','W','i','n',0};
1171             PUT_BLOCK(AtlAxWin, sizeof(AtlAxWin)/sizeof(WORD));
1172             PUT_BLOCK(tmp, strlenW(tmp)+1);
1173         } else
1174             PUT_BLOCK(tmp, src-tmp);
1175
1176         if ( GET_WORD(src) )
1177         {
1178             WORD size = (GET_WORD(src)+sizeof(WORD)-1) / sizeof(WORD); /* quite ugly :( Maybe use BYTE* instead of WORD* everywhere ? */
1179             PUT_BLOCK(src, size);
1180             src+=size;
1181         }
1182         else
1183         {
1184             PUT_WORD(0);
1185             src++;
1186         }
1187     }
1188     return (LPDLGTEMPLATEW) output;
1189 }
1190
1191 /***********************************************************************
1192  *           AtlAxCreateDialogA           [ATL.@]
1193  *
1194  * Creates a dialog window
1195  *
1196  * PARAMS
1197  *  hInst   [I] Application instance
1198  *  name    [I] Dialog box template name
1199  *  owner   [I] Dialog box parent HWND
1200  *  dlgProc [I] Dialog box procedure
1201  *  param   [I] This value will be passed to dlgProc as WM_INITDIALOG's message lParam 
1202  *
1203  * RETURNS
1204  *  Window handle of dialog window.
1205  */
1206 HWND WINAPI AtlAxCreateDialogA(HINSTANCE hInst, LPCSTR name, HWND owner, DLGPROC dlgProc ,LPARAM param)
1207 {
1208     HWND res = NULL;
1209     int length;
1210     WCHAR *nameW;
1211
1212     if ( HIWORD(name) == 0 )
1213         return AtlAxCreateDialogW( hInst, (LPCWSTR) name, owner, dlgProc, param );
1214
1215     length = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
1216     nameW = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) );
1217     if (nameW)
1218     {
1219         MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, length );
1220         res = AtlAxCreateDialogW( hInst, nameW, owner, dlgProc, param );
1221         HeapFree( GetProcessHeap(), 0, nameW );
1222     }
1223     return res;
1224 }
1225
1226 /***********************************************************************
1227  *           AtlAxCreateDialogW           [ATL.@]
1228  *
1229  * See AtlAxCreateDialogA
1230  *
1231  */
1232 HWND WINAPI AtlAxCreateDialogW(HINSTANCE hInst, LPCWSTR name, HWND owner, DLGPROC dlgProc ,LPARAM param)
1233 {
1234     HRSRC hrsrc;
1235     HGLOBAL hgl;
1236     LPCDLGTEMPLATEW ptr;
1237     LPDLGTEMPLATEW newptr;
1238     HWND res;
1239
1240     FIXME("(%p %s %p %p %lx) - not tested\n", hInst, debugstr_w(name), owner, dlgProc, param);
1241
1242     hrsrc = FindResourceW( hInst, name, (LPWSTR)RT_DIALOG );
1243     if ( !hrsrc )
1244         return NULL;
1245     hgl = LoadResource (hInst, hrsrc);
1246     if ( !hgl )
1247         return NULL;
1248     ptr = (LPCDLGTEMPLATEW)LockResource ( hgl );
1249     if (!ptr)
1250     {
1251         FreeResource( hgl );
1252         return NULL;
1253     }
1254     newptr = AX_ConvertDialogTemplate( ptr );
1255     if ( newptr )
1256     {
1257             res = CreateDialogIndirectParamW( hInst, newptr, owner, dlgProc, param );
1258             HeapFree( GetProcessHeap(), 0, newptr );
1259     } else
1260         res = NULL;
1261     FreeResource ( hrsrc );
1262     return res;
1263 }
1264
1265 /***********************************************************************
1266  *           AtlAxGetHost                 [ATL.@]
1267  *
1268  */
1269 HRESULT WINAPI AtlAxGetHost(HWND hWnd, IUnknown **pUnk)
1270 {
1271     IOCS *This;
1272
1273     TRACE( "(%p, %p)\n", hWnd, pUnk );
1274
1275     *pUnk = NULL;
1276
1277     This = (IOCS*) GetWindowLongPtrW( hWnd, GWLP_USERDATA );
1278     if ( !This )
1279     {
1280         WARN("No container attached to %p\n", hWnd );
1281         return E_FAIL;
1282     }
1283
1284     return IOCS_QueryInterface( This, &IID_IUnknown, (void**) pUnk );
1285 }
1286
1287 /***********************************************************************
1288  *           AtlAxGetControl              [ATL.@]
1289  *
1290  */
1291 HRESULT WINAPI AtlAxGetControl(HWND hWnd, IUnknown **pUnk)
1292 {
1293     IOCS *This;
1294
1295     TRACE( "(%p, %p)\n", hWnd, pUnk );
1296
1297     *pUnk = NULL;
1298
1299     This = (IOCS*) GetWindowLongPtrW( hWnd, GWLP_USERDATA );
1300     if ( !This || !This->control )
1301     {
1302         WARN("No control attached to %p\n", hWnd );
1303         return E_FAIL;
1304     }
1305
1306     return IOleObject_QueryInterface( This->control, &IID_IUnknown, (void**) pUnk );
1307 }