void CScrollV::SetControlRect(CRect rc) { m_rc = rc; SetRange(); CRect rcTemp; for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase) { pControlBase->SetVisible(m_bShowScroll); UINT uControlID = pControlBase->GetControlID(); if (BT_UP == uControlID) { rcTemp = m_rc; rcTemp.bottom = m_rc.top + 20; } else if(BT_DOWN == uControlID) { rcTemp = m_rc; rcTemp.top = m_rc.bottom - 20; } else { continue; } pControlBase->SetRect(rcTemp); } } }
void CDlgPopup::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // 当前控件是否能处理 if (m_pControl && m_pControl->OnKeyDown(nChar, nRepCnt, nFlags)) { return; } // 子控件是否能处理 for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase && pControlBase->OnKeyDown(nChar, nRepCnt, nFlags)) { return; } } if(OnControlKeyDown(nChar, nRepCnt, nFlags)) { return; } CWnd::OnKeyDown(nChar, nRepCnt, nFlags); }
// 清除指定名字的子控件 BOOL CControlBase::RemoveControl(CString strControlName, UINT uControlID) { vector<CControlBase*>::iterator it; for(it=m_vecControl.begin();it!=m_vecControl.end();++it) { CControlBase* pControlBase = *it; if (pControlBase && pControlBase->IsThisObject(uControlID, strControlName)) { // 如果是焦点控件,则需要先将焦点设置为空 if(pControlBase->IsFocusControl()) { CDlgBase* pDlg = GetParentDialog(FALSE); if(pDlg) { pDlg->SetFocusControlPtr(NULL); } } m_vecControl.erase(it); delete pControlBase; return TRUE; } } return FALSE; }
// 重载设置控件可见性的函数,需要调用子控件的函数 void CDuiPanel::SetControlVisible(BOOL bIsVisible) { __super::SetControlVisible(bIsVisible); // 设置每个子控件的原生Windows控件的可见性 for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase) { if(pControlBase->IsClass(_T("div")) || pControlBase->IsClass(_T("tabctrl"))) { pControlBase->SetControlVisible(bIsVisible); }else { // Panel可见性变化时候,只会隐藏原生控件,不主动显示原生控件 //if(!bIsVisible) { pControlBase->SetControlWndVisible(bIsVisible); } } } } if(m_pDuiPluginObject) { m_pDuiPluginObject->SetVisible(bIsVisible); } }
void CDuiText::SetControlRect(CRect rc) { m_rc = rc; CRect rcTemp; for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase) { UINT uControlID = pControlBase->GetControlID(); if((SCROLL_V == uControlID) && m_bScrollV) { rcTemp = m_rc; rcTemp.left = rcTemp.right - m_nScrollWidth; }else if(LISTBK_AREA == uControlID) { rcTemp = m_rc; rcTemp.right -= m_nScrollWidth; }else { continue; } pControlBase->SetRect(rcTemp); } } }
// UI初始化,此函数在窗口的OnCreate函数中调用 void CDuiMenu::InitUI(CRect rcClient) { // 如果有菜单项的预设置值,则设置相应的值到控件 if(m_vecMenuItemValue.size() > 0) { for (size_t i = 0; i < m_vecMenuItemValue.size(); i++) { MenuItemValue& itemValue = m_vecMenuItemValue.at(i); CControlBase* pControlBase = GetControl(itemValue.strName); if(pControlBase) { if(!itemValue.strTitle.IsEmpty()) { ((CControlBaseFont*)pControlBase)->SetTitle(itemValue.strTitle); } if(!itemValue.bVisible) { pControlBase->SetVisible(FALSE); } if(itemValue.bDisable) { pControlBase->SetDisable(TRUE); } if(itemValue.nCheck != -1) { ((CMenuItem*)pControlBase)->SetCheck(itemValue.nCheck); } } } // 刷新菜单项位置信息 SetMenuPoint(); } }
// 鼠标滚轮消息处理 BOOL CDlgPopup::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { ScreenToClient(&pt); zDelta /= WHEEL_DELTA; UINT nFlag = (zDelta>0) ? SB_LINEUP : SB_LINEDOWN; zDelta = abs(zDelta); BOOL bResponse = FALSE; for(short i = 0; i < zDelta; i++) { if (m_pControl && m_pControl->OnScroll(TRUE, nFlag, pt)) { bResponse = TRUE; continue; }else { // 窗口控件事件处理 for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase && pControlBase->OnScroll(TRUE, nFlag, pt)) { bResponse = TRUE; break; } } } } return bResponse; }
// 键盘事件处理 BOOL CControlBase::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if(!m_bIsVisible || !m_bRresponse) return false; BOOL bRresponse = false; // 判断当前活动控件 if(m_pControl && m_pControl->OnKeyDown(nChar, nRepCnt, nFlags)) { return true; } // 控件自身是否可以处理此事件 if(OnControlKeyDown(nChar, nRepCnt, nFlags)) { return true; } // 此控件没有处理,则遍历子控件看是否能处理 for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase && pControlBase->OnKeyDown(nChar, nRepCnt, nFlags)) { return true; } } return false; }
void CALLBACK CControlBase::TimerCallProc(UINT TimerID2, UINT msg, DWORD dwUser, DWORD dwa, DWORD dwb) { CControlBase *pControlBase = (CControlBase *)dwUser; if (pControlBase) { pControlBase->OnTimer(); } }
// 鼠标左键按下事件处理 BOOL CControlBase::OnLButtonDown(UINT nFlags, CPoint point) { if(!m_bIsVisible || !m_bRresponse) return false; // 保存原始的鼠标位置,并进行位置变换 CPoint oldPoint = point; OnMousePointChange(point); m_bMouseDown = m_rc.PtInRect(point); // 查找鼠标是否在某个内部控件位置,如果是的话就更新当前子控件(按照反向顺序查找,因为定义在后面的控件是优先级更高的) // 找到第一个符合条件的就结束查找 for (int i = m_vecControl.size()-1; i >= 0; i--) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase && pControlBase->PtInRect(point)) { if(pControlBase->GetVisible() && !pControlBase->GetDisable() && pControlBase->GetRresponse()) { m_pControl = pControlBase; break; } } } if(m_pControl != NULL) { // 如果是控件内置滚动条子控件,则不进行位置变换,因为滚动条位置是不需要变换的 UINT uControlID = m_pControl->GetControlID(); if((SCROLL_V == uControlID) || (SCROLL_H == uControlID)) { point = oldPoint; } if(m_pControl->OnLButtonDown(nFlags, point)) { return true; } } else { // 切换对话框中的当前焦点控件(暂不处理Popup窗口的切换) CDlgBase* pDlg = GetParentDialog(FALSE); if(pDlg) { pDlg->SetFocusControl(this); } // 发送鼠标左键按下DUI消息 if(m_bDuiMsgMouseLDown && m_rc.PtInRect(point)) { SendMessage(MSG_MOUSE_LDOWN, (WPARAM)nFlags, (LPARAM)(&point)); } return OnControlLButtonDown(nFlags, point); } return false; }
// 禁用控件 CControlBase * CDlgPopup::SetControlDisable(UINT uControlID, BOOL bDisable) { CControlBase *pControlBase = GetControl(uControlID); if(pControlBase) { pControlBase->SetDisable(bDisable); UpdateHover(); } return pControlBase; }
// 移动控件 CControlBase * CDlgPopup::SetControlRect(UINT uControlID, CRect rc) { CControlBase *pControlBase = GetControl(uControlID); if(pControlBase) { pControlBase->SetRect(rc); UpdateHover(); } return pControlBase; }
// 初始化窗口控件 void CDuiPanel::InitUI(CRect rcClient, DuiXmlNode pNode) { CRect rcTemp; int nStartX = 0; int nStartY = 0; CControlBase * pControlBase = NULL; // 加载所有窗口控件 if(pNode) { m_nVirtualHeight = 0; m_nVirtualWidth = 0; for (DuiXmlNode pControlElem = pNode.first_child(); pControlElem; pControlElem=pControlElem.next_sibling()) { if(pControlElem != NULL) { CString strControlName = pControlElem.name(); CControlBase* pControl = _CreateControlByName(strControlName); if(pControl) { pControl->Load(pControlElem); if(pControl->IsClass(CArea::GetClassName())) { // Area不能响应鼠标,必须加到Area列表中 m_vecArea.push_back(pControl); }else { m_vecControl.push_back(pControl); } CRect rcCtrl = pControl->GetRect(); if(rcCtrl.bottom > m_nVirtualHeight) { m_nVirtualHeight = rcCtrl.bottom - m_rc.top; } if(rcCtrl.right > m_nVirtualWidth) { m_nVirtualWidth = rcCtrl.right - m_rc.left; } } } } // 需要的总高度大于显示区高度才会显示垂直滚动条 m_pControScrollV->SetVisible(m_nVirtualHeight > m_rc.Height()); ((CDuiScrollVertical*)m_pControScrollV)->SetScrollMaxRange(m_nVirtualHeight); // 需要的总宽度大于显示区宽度才会显示垂直滚动条 m_pControScrollH->SetVisible(m_nVirtualWidth > m_rc.Width()); ((CDuiScrollHorizontal*)m_pControScrollH)->SetScrollMaxRange(m_nVirtualWidth); } m_bInit = true; }
// 清除指定类型的子控件 void CControlBase::RemoveControls(CStringA strClassName) { for (int i = m_vecControl.size()-1; i >= 0; i--) { CControlBase* pControlBase = m_vecControl.at(i); if(pControlBase->IsClass(strClassName)) { RemoveControl(pControlBase); } } }
// 设置控件的位置 void CDuiPanel::SetControlRect(CRect rc) { m_rc = rc; if(m_pDuiPluginObject) { m_pDuiPluginObject->SetRect(rc); } CRect rcTemp; for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase) { UINT uControlID = pControlBase->GetControlID(); if(SCROLL_V == uControlID) { rcTemp = m_rc; rcTemp.left = rcTemp.right - m_nScrollWidth; }else if(SCROLL_H == uControlID) { rcTemp = m_rc; rcTemp.top = rcTemp.bottom - m_nScrollWidth; }else { rcTemp = pControlBase->GetRect(); if(rcTemp.bottom > m_nVirtualHeight) { // 刷新Panel的虚拟高度 m_nVirtualHeight = rcTemp.bottom - m_rc.top; } if(rcTemp.right > m_nVirtualWidth) { // 刷新Panel的虚拟宽度 m_nVirtualWidth = rcTemp.right - m_rc.left; } continue; } pControlBase->SetRect(rcTemp); } } // 需要的总高度大于显示区高度才会显示滚动条 m_pControScrollV->SetVisible(m_nVirtualHeight > m_rc.Height()); ((CDuiScrollVertical*)m_pControScrollV)->SetScrollMaxRange(m_nVirtualHeight); // 需要的总宽度大于显示区宽度才会显示垂直滚动条 m_pControScrollH->SetVisible(m_nVirtualWidth > m_rc.Width()); ((CDuiScrollHorizontal*)m_pControScrollH)->SetScrollMaxRange(m_nVirtualWidth); }
void CControlBase::SetUpdate(BOOL bUpdate, COLORREF clr/* = 0*/) { m_bUpdate = bUpdate; for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase) { pControlBase->SetUpdate(bUpdate, clr); } } }
// 画子控件 BOOL CControlBase::DrawSubControls(CDC &dc, CRect rcUpdate) { for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase && pControlBase->GetVisible()) { pControlBase->Draw(dc, rcUpdate); } } return TRUE; }
// 重载设置控件可见性的函数,需要调用子控件的函数 void CDuiPanel::SetControlVisible(BOOL bIsVisible) { __super::SetControlVisible(bIsVisible); // 设置每个子控件的原生Windows控件的可见性 for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase) { if(pControlBase->IsClass(_T("div")) || pControlBase->IsClass(_T("tabctrl")) || pControlBase->IsClass(_T("layout"))) { // 如果子控件是容器类型控件,则调用子控件的设置可见性函数 pControlBase->SetControlVisible(bIsVisible); }else { // 判断子控件当前是否可见,根据可见性设置子控件的原生控件的可见性 // 如果是edit控件,暂时不显示原生控件,否则tab页切换时候会有问题 BOOL bVisible = pControlBase->GetVisible(); if(pControlBase->IsClass(CDuiEdit::GetClassName())) { bVisible = FALSE; } pControlBase->SetControlWndVisible(bVisible); } } } // 如果有插件,则设置插件的可见性 if(m_pDuiPluginObject) { m_pDuiPluginObject->SetVisible(bIsVisible); } }
// 控件的位置信息需要刷新 void CControlBase::OnPositionChange() { // 刷新控件自身的位置 OnAttributePosChange(m_strPos, FALSE); // 刷新子控件的位置 for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase) { pControlBase->OnPositionChange(); } } }
LRESULT CDlgPopup::OnMessage(UINT uID, UINT Msg, WPARAM wParam, LPARAM lParam) { // 遍历每个控件,看哪个控件是此ID,则进行事件的处理 CControlBase * pThisControlBase = NULL; for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase && (pControlBase->GetControlID() == uID)) { pThisControlBase = pControlBase; pControlBase->OnMessage(uID, Msg, wParam, lParam); } } return 0; }
// 清除指定名字的子控件 BOOL CControlBase::RemoveControl(CString strControlName, UINT uControlID) { vector<CControlBase*>::iterator it; for(it=m_vecControl.begin();it!=m_vecControl.end();++it) { CControlBase* pControlBase = *it; if (pControlBase && pControlBase->IsThisObject(uControlID, strControlName)) { m_vecControl.erase(it); delete pControlBase; return TRUE; } } return FALSE; }
// 重载设置控件中windows原生控件可见性的函数,需要调用子控件的函数 void CDuiLayout::SetControlWndVisible(BOOL bIsVisible) { __super::SetControlWndVisible(bIsVisible); // 设置每个子控件的原生Windows控件的可见性 for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase) { // 判断子控件当前是否可见,根据可见性设置子控件的原生控件的可见性 BOOL bVisible = pControlBase->GetVisible(); pControlBase->SetControlWndVisible(bVisible); } } }
// 定时器消息 void CDlgPopup::OnTimer(UINT uTimerID) { //if(!::IsWindow(GetSafeHwnd())) return ; // 动画定时器 if(m_uTimerAnimation == uTimerID) { for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase) { pControlBase->OnTimer(); } } } }
// 获取当前处于活动状态的子菜单项 CMenuItem* CDuiMenu::GetHoverMenuItem() { for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl[i]; if(pControlBase->IsClass(CMenuItem::GetClassName())) // 如果是MenuItem类型控件 { CMenuItem* pMenuItem = (CMenuItem*)pControlBase; if(pMenuItem->IsHover()) { return pMenuItem; } } } return NULL; }
// 消息响应 LRESULT CDuiMenu::OnMessage(UINT uID, UINT Msg, WPARAM wParam, LPARAM lParam) { if((Msg != BUTTOM_UP) && (Msg != BUTTOM_CHECK)) { return 0; } CControlBase* pControl = GetControl(uID); if(pControl && !pControl->GetAction().IsEmpty()) { // 如果菜单项设置了action,则添加到动作任务队列中,通过任务来执行 CString strControlName = pControl->GetName(); CString strAction = pControl->GetAction(); //CDuiObject* pParent = pControl->GetParent(); CDlgBase* pParentDlg = pControl->GetParentDialog(); DuiSystem::Instance()->AddDuiActionTask(uID, Msg, wParam, lParam, strControlName, strAction, pParentDlg); }else { // 否则就调用Popup的函数 __super::OnMessage(uID, Msg, wParam, lParam); /*tagMenuInfo* pMenuInfo = new tagMenuInfo; pMenuInfo->uMenuID = uID; pMenuInfo->bSelect = (bool)lParam; pMenuInfo->bDown = (bool)wParam; PostMessage(m_uMessageID, Msg, (LPARAM)pMenuInfo);*/ } if(Msg == BUTTOM_UP) { // 如果有父菜单,将父菜单关闭,不采用直接关闭的方法,而是设置自动关闭标识,并通过鼠标事件触发自动关闭 CDuiMenu* pParentMenu = GetParentMenu(); if(pParentMenu && !pParentMenu->IsAutoClose()) { pParentMenu->SetAutoClose(TRUE); pParentMenu->SetForegroundWindow(); pParentMenu->PostMessage(WM_LBUTTONDOWN, 0, 0); } // 关闭自身 CloseWindow(); } return 0; }
// 刷新父控件下面所有同一个组的RadioButton控件的状态 BOOL CMenuItem::ResetGroupCheck() { CDuiObject* pParentObj = GetParent(); if(pParentObj == NULL) { return FALSE; } vector<CControlBase*>* pvecControl = NULL; if(pParentObj->IsClass(_T("dlg"))) { CDlgBase* pDlg = static_cast<CDlgBase*>(pParentObj); pvecControl = pDlg->GetControls(); }else if(pParentObj->IsClass(_T("popup"))) { CDlgPopup* pDlg = static_cast<CDlgPopup*>(pParentObj); pvecControl = pDlg->GetControls(); }else { CControlBase* pControlBase = static_cast<CControlBase*>(pParentObj); pvecControl = pControlBase->GetControls(); } if(pvecControl == NULL) { return FALSE; } for(int i=0; i<(int)pvecControl->size(); i++) { CControlBase* pControlBase = pvecControl->at(i); if(pControlBase->IsClass(CMenuItem::GetClassName()) && pControlBase->GetVisible() && !pControlBase->GetDisable()) { CMenuItem* pControl = static_cast<CMenuItem*>(pControlBase); if((pControl->GetGroupName() == m_strGroupName) && (pControl != this)) { // 重置控件状态 pControl->SetControlCheck(FALSE); } } } return TRUE; }
// 重载设置控件隐藏状态的函数,需要调用子控件的函数 void CDuiPanel::SetControlHide(BOOL bIsHide) { __super::SetControlHide(bIsHide); // 设置每个子控件的原生Windows控件的可见性 for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase) { if(pControlBase->IsClass(_T("div")) || pControlBase->IsClass(_T("tabctrl")) || pControlBase->IsClass(_T("layout"))) { // 如果子控件是容器类型控件,则调用子控件的设置隐藏函数 pControlBase->SetControlHide(bIsHide); }else { // 判断子控件当前是否可见,根据可见性设置子控件的原生控件的可见性 pControlBase->SetControlWndVisible(pControlBase->GetVisible()); } } } // 如果有插件,则设置插件的显示状态(插件接口暂不支持SetHide函数) if(m_pDuiPluginObject) { m_pDuiPluginObject->SetVisible(!bIsHide); } }
// 键盘事件处理 BOOL CControlBase::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if(!m_bIsVisible || !m_bRresponse) return false; BOOL bRresponse = false; // 判断当前活动控件 if(m_pControl && m_pControl->OnKeyDown(nChar, nRepCnt, nFlags)) { return true; } // 控件自身是否可以处理此事件 if(OnControlKeyDown(nChar, nRepCnt, nFlags)) { // 发送键盘按下DUI消息 if(m_bDuiMsgKeyDown) { SendMessage(MSG_KEY_DOWN, (WPARAM)nChar, (LPARAM)nFlags); } return true; } // 此控件没有处理,则遍历子控件看是否能处理 for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl.at(i); if (pControlBase && pControlBase->OnKeyDown(nChar, nRepCnt, nFlags)) { // 发送键盘按下DUI消息 if(m_bDuiMsgKeyDown) { SendMessage(MSG_KEY_DOWN, (WPARAM)nChar, (LPARAM)nFlags); } return true; } } // 发送键盘按下DUI消息 if(m_bDuiMsgKeyDown) { SendMessage(MSG_KEY_DOWN, (WPARAM)nChar, (LPARAM)nFlags); } return false; }
// 获取当前处于活动状态的子菜单项(根据鼠标位置查找) CMenuItem* CDuiMenu::GetMenuItemWithPoint(CPoint point) { for (size_t i = 0; i < m_vecControl.size(); i++) { CControlBase * pControlBase = m_vecControl[i]; if(pControlBase->IsClass(CMenuItem::GetClassName())) // 如果是MenuItem类型控件 { CMenuItem* pMenuItem = (CMenuItem*)pControlBase; CRect rc = pMenuItem->GetRect(); if(rc.PtInRect(point)) { return pMenuItem; } } } return NULL; }
// 消息响应 LRESULT CDlgPopup::OnBaseMessage(UINT uID, UINT uMsg, WPARAM wParam, LPARAM lParam) { CControlBase* pControl = GetControl(uID); if(pControl == NULL) { return 0L; } // 点击了关闭按钮,则执行关闭动作 if(pControl->IsThisObject(BT_CLOSE, NAME_BT_CLOSE)) { CloseWindow(); }else { OnMessage(uID, uMsg, wParam, lParam); } return 0L; }