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