CTreeCtrl 을 사용하여 체크 박스를 단 후 체크박스를 체크하면 자식들도 모두 체크하거나 체크 해제하고 싶을 경우가 있다. 이럴 경우에는 다음과 같은 방법으로 자식노드를 재귀호출하여 체크/해제 할 수 있다. 

먼저 다음과 같이 트리컨트롤에서 마우스 오른쪽을 클릭한 후 이벤트 핸들러를 등록한다. 이벤트 핸들러는 TVN 계열과 NM 계열이 나타난다. 해당 체크박스를 왼쪽 클릭했을 때 자식아이템을 체크/해제 하기를 원하기 때문에 "NM_CLICK" 이벤트를 선택한다. TVN과 NM의 차이는 검색을 통해 찾아보기 바란다. 



해당 이벤트 핸들러가 등록되면 다음과 같이 코드를 작성한다.
//
// CTreeCtrl에 왼쪽 마우스 이벤트가 발생했을 경우
// 이벤트가 발생한 좌표에 트리아이템이 존재하고 체크박스가 체크된 경우 
// 정해진 작업을 수행한다.
//
void [CMainClass]::OnNMClickTreeDevices(NMHDR *pNMHDR, LRESULT *pResult)
{
	*pResult = 0;

	CPoint		point;
	UINT		nFlags = 0;
	
	GetCursorPos(&point);
	::ScreenToClient(m_ctrlTree.m_hWnd, &point);

	HTREEITEM	hItem = m_ctrlTree.HitTest(point, &nFlags);

	// 아이템이 존재하고 체크박스에 이벤트가 발생했다면
	if (hItem != NULL && (nFlags & TVHT_ONITEMSTATEICON) != 0)
	{
		// 해당 아이템이 체크되어 있다면 
		if (m_ctrlTree.GetCheck(hItem))
		{
			UnCheckChildItems(hItem);
		}
		// 해당 아이템이 체크되어 있지 않다면
		else
		{
			CheckChildItems(hItem);
		}
	}
}


//
//
// 입력받은 트리아이템의 자식아이템들을 모두 체크한다.
//
void [CMainClass]::CheckChildItems(HTREEITEM hItem)
{
	HTREEITEM	hChildItem = m_ctrlTree.GetChildItem(hItem);

	while (hChildItem != NULL)
	{
		m_ctrlTree.SetCheck(hChildItem, TRUE);

		if (m_ctrlTree.ItemHasChildren(hChildItem))
		{
			CheckChildItems(hChildItem);
		}
			
		hChildItem = m_ctrlTree.GetNextItem(hChildItem, TVGN_NEXT);
	}
}


//
//
// 입력받은 트리아이템의 자식아이템들을 모두 체크 해제한다.
//
void [CMainClass]::UnCheckChildItems(HTREEITEM hItem)
{
	HTREEITEM	hChildItem = m_ctrlTree.GetChildItem(hItem);

	while (hChildItem != NULL)
	{
		m_ctrlTree.SetCheck(hChildItem, FALSE);

		if (m_ctrlTree.ItemHasChildren(hChildItem))
		{
			UnCheckChildItems(hChildItem);
		}

		hChildItem = m_ctrlTree.GetNextItem(hChildItem, TVGN_NEXT);
	}
}
저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Proneer

댓글을 달아 주세요


티스토리 툴바