The information in this article applies to:
- The Microsoft Active Template Library (ATL), versions 2.0, 2.1
SUMMARY
When writing ActiveX controls with the Active Template Library (ATL), it
may be useful to create your control based on a dialog box template. This
allows you to take advantage of the Visual C++ resource editor to lay out
contained controls or to reuse existing MFC dialog box templates and Visual
Basic forms.
You add an ActiveX control to your ATL project by selecting the
Insert- >'New ATL Object' menu item and clicking either Full Control or
Internet Explorer Control. On completion, the ATL Object Wizard generates
code that includes a class derived from CComControl, which further derives
from CWindowImpl.
This article demonstrates how to derive your control class from CDialogImpl
and associate a dialog box template with this class. This article also
demonstrates providing support for UI activation and navigation keys.
MORE INFORMATION
- Declare your own class, based on CComControl, which is derived from
CDialogImpl instead of CWindowImpl. The original definition of
CComControl can be found in ATLCTL.H. For example:
template <class T>
class ATL_NO_VTABLE CComDlgCtrl : public CComControlBase,
public CDialogImpl<T>
{
public:
CComDlgCtrl() : CComControlBase(m_hWnd) {}
HRESULT FireOnRequestEdit(DISPID dispID)
{
T* pT = static_cast<T*>(this);
return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnRequestEdit
(pT->GetUnknown(), dispID);
}
HRESULT FireOnChanged(DISPID dispID)
{
T* pT = static_cast<T*>(this);
return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnChanged
(pT->GetUnknown(), dispID);
}
virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv)
{
T* pT = static_cast<T*>(this);
return pT->_InternalQueryInterface(iid, ppv);
}
virtual HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
{
T* pT = static_cast<T*>(this);
return pT->Create(hWndParent);
// CDialogImpl::Create differs from CWindowImpl
}
};
- Derive your control from this new class, instead of CComControl. For
example:
class ATL_NO_VTABLE CMyDlgCtrl :
...
public CComDlgCtrl<CMyDlgCtrl>, // Replaced CComControl
...
- Create your dialog template and make sure it is marked as a "Child"
template. This will set up correctly if you use the IDD_FORMVIEW dialog
subtype when creating the dialog using the Insert->Resource menu item.
Update class definition to identify this resource. For example:
class ATL_NO_VTABLE CMyDlgCtrl :
...
{
public:
enum { IDD = IDD_MYDIALOG };
...
- Declare and implement a message handler for WM_INITDIALOG and any
required message, command, and notify handlers. For example:
BEGIN_MSG_MAP(CMyDlgCtrl)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_ID_HANDLER(IDC_SOMECOMMAND, OnSomeCommand)
END_MSG_MAP()
...
LRESULT OnInitDialog(UINT uMsg,WPARAM wParam,LPARAM lParam,
BOOL&bHandled)
{
InPlaceActivate( OLEIVERB_UIACTIVATE );
// Perform any dialog initialization
return FALSE;
}
LRESULT OnSomeCommand(WORD wNotifyCode,WORD wID,HWND hWndCtl,
BOOL&bHandled)
{
// Perform operation for this command.
return 0;
}
- Remove the OnDraw declaration and implementation.
- If you wish to handle UI activation of your control correctly, add a
WM_MOUSEACTIVATE message handler to call CComControl::InPlaceActivate.
For example:
BEGIN_MSG_MAP(CMyDlgCtrl)
...
MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
END_MSG_MAP()
...
LRESULT OnMouseActivate(UINT uMsg,WPARAM wParam,LPARAM lParam,
BOOL&bHandled)
{
// UI-Activate control
InPlaceActivate( OLEIVERB_UIACTIVATE );
return FALSE;
}
- If you wish to handle tabbing and other navigation keys correctly,
override IOleInPlaceActiveObjectImpl::TranslateAccelerator. For example:
STDMETHOD(TranslateAccelerator)(MSG *pMsg)
{
if ( ( pMsg->message < WM_KEYFIRST
|| pMsg->message > WM_KEYLAST )
&& ( pMsg->message < WM_MOUSEFIRST
|| pMsg->message > WM_MOUSELAST ) )
return S_FALSE;
return ( IsDialogMessage( m_hWnd, pMsg ) ) ? S_OK : S_FALSE;
}
- Depending on how you created the control, you need to set the
m_bWindowOnly variable to 1 in your control's constructor to force the
control to be non-Windowless. For example:
CMyDlgCtrl()
{
m_bWindowOnly = 1;
}
(c) Microsoft Corporation 1997, All Rights Reserved.
Contributions by Mark Davis, Microsoft Corporation
Keywords : AtlControl AXSDKControls
Technology : kbole
Version : WINDOWS:2.0,2.1
Platform : WINDOWS
Issue type : kbhowto
Solution Type : kbsample
|