Exemple #1
0
// 重载窗口去激活时候的关闭窗口操作
BOOL CDuiMenu::OnNcCloseWindow()
{
	// 如果有父菜单,将父菜单窗口关闭
	CDuiMenu* pParentMenu = GetParentMenu();
	if(pParentMenu && !pParentMenu->IsAutoClose())
	{
		// 如果鼠标在父菜单窗口中,则不关闭父窗口
		CMenuItem* pHoverItem = pParentMenu->GetHoverMenuItem();
		if(pHoverItem == NULL)
		{
			pParentMenu->SetAutoClose(TRUE);
			pParentMenu->SetForegroundWindow();
			pParentMenu->PostMessage(WM_LBUTTONDOWN, 0, 0);
		}
	}

	// 如果父对象是菜单项,则将菜单项中的弹出菜单指针设置为空
	CDuiObject* pParent = GetParent();
	if((pParent != NULL) && (pParent->IsClass(CMenuItem::GetClassName())))
	{
		((CMenuItem*)pParent)->SetPopupMenu(NULL);
	}

	// 关闭自身
	m_pParentDuiObject = NULL;
	CloseWindow();	

	return TRUE;
}
Exemple #2
0
// 消息响应
LRESULT CDuiMenu::OnMessage(UINT uID, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	if((Msg != MSG_BUTTON_UP) && (Msg != MSG_BUTTON_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 == MSG_BUTTON_UP)
	{
		// 如果点击的是弹出菜单,则不用关闭
		if(pControl && pControl->IsClass(CMenuItem::GetClassName()) && ((CMenuItem*)pControl)->IsPopup())
		{
			return 0;
		}

		// 如果有父菜单,将父菜单关闭,不采用直接关闭的方法,而是设置自动关闭标识,并通过鼠标事件触发自动关闭
		CDuiMenu* pParentMenu = GetParentMenu();
		if(pParentMenu && !pParentMenu->IsAutoClose())
		{
			pParentMenu->SetAutoClose(TRUE);
			pParentMenu->SetForegroundWindow();
			pParentMenu->PostMessage(WM_LBUTTONDOWN, 0, 0);
		}
		// 关闭自身
		CloseWindow();
	}

	return 0;
}
Exemple #3
0
BOOL CMenuItem::OnControlMouseMove(UINT nFlags, CPoint point)
{
	enumButtonState buttonState = m_enButtonState;
	if (!m_bIsDisable && !m_bMouseDown)
	{
		if(m_rc.PtInRect(point))
		{
			if(m_bSelect)
			{
				if(m_bDown)
				{
					m_enButtonState = enBSHoverDown;
				}
				else
				{
					m_enButtonState = enBSHover;
				}
			}
			else
			{
				m_enButtonState = enBSHover;
				// 如果有子菜单,则加载弹出菜单
				if(m_bIsPopup)
				{
					ShowPopupMenu();
				}
			}
		}
		else
		{
			// 如果存在弹出菜单,并且鼠标不在弹出菜单范围内,则关闭弹出菜单
			if(m_bIsPopup && (m_pPopupMenu != NULL))
			{
				// 检查父菜单的各个子菜单,看鼠标当前是否在其他菜单项上面
				CDuiMenu* pParentMenu = GetParentMenu();
				//CMenuItem* pHoverItem = pParentMenu->GetHoverMenuItem();
				CMenuItem* pHoverItem = pParentMenu->GetMenuItemWithPoint(point);
				if((pHoverItem != NULL) && (pHoverItem != this))
				{
					// 如果鼠标在其他平级的菜单上,则关闭子菜单
					if(IsWindow(m_pPopupMenu->GetSafeHwnd()))
					{
						m_pPopupMenu->CloseWindow();
					}
					m_pPopupMenu = NULL;
				
					// 父菜单对象设置回自动关闭
					CDuiMenu* pParentMenu = GetParentMenu();
					if(pParentMenu)
					{
						pParentMenu->SetAutoClose(TRUE);
						pParentMenu->SetForegroundWindow();
					}
				}
			}

			if(m_bSelect)
			{
				if(m_bDown)
				{
					m_enButtonState = enBSDown;
				}
				else
				{
					m_enButtonState = enBSNormal;
				}
			}
			else
			{
				m_enButtonState = enBSNormal;
			}
		}
	}
	
	if(buttonState != m_enButtonState)
	{
		UpdateControl();
		return true;
	}
	return false;
}
Exemple #4
0
// 显示弹出菜单
void CMenuItem::ShowPopupMenu()
{
	// 如果已经显示了子菜单,则直接退出
	if(m_pPopupMenu)
	{
		return;
	}

	if(m_bIsPopup)
	{
		m_pPopupMenu = new CDuiMenu(DuiSystem::GetDefaultFont(), 12);
		m_pPopupMenu->SetAutoClose(FALSE);
		m_pPopupMenu->SetParent(this);
		m_pPopupMenu->m_clrRowHover = m_clrHover;	// 设置菜单菜单的背景色
		CPoint point;
		CRect rc = GetRect();
		point.SetPoint(rc.left + rc.Width(), rc.top);
		int nMenuWidth = rc.Width();

		CDlgBase* pParentDlg = GetParentDialog();
		// 如果菜单项定义了XML文件,则使用此菜单项定义的XML文件加载子菜单
		// 否则查找父菜单对象,找到对应的XML文件名,使用此XML文件名加载子菜单
		CString strXmlFile = _T("");		
		CDuiMenu* pParentMenu = GetParentMenu();
		if(pParentMenu)
		{
			if(!m_strMenuXml.IsEmpty())
			{
				// 使用菜单项定义的XML文件
				strXmlFile = m_strMenuXml;
			}else
			{
				// XML文件设置为父菜单对象的XML文件
				strXmlFile = pParentMenu->GetXmlFile();
			}
			// 必须将父菜单对象的自动关闭关掉,否则子菜单显示时候,父菜单失去焦点,会自动销毁
			pParentMenu->SetAutoClose(FALSE);
			// 转换子菜单的坐标
			::ClientToScreen(pParentMenu->GetSafeHwnd(), &point);

			// 将父菜单的预设值菜单项列表添加到子菜单中
			for (size_t i = 0; i < pParentMenu->m_vecMenuItemValue.size(); i++)
			{
				MenuItemValue& itemValue = pParentMenu->m_vecMenuItemValue.at(i);
				m_pPopupMenu->m_vecMenuItemValue.push_back(itemValue);
			}
		}

		if(!strXmlFile.IsEmpty())
		{
			BOOL bSucc = m_pPopupMenu->LoadXmlFile(strXmlFile, pParentDlg, point, WM_DUI_MENU, GetName());
			if(bSucc)	// 加载弹出菜单成功才显示弹出菜单
			{
				// 计算菜单的位置并显示
				CRect rc;
				m_pPopupMenu->GetWindowRect(&rc);
				// 如果超出屏幕右侧范围,则菜单窗口往左移动一些,移动到当前菜单的左侧
				int nScreenWidth= GetSystemMetrics(SM_CXFULLSCREEN);
				if(rc.right > nScreenWidth)
				{
					//rc.OffsetRect(nScreenWidth - rc.right -10, 0);	// 移动到屏幕最右侧
					rc.OffsetRect(-(nMenuWidth + rc.Width()), 0);	// 移动到当前菜单左侧
				}
				int nScreenHeight= GetSystemMetrics(SM_CYFULLSCREEN);
				if(rc.bottom > nScreenHeight)
				{
					rc.OffsetRect(0, -(rc.Height() - m_rc.Height()));	// 高度超出屏幕则改为下对齐方式
				}
				m_pPopupMenu->MoveWindow(rc);
				m_pPopupMenu->ShowWindow(SW_SHOW);
				m_pPopupMenu->SetAutoClose(TRUE);
			}else
			{
				// 弹出菜单加载失败,删除菜单对象
				delete m_pPopupMenu;
				m_pPopupMenu = NULL;
			}
		}
	}
}
Exemple #5
0
// 鼠标左键放开事件处理
BOOL CMenuItem::OnControlLButtonUp(UINT nFlags, CPoint point)
{
	bool bSend = false;
	BOOL bbDown = FALSE;
	bool bSelect = false;
	enumButtonState buttonState = m_enButtonState;
	if (!m_bIsDisable)
	{
		if(m_rc.PtInRect(point))
		{
			if(m_bSelect)
			{
				if(m_bDown)
				{
					m_enButtonState = enBSHoverDown;
				}
				else
				{
					m_enButtonState = enBSHover;
				}
				if(m_bMouseDown)
				{
					// 如果组名非空,说明是radiobutton组,则刷新同一个组下面其他radiobtn
					if(!m_strGroupName.IsEmpty())
					{
						m_bDown = true;
						ResetGroupCheck();
					}else
					{
						m_bDown = !m_bDown;
					}
					bSend = false;
					bbDown = m_bDown;
					bSelect = true;
				}				
			}
			else
			{
				m_enButtonState = enBSHover;
				bSend = true;
				
			}
		}
		else
		{
			// 如果存在弹出菜单,并且鼠标不在弹出菜单范围内,则关闭父菜单
			if(m_bIsPopup)
			{
				// 父菜单对象设置回自动关闭
				CDuiMenu* pParentMenu = GetParentMenu();
				if(pParentMenu)
				{
					pParentMenu->SetAutoClose(TRUE);
					pParentMenu->SetForegroundWindow();
				}
			}

			if(m_bDown)
			{
				m_enButtonState = enBSDown;
			}
			else
			{
				m_enButtonState = enBSNormal;
			}			
		}
	}
	m_bMouseDown = false;
	
	if(buttonState != m_enButtonState)
	{
		UpdateControl();

		if(bSend)
		{
			SendMessage(MSG_BUTTON_UP, bbDown, bSelect);
		}
		return true;
	}
	return false;
}
// 消息处理
LRESULT CControlBase::OnMessage(UINT uID, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if(m_bTaskMsg)
	{
		// 如果设置了任务方式发消息的属性,则添加一个任务消息
		CString strControlName = GetName();
		CString strAction = GetAction();
		CDlgBase* pParentDlg = GetParentDialog();
		DuiSystem::Instance()->AddDuiActionTask(uID, uMsg, wParam, lParam, strControlName, strAction, pParentDlg);
		return 0;
	}

	if(m_strAction.Find(_T("dlg:")) == 0)	// 动作:打开一个对话框,有内存泄漏,改为通过DuiSystem创建和管理
	{
		if(uMsg == MSG_BUTTON_UP)	// 鼠标放开事件才处理
		{
			CString strXmlFile = m_strAction;
			strXmlFile.Delete(0, 4);
			DuiSystem::ShowDuiDialog(strXmlFile, GetParentDialog());
		}
	}else
	if(m_strAction.Find(_T("popup:")) == 0)	// 动作:打开一个Popup对话框
	{
		if(uMsg == MSG_BUTTON_UP)	// 鼠标放开事件才处理
		{
			/*UINT nIDTemplate = 0;
			CDlgBase* pParentDlg = GetParentDialog();
			if(pParentDlg != NULL)
			{
				nIDTemplate = pParentDlg->GetIDTemplate();
			}
			CDlgPopup* pPopup = new CDlgPopup;
			pPopup->SetParent(this);
			CString strXmlFile = m_strAction;
			strXmlFile.Delete(0, 6);
			pPopup->SetXmlFile(_T("xml:") +strXmlFile );
			CRect rc = pControlBase->GetRect();
			rc.OffsetRect(-95, rc.Height());
			ClientToScreen(&rc);
			pPopup->Create(this, rc, WM_SKIN);
			pPopup->ShowWindow(SW_SHOW);*/
		}
	}else
	if(m_strAction.Find(_T("menu:")) == 0)	// 动作:打开一个菜单
	{
		CDuiMenu *pDuiMenu = new CDuiMenu(DuiSystem::GetDefaultFont(), 12);	// 可以考虑改为通过DuiSystem创建和管理
		pDuiMenu->SetAutoClose(FALSE);
		pDuiMenu->SetParent(this);
		CPoint point;
		CRect rc = GetRect();
		// 计算菜单的显示位置
		if(m_posMenu.nCount >= 2)
		{
			// 使用设置的菜单位置
			int nMenuX = PositionItem2Value(m_posMenu.Left, rc.left, rc.right);
			int nMenuY = PositionItem2Value(m_posMenu.Top, rc.top, rc.bottom);
			point.SetPoint(nMenuX, nMenuY);
		}else
		{
			// 如果没有设置位置信息,则默认按照控件底部开始显示,水平方向中间对齐
			point.SetPoint(rc.left + rc.Width() / 2, rc.bottom);
		}
		CDlgBase* pParentDlg = GetParentDialog();
		if(pParentDlg != NULL)
		{
			pParentDlg->ClientToScreen(&point);
		}
		CString strXmlFile = m_strAction;
		strXmlFile.Delete(0, 5);
		if(pDuiMenu->LoadXmlFile(strXmlFile, pParentDlg, point, WM_DUI_MENU))
		{
			if(m_posMenu.nCount >= 4)
			{
				// 如果菜单pos有4个值,第三个值为负数表示菜单向左侧显示,第四个值为负数表示菜单向上显示
				CRect rcMenu;
				pDuiMenu->GetWindowRect(&rcMenu);
				int nOffsetX = 0;
				int nOffsetY = 0;
				if(m_posMenu.Right.bMinus)
				{
					nOffsetX = -rcMenu.Width();
				}
				if(m_posMenu.Bottom.bMinus)
				{
					nOffsetY = -rcMenu.Height();
				}
				rcMenu.OffsetRect(nOffsetX, nOffsetY);
				pDuiMenu->MoveWindow(rcMenu);
			}
			pDuiMenu->ShowWindow(SW_SHOW);
			pDuiMenu->SetAutoClose(TRUE);
		}
	}else
	if(m_strAction.Find(_T("link:")) == 0)	// 动作:打开一个页面链接
	{
		if(uMsg == MSG_BUTTON_UP)	// 鼠标放开事件才处理
		{
			CString strLink = m_strAction;
			strLink.Delete(0, 5);
			if(!strLink.IsEmpty())
			{
				ShellExecute(NULL, TEXT("open"), strLink, NULL,NULL,SW_NORMAL);
			}
		}
	}else
	if(m_strAction.Find(_T("run:")) == 0)	// 动作:执行一个进程
	{
		if(uMsg == MSG_BUTTON_UP)	// 鼠标放开事件才处理
		{
			CString strProcess = m_strAction;
			strProcess.Delete(0, 4);
			strProcess.MakeLower();
			if(!strProcess.IsEmpty())
			{
				strProcess.MakeLower();
				BOOL bForceAdmin = FALSE;
				if(strProcess.Find(_T("admin@")) == 0)
				{
					bForceAdmin = TRUE;
					strProcess.Delete(0, 6);
				}
				BOOL bWaitProcess = FALSE;
				if(strProcess.Find(_T("&")) == (strProcess.GetLength()-1))
				{
					bWaitProcess = TRUE;
					strProcess.Delete(strProcess.GetLength()-1, 1);
				}
				if(strProcess.Find(_T(".exe")) == -1)
				{
					strProcess = DuiSystem::Instance()->GetString(strProcess);
				}
				if(strProcess.Find(_T("{platpath}")) == 0)
				{
					strProcess.Delete(0, 10);
					strProcess = DuiSystem::GetExePath() + strProcess;
				}
				CString strCmdLine = _T("");
				int nPos = strProcess.Find(_T("|"));
				if(nPos != -1)
				{
					strCmdLine = strProcess;
					strCmdLine.Delete(0, nPos+1);
					strProcess = strProcess.Left(nPos);
				}
				DuiSystem::PathCanonicalize(strProcess);	// 路径标准化
				DuiSystem::ExecuteProcess(strProcess, strCmdLine, bForceAdmin, bWaitProcess);
			}
		}
	}else
	if(m_strAction.Find(ACTION_CLOSE_WINDOW) == 0)	// 动作:关闭指定的窗口
	{
		if(uMsg == MSG_BUTTON_UP)	// 鼠标放开事件才处理
		{
			CString strWndName = m_strAction;
			strWndName.Delete(0, 13);
			if(!strWndName.IsEmpty())
			{
				CDlgBase* pDlg = DuiSystem::Instance()->GetDuiDialog(strWndName);
				if(pDlg != NULL)
				{
					//pDlg->DoClose();
					pDlg->PostMessage(WM_QUIT, 0, 0);
				}
			}
		}
	}else
	{
		// 首先判断如果是几个默认按钮,则直接做相应的处理
		CDlgBase* pParentDlg = GetParentDialog();
		if(IsThisObject(BT_OK, NAME_BT_OK))
		{
			if((MSG_BUTTON_UP == uMsg) && (pParentDlg != NULL)) { pParentDlg->DoOK(); }
		}else
		if(IsThisObject(BT_CANCEL, NAME_BT_CANCEL))
		{
			if((MSG_BUTTON_UP == uMsg) && (pParentDlg != NULL)) { pParentDlg->DoCancel(); }
		}else
		if(IsThisObject(BT_YES, NAME_BT_YES))
		{
			if((MSG_BUTTON_UP == uMsg) && (pParentDlg != NULL)) { pParentDlg->DoYes(); }
		}else
		if(IsThisObject(BT_NO, NAME_BT_NO))
		{
			if((MSG_BUTTON_UP == uMsg) && (pParentDlg != NULL)) { pParentDlg->DoNo(); }
		}else
		{
			// 调用控件的DUI事件处理对象
			return CallDuiHandler(uMsg, wParam, lParam);
		}
	}

	return 0;
}