ATL複合控件 實例

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;
}

在atlAA.h中添加代碼

const UINT ID_SUB_B=1;//在創建子控件時使用
// CatlAA
class ATL_NO_VTABLE CatlAA :
	//public IDispEventImpl<ID_SUB_B,CatlAA,&DIID__IatlABEvents,&LIBID_DcecVideoLib,1,0>,//第一種方式
	public IDispEventImpl<ID_SUB_B,CatlAA>,//第二種方式
	public CComObjectRootEx<CComSingleThreadModel>,
	public CStockPropImpl<CatlAA, IatlAA>,
	public IPersistStreamInitImpl<CatlAA>, //...還有其他接口

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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章