Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » AddAnchor + ActiveX Control Collapse All
Subject Author Date
Jean-Yves Tremblay May 24, 2007 - 6:49 AM

Dear support,

There is a strange behavior when I resize my CExtResizableDialog in which I have an ActiveX control (Crystal Report Viewer 11) with some anchors.
There is no problem until the ActiveX control get the focus, then it is resized to its original size (Its dialog template size)

What should I do ?

Thank you

David

Jean-Yves Tremblay Jun 1, 2007 - 3:57 PM

Ok !!

I got something...

It is based on this

I Overrided ArrangeLayout and I added this code just before the pOleInPlaceObject->Release() call, and it seems to work :

IOleClientSite *pOleClientSite = NULL;
hr = pOleObject->GetClientSite(&pOleClientSite);
if (hr == S_OK)
{
   ASSERT( pOleClientSite != NULL );
   IOleInPlaceSite *pOleInPlaceSite = NULL;
   hr = pOleClientSite->QueryInterface(__uuidof(IOleInPlaceSite),
                                       (LPVOID*)(&pOleInPlaceSite));
   if (hr == S_OK)
   {
      ASSERT(pOleInPlaceSite != NULL);
      hr = pOleInPlaceSite->OnPosRectChange(&rc);
      ASSERT( SUCCEEDED( hr ) );
      pOleInPlaceSite->Release();
   }

   pOleClientSite->Release();
}


David

Technical Support Jun 2, 2007 - 7:25 AM

We confirm that it is a correct code update. You can put it into CExtWA::ArrangeLayout() method directly. Thank you.

Jean-Yves Tremblay Jun 1, 2007 - 1:37 PM

Thank you for your answer.

I have prof-uis 2.62.
Apparently, there is already such ActiveX control specific resizing code implemented in the CExtWA template class :

void CExtWA::ArrangeLayout(int cx = -1, int cy = -1)
{
    //...


    if( (m_nFlags&WF_OLECTLCONTAINER) != 0 )
    {
        for( pos = m_mapRDI.GetStartPosition(); pos != NULL; )
        {
            HWND _hWnd;
            RDI_t _rdi;
            m_mapRDI.GetNextAssoc( pos, _hWnd, _rdi );
            ASSERT( ::IsWindow( _hWnd ) );
            if( ! ::IsWindow( _hWnd ) )
                continue;
            CWnd * pWnd = CWnd::FromHandlePermanent( _hWnd );
            if( pWnd == NULL )
                continue;
            LPUNKNOWN pUnknown = pWnd->GetControlUnknown();
            if( pUnknown != NULL )
            {
                IOleObject * pOleObject = NULL;
                HRESULT hr =
                    pUnknown->QueryInterface(
                    __uuidof(IOleObject),
                    (LPVOID*)(&pOleObject)
                    );
                if( hr == S_OK )
                {
                    ASSERT( pOleObject != NULL );
                    IOleInPlaceObject * pOleInPlaceObject = NULL;
                    hr =
                        pUnknown->QueryInterface(
                        __uuidof(IOleInPlaceObject),
                        (LPVOID*)(&pOleInPlaceObject)
                        );
                    if( hr == S_OK )
                    {
                        ASSERT( pOleInPlaceObject != NULL );

                        CRect rcClient;
                        GetClientRect( &rcClient );
                        CRect rc;
                        pWnd->GetWindowRect( &rc );
                        ScreenToClient( &rc );

                        SIZEL _sizeL;
                        _sizeL.cx = rc.Width();
                        _sizeL.cy = rc.Height();
                        CClientDC dc(pWnd);
                        dc.DPtoHIMETRIC(&_sizeL);


                        hr = pOleObject->SetExtent( DVASPECT_CONTENT, &_sizeL );
                        ASSERT( SUCCEEDED( hr ) );
                        hr;

                        hr = pOleInPlaceObject->SetObjectRects( &rc, &rcClient );
                        ASSERT( SUCCEEDED( hr ) );
                        hr;


                        pOleInPlaceObject->Release();
                    } // if( hr == S_OK )
                    pOleObject->Release();
                } // if( hr == S_OK )
            } // if( pUnknown != NULL )
        } // for( pos = m_mapRDI.GetStartPosition(); pos != NULL; )
    } // if( (m_nFlags&WF_OLECTLCONTAINER) != 0 )

}



m_nFlags has the WF_OLECTLCONTAINER flag and it passes the condition

But I still get my ActiveX control resized to its original size when it gets the focus

Jean-Yves Tremblay May 24, 2007 - 9:46 AM

It seems to happen with any ActiveX Controls

Jean-Yves Tremblay May 24, 2007 - 7:22 AM

I mean the original size of the ActiveX...

Technical Support May 26, 2007 - 11:24 AM

The ActiveX controls should be resized using the IOleObject::SetExtent() COM API instead of the MoveWindow()/SetWindowPos() Win32 APIs. Unfortunately the CExtWA template class that is used as a base class of CExtResizableDialog does not perform ActiveX control specific resizing at present. But here is the source code for the ResizeAxControl() function which resizes the ActiveX control correctly:

static inline int inline_static_same_as_MAP_PIX_TO_LOGHIM( int x, int ppli )
{
      return ( ( 2540 * ( x ) + ( ( ppli ) >> 1 ) ) / ( ppli ) );
}

static inline void inline_static_same_as_AtlPixelToHiMetric( const SIZEL * lpSizeInPix, LPSIZEL lpSizeInHiMetric )
{
HDC hDCScreen = ::GetDC( NULL );
      ATLASSERT( hDCScreen != NULL );
int nPixelsPerInchX = ::GetDeviceCaps( hDCScreen, LOGPIXELSX );
int nPixelsPerInchY = ::GetDeviceCaps( hDCScreen, LOGPIXELSY );
      ::ReleaseDC( NULL, hDCScreen );
      lpSizeInHiMetric->cx = inline_static_same_as_MAP_PIX_TO_LOGHIM( lpSizeInPix->cx, nPixelsPerInchX );
      lpSizeInHiMetric->cy = inline_static_same_as_MAP_PIX_TO_LOGHIM( lpSizeInPix->cy, nPixelsPerInchY );
}

bool ResizeAxControl( CWnd & wndAxControl, int cx, int cy )
{
      ASSERT_VALID( this );
      bRedraw;
      if( cx < 0 || cy < 0 || wndAxControl.GetSafeHwnd() == NULL )
            return false;
IUnknown * pUnknown = wndAxControl.GetControlUnknown();
      if( pUnknown == NULL )
            return false;
IOleObject * pOleObject = NULL;
HRESULT hr = pUnknown->QueryInterface( __uuidof(IOleObject), (LPVOID*)&pOleObject );
      if( hr != S_OK )
            return false;
      ASSERT(  pOleObject != NULL );
SIZEL _size = { cx, cy };
      inline_static_same_as_AtlPixelToHiMetric( &_size, &_size );
      hr = pOleObject->SetExtent( DVASPECT_CONTENT, &_size );
      pOleObject->Release();
      // release is not required because there was no AddRef()
      // pUnknown->Release();
      return ( hr == S_OK ) ? true : false;
}