Hi:
I am using CExtDynamicControlBar to contain an ActiveX control.
It is redrawn correctly when docked or floating, but incorrectly when in TabbedDocument or Autohide mode: in these two mode, redrawing of the control is clipped to the size of CExtDynamicControlBar, instead of its current container (MDIChildWnd or AutoHide window).
Is there something else I must perform to get ActiveX control drawing correctly?
To duplicate with your sample project ’MDI_DynamicBars’:
---------------------------------------------
1. Create an ActiveX control, and register it.
I used the default VS2005 ’MFC ACtiveX control’ project, without any modifications.
Add your CLSID for ActiveX control to the code below.
2. Add the following code to MDI_DynamicBars\MainFrm.[h,cpp]
3. Run program, the new CExtDynamicControlBar should be docked to left side.
Redock it to TabbedDocument: you will see only a portion of it is redrawn: the remainder is clipped.
Redock it to AutoHide: you will see only a portion of it is redrawn: the remainder is clipped.
4. Problem discovered in ProfUIS v2.33, also verified in v2.54.
Appreciate any help, with thanks.
Dave
// Add to Mainframe.h
// -----------------
CSimpleActiveXControlBar* m_pActiveXBar;
class CSimpleActiveXControlBar : public CExtDynamicControlBar
{
public:
DECLARE_SERIAL( CSimpleActiveXControlBar );
CSimpleActiveXControlBar()
{
}
virtual ~CSimpleActiveXControlBar()
{
}
bool CreateControl( const CString& strCLSID )
{
USES_CONVERSION;
HRESULT hResult = S_OK;
m_strCLSID = strCLSID;
CLSID clsID;
hResult = CLSIDFromString( T2OLE(m_strCLSID), &clsID);
ASSERT(hResult == S_OK);
CRect rect;
GetClientRect(&rect);
if(!m_wndControl.CreateControl(clsID,
_T("Some ActiveX control"),
WS_CHILD | WS_VISIBLE,
rect,
this,
200)) // ID_VIEW
{
ASSERT(false);
return false;
}
return true; // success
}
static inline int stat_SameAs_MAP_PIX_TO_LOGHIM( int x, int ppli )
{
// is defined in ATLWIN.H, but can’t include it into this header
#ifndef HIMETRIC_PER_INCH
#define HIMETRIC_PER_INCH 2540
#endif
return ( (HIMETRIC_PER_INCH * (x) + ((ppli)>>1)) / (ppli) );
}
static inline void stat_SameAs_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 =
stat_SameAs_MAP_PIX_TO_LOGHIM( lpSizeInPix->cx, nPixelsPerInchX );
lpSizeInHiMetric->cy =
stat_SameAs_MAP_PIX_TO_LOGHIM( lpSizeInPix->cy, nPixelsPerInchY );
}
void OnRepositionSingleChild( int cx, int cy, bool bRedraw )
{
ASSERT_VALID( this );
// Perform special reposition
if( m_wndControl.GetSafeHwnd() != NULL )
{
if( cx < 0 || cy < 0 )
{
CRect _rc;
GetClientRect( &_rc );
cx = _rc.Width();
cy = _rc.Height();
}
// Per MSDN: Release() is not required because there was
// no AddRef() in GetControlUnknown()
IUnknown* pUnknown = m_wndControl.GetControlUnknown();
ASSERT(pUnknown);
CComQIPtr<IOleObject> pOleObject(pUnknown);
ASSERT(pOleObject);
SIZEL _size = { cx, cy };
stat_SameAs_AtlPixelToHiMetric( &_size, &_size );
if (pOleObject)
{
HRESULT hr = pOleObject->SetExtent( DVASPECT_CONTENT, &_size );
ASSERT( hr == S_OK );
}
}
}
public:
CString m_strCLSID;
CWnd m_wndControl; // My ActiveX control
protected:
private:
}; // class CSimpleActiveXControlBar
// Add to Mainframe.cpp
// -----------------
IMPLEMENT_SERIAL( CSimpleActiveXControlBar, CExtDynamicControlBar, VERSIONABLE_SCHEMA|1 );
// add this code to ’CMainFrame::OnCreate()’,
// immediately after the creation code for ’m_pBarPersistent’
// create controlbar that contains simple ActiveX control
m_pActiveXBar = static_cast<CSimpleActiveXControlBar*>(
CExtDynamicBarSite::BarAlloc(
_T("Simple ActiveX Bar"),
icon,
0,
RUNTIME_CLASS(CSimpleActiveXControlBar),
true // this bar is persistent
)
);
ASSERT(m_pActiveXBar);
m_pActiveXBar->m_nMdiMenuResourceID = IDR_DYNAMIC_BAR;
m_pActiveXBar->m_nMdiAccelTableResourceID = IDR_MAINFRAME;
nCmdID = (UINT)m_pBarPersistent->GetDlgCtrlID();
pCmdItem = g_CmdManager->CmdGetPtr(pApp->m_pszProfileName, nCmdID);
ASSERT( pCmdItem != NULL );
pCmdItem->StateSetBasic();
// create the ActiveXcontrol within this controlBar
m_pActiveXBar->CreateControl( _T("{*** CLSID FOR YOUR ACTIVE-X CONTROL GOES HERE ****}") );
static const CSize simpleActiveXBarsizedDocked( 100, 100 );
static const CSize simpleActiveXBarsizedFloating( 200, 150 );
m_pActiveXBar->SetInitDesiredSizeHorizontal( simpleActiveXBarsizedDocked );
m_pActiveXBar->SetInitDesiredSizeVertical( simpleActiveXBarsizedDocked );
m_pActiveXBar->SetInitDesiredSizeFloating( simpleActiveXBarsizedFloating );
ShowControlBar( m_pActiveXBar, TRUE, TRUE );