⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 doublelistpicker.cpp

📁 一个可以管理当前窗口显示和隐藏的完整程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	else
	{
		m_labelTitle.ShowWindow(SW_HIDE);
		nTitleLabelGap = EDGE_GAP_Y;
	}

	if (! m_bHorizontal)
	{
		// something like this:
		// title
		// label1		label2
		//   |		btn1	  |
		// list1	btn2	list2
		//   |		btn3	  |
		//   |		btn4	  |
		if (! m_sLabelLeft.IsEmpty() || ! m_sLabelRight.IsEmpty())
		{
			// put labels at the top, offset a bit, and alter rc to chop off the label heights
			int nLabelWidth = (rc.Width() - ((EDGE_GAP_X * 2) + (LIST_BTN_GAP * 2) + CX_BTN)) / 2;
			m_labelLeft.MoveWindow(rc.left + EDGE_GAP_X, rc.top + nTitleLabelGap, nLabelWidth, CY_LABEL);
			m_labelRight.MoveWindow((rc.left + rc.Width()) - (EDGE_GAP_X + nLabelWidth), rc.top + nTitleLabelGap, nLabelWidth, CY_LABEL);
			rc.top += (nTitleLabelGap + CY_LABEL);
			m_labelLeft.SetWindowText(m_sLabelLeft);
			m_labelRight.SetWindowText(m_sLabelRight);
		}

		int nCentreX = rc.left + (rc.Width() / 2);
		int nCentreY = ((rc.Height() - (nTitleLabelGap + LABEL_LIST_GAP)) / 2);

		// put the buttons in the middle left-to-right
		m_btnMoveRight.MoveWindow(nCentreX - (CX_BTN / 2), rc.top + (nCentreY - ((CY_BTN * 2) + BTN_BTN_GAP_SML + (BTN_BTN_GAP / 2))), CX_BTN, CY_BTN);
		m_btnMoveAllRight.MoveWindow(nCentreX - (CX_BTN / 2), rc.top + (nCentreY - (CY_BTN + (BTN_BTN_GAP / 2))), CX_BTN, CY_BTN);
		m_btnMoveLeft.MoveWindow(nCentreX - (CX_BTN / 2), rc.top + (nCentreY + (BTN_BTN_GAP / 2)), CX_BTN, CY_BTN);
		m_btnMoveAllLeft.MoveWindow(nCentreX - (CX_BTN / 2), rc.top + (nCentreY + (CY_BTN + BTN_BTN_GAP_SML + (BTN_BTN_GAP / 2))), CX_BTN, CY_BTN);

		// put lists one either side beside buttons
		int nListHeight = rc.Height() - (EDGE_GAP_Y + LABEL_LIST_GAP);
		int nListWidth = (rc.Width() - ((EDGE_GAP_X * 2) + (LIST_BTN_GAP * 2) + CX_BTN)) / 2;
		m_listLeft.MoveWindow(rc.left + EDGE_GAP_X, rc.top + LABEL_LIST_GAP, nListWidth, nListHeight);
		m_listRight.MoveWindow(rc.right - (nListWidth + EDGE_GAP_X), rc.top + LABEL_LIST_GAP, nListWidth, nListHeight);
	}
	else
	{
		// something like this:
		// title
		// labelleft
		// listleft
		//    btn1 btn2   btn3 btn4
		// labelright
		// listright
		CPoint ptCentre = rc.CenterPoint();
		int nCentreX = ptCentre.x;
		int nCentreY = nTitleLabelGap + ((rc.Height() - (nTitleLabelGap + LABEL_LIST_GAP)) / 2);

		int nLabelHeightLeft = m_sLabelLeft.IsEmpty() ? 0 : CY_LABEL;
		int nLabelHeightRight = m_sLabelRight.IsEmpty() ? 0 : CY_LABEL;

		// put the buttons in the middle top-to-bottom
		m_btnMoveRight.MoveWindow(nCentreX - ((CX_BTN * 2) + BTN_BTN_GAP_SML + (BTN_BTN_GAP / 2)), 
					  rc.top + (nCentreY - (CY_BTN / 2)), 
					  CX_BTN, CY_BTN);
		m_btnMoveAllRight.MoveWindow(nCentreX - (CX_BTN + (BTN_BTN_GAP / 2)), 
					     rc.top + (nCentreY - (CY_BTN / 2)), 
					     CX_BTN, CY_BTN);
		m_btnMoveLeft.MoveWindow(nCentreX + (BTN_BTN_GAP / 2), 
					 rc.top + (nCentreY - (CY_BTN / 2)), 
					 CX_BTN, CY_BTN);
		m_btnMoveAllLeft.MoveWindow(nCentreX + (CX_BTN + BTN_BTN_GAP_SML + (BTN_BTN_GAP / 2)), 
					    rc.top + (nCentreY - (CY_BTN / 2)), 
					    CX_BTN, CY_BTN);

		if (nLabelHeightLeft != 0)
			nLabelHeightLeft += LABEL_LIST_GAP;
		if (nLabelHeightRight != 0)
			nLabelHeightRight += LABEL_LIST_GAP;

		// put lists one at top, other at bottom, above and below buttons
		int nListHeight = (rc.Height() - ((EDGE_GAP_Y * 2) + (LIST_BTN_GAP * 2) + CY_BTN)) / 2;
		int nListWidth = rc.Width();
		m_listLeft.MoveWindow(rc.left + EDGE_GAP_X, rc.top + nTitleLabelGap + nLabelHeightLeft, nListWidth, nListHeight - nLabelHeightLeft);
		m_listRight.MoveWindow(rc.left + EDGE_GAP_X, (rc.bottom - (nListHeight + LABEL_LIST_GAP)) + nLabelHeightRight, nListWidth, nListHeight - nLabelHeightRight);

		if (! m_sLabelLeft.IsEmpty() || ! m_sLabelRight.IsEmpty())
		{
			// put labels above lists top, full width
			m_labelLeft.MoveWindow(rc.left + EDGE_GAP_X, rc.top + nTitleLabelGap, nListWidth, CY_LABEL);
			m_labelRight.MoveWindow(rc.left + EDGE_GAP_X, rc.bottom - nListHeight, nListWidth, CY_LABEL);
			m_labelLeft.SetWindowText(m_sLabelLeft);
			m_labelRight.SetWindowText(m_sLabelRight);
		}
	}

	// redraw self and the controls
	RedrawWindow();
	for (int n = 0; n < NUM_CTRLS; n++)
		m_apCtrls[n]->RedrawWindow();
}

void CDoubleListPicker::PreSubclassWindow() 
{
	CStatic::PreSubclassWindow();

	// grab the static text for the title, and clear the static text
	GetWindowText(m_sTitle);
	SetWindowText("");

	// remove edges used to locate control in resource editor
	// remove or modify this line if you really want the control
	// to have client or static edges
	ModifyStyleEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, 0);

	CreateChildControls();

	DoSizing();
}

void CDoubleListPicker::MoveListItems(BOOL bRightToLeft/*=FALSE*/, BOOL bAll/*=FALSE*/)
{
	CListBox& listFrom = GetListCtrl(! bRightToLeft);
	CListBox& listTo = GetListCtrl(bRightToLeft);

	// get the selected item in listLeft, and move to list 2
	int nSelCount = bAll ? listFrom.GetCount() : listFrom.GetSelCount();
	if (nSelCount <= 0)
		return;
	int* pnSels = new int[nSelCount];
	if (bAll)
		for (int n = 0; n < nSelCount; n++) pnSels[n] = n;
	else
		listFrom.GetSelItems(nSelCount, pnSels);
	for (int n = 0; n < nSelCount; n++)
	{
		CString sText;
		listFrom.GetText(pnSels[n], sText);
		int nIndex = listTo.AddString(sText);
		listTo.SetItemData(nIndex, listFrom.GetItemData(pnSels[n]));
	}
	// delete items copied - need to do in reverse order
	for (n = nSelCount - 1; n >= 0; n--)
		listFrom.DeleteString(pnSels[n]);
	delete [] pnSels;
}

void CDoubleListPicker::OnControlNotification(UINT nID, UINT nCode)
{
	switch (nCode)
	{
	case BN_CLICKED:
		switch (nID)
		{
		case ID_BTN_MOVE_RIGHT: MoveListItems(); break;
		case ID_BTN_MOVE_ALL_RIGHT: MoveListItems(FALSE, TRUE); break;
		case ID_BTN_MOVE_LEFT: MoveListItems(TRUE); break;
		case ID_BTN_MOVE_ALL_LEFT: MoveListItems(TRUE, TRUE); break;
		}
		break;
	case LBN_DBLCLK:
		switch (nID)
		{
		case ID_LIST_LEFT: MoveListItems(); break;
		case ID_LIST_RIGHT: MoveListItems(TRUE); break;
		}
		break;
	}
}

CListBox& CDoubleListPicker::GetListCtrl(BOOL bLeft/*=TRUE*/) const
{
	if (bLeft)
		return (CListBox&)m_listLeft;
	return (CListBox&)m_listRight;
}

CStatic& CDoubleListPicker::GetLabelCtrl(BOOL bLeft/*=TRUE*/) const
{
	if (bLeft)
		return (CStatic&)m_labelLeft;
	return (CStatic&)m_labelRight;
}

CStatic& CDoubleListPicker::GetTitleCtrl() const
{
	return (CStatic&)m_labelTitle;
}

void CDoubleListPicker::SetLabels(LPCSTR lpszLabelLeft, LPCSTR lpszLabelRight)
{
	m_sLabelLeft = lpszLabelLeft;
	m_sLabelRight = lpszLabelRight;
	if (m_listLeft.GetSafeHwnd() != NULL)
		m_labelLeft.SetWindowText(m_sLabelLeft);
	if (m_listRight.GetSafeHwnd() != NULL)
		m_labelRight.SetWindowText(m_sLabelRight);

	// new text may mean that the control is no longer needed
	// or simply that its size has changed, so do resizing
	if (GetSafeHwnd() == NULL)
		return;

	DoSizing();
}

void CDoubleListPicker::SetTitle(LPCSTR lpszTitle/*=NULL*/)
{
	m_sTitle = lpszTitle;

	if (m_labelTitle.GetSafeHwnd() == NULL)
		return;
	m_labelTitle.SetWindowText(m_sTitle);

	// new text may mean that the control is no longer needed
	// or simply that its size has changed, so do resizing
	DoSizing();
}

void CDoubleListPicker::RecreateList(BOOL bLeft)
{
	CListBox& list = GetListCtrl(bLeft);
	BOOL bSort = m_bSortListLeft;
	BOOL bMultiSel = m_bMultiSelLeft;
	if (! bLeft)
	{
		bSort = m_bSortListRight;
		bMultiSel = m_bMultiSelRight;
	}
	if (list.GetSafeHwnd() != NULL)
	{
		list.ModifyStyle(bSort ? 0 : LBS_SORT, bSort ? LBS_SORT : 0);
		list.ModifyStyle(bMultiSel ? 0 : LBS_EXTENDEDSEL, bMultiSel ? LBS_EXTENDEDSEL : 0);
		list.ModifyStyle(0, WS_VSCROLL);
		RecreateListBox(&list);
	}
}

void CDoubleListPicker::SetListSort(BOOL bLeft, BOOL bSort)
{
	if (bLeft)
		m_bSortListLeft = bSort;
	else
		m_bSortListRight = bSort;
	RecreateList(bLeft);
}

void CDoubleListPicker::SetListMultiSel(BOOL bLeft, BOOL bMultiSel/*=TRUE*/)
{
	if (bLeft)
		m_bMultiSelLeft = bMultiSel;
	else
		m_bMultiSelRight = bMultiSel;
	RecreateList(bLeft);
}

int CDoubleListPicker::AddListItem(BOOL bLeft, LPCSTR lpszItem, DWORD dwData)
{
	CListBox& list = GetListCtrl(bLeft);
	int nIndex = list.AddString(lpszItem);
	if (nIndex != -1)
		list.SetItemData(nIndex, dwData);
	return nIndex;
}

// add item to list, and return index of new item
int CDoubleListPicker::AddListItem(BOOL bLeft, LPCSTR lpszItem, LPVOID lpData)
{
	return AddListItem(bLeft, lpszItem, (DWORD)lpData);
}

// add items in slistItems to list, and return number added
int CDoubleListPicker::AddListItems(BOOL bLeft, const CStringList& slistItems)
{
	CListBox& list = GetListCtrl(bLeft);
	POSITION pos = slistItems.GetHeadPosition();
	while (pos != NULL)
		list.AddString(slistItems.GetNext(pos));
	return slistItems.GetCount();
}

// add items in saItems to list, and return number added
int CDoubleListPicker::AddListItems(BOOL bLeft, const CStringArray& saItems)
{
	CListBox& list = GetListCtrl(bLeft);
	int nNumItems = saItems.GetSize();
	for (int n = 0; n < nNumItems; n++)
		list.AddString(saItems.GetAt(n));
	return nNumItems;
}

// get items in list and add them to slistItems, and return number added
int CDoubleListPicker::GetListItems(BOOL bLeft, CStringList &slistItems) const
{
	CListBox& list = GetListCtrl(bLeft);
	int nNumItems = list.GetCount();
	for (int n = 0; n < nNumItems; n++)
	{
		CString sText;
		list.GetText(n, sText);
		slistItems.AddTail(sText);
	}
	return nNumItems;
}

// get items in list and add them to slistItems, and return number added
int CDoubleListPicker::GetListItems(BOOL bLeft, CStringArray &saItems) const
{
	CListBox& list = GetListCtrl(bLeft);
	int nNumItems = list.GetCount();
	for (int n = 0; n < nNumItems; n++)
	{
		CString sText;
		list.GetText(n, sText);
		saItems.Add(sText);
	}
	return nNumItems;
}

// if we have the focus set to us, then we really need to
// set the focus to our first focus-able control, ie the left list
void CDoubleListPicker::OnSetFocus(CWnd* pOldWnd) 
{
	CStatic::OnSetFocus(pOldWnd);

	// set the focus to the first list
	m_listLeft.SetFocus();
}

void CDoubleListPicker::OnEnable(BOOL bEnable) 
{
	CStatic::OnEnable(bEnable);

	// enable/disable all 'child' controls
	for (int n = 0; n < NUM_CTRLS; n++)
		m_apCtrls[n]->EnableWindow(bEnable);
}

void CDoubleListPicker::OnShowWindow(BOOL bShow, UINT nStatus) 
{
	CStatic::OnShowWindow(bShow, nStatus);

	// show/hide all 'child' controls
	for (int n = 0; n < NUM_CTRLS; n++)
		m_apCtrls[n]->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
	if (m_sTitle.IsEmpty())
		m_labelTitle.ShowWindow(SW_HIDE);
}

void CDoubleListPicker::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) 
{
	CStatic::OnWindowPosChanged(lpwndpos);

	DoSizing();

	if (lpwndpos->flags & SWP_NOZORDER)
		return;

	// we may have changed z-order, so re-adjust the 'child' controls
	for (int n = 0; n < NUM_CTRLS; n++)
	  SetZOrder(m_apCtrls[n], n == 0 ? this : m_apCtrls[n - 1]);
}

LRESULT CDoubleListPicker::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	switch (message)
	{
	case WM_GETTEXTLENGTH:
	case WM_GETTEXT:
		{
			if (m_labelTitle.GetSafeHwnd() != NULL)
				m_labelTitle.SendMessage(message, wParam, lParam);
		}
		break;

	case WM_SETTEXT:
		{
			SetTitle((LPCTSTR)lParam);
		}
		break;
	};
	return CStatic::WindowProc(message, wParam, lParam);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -