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