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