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

📄 sortlistctrl.cpp

📁 ◆◆◆ 《投掷飞镖记分工具》◆◆◆ 操作系统 : Windows Mobile 5.0 说明 : 中秋节和家人赏月
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	if ( !bInsertNorOK && !bInsertSmalOK )
		return FALSE;

	return TRUE;
}

BOOL CSortListCtrl::InsertBmpToImageList(
		CImageList &ImgList,
		CBitmap *pbmpInsert,				// 要插入的图片
		int nWidthPerImage,					// 单张小图的宽度,用来计算图像列表中小图的个数
		COLORREF crMask/*=RGB(255,255,0)*/
)
{
	if ( !pbmpInsert || !pbmpInsert->GetSafeHandle() )
	{
		return FALSE;
	}
	
	BITMAP bm;
	pbmpInsert->GetBitmap ( &bm );
	m_nImageNum = bm.bmWidth / nWidthPerImage;

	ImgList.Add ( pbmpInsert, crMask);

	return TRUE;
}

int CSortListCtrl::GetColumnCount()
{
	return m_iNumColumns;
}

int CSortListCtrl::InsertItem(int iItem, CStringArray &StrAry, int nImageIndex)
{
	if ( iItem == -1 )
		iItem = GetItemCount();
	// Use the LV_ITEM structure to insert the items
	ASSERT ( StrAry.GetSize() == m_iNumColumns );
	LVITEM lvItem;

	CString csText;
	csText = StrAry.GetAt(0);
	LPCTSTR* arrpsz = new LPCTSTR[ m_iNumColumns ];
	arrpsz[ 0 ] = new TCHAR[ csText.GetLength() + 1 ];
	(void)lstrcpy( (TCHAR*)arrpsz[ 0 ], csText.GetBuffer(0) );

	// Insert the first item
	lvItem.mask =  LVIF_IMAGE | LVIF_TEXT;
	lvItem.iItem = iItem;
	lvItem.iSubItem = 0;
	csText = csText;
	lvItem.pszText = (LPTSTR)(LPCTSTR)( csText );
	CImageList *pImgList_Nor = GetImageList ( LVSIL_NORMAL );
	CImageList *pImgList_Sma = GetImageList ( LVSIL_SMALL );

	if ( m_nImageNum < 1 )
	{
		if ( pImgList_Nor ) m_nImageNum = pImgList_Nor->GetImageCount ();
		else if ( pImgList_Sma ) m_nImageNum = pImgList_Sma->GetImageCount ();
	}

	if ( nImageIndex < 0 ) nImageIndex = 0;
	if ( nImageIndex >= 0 && m_nImageNum > 0 )
		lvItem.iImage = nImageIndex%m_nImageNum;

	iItem = CListCtrl::InsertItem(&lvItem);

	for( int iColumn = 1; iColumn < m_iNumColumns; iColumn++ )
	{
		csText = StrAry.GetAt ( iColumn );
		ASSERT_VALID_STRING( csText.GetBuffer(0) );
		VERIFY( CListCtrl::SetItemText( iItem, iColumn, csText ) );

		arrpsz[ iColumn ] = new TCHAR[ csText.GetLength() + 1 ];
		(void)lstrcpy( (TCHAR*)arrpsz[ iColumn ], csText.GetBuffer(0) );
	}

	VERIFY( SetTextArray( iItem, arrpsz ) );

	InsertItemSuccess ( iItem );
	return iItem;
}

BOOL CSortListCtrl::RowIsExist ( CStringArray &StrAry )
{
	ASSERT ( StrAry.GetSize() == m_iNumColumns );
	for ( int nItem=0; nItem<GetItemCount(); nItem++ )
	{
		BOOL bExist = TRUE;
		for ( int nSubItem=0; nSubItem<m_iNumColumns; nSubItem++ )
		{
			CString csText = GetItemText ( nItem, nSubItem );
			if ( csText != StrAry.GetAt ( nSubItem ) )
			{
				bExist = FALSE;
				break;
			}
		}
		if ( bExist ) return TRUE;
	}

	return FALSE;
}

int CSortListCtrl::InsertItem ( int iItem, int nImageIndex, LPCTSTR pszText, ... )
{
	CStringArray StrAry;
	StrAry.Add ( pszText );

	va_list list;
	va_start( list, pszText );
	for( int iColumn = 1; iColumn < m_iNumColumns; iColumn++ )
	{
		pszText = va_arg( list, LPCTSTR );
		ASSERT_VALID_STRING( pszText );
		StrAry.Add ( pszText );
	}
	va_end( list );
	return InsertItem ( iItem, StrAry, nImageIndex );
}

//改变列表框的属性,使之具有分割线、选中时所有项高亮
void CSortListCtrl::SetListCtrlGridAttr ( BOOL bSaveTypeMask, DWORD dwInitTypeMask )
{
	DWORD dwStyle = (DWORD)SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE);
	dwStyle |= LVS_EX_HEADERDRAGDROP | LVS_EX_GRIDLINES;
	dwStyle |= LVS_EX_FULLROWSELECT;
	SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)dwStyle);
	m_bSaveTypeMask = bSaveTypeMask;
	m_dwInitTypeMask = dwInitTypeMask;
}

void CSortListCtrl::SetListView(DWORD dwView)
{
	dwView = dwView&LVS_TYPEMASK;
	DWORD dwOldStyle;
	HWND hWndList = GetSafeHwnd();
	dwOldStyle = GetWindowLong(hWndList,GWL_STYLE);
	if ( (dwOldStyle & LVS_TYPEMASK) != dwView )
	{
		dwOldStyle &= ~LVS_TYPEMASK;
		dwOldStyle |= dwView;
		SetWindowLong ( hWndList,GWL_STYLE,dwOldStyle );
	}
	m_dwInitTypeMask = dwView;
}

DWORD CSortListCtrl::GetTypeMask ()
{
	DWORD dwOldStyle;
	HWND hWndList = GetSafeHwnd();
	dwOldStyle = GetWindowLong(hWndList,GWL_STYLE);
	return (dwOldStyle& LVS_TYPEMASK);
}

BOOL CSortListCtrl::SubclassWindow()
{
	return m_ctlHeader.SubclassWindow( GetHeaderCtrl()->GetSafeHwnd() );
}

//
// 某点是否包含在某个子项目里
// return :
//		0	: 不在这个范围里
//		1	: 在这个范围里
//
int CSortListCtrl::PtInRect ( int iItem, CPoint &pt )
{
	CRect rc;
	CListCtrl::GetItemRect ( iItem, &rc, LVIR_BOUNDS );
	ClientToScreen ( &rc );
	if ( rc.PtInRect ( pt ) )
		return 1;
	return 0;
}

//
// 鼠标是否指向有效的范围,即有数据的格子里
//
BOOL CSortListCtrl::IsCursorInValidRect()
{
	BOOL bSelected = FALSE;

	if ( GetTypeMask() == LVS_REPORT )
	{
		CRect rc,rcClient;
		if ( GetItemCount() > 0 )
		{
			CListCtrl::GetItemRect ( 0, &rc, LVIR_BOUNDS );
			rcClient.top = rc.top;
			rcClient.left = rc.left;

			CListCtrl::GetItemRect ( GetItemCount()-1, &rc, LVIR_BOUNDS );
			rcClient.right = rc.right;
			rcClient.bottom = rc.bottom;
			ClientToScreen ( &rcClient );
			
			CPoint pt;
			::GetCursorPos ( &pt );
			if ( rcClient.PtInRect ( pt ) )
				bSelected = TRUE;
		}
	}
	else if ( GetItemCount() > 0 )
	{
		if ( GetSelectionMark() < 0 )
			return FALSE;
		else
		{
			CPoint pt;
			::GetCursorPos ( &pt );
			int nTopIndex = GetTopIndex();
			int nCountPerPage = GetCountPerPage();
			for ( int nRow=0; nRow<nCountPerPage; nRow++ )
			{
				int nRet = PtInRect ( nRow+nTopIndex, pt );
				if ( nRet == -1 ) return FALSE;
				else if ( nRet == 1 ) return TRUE;
			}
		}
	}
	if ( !bSelected ) SetSelectionMark ( -1 );
	return bSelected;
}

BOOL CSortListCtrl::GetCurSelAllSubItemText(CStringArray &StrAry)
{
	int iItem = GetSelectionMark();
	if ( iItem < 0 || iItem >= GetItemCount() )
		return FALSE;
	if ( m_nLastSelItem == iItem )
		return FALSE;
	m_nLastSelItem = iItem;

	CString csText;
	for ( int i=0; i<GetColumnCount(); i++ )
	{
		StrAry.Add ( GetItemText ( iItem, i ) );
	}
	return TRUE;
}

CString CSortListCtrl::GetItemText(int iItem, int nSubItem) const
{
	if ( iItem < 0 ) return _T("ItemError");
	if ( nSubItem < 0 ) return _T("SubItemError");
	LPCTSTR* arrpsz = GetTextArray( iItem );
	LPCTSTR pszText = arrpsz[ nSubItem ];

	return GET_SAFE_STRING ( pszText );
}

BOOL CSortListCtrl::SetItemText( int iItem, int nSubItem, LPCTSTR lpszText )
{
	if ( iItem < 0 || nSubItem < 0 ) return FALSE;
	if( !CListCtrl::SetItemText( iItem, nSubItem, lpszText ) )
		return FALSE;

	LPCTSTR* arrpsz = GetTextArray( iItem );
	if ( !arrpsz ) return FALSE;
	LPCTSTR pszText = arrpsz[ nSubItem ];
	delete[] pszText;
	pszText = new TCHAR[ lstrlen( lpszText ) + 1 ];
	(void)lstrcpy( (TCHAR*)pszText, lpszText );
	arrpsz[ nSubItem ] = pszText;

	return TRUE;
}

BOOL CSortListCtrl::SetItemText( int iItem, CStringArray &StrAry )
{
	if ( iItem < 0 || iItem >= GetItemCount() ) return FALSE;
	ASSERT ( StrAry.GetSize() == m_iNumColumns );
	for ( int i=0; i<m_iNumColumns; i++ )
	{
		SetItemText ( iItem, i, StrAry.GetAt(i) );
	}
	return TRUE;
}

//
// 改变一行的图标,注意:要少用,因为这个函数实际上就是将原来
// 一行删除再添加的,所以操作比较慢
//
void CSortListCtrl::ChangeItemImage(int iItem, int nNewImageIndex)
{
	SetRedraw ( FALSE );
	CStringArray StrAry;
	StrAry.Add ( GetItemText ( iItem, 0 ) );

	UINT nItemState = GetItemState ( iItem, LVIS_SELECTED );
	ASSERT ( iItem>=0 && iItem<GetItemCount() );
	for( int iColumn = 1; iColumn < m_iNumColumns; iColumn++ )
	{
		StrAry.Add ( GetItemText ( iItem, iColumn ) );
	}

	CUIntArray UIntAry_ItemData;
	for ( int i=0; i<MAX_ITEMDATA_COUNT; i++ )
	{
		UIntAry_ItemData.Add ( GetItemData ( iItem, i ) );
	}
	
	DeleteItem ( iItem, FALSE );
	iItem = InsertItem ( iItem, StrAry, nNewImageIndex );

	for ( int i=0; i<MAX_ITEMDATA_COUNT; i++ )
	{
		SetItemData ( iItem, UIntAry_ItemData.GetAt(i), i );
	}
	SetItemState ( iItem, nItemState, LVIS_SELECTED );
	SetRedraw ( TRUE );
}

int CSortListCtrl::GetSelectionMark()
{
	m_nCurSelItem = CListCtrl::GetSelectionMark();
	return m_nCurSelItem;
}

void CSortListCtrl::ReSizing()
{
	if ( !::IsWindow(m_hWnd) ) return;

	CRect rcParent;
	CWnd *pWnd = GetParent();
	ASSERT ( pWnd );
	pWnd->GetClientRect ( &rcParent );
	MoveWindow ( &rcParent );
}

void CSortListCtrl::OnCustomdrawList(NMHDR *pNMHDR, LRESULT *pResult)
{
	NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
	
    // Take the default processing unless we set this to something else below.
    *pResult = 0;
	
    // First thing - check the draw stage. If it's the control's prepaint
    // stage, then tell Windows we want messages for every item.
    if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
	{
        *pResult = CDRF_NOTIFYITEMDRAW;
	}
    else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
	{
        // This is the prepaint stage for an item. Here's where we set the
        // item's text color. Our return value will tell Windows to draw the
        // item itself, but it will use the new color we set here.
        // We'll cycle the colors through red, green, and light blue.
		if ( GetItemCount() > 0 )
		{
			int iItem = pLVCD->nmcd.dwItemSpec;
			if ( iItem < GetItemCount() )
			{
				ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( iItem ) );
				if ( pid )
				{
					if ( pid->pAppItemData )
					{
						pLVCD->clrText = pid->pAppItemData->clrItemText;
						pLVCD->clrTextBk = pid->pAppItemData->clrItemBK;
					}
				}
			}
		}
        // Tell Windows to paint the control itself.
        *pResult = CDRF_DODEFAULT;
	}
}

//
// 改变一行的颜色,有些skin库可能会将 NM_CUSTOMDRAW 通知拦截了而导致该函数不能生效
//
void CSortListCtrl::ChangeLineColor(int iItem, COLORREF clrText, COLORREF clrTextBk/*=CLR_NONE*/)
{
	ASSERT ( iItem >= 0 && iItem < GetItemCount() );
	if ( clrText == clrTextBk )
	{
		clrText = GetInverseColor ( clrTextBk );
	}
	
	CSortListCtrl::t_ItemAppData ItemAppData;
	GetItemAppData ( iItem, ItemAppData );

	if ( clrText != CLR_NONE )
		ItemAppData.clrItemText = clrText;
	if ( clrTextBk != CLR_NONE )
		ItemAppData.clrItemBK = clrTextBk;
	SetItemAppData ( iItem, ItemAppData );

	RedrawItems ( iItem, iItem );
}

void CSortListCtrl::GetLineColor ( int iItem, COLORREF &clrText, COLORREF &clrTextBk )
{
	ASSERT ( iItem >= 0 && iItem < GetItemCount() );	
	CSortListCtrl::t_ItemAppData ItemAppData;
	GetItemAppData ( iItem, ItemAppData );

	clrText = ItemAppData.clrItemText;
	clrTextBk = ItemAppData.clrItemBK;
}

void CSortListCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult) 
{	
	*pResult = 0;

	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

	m_nCurSelItem = pNMListView->iItem;
	m_nCurSelSubItem = pNMListView->iSubItem;
	
	if ( !ModifySelItemContent ( m_nCurSelItem, m_nCurSelSubItem ) )
	{
		CWnd* pWnd = GetParent();
		if ( pWnd )
			pWnd->SendMessage ( WM_ITEM_CLICK, (WPARAM)pNMHDR );
	}
}

BOOL CSortListCtrl::ModifySelItemContent ( int iItem, int nSubItem )
{
	m_nCurSelItem = iItem;
	m_nCurSelSubItem = nSubItem;
	if ( m_nCurSelSubItem < 0 || m_nCurSelSubItem >= m_iNumColumns )
		return FALSE;
	
	// Make sure that the item is visible
	if ( !EnsureVisible ( m_nCurSelItem, TRUE ) )
	{
		return FALSE;
	}
	// 是禁止编辑的项
	if ( !CanEdit ( iItem ) ) return FALSE;

	E_COLUMN_TYPE eColumnType = E_COLUMN_TYPE_INVALID;
	int nRet = GetParent()->SendMessage ( WM_ITEM_ClickSubItem, WPARAM(m_nCurSelItem), LPARAM(m_nCurSelSubItem) );
	// 被父窗口处理了,所以我不管了
	if ( nRet == E_COLUMN_TYPE_NORMAL )
	{
		return FALSE;
	}
	// 父窗口告诉我应该画何种控件
	else if ( nRet > E_COLUMN_TYPE_NORMAL )
	{
		eColumnType = (E_COLUMN_TYPE)nRet;
	}
	// 父窗口根本没理会这条消息
	else
	{
		eColumnType = (E_COLUMN_TYPE)m_UIntAry_ColumnType.GetAt( m_nCurSelSubItem );
	}

	m_StrAry_CommonText.RemoveAll();
	if	(
			m_Callback_ListCtrl_AddListString
			&&
			(
				eColumnType == E_COLUMN_TYPE_MENU ||
				eColumnType == E_COLUMN_TYPE_COMBO
			)
		)
	{
		m_Callback_ListCtrl_AddListString ( m_nCurSelItem, m_nCurSelSubItem, &m_StrAry_CommonText, eColumnType, NULL );
	}

	if ( eColumnType == E_COLUMN_TYPE_COMBO )
	{
		ComboItem ( m_nCurSelItem, m_nCurSelSubItem, m_StrAry_CommonText );
	}
	else if ( eColumnType == E_COLUMN_TYPE_MENU )
	{
		PopupMenuItem ( m_nCurSelItem, m_nCurSelSubItem, m_StrAry_CommonText );
	}
	else if ( eColumnType == E_COLUMN_TYPE_EDIT )
	{
		EditItem ( m_nCurSelItem, m_nCurSelSubItem );
	}
	else return FALSE;

	return TRUE;
}

void CSortListCtrl::PopupMenuItem(int iItem, int nSubItem, CStringArray &StrAry)
{
	// Make sure that the item is visible
	if( !EnsureVisible ( iItem, TRUE ) )
	{
		return;
	}
	CRect rect;
	GetItemExposeRect ( iItem, nSubItem, rect );
	CPoint pt ( rect.left, rect.bottom );
	ClientToScreen ( &pt );
//	GenerateAndPopupMenuXP ( StrAry, SORTLISTCTRL_START_MENU_ID, this, &pt );
}

BOOL CSortListCtrl::OnCommand(WPARAM wParam, LPARAM lParam) 
{
	if ( wParam >= SORTLISTCTRL_START_MENU_ID )
	{
		int nMenuIndex = wParam-SORTLISTCTRL_START_MENU_ID;
		if ( nMenuIndex < m_StrAry_CommonText.GetSize() &&
			m_nCurSelItem >= 0 && m_nCurSelSubItem >= 0 )
		{
			SetItemText ( m_nCurSelItem, m_nCurSelSubItem, 
				m_StrAry_CommonText.GetAt ( nMenuIndex ) );
		}
	}
	return CListCtrl::OnCommand(wParam, lParam);
}

void CSortListCtrl::SetColumnType(E_COLUMN_TYPE eColumnType, int nCol, LPVOID lpParameter/*=NULL*/)
{
	ASSERT ( nCol >= 0 && nCol < m_iNumColumns );
	ASSERT ( m_iNumColumns == m_UIntAry_ColumnType.GetSize() );
	ASSERT ( eColumnType >= E_COLUMN_TYPE_NORMAL && eColumnType < E_COLUMN_TYPE_NUM );
	m_UIntAry_ColumnType.SetAt ( nCol, eColumnType );

}

void CSortListCtrl::SetColumnType(E_COLUMN_TYPE eColumnType, LPCTSTR lpszColumnText, LPVOID lpParameter/*=NULL*/)
{
	int nCol = GetColumnIndexByText ( lpszColumnText );
	SetColumnType ( eColumnType, nCol, lpParameter );
}

int CSortListCtrl::GetColumnIndexByText(LPCTSTR lpszColumnText)
{
	ASSERT ( lpszColumnText );
	for ( int i=0; i<m_iNumColumns; i++ )
	{
		if ( lstrcmpi ( GetColumnText(i), lpszColumnText ) == 0 )
			return i;
	}

	return -1;
}

CString CSortListCtrl::GetColumnText ( int nCol )
{
	ASSERT ( nCol >= 0 && nCol < GetColumnCount() );
	TCHAR szText[1024] = {0};
	LV_COLUMN lvCol;
	memset ( &lvCol, 0, sizeof(LV_COLUMN) );
	lvCol.mask = LVCF_TEXT;
	lvCol.pszText = szText;
	lvCol.cchTextMax = sizeof(szText);
	lvCol.iSubItem = nCol;
	if ( GetColumn ( nCol, &lvCol ) )
	{
		return lvCol.pszText;
	}

	return _T("");
}

void CSortListCtrl::SetColumnText ( int nCol, CString csNewColText )
{
	ASSERT ( nCol >= 0 && nCol < GetColumnCount() );
	TCHAR szText[1024] = {0};
	LV_COLUMN lvCol;
	memset ( &lvCol, 0, sizeof(LV_COLUMN) );

⌨️ 快捷键说明

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