void CFWL_CheckBoxImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
  if (!pMessage)
    return;

  switch (pMessage->GetClassID()) {
    case CFWL_MessageType::Activate: {
      OnActivate(pMessage);
      break;
    }
    case CFWL_MessageType::SetFocus: {
      OnFocusChanged(pMessage, TRUE);
      break;
    }
    case CFWL_MessageType::KillFocus: {
      OnFocusChanged(pMessage, FALSE);
      break;
    }
    case CFWL_MessageType::Mouse: {
      CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
      switch (pMsg->m_dwCmd) {
        case FWL_MouseCommand::LeftButtonDown: {
          OnLButtonDown(pMsg);
          break;
        }
        case FWL_MouseCommand::LeftButtonUp: {
          OnLButtonUp(pMsg);
          break;
        }
        case FWL_MouseCommand::Move: {
          OnMouseMove(pMsg);
          break;
        }
        case FWL_MouseCommand::Leave: {
          OnMouseLeave(pMsg);
          break;
        }
        default:
          break;
      }
      break;
    }
    case CFWL_MessageType::Key: {
      CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage);
      if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown)
        OnKeyDown(pKey);
      break;
    }
    default: {
      break;
    }
  }

  CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
}
void CxResLibImgList::OnMouseMove(UINT nFlags, CPoint point)
{
	SetMouseTrack( m_bMouseTracked, GetSafeHwnd(), g_dwToolTipDelay );

	LVHITTESTINFO hti;
	memset(&hti, NULL, sizeof(LVHITTESTINFO));
	hti.flags = LVHT_ABOVE;

	GetCursorPos(&(hti.pt));
	ScreenToClient(&hti.pt);

	int nItem = -1;

	//检测 Item 是否选中
	//当图片文字区域过长时,ListCtrl返回的区域会明显大于真实区域。
	//此处可以考虑用循环遍历真实绘图区来判断。
	nItem = HitTest(&hti);

	//焦点有变化
	if (m_nLastFocusItem != nItem)
	{
		if (m_nLastFocusItem >= 0)
			OnFocusChanged(m_nLastFocusItem, FALSE);
		if (nItem >= 0)
			OnFocusChanged(nItem, TRUE);
	}

	m_nLastFocusItem = nItem;

	if (m_nLastFocusItem == -1)
	{
		m_bMouseTracked = FALSE;
	}

	if (m_bDragLayer == TRUE && nFlags == MK_LBUTTON)
	{
		m_bDragLayer = FALSE;
		m_ToolTip.Deactivate();
		Invalidate();
		DragLayer();
	}

	Invalidate();

	//CxListCtrl::OnMouseMove(nFlags, point);
}
void CFWL_PushButton::OnProcessMessage(CFWL_Message* pMessage) {
  if (!pMessage)
    return;
  if (!IsEnabled())
    return;

  switch (pMessage->GetType()) {
    case CFWL_Message::Type::SetFocus:
      OnFocusChanged(pMessage, true);
      break;
    case CFWL_Message::Type::KillFocus:
      OnFocusChanged(pMessage, false);
      break;
    case CFWL_Message::Type::Mouse: {
      CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
      switch (pMsg->m_dwCmd) {
        case FWL_MouseCommand::LeftButtonDown:
          OnLButtonDown(pMsg);
          break;
        case FWL_MouseCommand::LeftButtonUp:
          OnLButtonUp(pMsg);
          break;
        case FWL_MouseCommand::Move:
          OnMouseMove(pMsg);
          break;
        case FWL_MouseCommand::Leave:
          OnMouseLeave(pMsg);
          break;
        default:
          break;
      }
      break;
    }
    case CFWL_Message::Type::Key: {
      CFWL_MessageKey* pKey = static_cast<CFWL_MessageKey*>(pMessage);
      if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown)
        OnKeyDown(pKey);
      break;
    }
    default:
      break;
  }
  CFWL_Widget::OnProcessMessage(pMessage);
}
void IFWL_DateTimePicker::OnProcessMessage(CFWL_Message* pMessage) {
  if (!pMessage)
    return;

  switch (pMessage->GetClassID()) {
    case CFWL_MessageType::SetFocus:
      OnFocusChanged(pMessage, true);
      break;
    case CFWL_MessageType::KillFocus:
      OnFocusChanged(pMessage, false);
      break;
    case CFWL_MessageType::Mouse: {
      CFWL_MsgMouse* pMouse = static_cast<CFWL_MsgMouse*>(pMessage);
      switch (pMouse->m_dwCmd) {
        case FWL_MouseCommand::LeftButtonDown:
          OnLButtonDown(pMouse);
          break;
        case FWL_MouseCommand::LeftButtonUp:
          OnLButtonUp(pMouse);
          break;
        case FWL_MouseCommand::Move:
          OnMouseMove(pMouse);
          break;
        case FWL_MouseCommand::Leave:
          OnMouseLeave(pMouse);
          break;
        default:
          break;
      }
      break;
    }
    case CFWL_MessageType::Key: {
      if (m_pEdit->GetStates() & FWL_WGTSTATE_Focused) {
        m_pEdit->GetDelegate()->OnProcessMessage(pMessage);
        return;
      }
      break;
    }
    default:
      break;
  }

  IFWL_Widget::OnProcessMessage(pMessage);
}
int32_t CFWL_PushButtonImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
  if (!pMessage)
    return 0;
  if (!m_pOwner->IsEnabled()) {
    return 1;
  }
  int32_t iRet = 1;
  FX_DWORD dwMsgCode = pMessage->GetClassID();
  switch (dwMsgCode) {
    case FWL_MSGHASH_SetFocus:
    case FWL_MSGHASH_KillFocus: {
      OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
      break;
    }
    case FWL_MSGHASH_Mouse: {
      CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
      FX_DWORD dwCmd = pMsg->m_dwCmd;
      switch (dwCmd) {
        case FWL_MSGMOUSECMD_LButtonDown: {
          OnLButtonDown(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_LButtonUp: {
          OnLButtonUp(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_MouseMove: {
          OnMouseMove(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_MouseLeave: {
          OnMouseLeave(pMsg);
          break;
        }
        default: {}
      }
      break;
    }
    case FWL_MSGHASH_Key: {
      CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage);
      if (pKey->m_dwCmd == FWL_MSGKEYCMD_KeyDown) {
        OnKeyDown(pKey);
      }
      break;
    }
    default: {
      iRet = 0;
      break;
    }
  }
  CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
  return iRet;
}
 virtual void OnChildFocusRequested(std::shared_ptr<UIWidget> w) override {
   auto old_focused_child = focused_child;
   
   if(w != focused_child){
     focused_child = nullptr;
       UIWidget::RequestFocus();
     focused_child = w;
     if(old_focused_child && old_focused_child != w) old_focused_child->OnFocusChanged(false);
     focused_child->OnFocusChanged(true);
   }else{
     UIWidget::RequestFocus();
   }
 }
BOOL CXTPDockingPaneSidePanel::Init(CXTPDockingPaneBase* pBasePane, XTPDockingPaneDirection direction, CRect rc)
{
	CXTPDockingPaneBaseList lstPanes;
	pBasePane->FindPane(xtpPaneTypeDockingPane, &lstPanes);
	if (lstPanes.GetCount() == 0)
		return FALSE;

	m_direction = direction;
	m_rcWindow = rc;
	CreateContainer();

	CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)GetDockingPaneManager()->
		OnCreatePane(xtpPaneTypeTabbedContainer, m_pLayout);

	BOOL bInit = FALSE;

	POSITION pos = lstPanes.GetHeadPosition();
	while (pos)
	{
		CXTPDockingPane* pPane = (CXTPDockingPane*)lstPanes.GetNext(pos);

		if (pPane->GetContainer())
		{
			pPane->GetContainer()->RemovePane(pPane);
		}

		if (!bInit)
		{
			pContainer->Init((CXTPDockingPane*)pPane, this);
		}
		else
		{
			pContainer->_InsertPane(pPane, FALSE);
		}
		bInit = TRUE;
	}

	_InsertPane(pContainer);

	OnFocusChanged();

	m_nIdleFlags = 0;

	return TRUE;
}
int32_t CFWL_DateTimePickerImpDelegate::OnProcessMessage(
    CFWL_Message* pMessage) {
  if (!pMessage)
    return 0;
  FX_DWORD dwMsgCode = pMessage->GetClassID();
  int32_t iRet = 1;
  switch (dwMsgCode) {
    case FWL_MSGHASH_SetFocus:
    case FWL_MSGHASH_KillFocus: {
      OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
      break;
    }
    case FWL_MSGHASH_Mouse: {
      CFWL_MsgMouse* pMouse = static_cast<CFWL_MsgMouse*>(pMessage);
      FX_DWORD dwCmd = pMouse->m_dwCmd;
      switch (dwCmd) {
        case FWL_MSGMOUSECMD_LButtonDown: {
          OnLButtonDown(pMouse);
          break;
        }
        case FWL_MSGMOUSECMD_LButtonUp: {
          OnLButtonUp(pMouse);
          break;
        }
        case FWL_MSGMOUSECMD_MouseMove: {
          OnMouseMove(pMouse);
          break;
        }
        case FWL_MSGMOUSECMD_MouseLeave: {
          OnMouseLeave(pMouse);
          break;
        }
        default: {}
      }
      break;
    }
    default: { iRet = 0; }
  }
  if (dwMsgCode == FWL_MSGHASH_Key &&
      m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) {
    IFWL_WidgetDelegate* pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
    return pDelegate->OnProcessMessage(pMessage);
  }
  return CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
}