Reference

OnDraw, OnDrawAdvanced in CComCompositeControl ATL Controls

When derriving ActiveX controls from CComCompositeControl the virtual functions OnDraw and OnDrawAdvanced are not being called.

Tags: activex atl com c++

Overview

A look at atlctl.h reveals that OnDraw is called from OnDrawAdvanced, which is in turn called from CComControlBase::OnPaint. The message handler for OnPaint, however, is declared in CComControl, and CComCompositeControl does not chain its message map to CComControl, so that WM_PAINT is never actually processed.

Solution

The workaround is to chain the message map to CComControl from your own control’s message map:

typedef CComControl<CYourActiveXControl, CAxDialogImpl<CYourActiveXControl> > TComControlBase;

BEGIN_MSG_MAP(CYourActiveXControl)
   // your message handlers here

   CHAIN_MSG_MAP(CComCompositeControl<CYourActiveXControl>)
   CHAIN_MSG_MAP(TComControlBase)
END_MSG_MAP()

Messages not processed by CComCompositeControl will now be forwarded to CComControl, and OnDraw and OnDrawAdvanced should be called as expected.

If OnDraw or OnDrawAdvanced are still not being called despite the changes described above, make sure that:

  • The function signatures are correct, so that they don’t overload instead of override
    HRESULT OnDraw (ATL_DRAWINFO &di);
    HRESULT OnDrawAdvanced (ATL_DRAWINFO& di);
  • The WM_PAINT message is not intercepted in your or a parent control, i.e. by adding a new message handler to the message maps.

Related Resources

A solution to this problem was first discussed in microsoft.public.vc.atl.