| /* |
| * Active Template Library ActiveX functions (atl.dll) |
| * |
| * Copyright 2006 Andrey Turkin |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include <stdarg.h> |
| #include <stdio.h> |
| |
| #define COBJMACROS |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winerror.h" |
| #include "winuser.h" |
| #include "wine/debug.h" |
| #include "objbase.h" |
| #include "objidl.h" |
| #include "ole2.h" |
| #include "exdisp.h" |
| #include "atlbase.h" |
| #include "atliface.h" |
| #include "atlwin.h" |
| #include "shlwapi.h" |
| |
| #include "wine/unicode.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(atl); |
| |
| typedef struct IOCS { |
| IOleClientSite IOleClientSite_iface; |
| IOleContainer IOleContainer_iface; |
| IOleInPlaceSiteWindowless IOleInPlaceSiteWindowless_iface; |
| IOleInPlaceFrame IOleInPlaceFrame_iface; |
| IOleControlSite IOleControlSite_iface; |
| |
| LONG ref; |
| HWND hWnd; |
| IOleObject *control; |
| RECT size; |
| WNDPROC OrigWndProc; |
| BOOL fActive, fInPlace, fWindowless; |
| } IOCS; |
| |
| static const WCHAR wine_atl_iocsW[] = {'_','_','W','I','N','E','_','A','T','L','_','I','O','C','S','\0'}; |
| |
| /********************************************************************** |
| * AtlAxWin class window procedure |
| */ |
| static LRESULT CALLBACK AtlAxWin_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam ) |
| { |
| if ( wMsg == WM_CREATE ) |
| { |
| DWORD len = GetWindowTextLengthW( hWnd ) + 1; |
| WCHAR *ptr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); |
| if (!ptr) |
| return 1; |
| GetWindowTextW( hWnd, ptr, len ); |
| AtlAxCreateControlEx( ptr, hWnd, NULL, NULL, NULL, NULL, NULL ); |
| HeapFree( GetProcessHeap(), 0, ptr ); |
| return 0; |
| } |
| return DefWindowProcW( hWnd, wMsg, wParam, lParam ); |
| } |
| |
| /*********************************************************************** |
| * AtlAxWinInit [atl100.@] |
| * Initializes the control-hosting code: registering the AtlAxWin, |
| * AtlAxWin7 and AtlAxWinLic7 window classes and some messages. |
| * |
| * RETURNS |
| * TRUE or FALSE |
| */ |
| |
| BOOL WINAPI AtlAxWinInit(void) |
| { |
| WNDCLASSEXW wcex; |
| |
| #if _ATL_VER <= _ATL_VER_30 |
| #define ATL_NAME_SUFFIX 0 |
| #elif _ATL_VER == _ATL_VER_80 |
| #define ATL_NAME_SUFFIX '8','0',0 |
| #elif _ATL_VER == _ATL_VER_90 |
| #define ATL_NAME_SUFFIX '9','0',0 |
| #elif _ATL_VER == _ATL_VER_100 |
| #define ATL_NAME_SUFFIX '1','0','0',0 |
| #elif _ATL_VER == _ATL_VER_110 |
| #define ATL_NAME_SUFFIX '1','1','0',0 |
| #else |
| #error Unsupported version |
| #endif |
| |
| const WCHAR AtlAxWinW[] = {'A','t','l','A','x','W','i','n',ATL_NAME_SUFFIX}; |
| |
| FIXME("version %04x semi-stub\n", _ATL_VER); |
| |
| if ( FAILED( OleInitialize(NULL) ) ) |
| return FALSE; |
| |
| wcex.cbSize = sizeof(wcex); |
| wcex.style = CS_GLOBALCLASS | (_ATL_VER > _ATL_VER_30 ? CS_DBLCLKS : 0); |
| wcex.cbClsExtra = 0; |
| wcex.cbWndExtra = 0; |
| wcex.hInstance = GetModuleHandleW( NULL ); |
| wcex.hIcon = NULL; |
| wcex.hCursor = NULL; |
| wcex.hbrBackground = NULL; |
| wcex.lpszMenuName = NULL; |
| wcex.hIconSm = 0; |
| |
| wcex.lpfnWndProc = AtlAxWin_wndproc; |
| wcex.lpszClassName = AtlAxWinW; |
| if ( !RegisterClassExW( &wcex ) ) |
| return FALSE; |
| |
| if(_ATL_VER > _ATL_VER_30) { |
| const WCHAR AtlAxWinLicW[] = {'A','t','l','A','x','W','i','n','L','i','c',ATL_NAME_SUFFIX}; |
| |
| wcex.lpszClassName = AtlAxWinLicW; |
| if ( !RegisterClassExW( &wcex ) ) |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * Atl container component implementation |
| */ |
| |
| /****** IOleClientSite *****/ |
| static inline IOCS *impl_from_IOleClientSite(IOleClientSite *iface) |
| { |
| return CONTAINING_RECORD(iface, IOCS, IOleClientSite_iface); |
| } |
| |
| static HRESULT IOCS_Detach( IOCS *This ) /* remove subclassing */ |
| { |
| if ( This->hWnd ) |
| { |
| SetWindowLongPtrW( This->hWnd, GWLP_WNDPROC, (ULONG_PTR) This->OrigWndProc ); |
| RemovePropW( This->hWnd, wine_atl_iocsW); |
| This->hWnd = NULL; |
| } |
| if ( This->control ) |
| { |
| IOleObject *control = This->control; |
| |
| This->control = NULL; |
| IOleObject_Close( control, OLECLOSE_NOSAVE ); |
| IOleObject_SetClientSite( control, NULL ); |
| IOleObject_Release( control ); |
| } |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OleClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv) |
| { |
| IOCS *This = impl_from_IOleClientSite(iface); |
| |
| TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); |
| |
| *ppv = NULL; |
| |
| if (IsEqualIID(&IID_IUnknown, riid) || |
| IsEqualIID(&IID_IOleClientSite, riid)) |
| { |
| *ppv = iface; |
| } |
| else if (IsEqualIID(&IID_IOleContainer, riid)) |
| { |
| *ppv = &This->IOleContainer_iface; |
| } |
| else if (IsEqualIID(&IID_IOleInPlaceSite, riid) || |
| IsEqualIID(&IID_IOleInPlaceSiteEx, riid) || |
| IsEqualIID(&IID_IOleInPlaceSiteWindowless, riid)) |
| { |
| *ppv = &This->IOleInPlaceSiteWindowless_iface; |
| } |
| else if (IsEqualIID(&IID_IOleInPlaceFrame, riid)) |
| { |
| *ppv = &This->IOleInPlaceFrame_iface; |
| } |
| else if (IsEqualIID(&IID_IOleControlSite, riid)) |
| { |
| *ppv = &This->IOleControlSite_iface; |
| } |
| |
| if (*ppv) |
| { |
| IOleClientSite_AddRef(iface); |
| return S_OK; |
| } |
| |
| WARN("unsupported interface %s\n", debugstr_guid(riid)); |
| return E_NOINTERFACE; |
| } |
| |
| static ULONG WINAPI OleClientSite_AddRef(IOleClientSite *iface) |
| { |
| IOCS *This = impl_from_IOleClientSite(iface); |
| ULONG ref = InterlockedIncrement(&This->ref); |
| TRACE("(%p)->(%d)\n", This, ref); |
| return ref; |
| } |
| |
| static ULONG WINAPI OleClientSite_Release(IOleClientSite *iface) |
| { |
| IOCS *This = impl_from_IOleClientSite(iface); |
| ULONG ref = InterlockedDecrement(&This->ref); |
| |
| TRACE("(%p)->(%d)\n", This, ref); |
| |
| if (!ref) |
| { |
| IOCS_Detach( This ); |
| HeapFree( GetProcessHeap(), 0, This ); |
| } |
| |
| return ref; |
| } |
| |
| static HRESULT WINAPI OleClientSite_SaveObject(IOleClientSite *iface) |
| { |
| IOCS *This = impl_from_IOleClientSite(iface); |
| FIXME( "(%p) - stub\n", This ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk) |
| { |
| IOCS *This = impl_from_IOleClientSite(iface); |
| |
| FIXME( "(%p, 0x%x, 0x%x, %p)\n", This, dwAssign, dwWhichMoniker, ppmk ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleClientSite_GetContainer(IOleClientSite *iface, IOleContainer **container) |
| { |
| IOCS *This = impl_from_IOleClientSite(iface); |
| TRACE("(%p, %p)\n", This, container); |
| return IOleClientSite_QueryInterface(iface, &IID_IOleContainer, (void**)container); |
| } |
| |
| static HRESULT WINAPI OleClientSite_ShowObject(IOleClientSite *iface) |
| { |
| IOCS *This = impl_from_IOleClientSite(iface); |
| FIXME( "(%p) - stub\n", This ); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OleClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow) |
| { |
| IOCS *This = impl_from_IOleClientSite(iface); |
| FIXME( "(%p, %s) - stub\n", This, fShow ? "TRUE" : "FALSE" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleClientSite_RequestNewObjectLayout(IOleClientSite *iface) |
| { |
| IOCS *This = impl_from_IOleClientSite(iface); |
| FIXME( "(%p) - stub\n", This ); |
| return E_NOTIMPL; |
| } |
| |
| |
| /****** IOleContainer *****/ |
| static inline IOCS *impl_from_IOleContainer(IOleContainer *iface) |
| { |
| return CONTAINING_RECORD(iface, IOCS, IOleContainer_iface); |
| } |
| |
| static HRESULT WINAPI OleContainer_QueryInterface( IOleContainer* iface, REFIID riid, void** ppv) |
| { |
| IOCS *This = impl_from_IOleContainer(iface); |
| return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv); |
| } |
| |
| static ULONG WINAPI OleContainer_AddRef(IOleContainer* iface) |
| { |
| IOCS *This = impl_from_IOleContainer(iface); |
| return IOleClientSite_AddRef(&This->IOleClientSite_iface); |
| } |
| |
| static ULONG WINAPI OleContainer_Release(IOleContainer* iface) |
| { |
| IOCS *This = impl_from_IOleContainer(iface); |
| return IOleClientSite_Release(&This->IOleClientSite_iface); |
| } |
| |
| static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer* iface, IBindCtx* pbc, |
| LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut) |
| { |
| IOCS *This = impl_from_IOleContainer(iface); |
| FIXME( "(%p,%p,%s,%p,%p) - stub\n", This, pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer* iface, DWORD grfFlags, IEnumUnknown** ppenum) |
| { |
| IOCS *This = impl_from_IOleContainer(iface); |
| FIXME( "(%p, %u, %p) - stub\n", This, grfFlags, ppenum ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleContainer_LockContainer(IOleContainer* iface, BOOL fLock) |
| { |
| IOCS *This = impl_from_IOleContainer(iface); |
| FIXME( "(%p, %s) - stub\n", This, fLock?"TRUE":"FALSE" ); |
| return E_NOTIMPL; |
| } |
| |
| |
| /****** IOleInPlaceSiteWindowless *******/ |
| static inline IOCS *impl_from_IOleInPlaceSiteWindowless(IOleInPlaceSiteWindowless *iface) |
| { |
| return CONTAINING_RECORD(iface, IOCS, IOleInPlaceSiteWindowless_iface); |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_QueryInterface(IOleInPlaceSiteWindowless *iface, REFIID riid, void **ppv) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv); |
| } |
| |
| static ULONG WINAPI OleInPlaceSiteWindowless_AddRef(IOleInPlaceSiteWindowless *iface) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| return IOleClientSite_AddRef(&This->IOleClientSite_iface); |
| } |
| |
| static ULONG WINAPI OleInPlaceSiteWindowless_Release(IOleInPlaceSiteWindowless *iface) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| return IOleClientSite_Release(&This->IOleClientSite_iface); |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_GetWindow(IOleInPlaceSiteWindowless* iface, HWND* phwnd) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| |
| TRACE("(%p,%p)\n", This, phwnd); |
| *phwnd = This->hWnd; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_ContextSensitiveHelp(IOleInPlaceSiteWindowless* iface, BOOL fEnterMode) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| FIXME("(%p,%d) - stub\n", This, fEnterMode); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_CanInPlaceActivate(IOleInPlaceSiteWindowless *iface) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| TRACE("(%p)\n", This); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceActivate(IOleInPlaceSiteWindowless *iface) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| |
| TRACE("(%p)\n", This); |
| |
| This->fInPlace = TRUE; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_OnUIActivate(IOleInPlaceSiteWindowless *iface) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| |
| TRACE("(%p)\n", This); |
| |
| return S_OK; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_GetWindowContext(IOleInPlaceSiteWindowless *iface, |
| IOleInPlaceFrame **frame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, |
| LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| |
| TRACE("(%p,%p,%p,%p,%p,%p)\n", This, frame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo); |
| |
| if ( lprcClipRect ) |
| *lprcClipRect = This->size; |
| if ( lprcPosRect ) |
| *lprcPosRect = This->size; |
| |
| if ( frame ) |
| { |
| *frame = &This->IOleInPlaceFrame_iface; |
| IOleInPlaceFrame_AddRef(*frame); |
| } |
| |
| if ( ppDoc ) |
| *ppDoc = NULL; |
| |
| if ( lpFrameInfo ) |
| { |
| lpFrameInfo->fMDIApp = FALSE; |
| lpFrameInfo->hwndFrame = This->hWnd; |
| lpFrameInfo->haccel = NULL; |
| lpFrameInfo->cAccelEntries = 0; |
| } |
| |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_Scroll(IOleInPlaceSiteWindowless *iface, SIZE scrollExtent) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| FIXME("(%p) - stub\n", This); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_OnUIDeactivate(IOleInPlaceSiteWindowless *iface, BOOL fUndoable) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| FIXME("(%p,%d) - stub\n", This, fUndoable); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceDeactivate(IOleInPlaceSiteWindowless *iface) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| |
| TRACE("(%p)\n", This); |
| |
| This->fInPlace = This->fWindowless = FALSE; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_DiscardUndoState(IOleInPlaceSiteWindowless *iface) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| FIXME("(%p) - stub\n", This); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_DeactivateAndUndo(IOleInPlaceSiteWindowless *iface) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| FIXME("(%p) - stub\n", This); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_OnPosRectChange(IOleInPlaceSiteWindowless *iface, LPCRECT lprcPosRect) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| FIXME("(%p,%p) - stub\n", This, lprcPosRect); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceActivateEx( IOleInPlaceSiteWindowless *iface, BOOL* pfNoRedraw, DWORD dwFlags) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| |
| TRACE("\n"); |
| |
| This->fActive = This->fInPlace = TRUE; |
| if ( dwFlags & ACTIVATE_WINDOWLESS ) |
| This->fWindowless = TRUE; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceDeactivateEx( IOleInPlaceSiteWindowless *iface, BOOL fNoRedraw) |
| { |
| IOCS *This = impl_from_IOleInPlaceSiteWindowless(iface); |
| |
| TRACE("\n"); |
| |
| This->fActive = This->fInPlace = This->fWindowless = FALSE; |
| return S_OK; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_RequestUIActivate( IOleInPlaceSiteWindowless *iface) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_CanWindowlessActivate( IOleInPlaceSiteWindowless *iface) |
| { |
| FIXME("\n"); |
| return S_OK; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_GetCapture( IOleInPlaceSiteWindowless *iface) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_SetCapture( IOleInPlaceSiteWindowless *iface, BOOL fCapture) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_GetFocus( IOleInPlaceSiteWindowless *iface) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_SetFocus( IOleInPlaceSiteWindowless *iface, BOOL fFocus) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_GetDC( IOleInPlaceSiteWindowless *iface, LPCRECT pRect, DWORD grfFlags, HDC* phDC) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_ReleaseDC( IOleInPlaceSiteWindowless *iface, HDC hDC) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_InvalidateRect( IOleInPlaceSiteWindowless *iface, LPCRECT pRect, BOOL fErase) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_InvalidateRgn( IOleInPlaceSiteWindowless *iface, HRGN hRGN, BOOL fErase) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_ScrollRect( IOleInPlaceSiteWindowless *iface, INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_AdjustRect( IOleInPlaceSiteWindowless *iface, LPRECT prc) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleInPlaceSiteWindowless_OnDefWindowMessage( IOleInPlaceSiteWindowless *iface, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult) |
| { |
| FIXME("\n"); |
| return E_NOTIMPL; |
| } |
| |
| |
| /****** IOleInPlaceFrame *******/ |
| static inline IOCS *impl_from_IOleInPlaceFrame(IOleInPlaceFrame *iface) |
| { |
| return CONTAINING_RECORD(iface, IOCS, IOleInPlaceFrame_iface); |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv); |
| } |
| |
| static ULONG WINAPI OleInPlaceFrame_AddRef(IOleInPlaceFrame *iface) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| return IOleClientSite_AddRef(&This->IOleClientSite_iface); |
| } |
| |
| static ULONG WINAPI OleInPlaceFrame_Release(IOleInPlaceFrame *iface) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| return IOleClientSite_Release(&This->IOleClientSite_iface); |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phWnd) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| TRACE( "(%p,%p)\n", This, phWnd ); |
| |
| *phWnd = This->hWnd; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p,%d) - stub\n", This, fEnterMode ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p,%p) - stub\n", This, lprectBorder ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface, LPCBORDERWIDTHS pborderwidths) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p,%p) - stub\n", This, pborderwidths ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface, LPCBORDERWIDTHS pborderwidths) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p,%p) - stub\n", This, pborderwidths ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p,%p,%s) - stub\n", This, pActiveObject, debugstr_w(pszObjName) ); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p,%p,%p) - stub\n", This, hmenuShared, lpMenuWidths ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p,%p,%p,%p) - stub\n", This, hmenuShared, holemenu, hwndActiveObject ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p, %p) - stub\n", This, hmenuShared ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p, %s) - stub\n", This, debugstr_w( pszStatusText ) ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p, %d) - stub\n", This, fEnable ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI OleInPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID) |
| { |
| IOCS *This = impl_from_IOleInPlaceFrame(iface); |
| |
| FIXME( "(%p, %p, %x) - stub\n", This, lpmsg, wID ); |
| return E_NOTIMPL; |
| } |
| |
| |
| /****** IOleControlSite *******/ |
| static inline IOCS *impl_from_IOleControlSite(IOleControlSite *iface) |
| { |
| return CONTAINING_RECORD(iface, IOCS, IOleControlSite_iface); |
| } |
| |
| static HRESULT WINAPI OleControlSite_QueryInterface(IOleControlSite *iface, REFIID riid, void **ppv) |
| { |
| IOCS *This = impl_from_IOleControlSite(iface); |
| return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppv); |
| } |
| |
| static ULONG WINAPI OleControlSite_AddRef(IOleControlSite *iface) |
| { |
| IOCS *This = impl_from_IOleControlSite(iface); |
| return IOleClientSite_AddRef(&This->IOleClientSite_iface); |
| } |
| |
| static ULONG WINAPI OleControlSite_Release(IOleControlSite *iface) |
| { |
| IOCS *This = impl_from_IOleControlSite(iface); |
| return IOleClientSite_Release(&This->IOleClientSite_iface); |
| } |
| |
| static HRESULT WINAPI OleControlSite_OnControlInfoChanged( IOleControlSite* This) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleControlSite_LockInPlaceActive( IOleControlSite* This, BOOL fLock) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleControlSite_GetExtendedControl( IOleControlSite* This, IDispatch** ppDisp) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleControlSite_TransformCoords( IOleControlSite* This, POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleControlSite_TranslateAccelerator( IOleControlSite* This, MSG* pMsg, DWORD grfModifiers) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleControlSite_OnFocus( IOleControlSite* This, BOOL fGotFocus) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| static HRESULT WINAPI OleControlSite_ShowPropertyFrame( IOleControlSite* This) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| |
| static const IOleClientSiteVtbl OleClientSite_vtbl = { |
| OleClientSite_QueryInterface, |
| OleClientSite_AddRef, |
| OleClientSite_Release, |
| OleClientSite_SaveObject, |
| OleClientSite_GetMoniker, |
| OleClientSite_GetContainer, |
| OleClientSite_ShowObject, |
| OleClientSite_OnShowWindow, |
| OleClientSite_RequestNewObjectLayout |
| }; |
| static const IOleContainerVtbl OleContainer_vtbl = { |
| OleContainer_QueryInterface, |
| OleContainer_AddRef, |
| OleContainer_Release, |
| OleContainer_ParseDisplayName, |
| OleContainer_EnumObjects, |
| OleContainer_LockContainer |
| }; |
| static const IOleInPlaceSiteWindowlessVtbl OleInPlaceSiteWindowless_vtbl = { |
| OleInPlaceSiteWindowless_QueryInterface, |
| OleInPlaceSiteWindowless_AddRef, |
| OleInPlaceSiteWindowless_Release, |
| OleInPlaceSiteWindowless_GetWindow, |
| OleInPlaceSiteWindowless_ContextSensitiveHelp, |
| OleInPlaceSiteWindowless_CanInPlaceActivate, |
| OleInPlaceSiteWindowless_OnInPlaceActivate, |
| OleInPlaceSiteWindowless_OnUIActivate, |
| OleInPlaceSiteWindowless_GetWindowContext, |
| OleInPlaceSiteWindowless_Scroll, |
| OleInPlaceSiteWindowless_OnUIDeactivate, |
| OleInPlaceSiteWindowless_OnInPlaceDeactivate, |
| OleInPlaceSiteWindowless_DiscardUndoState, |
| OleInPlaceSiteWindowless_DeactivateAndUndo, |
| OleInPlaceSiteWindowless_OnPosRectChange, |
| OleInPlaceSiteWindowless_OnInPlaceActivateEx, |
| OleInPlaceSiteWindowless_OnInPlaceDeactivateEx, |
| OleInPlaceSiteWindowless_RequestUIActivate, |
| OleInPlaceSiteWindowless_CanWindowlessActivate, |
| OleInPlaceSiteWindowless_GetCapture, |
| OleInPlaceSiteWindowless_SetCapture, |
| OleInPlaceSiteWindowless_GetFocus, |
| OleInPlaceSiteWindowless_SetFocus, |
| OleInPlaceSiteWindowless_GetDC, |
| OleInPlaceSiteWindowless_ReleaseDC, |
| OleInPlaceSiteWindowless_InvalidateRect, |
| OleInPlaceSiteWindowless_InvalidateRgn, |
| OleInPlaceSiteWindowless_ScrollRect, |
| OleInPlaceSiteWindowless_AdjustRect, |
| OleInPlaceSiteWindowless_OnDefWindowMessage |
| }; |
| static const IOleInPlaceFrameVtbl OleInPlaceFrame_vtbl = |
| { |
| OleInPlaceFrame_QueryInterface, |
| OleInPlaceFrame_AddRef, |
| OleInPlaceFrame_Release, |
| OleInPlaceFrame_GetWindow, |
| OleInPlaceFrame_ContextSensitiveHelp, |
| OleInPlaceFrame_GetBorder, |
| OleInPlaceFrame_RequestBorderSpace, |
| OleInPlaceFrame_SetBorderSpace, |
| OleInPlaceFrame_SetActiveObject, |
| OleInPlaceFrame_InsertMenus, |
| OleInPlaceFrame_SetMenu, |
| OleInPlaceFrame_RemoveMenus, |
| OleInPlaceFrame_SetStatusText, |
| OleInPlaceFrame_EnableModeless, |
| OleInPlaceFrame_TranslateAccelerator |
| }; |
| static const IOleControlSiteVtbl OleControlSite_vtbl = |
| { |
| OleControlSite_QueryInterface, |
| OleControlSite_AddRef, |
| OleControlSite_Release, |
| OleControlSite_OnControlInfoChanged, |
| OleControlSite_LockInPlaceActive, |
| OleControlSite_GetExtendedControl, |
| OleControlSite_TransformCoords, |
| OleControlSite_TranslateAccelerator, |
| OleControlSite_OnFocus, |
| OleControlSite_ShowPropertyFrame |
| }; |
| |
| static void IOCS_OnSize( IOCS* This, LPCRECT rect ) |
| { |
| SIZEL inPix, inHi; |
| |
| This->size = *rect; |
| |
| if ( !This->control ) |
| return; |
| |
| inPix.cx = rect->right - rect->left; |
| inPix.cy = rect->bottom - rect->top; |
| AtlPixelToHiMetric( &inPix, &inHi ); |
| IOleObject_SetExtent( This->control, DVASPECT_CONTENT, &inHi ); |
| |
| if ( This->fInPlace ) |
| { |
| IOleInPlaceObject *wl; |
| |
| if ( SUCCEEDED( IOleObject_QueryInterface( This->control, &IID_IOleInPlaceObject, (void**)&wl ) ) ) |
| { |
| IOleInPlaceObject_SetObjectRects( wl, rect, rect ); |
| IOleInPlaceObject_Release( wl ); |
| } |
| } |
| } |
| |
| static void IOCS_OnShow( IOCS *This, BOOL fShow ) |
| { |
| if (!This->control || This->fActive || !fShow ) |
| return; |
| |
| This->fActive = TRUE; |
| } |
| |
| static void IOCS_OnDraw( IOCS *This ) |
| { |
| IViewObject *view; |
| |
| if ( !This->control || !This->fWindowless ) |
| return; |
| |
| if ( SUCCEEDED( IOleObject_QueryInterface( This->control, &IID_IViewObject, (void**)&view ) ) ) |
| { |
| HDC dc = GetDC( This->hWnd ); |
| RECTL rect; |
| |
| rect.left = This->size.left; rect.top = This->size.top; |
| rect.bottom = This->size.bottom; rect.right = This->size.right; |
| |
| IViewObject_Draw( view, DVASPECT_CONTENT, ~0, NULL, NULL, 0, dc, &rect, &rect, NULL, 0 ); |
| IViewObject_Release( view ); |
| ReleaseDC( This->hWnd, dc ); |
| } |
| } |
| |
| static LRESULT IOCS_OnWndProc( IOCS *This, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) |
| { |
| WNDPROC OrigWndProc = This->OrigWndProc; |
| |
| switch( uMsg ) |
| { |
| case WM_DESTROY: |
| IOCS_Detach( This ); |
| break; |
| case WM_SIZE: |
| { |
| RECT r; |
| SetRect(&r, 0, 0, LOWORD(lParam), HIWORD(lParam)); |
| IOCS_OnSize( This, &r ); |
| } |
| break; |
| case WM_SHOWWINDOW: |
| IOCS_OnShow( This, (BOOL) wParam ); |
| break; |
| case WM_PAINT: |
| IOCS_OnDraw( This ); |
| break; |
| } |
| |
| return CallWindowProcW( OrigWndProc, hWnd, uMsg, wParam, lParam ); |
| } |
| |
| static LRESULT CALLBACK AtlHost_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam ) |
| { |
| IOCS *This = (IOCS*) GetPropW( hWnd, wine_atl_iocsW ); |
| return IOCS_OnWndProc( This, hWnd, wMsg, wParam, lParam ); |
| } |
| |
| static HRESULT IOCS_Attach( IOCS *This, HWND hWnd, IUnknown *pUnkControl ) /* subclass hWnd */ |
| { |
| This->hWnd = hWnd; |
| IUnknown_QueryInterface( pUnkControl, &IID_IOleObject, (void**)&This->control ); |
| IOleObject_SetClientSite( This->control, &This->IOleClientSite_iface ); |
| SetPropW( hWnd, wine_atl_iocsW, This ); |
| This->OrigWndProc = (WNDPROC)SetWindowLongPtrW( hWnd, GWLP_WNDPROC, (ULONG_PTR) AtlHost_wndproc ); |
| |
| return S_OK; |
| } |
| |
| static HRESULT IOCS_Init( IOCS *This ) |
| { |
| RECT rect; |
| static const WCHAR AXWIN[] = {'A','X','W','I','N',0}; |
| |
| IOleObject_SetHostNames( This->control, AXWIN, AXWIN ); |
| |
| GetClientRect( This->hWnd, &rect ); |
| IOCS_OnSize( This, &rect ); |
| IOleObject_DoVerb( This->control, OLEIVERB_INPLACEACTIVATE, NULL, &This->IOleClientSite_iface, |
| 0, This->hWnd, &rect ); |
| |
| return S_OK; |
| } |
| |
| /********************************************************************** |
| * Create new instance of Atl host component and attach it to window * |
| */ |
| static HRESULT IOCS_Create( HWND hWnd, IUnknown *pUnkControl, IUnknown **container ) |
| { |
| HRESULT hr; |
| IOCS *This; |
| |
| if (!container) |
| return S_OK; |
| |
| *container = NULL; |
| This = HeapAlloc(GetProcessHeap(), 0, sizeof(IOCS)); |
| |
| if (!This) |
| return E_OUTOFMEMORY; |
| |
| This->IOleClientSite_iface.lpVtbl = &OleClientSite_vtbl; |
| This->IOleContainer_iface.lpVtbl = &OleContainer_vtbl; |
| This->IOleInPlaceSiteWindowless_iface.lpVtbl = &OleInPlaceSiteWindowless_vtbl; |
| This->IOleInPlaceFrame_iface.lpVtbl = &OleInPlaceFrame_vtbl; |
| This->IOleControlSite_iface.lpVtbl = &OleControlSite_vtbl; |
| This->ref = 1; |
| |
| This->OrigWndProc = NULL; |
| This->hWnd = NULL; |
| This->fWindowless = This->fActive = This->fInPlace = FALSE; |
| |
| hr = IOCS_Attach( This, hWnd, pUnkControl ); |
| if ( SUCCEEDED( hr ) ) |
| hr = IOCS_Init( This ); |
| if ( SUCCEEDED( hr ) ) |
| *container = (IUnknown*)&This->IOleClientSite_iface; |
| else |
| { |
| IOCS_Detach( This ); |
| HeapFree(GetProcessHeap(), 0, This); |
| } |
| |
| return hr; |
| } |
| |
| |
| /*********************************************************************** |
| * AtlAxCreateControl [atl100.@] |
| */ |
| HRESULT WINAPI AtlAxCreateControl(LPCOLESTR lpszName, HWND hWnd, |
| IStream *pStream, IUnknown **ppUnkContainer) |
| { |
| return AtlAxCreateControlEx( lpszName, hWnd, pStream, ppUnkContainer, |
| NULL, NULL, NULL ); |
| } |
| |
| enum content |
| { |
| IsEmpty = 0, |
| IsGUID = 1, |
| IsHTML = 2, |
| IsURL = 3, |
| IsUnknown = 4 |
| }; |
| |
| static enum content get_content_type(LPCOLESTR name, CLSID *control_id) |
| { |
| WCHAR new_urlW[MAX_PATH]; |
| DWORD size = MAX_PATH; |
| WCHAR mshtml_prefixW[] = {'m','s','h','t','m','l',':','\0'}; |
| |
| if (!name || !name[0]) |
| { |
| WARN("name %s\n", wine_dbgstr_w(name)); |
| return IsEmpty; |
| } |
| |
| if (CLSIDFromString(name, control_id) == S_OK || |
| CLSIDFromProgID(name, control_id) == S_OK) |
| return IsGUID; |
| |
| if (PathIsURLW (name) || |
| UrlApplySchemeW(name, new_urlW, &size, URL_APPLY_GUESSSCHEME|URL_APPLY_GUESSFILE) == S_OK) |
| { |
| *control_id = CLSID_WebBrowser; |
| return IsURL; |
| } |
| |
| if (!strncmpiW(name, mshtml_prefixW, 7)) |
| { |
| FIXME("mshtml prefix not implemented\n"); |
| *control_id = CLSID_WebBrowser; |
| return IsHTML; |
| } |
| |
| return IsUnknown; |
| } |
| |
| /*********************************************************************** |
| * AtlAxCreateControlLicEx [atl100.@] |
| * |
| * REMARKS |
| * See http://www.codeproject.com/com/cwebpage.asp for some background |
| * |
| */ |
| HRESULT WINAPI AtlAxCreateControlLicEx(LPCOLESTR lpszName, HWND hWnd, |
| IStream *pStream, IUnknown **ppUnkContainer, IUnknown **ppUnkControl, |
| REFIID iidSink, IUnknown *punkSink, BSTR lic) |
| { |
| CLSID controlId; |
| HRESULT hRes; |
| IOleObject *pControl; |
| IUnknown *pUnkControl = NULL; |
| IPersistStreamInit *pPSInit; |
| IUnknown *pContainer = NULL; |
| enum content content; |
| |
| TRACE("(%s %p %p %p %p %p %p %s)\n", debugstr_w(lpszName), hWnd, pStream, |
| ppUnkContainer, ppUnkControl, iidSink, punkSink, debugstr_w(lic)); |
| |
| if (lic) |
| FIXME("semi stub\n"); |
| |
| if (ppUnkContainer) *ppUnkContainer = NULL; |
| if (ppUnkControl) *ppUnkControl = NULL; |
| |
| content = get_content_type(lpszName, &controlId); |
| |
| if (content == IsEmpty) |
| return S_OK; |
| |
| if (content == IsUnknown) |
| return CO_E_CLASSSTRING; |
| |
| hRes = CoCreateInstance( &controlId, 0, CLSCTX_ALL, &IID_IOleObject, |
| (void**) &pControl ); |
| if ( FAILED( hRes ) ) |
| { |
| WARN( "cannot create ActiveX control %s instance - error 0x%08x\n", |
| debugstr_guid( &controlId ), hRes ); |
| return hRes; |
| } |
| |
| hRes = IOleObject_QueryInterface( pControl, &IID_IPersistStreamInit, (void**) &pPSInit ); |
| if ( SUCCEEDED( hRes ) ) |
| { |
| if (!pStream) |
| IPersistStreamInit_InitNew( pPSInit ); |
| else |
| IPersistStreamInit_Load( pPSInit, pStream ); |
| IPersistStreamInit_Release( pPSInit ); |
| } else |
| WARN("cannot get IID_IPersistStreamInit out of control\n"); |
| |
| IOleObject_QueryInterface( pControl, &IID_IUnknown, (void**) &pUnkControl ); |
| IOleObject_Release( pControl ); |
| |
| |
| hRes = AtlAxAttachControl( pUnkControl, hWnd, &pContainer ); |
| if ( FAILED( hRes ) ) |
| WARN("cannot attach control to window\n"); |
| |
| if ( content == IsURL ) |
| { |
| IWebBrowser2 *browser; |
| |
| hRes = IOleObject_QueryInterface( pControl, &IID_IWebBrowser2, (void**) &browser ); |
| if ( !browser ) |
| WARN( "Cannot query IWebBrowser2 interface: %08x\n", hRes ); |
| else { |
| VARIANT url; |
| |
| IWebBrowser2_put_Visible( browser, VARIANT_TRUE ); /* it seems that native does this on URL (but do not on MSHTML:! why? */ |
| |
| V_VT(&url) = VT_BSTR; |
| V_BSTR(&url) = SysAllocString( lpszName ); |
| |
| hRes = IWebBrowser2_Navigate2( browser, &url, NULL, NULL, NULL, NULL ); |
| if ( FAILED( hRes ) ) |
| WARN( "IWebBrowser2::Navigate2 failed: %08x\n", hRes ); |
| SysFreeString( V_BSTR(&url) ); |
| |
| IWebBrowser2_Release( browser ); |
| } |
| } |
| |
| if (ppUnkContainer) |
| { |
| *ppUnkContainer = pContainer; |
| if ( pContainer ) |
| IUnknown_AddRef( pContainer ); |
| } |
| if (ppUnkControl) |
| { |
| *ppUnkControl = pUnkControl; |
| if ( pUnkControl ) |
| IUnknown_AddRef( pUnkControl ); |
| } |
| |
| if ( pUnkControl ) |
| IUnknown_Release( pUnkControl ); |
| if ( pContainer ) |
| IUnknown_Release( pContainer ); |
| |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * AtlAxAttachControl [atl100.@] |
| */ |
| HRESULT WINAPI AtlAxAttachControl(IUnknown *control, HWND hWnd, IUnknown **container) |
| { |
| HRESULT hr; |
| |
| TRACE("(%p %p %p)\n", control, hWnd, container); |
| |
| if (!control) |
| return E_INVALIDARG; |
| |
| hr = IOCS_Create( hWnd, control, container ); |
| return hWnd ? hr : S_FALSE; |
| } |
| |
| /********************************************************************** |
| * Helper function for AX_ConvertDialogTemplate |
| */ |
| static inline BOOL advance_array(WORD **pptr, DWORD *palloc, DWORD *pfilled, const WORD *data, DWORD size) |
| { |
| if ( (*pfilled + size) > *palloc ) |
| { |
| *palloc = ((*pfilled+size) + 0xFF) & ~0xFF; |
| *pptr = HeapReAlloc( GetProcessHeap(), 0, *pptr, *palloc * sizeof(WORD) ); |
| if (!*pptr) |
| return FALSE; |
| } |
| RtlMoveMemory( *pptr+*pfilled, data, size * sizeof(WORD) ); |
| *pfilled += size; |
| return TRUE; |
| } |
| |
| /********************************************************************** |
| * Convert ActiveX control templates to AtlAxWin class instances |
| */ |
| static LPDLGTEMPLATEW AX_ConvertDialogTemplate(LPCDLGTEMPLATEW src_tmpl) |
| { |
| #define GET_WORD(x) (*(const WORD *)(x)) |
| #define GET_DWORD(x) (*(const DWORD *)(x)) |
| #define PUT_BLOCK(x,y) do {if (!advance_array(&output, &allocated, &filled, (x), (y))) return NULL;} while (0) |
| #define PUT_WORD(x) do {WORD w = (x);PUT_BLOCK(&w, 1);} while(0) |
| const WORD *tmp, *src = (const WORD *)src_tmpl; |
| WORD *output; |
| DWORD allocated, filled; /* in WORDs */ |
| BOOL ext; |
| WORD signature, dlgver, rescount; |
| DWORD style; |
| |
| filled = 0; allocated = 256; |
| output = HeapAlloc( GetProcessHeap(), 0, allocated * sizeof(WORD) ); |
| if (!output) |
| return NULL; |
| |
| /* header */ |
| tmp = src; |
| signature = GET_WORD(src); |
| dlgver = GET_WORD(src + 1); |
| if (signature == 1 && dlgver == 0xFFFF) |
| { |
| ext = TRUE; |
| src += 6; |
| style = GET_DWORD(src); |
| src += 2; |
| rescount = GET_WORD(src++); |
| src += 4; |
| if ( GET_WORD(src) == 0xFFFF ) /* menu */ |
| src += 2; |
| else |
| src += strlenW(src) + 1; |
| if ( GET_WORD(src) == 0xFFFF ) /* class */ |
| src += 2; |
| else |
| src += strlenW(src) + 1; |
| src += strlenW(src) + 1; /* title */ |
| if ( style & (DS_SETFONT | DS_SHELLFONT) ) |
| { |
| src += 3; |
| src += strlenW(src) + 1; |
| } |
| } else { |
| ext = FALSE; |
| style = GET_DWORD(src); |
| src += 4; |
| rescount = GET_WORD(src++); |
| src += 4; |
| if ( GET_WORD(src) == 0xFFFF ) /* menu */ |
| src += 2; |
| else |
| src += strlenW(src) + 1; |
| if ( GET_WORD(src) == 0xFFFF ) /* class */ |
| src += 2; |
| else |
| src += strlenW(src) + 1; |
| src += strlenW(src) + 1; /* title */ |
| if ( style & DS_SETFONT ) |
| { |
| src++; |
| src += strlenW(src) + 1; |
| } |
| } |
| PUT_BLOCK(tmp, src-tmp); |
| |
| while(rescount--) |
| { |
| src = (const WORD *)( ( ((ULONG_PTR)src) + 3) & ~3); /* align on DWORD boundary */ |
| filled = (filled + 1) & ~1; /* depends on DWORD-aligned allocation unit */ |
| |
| tmp = src; |
| if (ext) |
| src += 12; |
| else |
| src += 9; |
| PUT_BLOCK(tmp, src-tmp); |
| |
| tmp = src; |
| if ( GET_WORD(src) == 0xFFFF ) /* class */ |
| { |
| src += 2; |
| } else |
| { |
| src += strlenW(src) + 1; |
| } |
| src += strlenW(src) + 1; /* title */ |
| if ( GET_WORD(tmp) == '{' ) /* all this mess created because of this line */ |
| { |
| static const WCHAR AtlAxWin[] = {'A','t','l','A','x','W','i','n', 0}; |
| PUT_BLOCK(AtlAxWin, sizeof(AtlAxWin)/sizeof(WCHAR)); |
| PUT_BLOCK(tmp, strlenW(tmp)+1); |
| } else |
| PUT_BLOCK(tmp, src-tmp); |
| |
| if ( GET_WORD(src) ) |
| { |
| WORD size = (GET_WORD(src)+sizeof(WORD)-1) / sizeof(WORD); /* quite ugly :( Maybe use BYTE* instead of WORD* everywhere ? */ |
| PUT_BLOCK(src, size); |
| src+=size; |
| } |
| else |
| { |
| PUT_WORD(0); |
| src++; |
| } |
| } |
| return (LPDLGTEMPLATEW) output; |
| } |
| |
| /*********************************************************************** |
| * AtlAxCreateDialogA [atl100.@] |
| * |
| * Creates a dialog window |
| * |
| * PARAMS |
| * hInst [I] Application instance |
| * name [I] Dialog box template name |
| * owner [I] Dialog box parent HWND |
| * dlgProc [I] Dialog box procedure |
| * param [I] This value will be passed to dlgProc as WM_INITDIALOG's message lParam |
| * |
| * RETURNS |
| * Window handle of dialog window. |
| */ |
| HWND WINAPI AtlAxCreateDialogA(HINSTANCE hInst, LPCSTR name, HWND owner, DLGPROC dlgProc ,LPARAM param) |
| { |
| HWND res = NULL; |
| int length; |
| WCHAR *nameW; |
| |
| if (IS_INTRESOURCE(name)) |
| return AtlAxCreateDialogW( hInst, (LPCWSTR) name, owner, dlgProc, param ); |
| |
| length = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 ); |
| nameW = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) ); |
| if (nameW) |
| { |
| MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, length ); |
| res = AtlAxCreateDialogW( hInst, nameW, owner, dlgProc, param ); |
| HeapFree( GetProcessHeap(), 0, nameW ); |
| } |
| return res; |
| } |
| |
| /*********************************************************************** |
| * AtlAxCreateDialogW [atl100.@] |
| * |
| * See AtlAxCreateDialogA |
| * |
| */ |
| HWND WINAPI AtlAxCreateDialogW(HINSTANCE hInst, LPCWSTR name, HWND owner, DLGPROC dlgProc ,LPARAM param) |
| { |
| HRSRC hrsrc; |
| HGLOBAL hgl; |
| LPCDLGTEMPLATEW ptr; |
| LPDLGTEMPLATEW newptr; |
| HWND res; |
| |
| TRACE("(%p %s %p %p %lx)\n", hInst, debugstr_w(name), owner, dlgProc, param); |
| |
| hrsrc = FindResourceW( hInst, name, (LPWSTR)RT_DIALOG ); |
| if ( !hrsrc ) |
| return NULL; |
| hgl = LoadResource (hInst, hrsrc); |
| if ( !hgl ) |
| return NULL; |
| ptr = LockResource ( hgl ); |
| if (!ptr) |
| { |
| FreeResource( hgl ); |
| return NULL; |
| } |
| newptr = AX_ConvertDialogTemplate( ptr ); |
| if ( newptr ) |
| { |
| res = CreateDialogIndirectParamW( hInst, newptr, owner, dlgProc, param ); |
| HeapFree( GetProcessHeap(), 0, newptr ); |
| } else |
| res = NULL; |
| FreeResource ( hrsrc ); |
| return res; |
| } |
| |
| /*********************************************************************** |
| * AtlAxGetHost [atl100.@] |
| * |
| */ |
| HRESULT WINAPI AtlAxGetHost(HWND hWnd, IUnknown **host) |
| { |
| IOCS *This; |
| |
| TRACE("(%p, %p)\n", hWnd, host); |
| |
| *host = NULL; |
| |
| This = (IOCS*) GetPropW( hWnd, wine_atl_iocsW ); |
| if ( !This ) |
| { |
| WARN("No container attached to %p\n", hWnd ); |
| return E_FAIL; |
| } |
| |
| return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, &IID_IUnknown, (void**)host); |
| } |
| |
| /*********************************************************************** |
| * AtlAxGetControl [atl100.@] |
| * |
| */ |
| HRESULT WINAPI AtlAxGetControl(HWND hWnd, IUnknown **pUnk) |
| { |
| IOCS *This; |
| |
| TRACE( "(%p, %p)\n", hWnd, pUnk ); |
| |
| *pUnk = NULL; |
| |
| This = (IOCS*) GetPropW( hWnd, wine_atl_iocsW ); |
| if ( !This || !This->control ) |
| { |
| WARN("No control attached to %p\n", hWnd ); |
| return E_FAIL; |
| } |
| |
| return IOleObject_QueryInterface( This->control, &IID_IUnknown, (void**) pUnk ); |
| } |
| |
| /*********************************************************************** |
| * AtlAxDialogBoxW [atl100.35] |
| * |
| */ |
| INT_PTR WINAPI AtlAxDialogBoxW(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, |
| LPARAM dwInitParam) |
| { |
| FIXME("(%p %s %p %p %lx)\n", hInstance, debugstr_w(lpTemplateName), hWndParent, lpDialogProc, dwInitParam); |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * AtlAxDialogBoxA [atl100.36] |
| * |
| */ |
| INT_PTR WINAPI AtlAxDialogBoxA(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, |
| LPARAM dwInitParam) |
| { |
| FIXME("(%p %s %p %p %lx)\n", hInstance, debugstr_a(lpTemplateName), hWndParent, lpDialogProc, dwInitParam); |
| return 0; |
| } |
| |
| /*********************************************************************** |
| * AtlAxCreateControlLic [atl100.59] |
| * |
| */ |
| HRESULT WINAPI AtlAxCreateControlLic(const WCHAR *lpTricsData, HWND hwnd, IStream *stream, IUnknown **container, BSTR lic) |
| { |
| return AtlAxCreateControlLicEx(lpTricsData, hwnd, stream, container, NULL, NULL, NULL, lic); |
| } |
| |
| /*********************************************************************** |
| * AtlAxCreateControlEx [atl100.@] |
| * |
| */ |
| HRESULT WINAPI AtlAxCreateControlEx(const WCHAR *lpTricsData, HWND hwnd, IStream *stream, |
| IUnknown **container, IUnknown **control, REFIID iidSink, IUnknown *punkSink) |
| { |
| return AtlAxCreateControlLicEx(lpTricsData, hwnd, stream, container, control, iidSink, punkSink, NULL); |
| } |