> 1) I must admit you lost me there. Can you sketch what exactly you
> intend to do with such a class? BTW, if you need CWindowImpl that also
> has methods of CAxWindow, try
> class C3rdPartyControl : public CWindowImpl<C3rdPartyControl, CAxWindow>
I appreciate your help. I'm new to a lot of the ATL Window classes. Don't
want to bog you down so what follows if relatively easy. I'm trying to wrap
the control (a grid) in my own class. Don't want to create it dynamically
since it's easier to manipulate with the resource editor. My class now looks
like this based on assistance from your last post (stripped down for
brevity - I believe it now works though):
class CGrid : public CAxWindow
CGrid() : m_GridWindow(this)
virtual LRESULT OnKillFocus(UINT, WPARAM wParam, LPARAM, BOOL
void Init(UINT uID, CWindow *pParent)
// Step 1
// Step 2
// Step 3 (based on your last post)
IVSFlexGridPtr m_spGrid; // Using #import
I simply call the above from WM_INITDIALOG for each grid on the dialog,
passing the control ID ("uID") and dialog window ("pParent") accordingly. I
can now add member functions and invoke the real methods via "m_spGrid"
accordingly. I can also trap WM_KILLFOCUS. However, it seems cleaner to
simply invoke "SubclassWindow()" inside "Init()". "CAxWindow" has no such
function however. If I use the hieararchy you suggested in your last post,
> That produces the correct inheritance hierarchy. It's unclear to me why
> you would ever want such a thing though.
> 2) The control calls IOleControlSite::OnFocus when it gains or loses
> focus. Unfortunately, ATL implementation does nothing there and it is
> difficult to customize it. There are two ways - simple but hackish and
> correct but complicated. Simple way is to copy <atlhost.h> header into
> your project directory, call it something else and include this copy
> where you would otherwise inclue atlhost.h. Then you simply make any
> change you want to OnFocus implementation, e.g. send a message to parent
> window. Of course the moment you upgrade your compiler and want to use
> updated ATL headers, you'll have to repeat this procedure (unless ATL
> hosting support is considerably improved in this new version).
> Another way is to aggregate client site implementation. You create a COM
> object that supports some of the interfaces you want to override (e.g.
> IOleControlSite). In FinalConstruct of this object you can use this code
> to create AxHostWindow (taken from <atlhost.h> line 2474 and slightly
> hr = CAxHostWindow::_CreatorClass::CreateInstance(this, IID_IUnknown,
> The first parameter is the outer unknown (NULL in the original code).
> spUnkContainer will become your inner unknown. Use
> COM_INTERFACE_ENTRY_AGGREGATE_BLIND at the end of your interface map to
> forward all interfaces you don't explicitly override to this inner
> unknown. You can also forward calls to it on a per-method basis.
> To actually host a control in this contraption, use
> IAxWinHostWindow::CreateControl or CreateControlEx. You'll need to pass
> an HWND to it - any will do, e.g. a static control of suitable size.
> CAxHostWindow subclasses it.
> This mechanism only works with controls you create dynamically at
> run-time. It cannot be used if you want to place controls on the dialog
> using Dialog Editor.
> With best wishes,
> Igor Tandetnik
> "For every complex problem, there is a solution that is simple, neat,
> and wrong." H.L. Mencken
> > Thanks.
> > > 1) CWindowImpl makes more sense to me.
> > Turns out that you can't use either "CWindowImpl" or
> "CContainedWindow". I
> > wanted a class that looked something like this for instance:
> > class C3rdPartyControl : public
> CAxWindowT<CWindowImpl<C3rdPartyControl> >
> > This would give my class both a message map and access to
> > "SubclassWindow()". I could then subclass the control's window and
> route its
> > messages through my class. The default constructor for "CAxWindowT"
> takes an
> > HWND however and passes it to its base class "CWindowImpl". The latter
> > has no such constructor however (neither does "CContainedWindow") so a
> > compiler error results (C2664). I guess they never expected anyone to
> > subclass an ActiveX control - either that or the design is flawed.
> > I simply inherited from "CAxWindow" directly (the normal route) and
> > a "CContainedWindow" member variable. I then subclass that member and
> > its messages through the message map of my class. Somewhat ugly but
> I'm open
> > to better suggestions.
> > > 2) ... Or are you asking how to subclass the window of third-party
> > > control you are hosting? It is not recommended - you are supposed to
> > > manipulate the control using its public interface. In case you
> > > need to do this for some reason, query the control for IOleWindow
> > > call IOleWindow::GetWindow. Naturally, that does not work on
> > > controls.
> > Yes, that's what I'm after. I'm manipulating the control normally but
> > to trap WM_KILLFOCUS. I'm wondering if most controls don't provide an
> > for this. The one I'm using ("VSFlexGrid" - fairly well known) doesn't
> > provide it. I'd therefore like to trap it and pass it to the parent
> > (dialog) as a (customized) control notification message (say,
> > The control would then behave consistently with the standard Windows
> > controls. Any comments? Thanks again.