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