wine/dlls/atl/atl_ax.c

224 lines
6.7 KiB
C

/*
* 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 "winuser.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 "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(atl);
/**********************************************************************
* AtlAxWin class window procedure
*/
LRESULT static 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 [ATL.@]
* 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;
const WCHAR AtlAxWin[] = {'A','t','l','A','x','W','i','n',0};
FIXME("semi-stub\n");
if ( FAILED( OleInitialize(NULL) ) )
return FALSE;
wcex.cbSize = sizeof(wcex);
wcex.style = 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 = AtlAxWin;
if ( !RegisterClassExW( &wcex ) )
return FALSE;
return TRUE;
}
/***********************************************************************
* AtlAxCreateControl [ATL.@]
*/
HRESULT WINAPI AtlAxCreateControl(LPCOLESTR lpszName, HWND hWnd,
IStream *pStream, IUnknown **ppUnkContainer)
{
return AtlAxCreateControlEx( lpszName, hWnd, pStream, ppUnkContainer,
NULL, NULL, NULL );
}
/***********************************************************************
* AtlAxCreateControlEx [ATL.@]
*
* REMARKS
* See http://www.codeproject.com/com/cwebpage.asp for some background
*
*/
HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd,
IStream *pStream, IUnknown **ppUnkContainer, IUnknown **ppUnkControl,
REFIID iidSink, IUnknown *punkSink)
{
CLSID controlId;
HRESULT hRes;
IOleObject *pControl;
IUnknown *pUnkControl;
IPersistStreamInit *pPSInit;
IUnknown *pContainer;
enum {IsGUID=0,IsHTML=1,IsURL=2} content;
TRACE("(%s %p %p %p %p %p %p)\n", debugstr_w(lpszName), hWnd, pStream,
ppUnkContainer, ppUnkControl, iidSink, punkSink);
hRes = CLSIDFromString( (LPOLESTR) lpszName, &controlId );
if ( FAILED(hRes) )
hRes = CLSIDFromProgID( lpszName, &controlId );
if ( SUCCEEDED( hRes ) )
content = IsGUID;
else {
/* FIXME - check for MSHTML: prefix! */
content = IsURL;
memcpy( &controlId, &CLSID_WebBrowser, sizeof(controlId) );
}
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 );
}
IUnknown_Release( pUnkControl );
if ( pContainer )
IUnknown_Release( pContainer );
return S_OK;
}
/***********************************************************************
* AtlAxAttachControl [ATL.@]
*/
HRESULT WINAPI AtlAxAttachControl(IUnknown* pControl, HWND hWnd, IUnknown** ppUnkContainer)
{
FIXME( "(%p %p %p) - stub\n", pControl, hWnd, ppUnkContainer );
return E_NOTIMPL;
}