ATL复合控件和其中子控件的交互
参见《深入解析ATL(第二版)》 P579
在cc.h文件中声明控件
public:
CEdit m_edit;
在cpp文件中的初始化和销毁方法中编写
LRESULT Ccc1::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_edit.Attach(GetDlgItem(IDC_EDIT1));
m_edit.SetWindowText(_T("您好"));
return TRUE;
}
LRESULT Ccc1::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//m_edit.DestroyWindow();
m_edit.Detach();
return 0;
}
在按钮响应函数中测试
LRESULT Ccc1::OnBnClickedButton1(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// TODO: 在此添加控件通知处理程序代码
wchar_t* name=new wchar_t(10);
m_edit.GetWindowText(name,sizeof(name));
MessageBox(name);
return 0;
}
================================
窗口或复合控件处理自定义控件的方法和消息
============================================
窗口或复合控件和自定义子控件的事件响应
参见《深入解析ATL(第二版)》 P655
前提,在子控件中实现了事件。
首先在atlAA.cpp中添加实现子控件实例化的代码
LRESULT CatlAA::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
AtlAxWinInit();
RECT rect = { 0, 0, 200, 200 };
if(!m_ab.m_hWnd)
{
m_ab.Create(m_hWnd,rect,_T("{304AAA33-D5B1-4D49-B312-BC968468CA88}"),WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,0,ID_SUB_B);
}
m_ab.MoveWindow(0,0,300,300);
m_ab.ShowWindow(SW_SHOW);
if(!m_ac.m_hWnd)
{
m_ac.Create(m_hWnd,rect,_T("{D479C48F-7574-4E9A-8942-2156197E581B}"),WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
}
m_ac.MoveWindow(305,0,300,300);
m_ac.ShowWindow(SW_SHOW);
AtlAdviseSinkMap(this,true);//为事件响应添加的
return TRUE;
}
在下面添加没有执行
LRESULT CatlAA::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//在Create函数中实例化子控件没有被执行???
return 0;
}
const UINT ID_SUB_B=1;//在创建子控件时使用
// CatlAA
class ATL_NO_VTABLE CatlAA :
//public IDispEventImpl,//第一种方式
public IDispEventImpl,//第二种方式
public CComObjectRootEx,
public CStockPropImpl,
public IPersistStreamInitImpl, //...还有其他接口
BEGIN_SINK_MAP(CatlAA)
//请确保事件处理程序含有 __stdcall 调用约定
//SINK_ENTRY_EX(ID_SUB_B,DIID__IatlABEvents,1,OnMeClick)
SINK_ENTRY(ID_SUB_B,1,OnMeClick)
SINK_ENTRY(ID_SUB_B,2,OnMeRClick)
END_SINK_MAP()
void __stdcall OnMeClick(){
MessageBox(_T("响应子控件的 单击 事件!"));
}
void __stdcall OnMeRClick(){
MessageBox(_T("响应子控件的 右击 事件!"));
}
LRESULT CatlAA::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
AtlAdviseSinkMap(this,false);
return 0;
}
===================================
区分单击和双击事件
LRESULT CatlAB::OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//if(m_hWnd)
MSG message;
DWORD st = GetTickCount();
while(1)
{
if(::PeekMessage(&message, NULL, 0 ,0 , PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
if(message.message == WM_LBUTTONDBLCLK)
return 0;
}
DWORD et = GetTickCount();
if(et - st > 200)
break;
}
Fire_MeClick();//调用自定义事件,
return 0;
}