/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"

#include <com/sun/star/awt/WindowEvent.hpp>
#include <com/sun/star/awt/KeyEvent.hpp>
#include <com/sun/star/awt/KeyModifier.hpp>
#include <com/sun/star/awt/MouseEvent.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/awt/MouseWheelBehavior.hpp>
#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/awt/Style.hpp>
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/awt/DockingEvent.hpp>
#include <com/sun/star/awt/EndDockingEvent.hpp>
#include <com/sun/star/awt/EndPopupModeEvent.hpp>
#include <com/sun/star/awt/XWindowListener2.hpp>
#include <com/sun/star/style/VerticalAlignment.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/text/WritingMode2.hpp>
#include <toolkit/awt/vclxwindow.hxx>
#include <toolkit/awt/vclxpointer.hxx>
#include <toolkit/awt/vclxwindows.hxx>
#include <toolkit/helper/macros.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/convert.hxx>
#include <toolkit/helper/macros.hxx>
#include <toolkit/helper/property.hxx>
#include <toolkit/helper/accessibilityclient.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <rtl/memory.h>
#include <rtl/uuid.h>
#include <rtl/ustrbuf.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include <tools/color.hxx>
#include <vcl/dockwin.hxx>
#include <vcl/pdfextoutdevdata.hxx>
#include <vcl/tabpage.hxx>
#include <vcl/button.hxx>
#include <comphelper/asyncnotification.hxx>
#include <comphelper/flagguard.hxx>
#include <toolkit/helper/solarrelease.hxx>
#include "stylesettings.hxx"
#include <tools/urlobj.hxx>
#include <toolkit/helper/unopropertyarrayhelper.hxx>

#include <boost/bind.hpp>

using namespace ::com::sun::star;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::lang::EventObject;
using ::com::sun::star::awt::XWindowListener2;
using ::com::sun::star::awt::XDockableWindowListener;
using ::com::sun::star::awt::XDevice;
using ::com::sun::star::awt::XStyleSettings;
using ::com::sun::star::lang::DisposedException;
using ::com::sun::star::style::VerticalAlignment;
using ::com::sun::star::style::VerticalAlignment_TOP;
using ::com::sun::star::style::VerticalAlignment_MIDDLE;
using ::com::sun::star::style::VerticalAlignment_BOTTOM;
using ::com::sun::star::style::VerticalAlignment_MAKE_FIXED_SIZE;

namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
namespace MouseWheelBehavior = ::com::sun::star::awt::MouseWheelBehavior;

using ::toolkit::ReleaseSolarMutex;

//====================================================================
//= VCLXWindowImpl
//====================================================================
class SAL_DLLPRIVATE VCLXWindowImpl
{
private:
    typedef ::std::vector< VCLXWindow::Callback >                       CallbackArray;

private:
    VCLXWindow&                         mrAntiImpl;
    ::vos::IMutex&                      mrMutex;
    ::toolkit::AccessibilityClient      maAccFactory;
    bool                                mbDisposed;
    bool                                mbDrawingOntoParent;    // no bit mask, is passed around  by reference
    sal_Bool                            mbEnableVisible;
    sal_Bool                            mbDirectVisible;

    ::osl::Mutex                        maListenerContainerMutex;
    ::cppu::OInterfaceContainerHelper   maWindow2Listeners;
    ::cppu::OInterfaceContainerHelper   maDockableWindowListeners;
    EventListenerMultiplexer		    maEventListeners;
    FocusListenerMultiplexer		    maFocusListeners;
    WindowListenerMultiplexer		    maWindowListeners;
    KeyListenerMultiplexer			    maKeyListeners;
    MouseListenerMultiplexer		    maMouseListeners;
    MouseMotionListenerMultiplexer	    maMouseMotionListeners;
    PaintListenerMultiplexer		    maPaintListeners;
    VclContainerListenerMultiplexer	    maContainerListeners;
    TopWindowListenerMultiplexer	    maTopWindowListeners;

    CallbackArray                       maCallbackEvents;
    sal_uLong                               mnCallbackEventId;

public:
	bool                                mbDisposing             : 1;
	bool                                mbDesignMode            : 1;
    bool                                mbSynthesizingVCLEvent  : 1;
    bool                                mbWithDefaultProps      : 1;

	sal_uLong                               mnListenerLockLevel;
    sal_Int16                           mnWritingMode;
    sal_Int16                           mnContextWritingMode;

    UnoPropertyArrayHelper*             mpPropHelper;

	::com::sun::star::uno::Reference< ::com::sun::star::awt::XPointer >
                                        mxPointer;
	::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
                                        mxAccessibleContext;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >
                                        mxViewGraphics;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XStyleSettings >
                                        mxWindowStyleSettings;

public:
    bool&   getDrawingOntoParent_ref()  { return mbDrawingOntoParent; }

public:
    /** ctor
    @param _pAntiImpl
        the <type>VCLXWindow</type> instance which the object belongs to. Must
        live longer then the object just being constructed.
    */
    VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex, bool _bWithDefaultProps );

    /** synchronously mbEnableVisible
    */
    void    setEnableVisible( sal_Bool bEnableVisible ) { mbEnableVisible = bEnableVisible; }
    sal_Bool    isEnableVisible() { return mbEnableVisible; }
    /** synchronously mbDirectVisible;
    */
    void    setDirectVisible( sal_Bool bDirectVisible ) { mbDirectVisible = bDirectVisible; }
    sal_Bool    isDirectVisible() { return mbDirectVisible; }

    /** impl-version of VCLXWindow::ImplExecuteAsyncWithoutSolarLock
    */
    void    callBackAsync( const VCLXWindow::Callback& i_callback );

    /** notifies the object that its VCLXWindow is being disposed
    */
    void    disposing();

    inline ::toolkit::AccessibilityClient& getAccessibleFactory()
    {
        return maAccFactory;
    }

    Reference< XStyleSettings > getStyleSettings();

    /** returns the container of registered XWindowListener2 listeners
    */
    inline ::cppu::OInterfaceContainerHelper&   getWindow2Listeners()       { return maWindow2Listeners; }
    inline ::cppu::OInterfaceContainerHelper&   getDockableWindowListeners(){ return maDockableWindowListeners; }
    inline EventListenerMultiplexer&            getEventListeners()         { return maEventListeners; }
    inline FocusListenerMultiplexer&            getFocusListeners()         { return maFocusListeners; }
    inline WindowListenerMultiplexer&           getWindowListeners()        { return maWindowListeners; }
    inline KeyListenerMultiplexer&              getKeyListeners()           { return maKeyListeners; }
    inline MouseListenerMultiplexer&            getMouseListeners() 	    { return maMouseListeners; }
    inline MouseMotionListenerMultiplexer&      getMouseMotionListeners()   { return maMouseMotionListeners; }
    inline PaintListenerMultiplexer&            getPaintListeners() 	    { return maPaintListeners; }
    inline VclContainerListenerMultiplexer&     getContainerListeners()     { return maContainerListeners; }
    inline TopWindowListenerMultiplexer&        getTopWindowListeners()	    { return maTopWindowListeners; }

    virtual ~VCLXWindowImpl();

protected:
    virtual void SAL_CALL acquire();
    virtual void SAL_CALL release();

private:
    DECL_LINK( OnProcessCallbacks, void* );

private:
    VCLXWindowImpl();                                   // never implemented
    VCLXWindowImpl( const VCLXWindowImpl& );            // never implemented
    VCLXWindowImpl& operator=( const VCLXWindowImpl& ); // never implemented
};

//--------------------------------------------------------------------
VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex, bool _bWithDefaultProps )
    :mrAntiImpl( _rAntiImpl )
    ,mrMutex( _rMutex )
    ,mbDisposed( false )
    ,mbDrawingOntoParent( false )
    ,mbEnableVisible(sal_True)
    ,mbDirectVisible(sal_True)
    ,maListenerContainerMutex( )
    ,maWindow2Listeners( maListenerContainerMutex )
    ,maDockableWindowListeners( maListenerContainerMutex )
    ,maEventListeners( _rAntiImpl )
    ,maFocusListeners( _rAntiImpl )
    ,maWindowListeners( _rAntiImpl )
    ,maKeyListeners( _rAntiImpl )
    ,maMouseListeners( _rAntiImpl )
    ,maMouseMotionListeners( _rAntiImpl )
    ,maPaintListeners( _rAntiImpl )
    ,maContainerListeners( _rAntiImpl )
    ,maTopWindowListeners( _rAntiImpl )
    ,mnCallbackEventId( 0 )
    ,mbDisposing( false )
    ,mbDesignMode( false )
    ,mbSynthesizingVCLEvent( false )
    ,mbWithDefaultProps( _bWithDefaultProps )
    ,mnListenerLockLevel( 0 )
    ,mnWritingMode( WritingMode2::CONTEXT )
    ,mnContextWritingMode( WritingMode2::CONTEXT )
    ,mpPropHelper( NULL )
{
}

VCLXWindowImpl::~VCLXWindowImpl()
{
    delete mpPropHelper;
}

//--------------------------------------------------------------------
void VCLXWindowImpl::disposing()
{
	::vos::OGuard aGuard( mrMutex );
    if ( mnCallbackEventId )
        Application::RemoveUserEvent( mnCallbackEventId );
    mnCallbackEventId = 0;

    mbDisposed= true;

	::com::sun::star::lang::EventObject aEvent;
	aEvent.Source = mrAntiImpl;

	maEventListeners.disposeAndClear( aEvent );
	maFocusListeners.disposeAndClear( aEvent );
	maWindowListeners.disposeAndClear( aEvent );
	maKeyListeners.disposeAndClear( aEvent );
	maMouseListeners.disposeAndClear( aEvent );
	maMouseMotionListeners.disposeAndClear( aEvent );
	maPaintListeners.disposeAndClear( aEvent );
	maContainerListeners.disposeAndClear( aEvent );
	maTopWindowListeners.disposeAndClear( aEvent );

    ::toolkit::WindowStyleSettings* pStyleSettings = static_cast< ::toolkit::WindowStyleSettings* >( mxWindowStyleSettings.get() );
    if ( pStyleSettings != NULL )
        pStyleSettings->dispose();
    mxWindowStyleSettings.clear();
}

//--------------------------------------------------------------------
void VCLXWindowImpl::callBackAsync( const VCLXWindow::Callback& i_callback )
{
    DBG_TESTSOLARMUTEX();
    maCallbackEvents.push_back( i_callback );
    if ( !mnCallbackEventId )
    {
        // ensure our VCLXWindow is not destroyed while the event is underway
        mrAntiImpl.acquire();
        mnCallbackEventId = Application::PostUserEvent( LINK( this, VCLXWindowImpl, OnProcessCallbacks ) );
    }
}

//----------------------------------------------------------------------------------------------------------------------
IMPL_LINK( VCLXWindowImpl, OnProcessCallbacks, void*, EMPTYARG )
{
    const Reference< uno::XInterface > xKeepAlive( mrAntiImpl );

    // work on a copy of the callback array
    CallbackArray aCallbacksCopy;
    {
	    ::vos::OGuard aGuard( mrMutex );
        aCallbacksCopy = maCallbackEvents;
        maCallbackEvents.clear();

        // we acquired our VCLXWindow once before posting the event, release this one ref now
        mrAntiImpl.release();

        if ( !mnCallbackEventId )
            // we were disposed while waiting for the mutex to lock
            return 1L;

        mnCallbackEventId = 0;
    }

    {
        ReleaseSolarMutex aReleaseSolar( ReleaseSolarMutex::RescheduleDuringAcquire );
        for (   CallbackArray::const_iterator loop = aCallbacksCopy.begin();
                loop != aCallbacksCopy.end();
                ++loop
            )
        {
            (*loop)();
        }
    }

    return 0L;
}

//--------------------------------------------------------------------
void SAL_CALL VCLXWindowImpl::acquire()
{
    mrAntiImpl.acquire();
}

//--------------------------------------------------------------------
void SAL_CALL VCLXWindowImpl::release()
{
    mrAntiImpl.release();
}

//--------------------------------------------------------------------
Reference< XStyleSettings > VCLXWindowImpl::getStyleSettings()
{
    ::vos::OGuard  aGuard( mrMutex );
    if ( mbDisposed )
        throw DisposedException( ::rtl::OUString(), mrAntiImpl );
    if ( !mxWindowStyleSettings.is() )
        mxWindowStyleSettings = new ::toolkit::WindowStyleSettings( mrMutex, maListenerContainerMutex, mrAntiImpl );
    return mxWindowStyleSettings;
}

//====================================================================
//====================================================================

// Mit Out-Parameter besser als Rueckgabewert, wegen Ref-Objekt...

void ImplInitWindowEvent( ::com::sun::star::awt::WindowEvent& rEvent, Window* pWindow )
{
	Point aPos = pWindow->GetPosPixel();
	Size aSz = pWindow->GetSizePixel();

	rEvent.X = aPos.X();
    rEvent.Y = aPos.Y();

	rEvent.Width = aSz.Width();
    rEvent.Height = aSz.Height();

	pWindow->GetBorder( rEvent.LeftInset, rEvent.TopInset, rEvent.RightInset, rEvent.BottomInset );
}

//	----------------------------------------------------
//	class VCLXWindow
//	----------------------------------------------------

DBG_NAME(VCLXWindow);

VCLXWindow::VCLXWindow( bool _bWithDefaultProps )
    :mpImpl( NULL )
{
	DBG_CTOR( VCLXWindow, 0 );

    mpImpl = new VCLXWindowImpl( *this, GetMutex(), _bWithDefaultProps );
}

VCLXWindow::~VCLXWindow()
{
	DBG_DTOR( VCLXWindow, 0 );

    delete mpImpl;

	if ( GetWindow() )
    {
        GetWindow()->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
		GetWindow()->SetWindowPeer( NULL, NULL );
		GetWindow()->SetAccessible( NULL );
    }
}

//----------------------------------------------------------------------------------------------------------------------
void VCLXWindow::ImplExecuteAsyncWithoutSolarLock( const Callback& i_callback )
{
    mpImpl->callBackAsync( i_callback );
}

//----------------------------------------------------------------------------------------------------------------------
::toolkit::IAccessibleFactory& VCLXWindow::getAccessibleFactory()
{
    return mpImpl->getAccessibleFactory().getFactory();
}

void VCLXWindow::SetWindow( Window* pWindow )
{
    if ( GetWindow() )
    {
        GetWindow()->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
//        GetWindow()->DbgAssertNoEventListeners();
    }

    SetOutputDevice( pWindow );

    if ( GetWindow() )
    {
        GetWindow()->AddEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
        sal_Bool bDirectVisible = pWindow ? pWindow->IsVisible() : false;
        mpImpl->setDirectVisible( bDirectVisible );
    }
    
}

void VCLXWindow::suspendVclEventListening( )
{
    ++mpImpl->mnListenerLockLevel;
}

void VCLXWindow::resumeVclEventListening( )
{
    DBG_ASSERT( mpImpl->mnListenerLockLevel, "VCLXWindow::resumeVclEventListening: not suspended!" );
    --mpImpl->mnListenerLockLevel;
}

void VCLXWindow::notifyWindowRemoved( Window& _rWindow )
{
	if ( mpImpl->getContainerListeners().getLength() )
	{
        awt::VclContainerEvent aEvent;
		aEvent.Source = *this;
		aEvent.Child = static_cast< XWindow* >( _rWindow.GetWindowPeer() );
		mpImpl->getContainerListeners().windowRemoved( aEvent );
	}
}

IMPL_LINK( VCLXWindow, WindowEventListener, VclSimpleEvent*, pEvent )
{
    if ( mpImpl->mnListenerLockLevel )
        return 0L;

    DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
    if ( pEvent && pEvent->ISA( VclWindowEvent ) )
    {
        DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow() && GetWindow(), "Window???" );
        ProcessWindowEvent( *(VclWindowEvent*)pEvent );
    }
    return 0;
}

namespace
{
    struct CallWindow2Listener
    {
        CallWindow2Listener( ::cppu::OInterfaceContainerHelper& i_rWindow2Listeners, const bool i_bEnabled, const EventObject& i_rEvent )
            :m_rWindow2Listeners( i_rWindow2Listeners )
            ,m_bEnabled( i_bEnabled )
            ,m_aEvent( i_rEvent )
        {
        }

        void operator()()
        {
            m_rWindow2Listeners.notifyEach( m_bEnabled ? &XWindowListener2::windowEnabled : &XWindowListener2::windowDisabled, m_aEvent );
        }

        ::cppu::OInterfaceContainerHelper&  m_rWindow2Listeners;
        const bool                          m_bEnabled;
        const EventObject                   m_aEvent;
    };
}

void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xThis( (::cppu::OWeakObject*)this );

    switch ( rVclWindowEvent.GetId() )
    {
        case VCLEVENT_WINDOW_ENABLED:
        case VCLEVENT_WINDOW_DISABLED:
        {
            Callback aCallback = CallWindow2Listener(
                mpImpl->getWindow2Listeners(),
                ( VCLEVENT_WINDOW_ENABLED == rVclWindowEvent.GetId() ),
                EventObject( *this )
            );
            ImplExecuteAsyncWithoutSolarLock( aCallback );
        }
        break;

        case VCLEVENT_WINDOW_PAINT:
        {
        	if ( mpImpl->getPaintListeners().getLength() )
        	{
        		::com::sun::star::awt::PaintEvent aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
        		aEvent.UpdateRect = AWTRectangle( *(Rectangle*)rVclWindowEvent.GetData() );
        		aEvent.Count = 0;
        		mpImpl->getPaintListeners().windowPaint( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_MOVE:
        {
        	if ( mpImpl->getWindowListeners().getLength() )
        	{
        		::com::sun::star::awt::WindowEvent aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
        		ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
        		mpImpl->getWindowListeners().windowMoved( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_RESIZE:
        {
        	if ( mpImpl->getWindowListeners().getLength() )
        	{
        		::com::sun::star::awt::WindowEvent aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
        		ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
        		mpImpl->getWindowListeners().windowResized( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_SHOW:
        {
        	if ( mpImpl->getWindowListeners().getLength() )
        	{
        		::com::sun::star::awt::WindowEvent aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
        		ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
                mpImpl->getWindowListeners().windowShown( aEvent );
        	}

        	// For TopWindows this means opened...
        	if ( mpImpl->getTopWindowListeners().getLength() )
        	{
        		::com::sun::star::lang::EventObject aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
                mpImpl->getTopWindowListeners().windowOpened( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_HIDE:
        {
        	if ( mpImpl->getWindowListeners().getLength() )
        	{
        		::com::sun::star::awt::WindowEvent aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
        		ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
                mpImpl->getWindowListeners().windowHidden( aEvent );
        	}

        	// For TopWindows this means closed...
        	if ( mpImpl->getTopWindowListeners().getLength() )
        	{
        		::com::sun::star::lang::EventObject aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
                mpImpl->getTopWindowListeners().windowClosed( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_ACTIVATE:
        {
        	if ( mpImpl->getTopWindowListeners().getLength() )
        	{
        		::com::sun::star::lang::EventObject aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
        		mpImpl->getTopWindowListeners().windowActivated( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_DEACTIVATE:
        {
        	if ( mpImpl->getTopWindowListeners().getLength() )
        	{
        		::com::sun::star::lang::EventObject aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
        		mpImpl->getTopWindowListeners().windowDeactivated( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_CLOSE:
        {
        	if ( mpImpl->getDockableWindowListeners().getLength() )
        	{
                ::com::sun::star::lang::EventObject aEvent;
                aEvent.Source = (::cppu::OWeakObject*)this;
                mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::closed, aEvent );
        	}
        	if ( mpImpl->getTopWindowListeners().getLength() )
        	{
        		::com::sun::star::lang::EventObject aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
        		mpImpl->getTopWindowListeners().windowClosing( aEvent );
        	}
        }
        break;
		case VCLEVENT_CONTROL_GETFOCUS:
        case VCLEVENT_WINDOW_GETFOCUS:
        {
            if	(	(	rVclWindowEvent.GetWindow()->IsCompoundControl()
					&&	rVclWindowEvent.GetId() == VCLEVENT_CONTROL_GETFOCUS
					)
				||	(	!rVclWindowEvent.GetWindow()->IsCompoundControl()
					&&	rVclWindowEvent.GetId() == VCLEVENT_WINDOW_GETFOCUS
					)
				)
			{
        		if ( mpImpl->getFocusListeners().getLength() )
        		{
        			::com::sun::star::awt::FocusEvent aEvent;
        			aEvent.Source = (::cppu::OWeakObject*)this;
        			aEvent.FocusFlags = rVclWindowEvent.GetWindow()->GetGetFocusFlags();
        			aEvent.Temporary = sal_False;
        			mpImpl->getFocusListeners().focusGained( aEvent );
        		}
			}
        }
        break;
		case VCLEVENT_CONTROL_LOSEFOCUS:
        case VCLEVENT_WINDOW_LOSEFOCUS:
        {
            if	(	(	rVclWindowEvent.GetWindow()->IsCompoundControl()
					&&	rVclWindowEvent.GetId() == VCLEVENT_CONTROL_LOSEFOCUS
					)
				||	(	!rVclWindowEvent.GetWindow()->IsCompoundControl()
					&&	rVclWindowEvent.GetId() == VCLEVENT_WINDOW_LOSEFOCUS
					)
				)
			{
        		if ( mpImpl->getFocusListeners().getLength() )
        		{
        			::com::sun::star::awt::FocusEvent aEvent;
        			aEvent.Source = (::cppu::OWeakObject*)this;
        			aEvent.FocusFlags = rVclWindowEvent.GetWindow()->GetGetFocusFlags();
        			aEvent.Temporary = sal_False;

        			Window* pNext = Application::GetFocusWindow();
        			if ( pNext )
        			{
        				// Bei zusammengesetzten Controls interessiert sich keiner fuer das Innenleben:
        				Window* pNextC = pNext;
        				while ( pNextC && !pNextC->IsCompoundControl() )
        					pNextC = pNextC->GetParent();
        				if ( pNextC )
        					pNext = pNextC;

        				pNext->GetComponentInterface( sal_True );
        				aEvent.NextFocus = (::cppu::OWeakObject*)pNext->GetWindowPeer();
        			}
        			mpImpl->getFocusListeners().focusLost( aEvent );
				}
        	}
        }
        break;
        case VCLEVENT_WINDOW_MINIMIZE:
        {
        	if ( mpImpl->getTopWindowListeners().getLength() )
        	{
        		::com::sun::star::lang::EventObject aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
        		mpImpl->getTopWindowListeners().windowMinimized( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_NORMALIZE:
        {
        	if ( mpImpl->getTopWindowListeners().getLength() )
        	{
        		::com::sun::star::lang::EventObject aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
        		mpImpl->getTopWindowListeners().windowNormalized( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_KEYINPUT:
        {
        	if ( mpImpl->getKeyListeners().getLength() )
        	{
        		::com::sun::star::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
                    *(KeyEvent*)rVclWindowEvent.GetData(), *this
                ) );
        		mpImpl->getKeyListeners().keyPressed( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_KEYUP:
        {
        	if ( mpImpl->getKeyListeners().getLength() )
        	{
        		::com::sun::star::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
                    *(KeyEvent*)rVclWindowEvent.GetData(), *this
                ) );
        		mpImpl->getKeyListeners().keyReleased( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_COMMAND:
        {
            CommandEvent* pCmdEvt = (CommandEvent*)rVclWindowEvent.GetData();
        	if ( mpImpl->getMouseListeners().getLength() && ( pCmdEvt->GetCommand() == COMMAND_CONTEXTMENU ) )
        	{
        		// COMMAND_CONTEXTMENU als mousePressed mit PopupTrigger = sal_True versenden...
				Point aWhere = static_cast< CommandEvent* >( rVclWindowEvent.GetData() )->GetMousePosPixel();
				if ( !pCmdEvt->IsMouseEvent() )
				{	// for keyboard events, we set the coordinates to -1,-1. This is a slight HACK, but the current API
					// handles a context menu command as special case of a mouse event, which is simply wrong.
					// Without extending the API, we would not have another chance to notify listeners of a
					// keyboard-triggered context menu request
					// 102205 - 16.08.2002 - fs@openoffice.org
					aWhere = Point( -1, -1 );
				}

				MouseEvent aMEvt( aWhere, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT, 0 );
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( aMEvt, *this ) );
        		aEvent.PopupTrigger = sal_True;

                Callback aCallback = ::boost::bind(
                    &MouseListenerMultiplexer::mousePressed,
                    &mpImpl->getMouseListeners(),
                    aEvent
                );
                ImplExecuteAsyncWithoutSolarLock( aCallback );
        	}
        }
        break;
        case VCLEVENT_WINDOW_MOUSEMOVE:
        {
            MouseEvent* pMouseEvt = (MouseEvent*)rVclWindowEvent.GetData();
    		if ( mpImpl->getMouseListeners().getLength() && ( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) )
    		{
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) );

                Callback aCallback = ::boost::bind(
                    pMouseEvt->IsEnterWindow() ? &MouseListenerMultiplexer::mouseEntered : &MouseListenerMultiplexer::mouseExited,
                    &mpImpl->getMouseListeners(),
                    aEvent
                );
                ImplExecuteAsyncWithoutSolarLock( aCallback );
    		}

    		if ( mpImpl->getMouseMotionListeners().getLength() && !pMouseEvt->IsEnterWindow() && !pMouseEvt->IsLeaveWindow() )
    		{
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) );
                aEvent.ClickCount = 0;  // #92138#
    			if ( pMouseEvt->GetMode() & MOUSE_SIMPLEMOVE )
    				mpImpl->getMouseMotionListeners().mouseMoved( aEvent );
    			else
    				mpImpl->getMouseMotionListeners().mouseDragged( aEvent );
    		}
    	}
        break;
        case VCLEVENT_WINDOW_MOUSEBUTTONDOWN:
        {
        	if ( mpImpl->getMouseListeners().getLength() )
        	{
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *(MouseEvent*)rVclWindowEvent.GetData(), *this ) );
                Callback aCallback = ::boost::bind(
                    &MouseListenerMultiplexer::mousePressed,
                    &mpImpl->getMouseListeners(),
                    aEvent
                );
                ImplExecuteAsyncWithoutSolarLock( aCallback );
        	}
        }
        break;
        case VCLEVENT_WINDOW_MOUSEBUTTONUP:
        {
        	if ( mpImpl->getMouseListeners().getLength() )
        	{
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *(MouseEvent*)rVclWindowEvent.GetData(), *this ) );
                Callback aCallback = ::boost::bind(
                    &MouseListenerMultiplexer::mouseReleased,
                    &mpImpl->getMouseListeners(),
                    aEvent
                );
                ImplExecuteAsyncWithoutSolarLock( aCallback );
        	}
        }
        break;
        case VCLEVENT_WINDOW_STARTDOCKING:
        {
        	if ( mpImpl->getDockableWindowListeners().getLength() )
        	{
                DockingData *pData = (DockingData*)rVclWindowEvent.GetData();

                if( pData )
                {
        		    ::com::sun::star::awt::DockingEvent aEvent;
        		    aEvent.Source = (::cppu::OWeakObject*)this;
                    aEvent.TrackingRectangle = AWTRectangle( pData->maTrackRect );
                    aEvent.MousePos.X = pData->maMousePos.X();
                    aEvent.MousePos.Y = pData->maMousePos.Y();
                    aEvent.bLiveMode = pData->mbLivemode;
                    aEvent.bInteractive = pData->mbInteractive;

                    mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::startDocking, aEvent );
                }
        	}
        }
        break;
        case VCLEVENT_WINDOW_DOCKING:
        {
        	if ( mpImpl->getDockableWindowListeners().getLength() )
        	{
                DockingData *pData = (DockingData*)rVclWindowEvent.GetData();

                if( pData )
                {
        		    ::com::sun::star::awt::DockingEvent aEvent;
        		    aEvent.Source = (::cppu::OWeakObject*)this;
                    aEvent.TrackingRectangle = AWTRectangle( pData->maTrackRect );
                    aEvent.MousePos.X = pData->maMousePos.X();
                    aEvent.MousePos.Y = pData->maMousePos.Y();
                    aEvent.bLiveMode = pData->mbLivemode;
                    aEvent.bInteractive = pData->mbInteractive;

                    Reference< XDockableWindowListener > xFirstListener;
                    ::cppu::OInterfaceIteratorHelper aIter( mpImpl->getDockableWindowListeners() );
                    while ( aIter.hasMoreElements() && !xFirstListener.is() )
                    {
                        xFirstListener.set( aIter.next(), UNO_QUERY );
                    }

                    ::com::sun::star::awt::DockingData aDockingData =
                        xFirstListener->docking( aEvent );
                    pData->maTrackRect = VCLRectangle( aDockingData.TrackingRectangle );
                    pData->mbFloating = aDockingData.bFloating;
                }
        	}
        }
        break;
        case VCLEVENT_WINDOW_ENDDOCKING:
        {
        	if ( mpImpl->getDockableWindowListeners().getLength() )
        	{
                EndDockingData *pData = (EndDockingData*)rVclWindowEvent.GetData();

                if( pData )
                {
        		    ::com::sun::star::awt::EndDockingEvent aEvent;
        		    aEvent.Source = (::cppu::OWeakObject*)this;
                    aEvent.WindowRectangle = AWTRectangle( pData->maWindowRect );
                    aEvent.bFloating = pData->mbFloating;
                    aEvent.bCancelled = pData->mbCancelled;
                    mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endDocking, aEvent );
                }
        	}
        }
        break;
        case VCLEVENT_WINDOW_PREPARETOGGLEFLOATING:
        {
        	if ( mpImpl->getDockableWindowListeners().getLength() )
        	{
                sal_Bool *p_bFloating = (sal_Bool*)rVclWindowEvent.GetData();

        		::com::sun::star::lang::EventObject aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;

                Reference< XDockableWindowListener > xFirstListener;
                ::cppu::OInterfaceIteratorHelper aIter( mpImpl->getDockableWindowListeners() );
                while ( aIter.hasMoreElements() && !xFirstListener.is() )
                {
                    xFirstListener.set( aIter.next(), UNO_QUERY );
                }

                *p_bFloating = xFirstListener->prepareToggleFloatingMode( aEvent );
        	}
        }
        break;
        case VCLEVENT_WINDOW_TOGGLEFLOATING:
        {
        	if ( mpImpl->getDockableWindowListeners().getLength() )
        	{
        		::com::sun::star::lang::EventObject aEvent;
        		aEvent.Source = (::cppu::OWeakObject*)this;
                mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::toggleFloatingMode, aEvent );
        	}
       }
        break;
        case VCLEVENT_WINDOW_ENDPOPUPMODE:
        {
        	if ( mpImpl->getDockableWindowListeners().getLength() )
        	{
                EndPopupModeData *pData = (EndPopupModeData*)rVclWindowEvent.GetData();

                if( pData )
                {
        		    ::com::sun::star::awt::EndPopupModeEvent aEvent;
        		    aEvent.Source = (::cppu::OWeakObject*)this;
                    aEvent.FloatingPosition.X = pData->maFloatingPos.X();
                    aEvent.FloatingPosition.Y = pData->maFloatingPos.Y();
                    aEvent.bTearoff = pData->mbTearoff;
                    mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endPopupMode, aEvent );
                }
        	}
        }
        break;

    }
}

uno::Reference< accessibility::XAccessibleContext > VCLXWindow::CreateAccessibleContext()
{
	::vos::OGuard aGuard( GetMutex() );
    return getAccessibleFactory().createAccessibleContext( this );
}

void VCLXWindow::SetSynthesizingVCLEvent( sal_Bool _b )
{
    mpImpl->mbSynthesizingVCLEvent = _b;
}

sal_Bool VCLXWindow::IsSynthesizingVCLEvent() const
{
    return mpImpl->mbSynthesizingVCLEvent;
}

Size VCLXWindow::ImplCalcWindowSize( const Size& rOutSz ) const
{
	Size aSz = rOutSz;

	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		sal_Int32 nLeft, nTop, nRight, nBottom;
		pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
		aSz.Width() += nLeft+nRight;
		aSz.Height() += nTop+nBottom;
	}
	return aSz;
}


// ::com::sun::star::lang::XUnoTunnel
IMPL_XUNOTUNNEL2( VCLXWindow, VCLXDevice )

// ::com::sun::star::lang::Component
void VCLXWindow::dispose(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	mpImpl->mxViewGraphics = NULL;

	if ( !mpImpl->mbDisposing )
	{
		mpImpl->mbDisposing = true;

        mpImpl->disposing();

		if ( GetWindow() )
		{
			OutputDevice* pOutDev = GetOutputDevice();
			SetWindow( NULL );	// Damit ggf. Handler abgemeldet werden (virtuell).
			SetOutputDevice( pOutDev );
			DestroyOutputDevice();
		}

        // #i14103# dispose the accessible context after the window has been destroyed,
        // otherwise the old value in the child event fired in VCLXAccessibleComponent::ProcessWindowEvent()
        // for VCLEVENT_WINDOW_CHILDDESTROYED contains a reference to an already disposed accessible object
        try
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComponent( mpImpl->mxAccessibleContext, ::com::sun::star::uno::UNO_QUERY );
            if ( xComponent.is() )
                xComponent->dispose();
        }
        catch ( const ::com::sun::star::uno::Exception& )
        {
            DBG_ERROR( "VCLXWindow::dispose: could not dispose the accessible context!" );
        }
        mpImpl->mxAccessibleContext.clear();

		mpImpl->mbDisposing = false;
	}
}

void VCLXWindow::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	mpImpl->getEventListeners().addInterface( rxListener );
}

void VCLXWindow::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	mpImpl->getEventListeners().removeInterface( rxListener );
}


// ::com::sun::star::awt::XWindow
void VCLXWindow::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
    {
        if( Window::GetDockingManager()->IsDockable( GetWindow() ) )
            Window::GetDockingManager()->SetPosSizePixel( GetWindow() , X, Y, Width, Height, Flags );
        else
		    GetWindow()->SetPosSizePixel( X, Y, Width, Height, Flags );
    }
}

::com::sun::star::awt::Rectangle VCLXWindow::getPosSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::awt::Rectangle aBounds;
	if ( GetWindow() )
    {
        if( Window::GetDockingManager()->IsDockable( GetWindow() ) )
            aBounds = AWTRectangle( Window::GetDockingManager()->GetPosSizePixel( GetWindow() ) );
        else
		    aBounds = AWTRectangle( Rectangle( GetWindow()->GetPosPixel(), GetWindow()->GetSizePixel() ) );
    }

	return aBounds;
}

void VCLXWindow::setVisible( sal_Bool bVisible ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( pWindow )
	{
/*
		if ( bVisible )
		{
			// #57167# TopWindows mit unsichtbaren Parent anzeigen...
			::com::sun::star::uno::Any aTest = queryInterface( ::getCppuType(  (const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindow >*)  0 ) );
			if ( aTest.hasValue() )
			{
				Window* pParent = pWindow->GetWindow( WINDOW_PARENTOVERLAP );
				if ( pParent && !pParent->IsReallyVisible() )
		    		pWindow->SetParent( pWindow->GetWindow( WINDOW_FRAME ) );
			}
		}
*/
		mpImpl->setDirectVisible( bVisible );
		pWindow->Show( bVisible &&  mpImpl->isEnableVisible() );
	}
}

void VCLXWindow::setEnable( sal_Bool bEnable ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		pWindow->Enable( bEnable, sal_False ); // #95824# without children!
		pWindow->EnableInput( bEnable );
	}
}

void VCLXWindow::setFocus(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
		GetWindow()->GrabFocus();
}

void VCLXWindow::addWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	mpImpl->getWindowListeners().addInterface( rxListener );

    Reference< XWindowListener2 > xListener2( rxListener, UNO_QUERY );
    if ( xListener2.is() )
        mpImpl->getWindow2Listeners().addInterface( xListener2 );

    // #100119# Get all resize events, even if height or width 0, or invisible
    if ( GetWindow() )
		GetWindow()->EnableAllResize( sal_True );
}

void VCLXWindow::removeWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    Reference< XWindowListener2 > xListener2( rxListener, UNO_QUERY );
    if ( xListener2.is() )
        mpImpl->getWindow2Listeners().removeInterface( xListener2 );

    mpImpl->getWindowListeners().removeInterface( rxListener );
}

void VCLXWindow::addFocusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	mpImpl->getFocusListeners().addInterface( rxListener );
}

void VCLXWindow::removeFocusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	mpImpl->getFocusListeners().removeInterface( rxListener );
}

void VCLXWindow::addKeyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XKeyListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	mpImpl->getKeyListeners().addInterface( rxListener );
}

void VCLXWindow::removeKeyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XKeyListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	mpImpl->getKeyListeners().removeInterface( rxListener );
}

void VCLXWindow::addMouseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	mpImpl->getMouseListeners().addInterface( rxListener );
}

void VCLXWindow::removeMouseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	mpImpl->getMouseListeners().removeInterface( rxListener );
}

void VCLXWindow::addMouseMotionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseMotionListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	mpImpl->getMouseMotionListeners().addInterface( rxListener );
}

void VCLXWindow::removeMouseMotionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseMotionListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	mpImpl->getMouseMotionListeners().removeInterface( rxListener );
}

void VCLXWindow::addPaintListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XPaintListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	mpImpl->getPaintListeners().addInterface( rxListener );
}

void VCLXWindow::removePaintListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XPaintListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	mpImpl->getPaintListeners().removeInterface( rxListener );
}

// ::com::sun::star::awt::XWindowPeer
::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > VCLXWindow::getToolkit(  ) throw(::com::sun::star::uno::RuntimeException)
{
	// no guard. nothing to guard here.
	// 82463 - 12/21/00 - fs
	return Application::GetVCLToolkit();
}

void VCLXWindow::setPointer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XPointer >& rxPointer ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	VCLXPointer* pPointer = VCLXPointer::GetImplementation( rxPointer );
	if ( pPointer )
	{
		mpImpl->mxPointer = rxPointer;
		if ( GetWindow() )
			GetWindow()->SetPointer( pPointer->GetPointer() );
	}
}

void VCLXWindow::setBackground( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
	{
		Color aColor( (sal_uInt32)nColor );
		GetWindow()->SetBackground( aColor );
		GetWindow()->SetControlBackground( aColor );

		WindowType eWinType = GetWindow()->GetType();
		if ( ( eWinType == WINDOW_WINDOW ) ||
			 ( eWinType == WINDOW_WORKWINDOW ) ||
			 ( eWinType == WINDOW_FLOATINGWINDOW ) )
		{
			GetWindow()->Invalidate();
		}
	}
}

void VCLXWindow::invalidate( sal_Int16 nInvalidateFlags ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
		GetWindow()->Invalidate( (sal_uInt16) nInvalidateFlags );
}

void VCLXWindow::invalidateRect( const ::com::sun::star::awt::Rectangle& rRect, sal_Int16 nInvalidateFlags ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
		GetWindow()->Invalidate( VCLRectangle(rRect), (sal_uInt16) nInvalidateFlags );
}


// ::com::sun::star::awt::XVclWindowPeer
sal_Bool VCLXWindow::isChild( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& rxPeer ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	sal_Bool bIsChild = sal_False;
	Window* pWindow = GetWindow();
	if ( pWindow )
	{
		Window* pPeerWindow = VCLUnoHelper::GetWindow( rxPeer );
		bIsChild = pPeerWindow && pWindow->IsChild( pPeerWindow );
	}

	return bIsChild;
}

void VCLXWindow::setDesignMode( sal_Bool bOn ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	mpImpl->mbDesignMode = bOn;
}

sal_Bool VCLXWindow::isDesignMode(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
	return mpImpl->mbDesignMode;
}

void VCLXWindow::enableClipSiblings( sal_Bool bClip ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
		GetWindow()->EnableClipSiblings( bClip );
}

void VCLXWindow::setForeground( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
	{
		Color aColor( (sal_uInt32)nColor );
		GetWindow()->SetControlForeground( aColor );
	}
}

void VCLXWindow::setControlFont( const ::com::sun::star::awt::FontDescriptor& rFont ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
		GetWindow()->SetControlFont( VCLUnoHelper::CreateFont( rFont, GetWindow()->GetControlFont() ) );
}

void VCLXWindow::getStyles( sal_Int16 nType, ::com::sun::star::awt::FontDescriptor& Font, sal_Int32& ForegroundColor, sal_Int32& BackgroundColor ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
	{
		const StyleSettings& rStyleSettings = GetWindow()->GetSettings().GetStyleSettings();

		switch ( nType )
		{
			case ::com::sun::star::awt::Style::FRAME:
			{
				Font = VCLUnoHelper::CreateFontDescriptor( rStyleSettings.GetAppFont() );
				ForegroundColor = rStyleSettings.GetWindowTextColor().GetColor();
				BackgroundColor = rStyleSettings.GetWindowColor().GetColor();
			}
			break;
			case ::com::sun::star::awt::Style::DIALOG:
			{
				Font = VCLUnoHelper::CreateFontDescriptor( rStyleSettings.GetAppFont() );
				ForegroundColor = rStyleSettings.GetDialogTextColor().GetColor();
				BackgroundColor = rStyleSettings.GetDialogColor().GetColor();
			}
			break;
			default: DBG_ERROR( "VCLWindow::getStyles() - unknown Type" );
		}

	}
}

namespace toolkit
{
    static void setColorSettings( Window* _pWindow, const ::com::sun::star::uno::Any& _rValue,
        void (StyleSettings::*pSetter)( const Color& ), const Color& (StyleSettings::*pGetter)( ) const )
    {
	    sal_Int32 nColor = 0;
	    if ( !( _rValue >>= nColor ) )
            nColor = (Application::GetSettings().GetStyleSettings().*pGetter)().GetColor();

        AllSettings aSettings = _pWindow->GetSettings();
	    StyleSettings aStyleSettings = aSettings.GetStyleSettings();

        (aStyleSettings.*pSetter)( Color( nColor ) );

        aSettings.SetStyleSettings( aStyleSettings );
        _pWindow->SetSettings( aSettings, sal_True );
    }
}

// Terminated by BASEPROPERTY_NOTFOUND (or 0)
void VCLXWindow::PushPropertyIds( std::list< sal_uInt16 > &rIds,
                                  int nFirstId, ...)
{
	va_list pVarArgs;
	va_start( pVarArgs, nFirstId );

	for ( int nId = nFirstId; nId != BASEPROPERTY_NOTFOUND;
          nId = va_arg( pVarArgs, int ) )
        rIds.push_back( (sal_uInt16) nId );

	va_end( pVarArgs );
}

void VCLXWindow::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds, bool bWithDefaults )
{
    // These are common across ~all VCLXWindow derived classes
    if( bWithDefaults )
        PushPropertyIds( rIds,
                         BASEPROPERTY_ALIGN,
                         BASEPROPERTY_BACKGROUNDCOLOR,
                         BASEPROPERTY_BORDER,
                         BASEPROPERTY_BORDERCOLOR,
                         BASEPROPERTY_DEFAULTCONTROL,
                         BASEPROPERTY_ENABLED,
                         BASEPROPERTY_FONTDESCRIPTOR,
                         BASEPROPERTY_HELPTEXT,
                         BASEPROPERTY_HELPURL,
                         BASEPROPERTY_TEXT,
                         BASEPROPERTY_PRINTABLE,
                         BASEPROPERTY_ENABLEVISIBLE, // for visibility
                         BASEPROPERTY_TABSTOP,
                         0);

    // lovely hack from:
    // void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId )
    std::list< sal_uInt16 >::const_iterator iter;
    for( iter = rIds.begin(); iter != rIds.end(); iter++) {
        if( *iter == BASEPROPERTY_FONTDESCRIPTOR )
        {
            // some properties are not included in the FontDescriptor, but everytime
            // when we have a FontDescriptor we want to have these properties too.
            // => Easier to register the here, istead everywhere where I register the FontDescriptor...
            
            rIds.push_back( BASEPROPERTY_TEXTCOLOR );
            rIds.push_back( BASEPROPERTY_TEXTLINECOLOR );
            rIds.push_back( BASEPROPERTY_FONTRELIEF );
            rIds.push_back( BASEPROPERTY_FONTEMPHASISMARK );
            break;
        }
    }
}

void VCLXWindow::GetPropertyIds( std::list< sal_uInt16 >& _out_rIds )
{
    return ImplGetPropertyIds( _out_rIds, mpImpl->mbWithDefaultProps );
}

::cppu::OInterfaceContainerHelper& VCLXWindow::GetContainerListeners()
{
    return mpImpl->getContainerListeners();
}

::cppu::OInterfaceContainerHelper& VCLXWindow::GetTopWindowListeners()
{
    return mpImpl->getTopWindowListeners();
}

namespace
{
    void    lcl_updateWritingMode( Window& _rWindow, const sal_Int16 _nWritingMode, const sal_Int16 _nContextWritingMode )
    {
        sal_Bool bEnableRTL = sal_False;
        switch ( _nWritingMode )
        {
        case WritingMode2::LR_TB:   bEnableRTL = sal_False; break;
        case WritingMode2::RL_TB:   bEnableRTL = sal_True; break;
        case WritingMode2::CONTEXT:
        {
            // consult our ContextWritingMode. If it has an explicit RTL/LTR value, then use
            // it. If it doesn't (but is CONTEXT itself), then just ask the parent window of our
            // own window for its RTL mode
            switch ( _nContextWritingMode )
            {
                case WritingMode2::LR_TB:   bEnableRTL = sal_False; break;
                case WritingMode2::RL_TB:   bEnableRTL = sal_True; break;
                case WritingMode2::CONTEXT:
                {
                    const Window* pParent = _rWindow.GetParent();
                    OSL_ENSURE( pParent, "lcl_updateWritingMode: cannot determine context's writing mode!" );
                    if ( pParent )
                        bEnableRTL = pParent->IsRTLEnabled();
                }
                break;
            }
        }
        break;
        default:
            OSL_ENSURE( false, "lcl_updateWritingMode: unsupported WritingMode!" );
        }   // switch ( nWritingMode )

        _rWindow.EnableRTL( bEnableRTL );
    }
}

void VCLXWindow::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( !pWindow )
        return;

	sal_Bool bVoid = Value.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;

	WindowType eWinType = pWindow->GetType();
	sal_uInt16 nPropType = GetPropertyId( PropertyName );
	switch ( nPropType )
	{
        case BASEPROPERTY_REFERENCE_DEVICE:
        {
            Control* pControl = dynamic_cast< Control* >( pWindow );
            OSL_ENSURE( pControl, "VCLXWindow::setProperty( RefDevice ): need a Control for this!" );
            if ( !pControl )
                break;
            Reference< XDevice > xDevice( Value, UNO_QUERY );
            OutputDevice* pDevice = VCLUnoHelper::GetOutputDevice( xDevice );
            pControl->SetReferenceDevice( pDevice );
        }
        break;

        case BASEPROPERTY_CONTEXT_WRITING_MODE:
        {
            OSL_VERIFY( Value >>= mpImpl->mnContextWritingMode );
            if ( mpImpl->mnWritingMode == WritingMode2::CONTEXT )
                lcl_updateWritingMode( *pWindow, mpImpl->mnWritingMode, mpImpl->mnContextWritingMode );
        }
        break;

        case BASEPROPERTY_WRITING_MODE:
        {
            sal_Bool bProperType = ( Value >>= mpImpl->mnWritingMode );
            OSL_ENSURE( bProperType, "VCLXWindow::setProperty( 'WritingMode' ): illegal value type!" );
            if ( bProperType )
                lcl_updateWritingMode( *pWindow, mpImpl->mnWritingMode, mpImpl->mnContextWritingMode );
        }
        break;

        case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:
        {
            sal_uInt16 nWheelBehavior( MouseWheelBehavior::SCROLL_FOCUS_ONLY );
            OSL_VERIFY( Value >>= nWheelBehavior );

            AllSettings aSettings = pWindow->GetSettings();
            MouseSettings aMouseSettings = aSettings.GetMouseSettings();

            sal_uInt16 nVclBehavior( MOUSE_WHEEL_FOCUS_ONLY );
            switch ( nWheelBehavior )
            {
            case MouseWheelBehavior::SCROLL_DISABLED:   nVclBehavior = MOUSE_WHEEL_DISABLE;     break;
            case MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclBehavior = MOUSE_WHEEL_FOCUS_ONLY;  break;
            case MouseWheelBehavior::SCROLL_ALWAYS:     nVclBehavior = MOUSE_WHEEL_ALWAYS;      break;
            default:
                OSL_ENSURE( false, "VCLXWindow::setProperty( 'MouseWheelBehavior' ): illegal property value!" );
            }

            aMouseSettings.SetWheelBehavior( nWheelBehavior );
            aSettings.SetMouseSettings( aMouseSettings );
            pWindow->SetSettings( aSettings, sal_True );
        }
        break;

        case BASEPROPERTY_NATIVE_WIDGET_LOOK:
        {
			sal_Bool bEnable( sal_True );
			OSL_VERIFY( Value >>= bEnable );
            pWindow->EnableNativeWidget( bEnable );
        }
        break;

		case BASEPROPERTY_PLUGINPARENT:
		{
			// set parent handle
			SetSystemParent_Impl( Value );
		}
		break;

		case BASEPROPERTY_ENABLED:
		{
			sal_Bool b = sal_Bool();
			if ( Value >>= b )
				setEnable( b );
		}
		break;
        case BASEPROPERTY_ENABLEVISIBLE:
        {
            sal_Bool b = sal_False;
            if ( Value >>= b )
            {
                if( b != mpImpl->isEnableVisible() )
                {
                    mpImpl->setEnableVisible( b );
                    pWindow->Show( b && mpImpl->isDirectVisible() );
                }
            }
        }
        break;
		case BASEPROPERTY_TEXT:
		case BASEPROPERTY_LABEL:
		case BASEPROPERTY_TITLE:
		{
		    ::rtl::OUString aText;
		    if ( Value >>= aText )
		    {
		        switch (eWinType)
		        {
		            case WINDOW_OKBUTTON:
		            case WINDOW_CANCELBUTTON:
		            case WINDOW_HELPBUTTON:
		                // Standard Button: overwrite only if not empty.
		                if (aText.getLength())
			                pWindow->SetText( aText );
		                break;
		            
                    default:
		                pWindow->SetText( aText );
		                break;
		        }
		    }
		}
		break;
		case BASEPROPERTY_ACCESSIBLENAME:
		{
			::rtl::OUString aText;
			if ( Value >>= aText )
				pWindow->SetAccessibleName( aText );
		}
		break;
		case BASEPROPERTY_HELPURL:
		{
			::rtl::OUString aURL;
			if ( Value >>= aURL )
			{
				INetURLObject aHelpURL( aURL );
				if ( aHelpURL.GetProtocol() == INET_PROT_HID )
					pWindow->SetHelpId( rtl::OUStringToOString( aHelpURL.GetURLPath(), RTL_TEXTENCODING_UTF8 ) );
				else
				    pWindow->SetHelpId( rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ) );
			}
		}
		break;
		case BASEPROPERTY_HELPTEXT:
		{
			::rtl::OUString aHelpText;
			if ( Value >>= aHelpText )
			{
				pWindow->SetQuickHelpText( aHelpText );	
			}
		}
		break;
		case BASEPROPERTY_FONTDESCRIPTOR:
		{
			if ( bVoid )
				pWindow->SetControlFont( Font() );
			else
			{
				::com::sun::star::awt::FontDescriptor aFont;
				if ( Value >>= aFont )
					pWindow->SetControlFont( VCLUnoHelper::CreateFont( aFont, pWindow->GetControlFont() ) );
			}
		}
		break;
		case BASEPROPERTY_FONTRELIEF:
		{
            sal_Int16 n = sal_Int16();
			if ( Value >>= n )
            {
                Font aFont = pWindow->GetControlFont();
                aFont.SetRelief( (FontRelief)n );
				pWindow->SetControlFont( aFont );
            }
		}
		break;
		case BASEPROPERTY_FONTEMPHASISMARK:
		{
            sal_Int16 n = sal_Int16();
			if ( Value >>= n )
            {
                Font aFont = pWindow->GetControlFont();
                aFont.SetEmphasisMark( n );
				pWindow->SetControlFont( aFont );
            }
		}
		break;
		case BASEPROPERTY_BACKGROUNDCOLOR:
			if ( bVoid )
			{
                switch ( eWinType )
                {
                    // set dialog color for default
                    case WINDOW_DIALOG:
                    case WINDOW_MESSBOX:
		            case WINDOW_INFOBOX:
		            case WINDOW_WARNINGBOX:
		            case WINDOW_ERRORBOX:
		            case WINDOW_QUERYBOX:
                    case WINDOW_TABPAGE:
                    {
                        Color aColor = pWindow->GetSettings().GetStyleSettings().GetDialogColor();
                        pWindow->SetBackground( aColor );
                        pWindow->SetControlBackground( aColor );
                        break;
                    }

                    case WINDOW_FIXEDTEXT:
                    case WINDOW_CHECKBOX:
                    case WINDOW_RADIOBUTTON:
                    case WINDOW_GROUPBOX:
                    case WINDOW_FIXEDLINE:
                    {
                        // support transparency only for special controls
                        pWindow->SetBackground();
				        pWindow->SetControlBackground();
                        pWindow->SetPaintTransparent( sal_True );
                        break;
                    }
                    
                    default:
                    {    
                        // default code which enables transparency for
                        // compound controls. It's not real transparency
                        // as most of these controls repaint their client
                        // area completely new.
                        if ( pWindow->IsCompoundControl() )
                            pWindow->SetBackground();
                        pWindow->SetControlBackground();
                        break;
                    }
                }
			}
			else
			{
				sal_Int32 nColor = 0;
				if ( Value >>= nColor )
				{
					Color aColor( nColor );
                    pWindow->SetControlBackground( aColor );
					pWindow->SetBackground( aColor );
                    switch ( eWinType )
                    {
                        // reset paint transparent mode
                        case WINDOW_FIXEDTEXT:
                        case WINDOW_CHECKBOX:
                        case WINDOW_RADIOBUTTON:
                        case WINDOW_GROUPBOX:
                        case WINDOW_FIXEDLINE:
                            pWindow->SetPaintTransparent( sal_False );
                        default: ;
                    }
					pWindow->Invalidate();	// Falls das Control nicht drauf reagiert
				}
			}
		break;
		case BASEPROPERTY_TEXTCOLOR:
			if ( bVoid )
			{
				pWindow->SetControlForeground();
			}
			else
			{
				sal_Int32 nColor = 0;
				if ( Value >>= nColor )
				{
					Color aColor( nColor );
					pWindow->SetTextColor( aColor );
					pWindow->SetControlForeground( aColor );
				}
			}
		break;
		case BASEPROPERTY_TEXTLINECOLOR:
			if ( bVoid )
			{
				pWindow->SetTextLineColor();
			}
			else
			{
				sal_Int32 nColor = 0;
				if ( Value >>= nColor )
				{
					Color aColor( nColor );
					pWindow->SetTextLineColor( aColor );
				}
			}
		break;
		case BASEPROPERTY_FILLCOLOR:
			if ( bVoid )
				pWindow->SetFillColor();
			else
			{
				sal_Int32 nColor = 0;
				if ( Value >>= nColor )
				{
					Color aColor( nColor );
					pWindow->SetFillColor( aColor );
				}
			}
		break;
		case BASEPROPERTY_LINECOLOR:
			if ( bVoid )
				pWindow->SetLineColor();
			else
			{
				sal_Int32 nColor = 0;
				if ( Value >>= nColor )
				{
					Color aColor( nColor );
					pWindow->SetLineColor( aColor );
				}
			}
		break;
		case BASEPROPERTY_BORDER:
		{
			WinBits nStyle = pWindow->GetStyle();
			sal_uInt16 nBorder = 0;
			Value >>= nBorder;
			if ( !nBorder )
			{
				pWindow->SetStyle( nStyle & ~WB_BORDER );
			}
			else
			{
				pWindow->SetStyle( nStyle | WB_BORDER );
				pWindow->SetBorderStyle( nBorder );
			}
		}
		break;
		case BASEPROPERTY_TABSTOP:
		{
			WinBits nStyle = pWindow->GetStyle() & ~WB_TABSTOP;
			if ( !bVoid )
			{
				sal_Bool bTab = false;
				Value >>= bTab;
				if ( bTab )
					nStyle |= WB_TABSTOP;
				else
					nStyle |= WB_NOTABSTOP;
			}
			pWindow->SetStyle( nStyle );
		}
		break;
		case BASEPROPERTY_VERTICALALIGN:
        {
            VerticalAlignment eAlign = VerticalAlignment_MAKE_FIXED_SIZE;
			WinBits nStyle = pWindow->GetStyle();
			nStyle &= ~(WB_TOP|WB_VCENTER|WB_BOTTOM);
			if ( !bVoid )
				Value >>= eAlign;
            switch ( eAlign )
            {
            case VerticalAlignment_TOP:
                nStyle |= WB_TOP;
                break;
            case VerticalAlignment_MIDDLE:
                nStyle |= WB_VCENTER;
                break;
            case VerticalAlignment_BOTTOM:
                nStyle |= WB_BOTTOM;
                break;
			default: ; // for warning free code, MAKE_FIXED_SIZE
            }
			pWindow->SetStyle( nStyle );
        }
        break;
		case BASEPROPERTY_ALIGN:
		{
            sal_Int16 nAlign = PROPERTY_ALIGN_LEFT;
			switch ( eWinType )
			{
                case WINDOW_COMBOBOX:
                case WINDOW_BUTTON:
                case WINDOW_PUSHBUTTON:
                case WINDOW_OKBUTTON:
                case WINDOW_CANCELBUTTON:
                case WINDOW_HELPBUTTON:
                    nAlign = PROPERTY_ALIGN_CENTER;
                    // no break here!
                case WINDOW_FIXEDTEXT:
				case WINDOW_EDIT:
				case WINDOW_MULTILINEEDIT:
				case WINDOW_CHECKBOX:
				case WINDOW_RADIOBUTTON:
				case WINDOW_LISTBOX:
				{
					WinBits nStyle = pWindow->GetStyle();
					nStyle &= ~(WB_LEFT|WB_CENTER|WB_RIGHT);
					if ( !bVoid )
						Value >>= nAlign;
					if ( nAlign == PROPERTY_ALIGN_LEFT )
						nStyle |= WB_LEFT;
					else if ( nAlign == PROPERTY_ALIGN_CENTER )
						nStyle |= WB_CENTER;
					else
						nStyle |= WB_RIGHT;
					pWindow->SetStyle( nStyle );
				}
				break;
			}
		}
		break;
		case BASEPROPERTY_MULTILINE:
		{
			if  (  ( eWinType == WINDOW_FIXEDTEXT )
                || ( eWinType == WINDOW_CHECKBOX )
                || ( eWinType == WINDOW_RADIOBUTTON )
                || ( eWinType == WINDOW_BUTTON )
                || ( eWinType == WINDOW_PUSHBUTTON )
                || ( eWinType == WINDOW_OKBUTTON )
                || ( eWinType == WINDOW_CANCELBUTTON )
                || ( eWinType == WINDOW_HELPBUTTON )
                )
			{
				WinBits nStyle = pWindow->GetStyle();
				sal_Bool bMulti = false;
				Value >>= bMulti;
				if ( bMulti )
					nStyle |= WB_WORDBREAK;
				else
					nStyle &= ~WB_WORDBREAK;
				pWindow->SetStyle( nStyle );
			}
		}
		break;
		case BASEPROPERTY_ORIENTATION:
		{
			switch ( eWinType )
			{
				case WINDOW_FIXEDLINE:
				{
					sal_Int32 nOrientation = 0;
					if ( Value >>= nOrientation )
					{
						WinBits nStyle = pWindow->GetStyle();
						nStyle &= ~(WB_HORZ|WB_VERT);
						if ( nOrientation == 0 )
							nStyle |= WB_HORZ;
						else
							nStyle |= WB_VERT;

						pWindow->SetStyle( nStyle );
					}
				}
				break;
			}
		}
		break;
        case BASEPROPERTY_AUTOMNEMONICS:
        {
            sal_Bool bAutoMnemonics = false;
            Value >>= bAutoMnemonics;
		    AllSettings aSettings = pWindow->GetSettings();
		    StyleSettings aStyleSettings = aSettings.GetStyleSettings();
            if ( aStyleSettings.GetAutoMnemonic() != bAutoMnemonics )
            {
		        aStyleSettings.SetAutoMnemonic( bAutoMnemonics );
		        aSettings.SetStyleSettings( aStyleSettings );
		        pWindow->SetSettings( aSettings );
            }
        }
		break;
        case BASEPROPERTY_MOUSETRANSPARENT:
        {
            sal_Bool bMouseTransparent = false;
            Value >>= bMouseTransparent;
            pWindow->SetMouseTransparent( bMouseTransparent );
        }
		break;
        case BASEPROPERTY_PAINTTRANSPARENT:
        {
            sal_Bool bPaintTransparent = false;
            Value >>= bPaintTransparent;
            pWindow->SetPaintTransparent( bPaintTransparent );
//                pWindow->SetBackground();
        }
		break;

        case BASEPROPERTY_REPEAT:
        {
			sal_Bool bRepeat( sal_False );
			Value >>= bRepeat;

            WinBits nStyle = pWindow->GetStyle();
            if ( bRepeat )
                nStyle |= WB_REPEAT;
            else
                nStyle &= ~WB_REPEAT;
            pWindow->SetStyle( nStyle );
        }
        break;

        case BASEPROPERTY_REPEAT_DELAY:
        {
			sal_Int32 nRepeatDelay = 0;
			if ( Value >>= nRepeatDelay )
            {
                AllSettings aSettings = pWindow->GetSettings();
                MouseSettings aMouseSettings = aSettings.GetMouseSettings();

                aMouseSettings.SetButtonRepeat( nRepeatDelay );
                aSettings.SetMouseSettings( aMouseSettings );

                pWindow->SetSettings( aSettings, sal_True );
            }
        }
        break;

        case BASEPROPERTY_SYMBOL_COLOR:
            ::toolkit::setColorSettings( pWindow, Value, &StyleSettings::SetButtonTextColor, &StyleSettings::GetButtonTextColor );
            break;

        case BASEPROPERTY_BORDERCOLOR:
            ::toolkit::setColorSettings( pWindow, Value, &StyleSettings::SetMonoColor, &StyleSettings::GetMonoColor);
            break;
	    case BASEPROPERTY_DEFAULTCONTROL:
		{
		    rtl::OUString aName;
			Value >>= aName;
		    break;
		}
	}
}

::com::sun::star::uno::Any VCLXWindow::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Any aProp;
	if ( GetWindow() )
	{
		WindowType eWinType = GetWindow()->GetType();
		sal_uInt16 nPropType = GetPropertyId( PropertyName );
		switch ( nPropType )
		{
            case BASEPROPERTY_REFERENCE_DEVICE:
            {
                Control* pControl = dynamic_cast< Control* >( GetWindow() );
                OSL_ENSURE( pControl, "VCLXWindow::setProperty( RefDevice ): need a Control for this!" );
                if ( !pControl )
                    break;

                VCLXDevice* pDevice = new VCLXDevice;
		        pDevice->SetOutputDevice( pControl->GetReferenceDevice() );
                aProp <<= Reference< XDevice >( pDevice );
            }
            break;

            case BASEPROPERTY_CONTEXT_WRITING_MODE:
                aProp <<= mpImpl->mnContextWritingMode;
                break;

            case BASEPROPERTY_WRITING_MODE:
                aProp <<= mpImpl->mnWritingMode;
                break;

            case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:
            {
                sal_uInt16 nVclBehavior = GetWindow()->GetSettings().GetMouseSettings().GetWheelBehavior();
                sal_Int16 nBehavior = MouseWheelBehavior::SCROLL_FOCUS_ONLY;
                switch ( nVclBehavior )
                {
                case MOUSE_WHEEL_DISABLE:       nBehavior = MouseWheelBehavior::SCROLL_DISABLED;    break;
                case MOUSE_WHEEL_FOCUS_ONLY:    nBehavior = MouseWheelBehavior::SCROLL_FOCUS_ONLY;  break;
                case MOUSE_WHEEL_ALWAYS:        nBehavior = MouseWheelBehavior::SCROLL_ALWAYS;      break;
                default:
                    OSL_ENSURE( false, "VCLXWindow::getProperty( 'MouseWheelBehavior' ): illegal VCL value!" );
                }
                aProp <<= nBehavior;
            }
            break;

            case BASEPROPERTY_NATIVE_WIDGET_LOOK:
				aProp <<= (sal_Bool) GetWindow()->IsNativeWidgetEnabled();
                break;

			case BASEPROPERTY_ENABLED:
				aProp <<= (sal_Bool) GetWindow()->IsEnabled();
			    break;

			case BASEPROPERTY_ENABLEVISIBLE:
				aProp <<= (sal_Bool) mpImpl->isEnableVisible();
			    break;

			case BASEPROPERTY_HIGHCONTRASTMODE:
				aProp <<= (sal_Bool) GetWindow()->GetSettings().GetStyleSettings().GetHighContrastMode();
			    break;

			case BASEPROPERTY_TEXT:
			case BASEPROPERTY_LABEL:
			case BASEPROPERTY_TITLE:
			{
				::rtl::OUString aText = GetWindow()->GetText();
				aProp <<= aText;
			}
			break;
			case BASEPROPERTY_ACCESSIBLENAME:
			{
				::rtl::OUString aText = GetWindow()->GetAccessibleName();
				aProp <<= aText;
			}
			break;
			case BASEPROPERTY_HELPTEXT:
			{
				::rtl::OUString aText = GetWindow()->GetQuickHelpText();
				aProp <<= aText;
			}
			break;
            case BASEPROPERTY_HELPURL:
            {
                rtl::OUString aHelpId( rtl::OStringToOUString( GetWindow()->GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
                aProp <<= ::rtl::OUString( aHelpId );
            }
            break;
			case BASEPROPERTY_FONTDESCRIPTOR:
			{
				Font aFont = GetWindow()->GetControlFont();
				::com::sun::star::awt::FontDescriptor aFD = VCLUnoHelper::CreateFontDescriptor( aFont );
				aProp <<= aFD;
			}
			break;
			case BASEPROPERTY_BACKGROUNDCOLOR:
				aProp <<= (sal_Int32) GetWindow()->GetControlBackground().GetColor();
			break;
			case BASEPROPERTY_DISPLAYBACKGROUNDCOLOR:
				aProp <<= (sal_Int32) GetWindow()->GetDisplayBackground().GetColor().GetColor();
			break;
			case BASEPROPERTY_FONTRELIEF:
				aProp <<= (sal_Int16) GetWindow()->GetControlFont().GetRelief();
			break;
			case BASEPROPERTY_FONTEMPHASISMARK:
				aProp <<= (sal_Int16) GetWindow()->GetControlFont().GetEmphasisMark();
			break;
			case BASEPROPERTY_TEXTCOLOR:
				aProp <<= (sal_Int32) GetWindow()->GetControlForeground().GetColor();
			break;
			case BASEPROPERTY_TEXTLINECOLOR:
				aProp <<= (sal_Int32) GetWindow()->GetTextLineColor().GetColor();
			break;
			case BASEPROPERTY_FILLCOLOR:
				aProp <<= (sal_Int32) GetWindow()->GetFillColor().GetColor();
			break;
			case BASEPROPERTY_LINECOLOR:
				aProp <<= (sal_Int32) GetWindow()->GetLineColor().GetColor();
			break;
			case BASEPROPERTY_BORDER:
			{
				sal_Int16 nBorder = 0;
				if ( GetWindow()->GetStyle() & WB_BORDER )
					nBorder = GetWindow()->GetBorderStyle();
				aProp <<= nBorder;
			}
			break;
			case BASEPROPERTY_TABSTOP:
				aProp <<= (sal_Bool) ( GetWindow()->GetStyle() & WB_TABSTOP ) ? sal_True : sal_False;
			break;
			case BASEPROPERTY_VERTICALALIGN:
            {
				WinBits nStyle = GetWindow()->GetStyle();
				if ( nStyle & WB_TOP )
					aProp <<= VerticalAlignment_TOP;
				else if ( nStyle & WB_VCENTER )
					aProp <<= VerticalAlignment_MIDDLE;
				else if ( nStyle & WB_BOTTOM )
					aProp <<= VerticalAlignment_BOTTOM;
            }
            break;
			case BASEPROPERTY_ALIGN:
			{
				switch ( eWinType )
				{
					case WINDOW_FIXEDTEXT:
					case WINDOW_EDIT:
                    case WINDOW_MULTILINEEDIT:
					case WINDOW_CHECKBOX:
					case WINDOW_RADIOBUTTON:
					case WINDOW_LISTBOX:
					case WINDOW_COMBOBOX:
                    case WINDOW_BUTTON:
                    case WINDOW_PUSHBUTTON:
                    case WINDOW_OKBUTTON:
                    case WINDOW_CANCELBUTTON:
                    case WINDOW_HELPBUTTON:
					{
						WinBits nStyle = GetWindow()->GetStyle();
						if ( nStyle & WB_LEFT )
							aProp <<= (sal_Int16) PROPERTY_ALIGN_LEFT;
						else if ( nStyle & WB_CENTER )
							aProp <<= (sal_Int16) PROPERTY_ALIGN_CENTER;
						else if ( nStyle & WB_RIGHT )
							aProp <<= (sal_Int16) PROPERTY_ALIGN_RIGHT;
					}
					break;
				}
			}
			case BASEPROPERTY_MULTILINE:
			{
				if  (  ( eWinType == WINDOW_FIXEDTEXT )
                    || ( eWinType == WINDOW_CHECKBOX )
                    || ( eWinType == WINDOW_RADIOBUTTON )
                    || ( eWinType == WINDOW_BUTTON )
                    || ( eWinType == WINDOW_PUSHBUTTON )
                    || ( eWinType == WINDOW_OKBUTTON )
                    || ( eWinType == WINDOW_CANCELBUTTON )
                    || ( eWinType == WINDOW_HELPBUTTON )
                    )
					aProp <<= (sal_Bool) ( GetWindow()->GetStyle() & WB_WORDBREAK ) ? sal_True : sal_False;
			}
			break;
            case BASEPROPERTY_AUTOMNEMONICS:
            {
                sal_Bool bAutoMnemonics = GetWindow()->GetSettings().GetStyleSettings().GetAutoMnemonic();
                aProp <<= bAutoMnemonics;
            }
			break;
            case BASEPROPERTY_MOUSETRANSPARENT:
            {
                sal_Bool bMouseTransparent = GetWindow()->IsMouseTransparent();
                aProp <<= bMouseTransparent;
            }
			break;
            case BASEPROPERTY_PAINTTRANSPARENT:
            {
                sal_Bool bPaintTransparent = GetWindow()->IsPaintTransparent();
                aProp <<= bPaintTransparent;
            }
			break;

            case BASEPROPERTY_REPEAT:
                aProp <<= (sal_Bool)( 0 != ( GetWindow()->GetStyle() & WB_REPEAT ) );
                break;

            case BASEPROPERTY_REPEAT_DELAY:
            {
                sal_Int32 nButtonRepeat = GetWindow()->GetSettings().GetMouseSettings().GetButtonRepeat();
                aProp <<= (sal_Int32)nButtonRepeat;
            }
            break;

            case BASEPROPERTY_SYMBOL_COLOR:
                aProp <<= (sal_Int32)GetWindow()->GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
                break;

            case BASEPROPERTY_BORDERCOLOR:
                aProp <<= (sal_Int32)GetWindow()->GetSettings().GetStyleSettings().GetMonoColor().GetColor();
                break;
		}
	}
	return aProp;
}


// ::com::sun::star::awt::XLayoutConstrains
::com::sun::star::awt::Size VCLXWindow::getMinimumSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	// Diese Methode sollte nur fuer Componenten gerufen werden, die zwar
	// ueber das ::com::sun::star::awt::Toolkit erzeugt werden koennen, aber fuer die es
	// kein Interface gibt.

	Size aSz;
	if ( GetWindow() )
	{
		WindowType nWinType = GetWindow()->GetType();
		switch ( nWinType )
		{
			case WINDOW_CONTROL:
				aSz.Width() = GetWindow()->GetTextWidth( GetWindow()->GetText() )+2*12;
				aSz.Height() = GetWindow()->GetTextHeight()+2*6;
			break;

			case WINDOW_PATTERNBOX:
			case WINDOW_NUMERICBOX:
			case WINDOW_METRICBOX:
			case WINDOW_CURRENCYBOX:
			case WINDOW_DATEBOX:
			case WINDOW_TIMEBOX:
			case WINDOW_LONGCURRENCYBOX:
				aSz.Width() = GetWindow()->GetTextWidth( GetWindow()->GetText() )+2*2;
				aSz.Height() = GetWindow()->GetTextHeight()+2*2;
			break;
			case WINDOW_SCROLLBARBOX:
                return VCLXScrollBar::implGetMinimumSize( GetWindow() );
			default:
				aSz = GetWindow()->GetOptimalSize( WINDOWSIZE_MINIMUM );
		}
	}

	return ::com::sun::star::awt::Size( aSz.Width(), aSz.Height() );
}

::com::sun::star::awt::Size VCLXWindow::getPreferredSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	return getMinimumSize();
}

::com::sun::star::awt::Size VCLXWindow::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::awt::Size aNewSize( rNewSize );
	::com::sun::star::awt::Size aMinSize = getMinimumSize();

	if ( aNewSize.Width < aMinSize.Width )
		aNewSize.Width = aMinSize.Width;
	if ( aNewSize.Height < aMinSize.Height )
		aNewSize.Height = aMinSize.Height;

	return aNewSize;
}


// ::com::sun::star::awt::XView
sal_Bool VCLXWindow::setGraphics( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >& rxDevice ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( VCLUnoHelper::GetOutputDevice( rxDevice ) )
		mpImpl->mxViewGraphics = rxDevice;
	else
		mpImpl->mxViewGraphics = NULL;

	return mpImpl->mxViewGraphics.is();
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > VCLXWindow::getGraphics(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	return mpImpl->mxViewGraphics;
}

::com::sun::star::awt::Size VCLXWindow::getSize(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Size aSz;
	if ( GetWindow() )
		aSz = GetWindow()->GetSizePixel();
	return ::com::sun::star::awt::Size( aSz.Width(), aSz.Height() );
}

void VCLXWindow::draw( sal_Int32 nX, sal_Int32 nY ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
    if ( !pWindow )
        return;
    
	if ( isDesignMode() || mpImpl->isEnableVisible() )
	{
		TabPage* pTabPage = dynamic_cast< TabPage* >( pWindow );
        if ( pTabPage )
        {
		    Point aPos( nX, nY );
            Size  aSize = pWindow->GetSizePixel();

            OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( mpImpl->mxViewGraphics );
            aPos  = pDev->PixelToLogic( aPos );
            aSize = pDev->PixelToLogic( aSize );

            pTabPage->Draw( pDev, aPos, aSize, 0 );
            return;
        }

        OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( mpImpl->mxViewGraphics );
		Point aPos( nX, nY );

		if ( !pDev )
			pDev = pWindow->GetParent();

		if ( pWindow->GetParent() && !pWindow->IsSystemWindow() && ( pWindow->GetParent() == pDev ) )
		{
			// #i40647# don't draw here if this is a recursive call
			// sometimes this is called recursively, because the Update call on the parent
			// (strangely) triggers another paint. Prevent a stack overflow here
			// Yes, this is only fixing symptoms for the moment ....
			// #i40647# / 2005-01-18 / frank.schoenheit@sun.com
			if ( !mpImpl->getDrawingOntoParent_ref() )
			{
                ::comphelper::FlagGuard aDrawingflagGuard( mpImpl->getDrawingOntoParent_ref() );

                sal_Bool bWasVisible = pWindow->IsVisible();
                Point aOldPos( pWindow->GetPosPixel() );

                if ( bWasVisible && aOldPos == aPos )
                {
                    pWindow->Update();
                    return;
                }

				pWindow->SetPosPixel( aPos );

				// Erstmal ein Update auf den Parent, damit nicht beim Update
				// auf dieses Fenster noch ein Paint vom Parent abgearbeitet wird,
				// wo dann ggf. dieses Fenster sofort wieder gehidet wird.
				if( pWindow->GetParent() )
					pWindow->GetParent()->Update();

				pWindow->Show();
				pWindow->Update();
				pWindow->SetParentUpdateMode( sal_False );
				pWindow->Hide();
				pWindow->SetParentUpdateMode( sal_True );

				pWindow->SetPosPixel( aOldPos );
                if ( bWasVisible )
                    pWindow->Show( sal_True );
			}
		}
		else if ( pDev )
		{
			Size aSz = pWindow->GetSizePixel();
			aSz = pDev->PixelToLogic( aSz );
			Point aP = pDev->PixelToLogic( aPos );

            vcl::PDFExtOutDevData* pPDFExport   = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData());
            bool bDrawSimple =    ( pDev->GetOutDevType() == OUTDEV_PRINTER )
                               || ( pDev->GetOutDevViewType() == OUTDEV_VIEWTYPE_PRINTPREVIEW )
                               || ( pPDFExport != NULL );
            if ( bDrawSimple )
            {
			    pWindow->Draw( pDev, aP, aSz, WINDOW_DRAW_NOCONTROLS );
            }
            else
            {
				sal_Bool bOldNW =pWindow->IsNativeWidgetEnabled();
				if( bOldNW )
					pWindow->EnableNativeWidget(sal_False);
                pWindow->PaintToDevice( pDev, aP, aSz );
				if( bOldNW )
					pWindow->EnableNativeWidget(sal_True);
            }
		}
	}
}

void VCLXWindow::setZoom( float fZoomX, float /*fZoomY*/ ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	if ( GetWindow() )
    {
        // Fraction::Fraction takes a double, but we have a float only.
        // The implicit conversion from float to double can result in a precision loss, i.e. 1.2 is converted to
        // 1.200000000047something. To prevent this, we convert explicitly to double, and round it.
        double nZoom( fZoomX );
        nZoom = ::rtl::math::round( nZoom, 4 );
		GetWindow()->SetZoom( Fraction( nZoom ) );
    }
}

// ::com::sun::star::lang::XEventListener
void SAL_CALL VCLXWindow::disposing( const ::com::sun::star::lang::EventObject& _rSource ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	// check if it comes from our AccessibleContext
    uno::Reference< uno::XInterface > aAC( mpImpl->mxAccessibleContext, uno::UNO_QUERY );
	uno::Reference< uno::XInterface > xSource( _rSource.Source, uno::UNO_QUERY );

	if ( aAC.get() == xSource.get() )
	{	// yep, it does
		mpImpl->mxAccessibleContext = uno::Reference< accessibility::XAccessibleContext >();
	}
}

// ::com::sun::star::accessibility::XAccessible
::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXWindow::getAccessibleContext(  ) throw (::com::sun::star::uno::RuntimeException)
{
	using namespace ::com::sun::star;

	::vos::OGuard aGuard( GetMutex() );
    
    // already disposed
    if( ! mpImpl )
        return uno::Reference< accessibility::XAccessibleContext >();

    if ( !mpImpl->mxAccessibleContext.is() && GetWindow() )
    {
        mpImpl->mxAccessibleContext = CreateAccessibleContext();

		// add as event listener to this component
		// in case somebody disposes it, we do not want to have a (though weak) reference to a dead
		// object
		uno::Reference< lang::XComponent > xComp( mpImpl->mxAccessibleContext, uno::UNO_QUERY );
		if ( xComp.is() )
			xComp->addEventListener( this );
    }

    return mpImpl->mxAccessibleContext;
}

// ::com::sun::star::awt::XDockable
void SAL_CALL VCLXWindow::addDockableWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDockableWindowListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    if ( xListener.is() )
        mpImpl->getDockableWindowListeners().addInterface( xListener );

}

void SAL_CALL VCLXWindow::removeDockableWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDockableWindowListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

    mpImpl->getDockableWindowListeners().removeInterface( xListener );
}

void SAL_CALL VCLXWindow::enableDocking( sal_Bool bEnable ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
	if ( pWindow )
        pWindow->EnableDocking( bEnable );
}

sal_Bool SAL_CALL VCLXWindow::isFloating(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
    if( pWindow )
        return Window::GetDockingManager()->IsFloating( pWindow );
    else
        return sal_False;
}

void SAL_CALL VCLXWindow::setFloatingMode( sal_Bool bFloating ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
    if( pWindow )
        Window::GetDockingManager()->SetFloatingMode( pWindow, bFloating );
}

sal_Bool SAL_CALL VCLXWindow::isLocked(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
    if( pWindow )
        return Window::GetDockingManager()->IsLocked( pWindow );
    else
        return sal_False;
}

void SAL_CALL VCLXWindow::lock(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
    if( pWindow && !Window::GetDockingManager()->IsFloating( pWindow ) )
        Window::GetDockingManager()->Lock( pWindow );
}

void SAL_CALL VCLXWindow::unlock(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	Window* pWindow = GetWindow();
    if( pWindow && !Window::GetDockingManager()->IsFloating( pWindow ) )
        Window::GetDockingManager()->Unlock( pWindow );
}
void SAL_CALL VCLXWindow::startPopupMode( const ::com::sun::star::awt::Rectangle& ) throw (::com::sun::star::uno::RuntimeException)
{
    // TODO: remove interface in the next incompatible build
	::vos::OGuard aGuard( GetMutex() );

}

sal_Bool SAL_CALL VCLXWindow::isInPopupMode(  ) throw (::com::sun::star::uno::RuntimeException)
{
    // TODO: remove interface in the next incompatible build
	::vos::OGuard aGuard( GetMutex() );
    return sal_False;
}


// ::com::sun::star::awt::XWindow2

void SAL_CALL VCLXWindow::setOutputSize( const ::com::sun::star::awt::Size& aSize ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
    Window *pWindow;
    if( (pWindow = GetWindow()) != NULL )
    {
        DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >(pWindow);
        if( pDockingWindow )
            pDockingWindow->SetOutputSizePixel( VCLSize( aSize ) );
        else
            pWindow->SetOutputSizePixel( VCLSize( aSize ) );
    }
}

::com::sun::star::awt::Size SAL_CALL VCLXWindow::getOutputSize(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
    Window *pWindow;
    if( (pWindow = GetWindow()) != NULL )
    {
        DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >(pWindow);
        if( pDockingWindow )
            return AWTSize( pDockingWindow->GetOutputSizePixel() );
        else
            return AWTSize( pWindow->GetOutputSizePixel() );
    }
    else
        return ::com::sun::star::awt::Size();
}

sal_Bool SAL_CALL VCLXWindow::isVisible(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
    if( GetWindow() )
        return GetWindow()->IsVisible();
    else
        return sal_False;
}

sal_Bool SAL_CALL VCLXWindow::isActive(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
    if( GetWindow() )
        return GetWindow()->IsActive();
    else
        return sal_False;

}

sal_Bool SAL_CALL VCLXWindow::isEnabled(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
    if( GetWindow() )
        return GetWindow()->IsEnabled();
    else
        return sal_False;
}

sal_Bool SAL_CALL VCLXWindow::hasFocus(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );
    if( GetWindow() )
        return GetWindow()->HasFocus();
    else
        return sal_False;
}

// ::com::sun::star::beans::XPropertySetInfo

UnoPropertyArrayHelper *
VCLXWindow::GetPropHelper()
{
	::vos::OGuard aGuard( GetMutex() );
    if ( mpImpl->mpPropHelper == NULL )
	{
	    std::list< sal_uInt16 > aIDs;
		GetPropertyIds( aIDs );
		mpImpl->mpPropHelper = new UnoPropertyArrayHelper( aIDs );
	}
	return mpImpl->mpPropHelper;
}

::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL
VCLXWindow::getProperties() throw (::com::sun::star::uno::RuntimeException)
{
    return GetPropHelper()->getProperties();
}
::com::sun::star::beans::Property SAL_CALL
VCLXWindow::getPropertyByName( const ::rtl::OUString& rName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
{
    return GetPropHelper()->getPropertyByName( rName );
}

::sal_Bool SAL_CALL
VCLXWindow::hasPropertyByName( const ::rtl::OUString& rName ) throw (::com::sun::star::uno::RuntimeException)
{
    return GetPropHelper()->hasPropertyByName( rName );
}

Reference< XStyleSettings > SAL_CALL VCLXWindow::getStyleSettings() throw (RuntimeException)
{
    return mpImpl->getStyleSettings();
}
