// ComboTreeCtrl.cpp : implementation file
//

#include "pch.h"
#include "ComboTreeCtrl.h"

#include "TreeComboBox.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CComboTreeCtrl

CComboTreeCtrl::CComboTreeCtrl() :m_pCombo(NULL)
{
}

CComboTreeCtrl::~CComboTreeCtrl()
{
}


BEGIN_MESSAGE_MAP(CComboTreeCtrl, CTreeCtrl)
	ON_NOTIFY_REFLECT(NM_KILLFOCUS, OnKillfocus)
	ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
	ON_NOTIFY_REFLECT(TVN_KEYDOWN, OnKeydown)
	ON_MESSAGE(TREECTRL_CHECK_STATE_CHANGE, OnTreeCtrlCheckStateChange)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CComboTreeCtrl message handlers

void CComboTreeCtrl::Display(IN CRect rc)
{
	if (GetSafeHwnd() == NULL)
		return;

	SetWindowPos(&wndNoTopMost, rc.left, rc.top, rc.right, rc.bottom, SWP_SHOWWINDOW);

	CWnd* pTopParent = GetParent()->GetParentOwner();
	if (pTopParent != NULL)
	{
		pTopParent->SendMessage(WM_NCACTIVATE, TRUE);
		pTopParent->SetRedraw(TRUE);
	}
}

BOOL CComboTreeCtrl::PreTranslateMessage(MSG* pMsg)
{
	if (pMsg->hwnd != m_hWnd)
		return FALSE;

	// 过滤掉Alt+F4;
	if (WM_SYSKEYDOWN == pMsg->message && VK_F4 == pMsg->wParam)
		return TRUE;

	// 回车键和esc键关闭控件;
	if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE))
	{
		// WMU_CLOSE_CONTROL->关闭控件;
		::PostMessage(m_pCombo->m_hWnd, WMU_CLOSE_CONTROL, (WPARAM)0, (LPARAM)0);
		return TRUE;
	}

	return CTreeCtrl::PreTranslateMessage(pMsg);
}

void CComboTreeCtrl::OnKillfocus(NMHDR* pNMHDR, LRESULT* pResult)
{
	// WMU_CLOSE_CONTROL->关闭控件;
	::PostMessage(m_pCombo->m_hWnd, WMU_CLOSE_CONTROL, (WPARAM)0, (LPARAM)0);
}

LRESULT CComboTreeCtrl::OnTreeCtrlCheckStateChange(WPARAM wParam, LPARAM lParam)
{
	HTREEITEM hItemChanged = (HTREEITEM)lParam;
	BOOL bCheckState = GetCheck(hItemChanged);
	SelectItem(hItemChanged);

	while (hItemChanged = GetParentItem(hItemChanged))
		SetCheck(hItemChanged);

	return 1;
}

void CComboTreeCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
	UINT nFlags;
	HTREEITEM hItem;
	// verify that we have a mouse click in the check box area 
	DWORD dwPos = GetMessagePos();
	CPoint point(LOWORD(dwPos), HIWORD(dwPos));
	ScreenToClient(&point);
	hItem = HitTest(point, &nFlags);
	if (hItem)
	{
		if (GetParentItem(hItem))
			::PostMessage(m_pCombo->m_hWnd, WMU_CLOSE_CONTROL, (WPARAM)0, (LPARAM)hItem);// WMU_CLOSE_CONTROL->关闭控件;
	}

	*pResult = 0;
}

void CComboTreeCtrl::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult)
{
	TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*)pNMHDR;
	if (pTVKeyDown->wVKey == VK_SPACE)
	{
		HTREEITEM hItem = GetSelectedItem();
		if (hItem != NULL)
		{
			// handle state change here or post message to another handler
			// Post message state has changed
			PostMessage(TREECTRL_CHECK_STATE_CHANGE, 0, (LPARAM)hItem);
		}
	}

	*pResult = 0;
}

/************************************************************************/
/*  函数：FindItem[12/7/2016 IT];
/*  描述：从指定父项开始查找指定名称的项;
/*  参数：;
/*  	[IN] strName：要查找的项名称;
/*  	[IN] hRoot：要开始查找的父项;
/*  返回：void;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
HTREEITEM CComboTreeCtrl::FindItem(IN const CString& strName, IN HTREEITEM hRoot)
{
	// 判断父项是否就是要查找的项;
	CString sText = GetItemText(hRoot);
	if (sText.Compare(strName) == 0)
		return hRoot;

	HTREEITEM hItem = NULL;
	// 获取第一个子项句柄;
	HTREEITEM hSub = GetChildItem(hRoot);
	// 遍历所有子项;
	while (hSub)
	{
		// 当前子项是否是要查找的子项;
		if ((hItem = FindItem(strName, hSub)) != NULL)
			break;

		// 若未到，查找下一个兄弟项;
		hSub = GetNextSiblingItem(hSub);
	}

	return hItem;
}
