Artigo: 250614 - Última revisão: terça-feira, 21 de Novembro de 2006 - Revisão: 1.2

Como ordenar itens numa CListCtrl na vista de relatório

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.
Expandir tudo | Reduzir tudo

Sumário

Não é a quantidade de informações forneceu para o processo de ordenar itens num controlo ListView, especialmente um moldado pela classe CListCtrl MFC. Os detalhes são fáceis de implementar e este artigo tenta preencher o intervalo na documentação para esta funcionalidade útil. O código de exemplo representa uma caixa de diálogo de MFC com um controlo de lista definido para o estilo LVS_REPORT.

Mais Informação

Para ordenar os itens num controlo ListView, tem de existir uma estrutura LVITEM associada ao produto. MFC fornece este para o programador, permitindo que um item a ser inserida através de uma chamada de função InsertItem(int nItem, LPCTSTR lpszItem) simples que cria a estrutura com predefinições razoáveis. Por vezes, pode ser enganadora tal uma memória intermédia de complexidade subjacente. No entanto, a estrutura LVITEM é uma chave importante para manipulação de itens ListView, incluindo o mecanismo de ordenação.

O elemento lParam LVITEM fornece informações necessárias. Quando a função SortItems classe CListCtrl é chamada, tem de fornecer um apontador de função para uma função de chamada de retorno de ordenação e um valor DWORD definidas pela aplicação. Durante a ordenação, a função de chamada de retorno repetidamente é invocada como dois itens do controlo de lista são seleccionados para comparação. Os parâmetros que recebe são o elemento lParam de LVITEM estrutura cada item e o valor DWORD transmitido pela chamada SortItems .

O código abaixo representa um exemplo simples de ordenar uma lista dos dez dos Estados Unidos CEOs num controlo ListView. Os CEOs inicialmente são armazenados numa matriz CString multidimensional estática.

static CString strData[10][3] =
{
	{ _T("Washington"), _T("George"), _T("1789-1797") },
	{ _T("Adams"), _T("John"), _T("1797-1801") },
	{ _T("Jefferson"), _T("Thomas"), _T("1801-1809") },
	{ _T("Madison"), _T("James"), _T("1809-1817") },
	{ _T("Monroe"), _T("James"), _T("1817-1825") },
	{ _T("Adams"), _T("John Quincy"), _T("1825-1829") },
	{ _T("Jackson"), _T("Andrew"), _T("1829-1837") },
	{ _T("Van Buren"), _T("Martin"), _T("1837-1841") },
	{ _T("Harrison"), _T("William Henry"), _T("1841") },
	{ _T("Tyler"), _T("John"), _T("1841-1845") }
};
				

A função de ordenação de chamada de retorno pode estar definida estaticamente como um membro de uma classe ou, como aqui apenas como uma função global:
int CALLBACK SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
				

O elemento lParam pode ser qualquer coisa desde simples para muito complexos. Frequentemente, uma estrutura é útil neste contexto, permitindo várias partes de dados a ser referenciada. Neste exemplo, uma estrutura chamada ITEMDATA foi definida para manter os três elementos que compõem um determinado item:
typedef struct {
	LPTSTR pszLastName;
	LPTSTR pszFirstName;
	LPTSTR pszTerm;
} ITEMDATA, *PITEMDATA;
				

Neste exemplo, a estrutura tiver sido definida no ficheiro de cabeçalho de uma classe CDialog , pelo que foi definida uma variável de membro de um ponteiro para uma matriz de 10:
	ITEMDATA* m_pData[10];
				

Um controlo ListView foi adicionado a uma caixa de diálogo e uma variável de membro definida chamado m_ctlListView. Os itens foram adicionados no OnInitDialog :

	m_ctlListView.InsertColumn(0, _T("Last Name"), LVCFMT_LEFT, 100);
	m_ctlListView.InsertColumn(1, _T("First Name"), LVCFMT_LEFT, 100);
	m_ctlListView.InsertColumn(2, _T("Term"), LVCFMT_LEFT, 100);

	for (int i=0; i<10; i++)
	{
		m_pData[i] = new ITEMDATA;
		m_pData[i]->pszLastName = (LPTSTR)(LPCTSTR)strData[i][0];
		m_pData[i]->pszFirstName = (LPTSTR)(LPCTSTR)strData[i][1];
		m_pData[i]->pszTerm = (LPTSTR)(LPCTSTR)strData[i][2];

		m_ctlListView.InsertItem(i, strData[i][0]);
		m_ctlListView.SetItemText(i, 1, strData[i][1]);
		m_ctlListView.SetItemText(i, 2, strData[i][2]);
		m_ctlListView.SetItemData(i, (LPARAM)m_pData[i]);
	}
				

Foram inseridas três colunas para o último nome, nome próprio e termo do escritório. Em seguida, para cada um dos dez itens, uma nova estrutura ITEMDATA está atribuída e inicializada da matriz CString. O produto é inserido muito simples, utilizando apenas o índice e a última cadeia do nome, em seguida, o texto está definido para as outras duas colunas do produto. Finalmente, a função SetItemData é chamado, passando ITEMDATA novo como um parâmetro. Isto reinicializa lParam da estrutura LVITEM do produto e prepara a forma para a ordenação.

MFC no Visual C++ 6.0 tem um problema com as notificações de cabeçalho para o controlo de ListView. Apesar de uma rotina de tratamento pode ser adicionada, na versão actual esta não é chamada. Por exemplo, utilize o Assistente de classe ou o WizardBar para adicionar um processador de mensagens do Windows. Se o ID de Controlo ListView estiver realçado, um número de mensagens de notificação está disponível para selecção. Para ordenar os itens quando o cabeçalho é clicado para uma determinada coluna, seleccione a notificação HDN_ITEMCLICK . Uma entrada de mapa de mensagem ON_NOTIFY é gerada, bem como uma função do processador. Por exemplo actual, aparece a entrada da seguinte forma:

	ON_NOTIFY(HDN_ITEMCLICK, IDC_LIST1, OnItemclickList1)
				

Aqui o problema é que a notificação não realmente provêm do controlo ListView; em vez disso, o controlo de cabeçalho criado por ListView envia a notificação. A entrada de mapa de mensagem listada acima não funciona. A correcção é simples, no entanto, uma vez que o controlo de cabeçalho tem sempre um ID de 0, a macro pode ser editada para funcionar correctamente:
	ON_NOTIFY(HDN_ITEMCLICK, 0, OnItemclickList1)
				

Em seguida, no processador de OnItemclickList1, é efectuada a chamada SortItems :
void CSortListDlg::OnItemclickList1(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NMLISTVIEW *pLV = (NMLISTVIEW *) pNMHDR;
	
	m_ctlListView.SortItems(SortFunc, pLV->iItem);
	
	*pResult = 0;
}
				

O cabeçalho de mensagem de notificação ( NMHDR ) é realmente uma notificação ListView, NMLISTVIEW , que contém o índice para a coluna que foi clicado. Neste exemplo, isto é representado por iItem . Listas mais complexas ser necessário referenciar o elemento iSubItem desta estrutura bem. O endereço da função de chamada de retorno é transmitido ao SortItems , juntamente com o número da coluna que foi clicado.

A rotina SortFunc é designado por repetidamente como pares de itens a ListView são transmitidos para a função de comparação. Os primeiros dois parâmetros são o elemento lParam da estrutura LVITEM dos respectivos itens e o terceiro parâmetro (definidas pelo aplicação) é o número de coluna fornecido na chamada SortItems .
int CALLBACK SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
	int nRetVal;

	PITEMDATA pData1 = (PITEMDATA)lParam1;
	PITEMDATA pData2 = (PITEMDATA)lParam2;


	switch(lParamSort)
	{
	case 0:	// Last Name
		nRetVal = strcmp(pData1->pszLastName,
                                 pData2->pszLastName);
		break;

	case 1:	// First Name
		nRetVal = strcmp(pData1->pszFirstName,
                                 pData2->pszFirstName);
		break;

	case 2: // Term
		nRetVal = strcmp(pData1->pszTerm, pData2->pszTerm);
		break;

	default:
		break;
	}

	return nRetVal;
}
				

O índice de coluna transmitido lParamSort determina o elemento de objectos ITEMDATA transmitido lParam1 e lParam2 deve ser utilizado para comparação. O resultado é devolvido e o processo continua até tem sido ordenados todos os itens.

Como um lembrete, as estruturas ITEMDATA que foram atribuídas os itens da lista tem de eventualmente ser destruído. Neste exemplo, o processador WM_DESTROY a caixa de diálogo itera através dos elementos membro e elimina-os.
	for (int i=0; i<10; i++)
		delete m_pData[i];
				

Referências

Para mais informações no controlo ListView comuns, consulte a documentação do Platform SDK em Controlos comuns do Windows na secção Serviços de interface de utilizador .

A informação contida neste artigo aplica-se a:
  • Microsoft Foundation Class Library 4.2
Palavras-chave: 
kbmt kbcmnctrls kbctrl kbhowto kblistview KB250614 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 250614  (http://support.microsoft.com/kb/250614/en-us/ )
Retired KB ArticleExclusão de Responsabilidade para Conteúdo sem Suporte na KB
Este artigo foi escrito sobre produtos para os quais a Microsoft já não fornece suporte. Por conseguinte, este artigo é oferecido "tal como está" e deixará de ser actualizado.