Utilisation de listview, trie des elements, et style xp

Description

Ca y est j'ai decidé de mettre mon premier code, j'ai vu que les list view étaient un prob recurrent donc voili un petit code. J'ai essayé de faire simple, normalement tout est suffisamment commenté pour suivre le fil ;-).

le code en lui-meme :

-> Initialisation du controle list view
-> creation des colonnes
-> gestion des fleches sur les colonnes
-> ajout d'element
-> filtrage de la listview sur clique (colonne) (le filtrage est fait sans structure supplementaire : la listview suffit)
-> Style XP (manifest inclut a l'exe -> c'est plus propre ;-))

Pour voir comment on met en place le style XP il suffit d'editer "res.rc" et de regarder a la fin du fichier. Ca devrait vous paraitre logique.

Sinon pour les fautes d'orthographe...dsl

voila hesitez pas a poser des questions si y a des trucs qui vous paraissent louche.

Source / Exemple :


#define _WIN32_WINNT			0x501 //Utile pour HDF_SORTUP et HDF_SORTDOWN

#include <windows.h>
#include <commctrl.h> //Pour les composants list_view
#pragma comment(lib,"comctl32.lib")

#include "resource.h"

static HINSTANCE hInst=NULL;
static HWND mainDlg=NULL; //Dialogue pricipale

void initListView(HWND hDlg)
//Initialise la list view
{
	HWND hwndListView = GetDlgItem(hDlg,IDC_LIST_FICHIER); 
	LV_COLUMN lvColumn; //descripteur de colonne
	lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
	lvColumn.fmt = LVCFMT_RIGHT;
	lvColumn.cx = 80;
	lvColumn.pszText = "Numero";
	ListView_InsertColumn(hwndListView,0,(LPARAM)&lvColumn);
	lvColumn.cx = 80;
	lvColumn.pszText = "Chaine";
	ListView_InsertColumn(hwndListView,0,(LPARAM)&lvColumn);
	ListView_SetExtendedListViewStyleEx(hwndListView,0,LVS_EX_FULLROWSELECT|
                                              LVS_EX_HEADERDRAGDROP);
}

void fillListView(HWND hDlg)
//Rempli la liste view par des lignes -> pas tres propre mais suffisant pour piger
{
	//recuperation de la list
	HWND hwndListView = GetDlgItem(hDlg,IDC_LIST_FICHIER);

	//Initialisation de la Structure de la ListView
	LVITEM LvItem;
	LvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
	LvItem.state = 0; 
	LvItem.stateMask = 0;
	LvItem.iItem = 0; //numéro de l'item
	LvItem.lParam = 0; //Sert lors d'un tri	
	LvItem.iSubItem = 0; //index dans la ligne

	int itemPos = ListView_InsertItem(hwndListView,(LPARAM)&LvItem);
	//Chaine
	ListView_SetItemText(hwndListView,itemPos,0,"Texte");
	//Chiffre
	ListView_SetItemText(hwndListView,itemPos,1,"455");

	itemPos = ListView_InsertItem(hwndListView,(LPARAM)&LvItem);
	//Chaine
	ListView_SetItemText(hwndListView,itemPos,0,"Texte2");
	//Chiffre
	ListView_SetItemText(hwndListView,itemPos,1,"2000");

	itemPos = ListView_InsertItem(hwndListView,(LPARAM)&LvItem);
	//Chaine
	ListView_SetItemText(hwndListView,itemPos,0,"Texte4");
	//Chiffre
	ListView_SetItemText(hwndListView,itemPos,1,"200");

	itemPos = ListView_InsertItem(hwndListView,(LPARAM)&LvItem);
	//Chaine
	ListView_SetItemText(hwndListView,itemPos,0,"_BlaBLUDI");
	//Chiffre
	ListView_SetItemText(hwndListView,itemPos,1,"400");
}

int CALLBACK CompareNumberFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
//Fonction de comparaison de chiffres
{
	//Lecture des items
	HWND hListView = GetDlgItem(mainDlg,IDC_LIST_FICHIER);
	char chaineChiffre1[11];
	ListView_GetItemText(hListView,lParam1,1,chaineChiffre1,11);
	char chaineChiffre2[11];
	ListView_GetItemText(hListView,lParam2,1,chaineChiffre2,11);

	//Conversion des chaines en int
	int chiffre1 = atoi(chaineChiffre1);
	int chiffre2 = atoi(chaineChiffre2);

	//Calcul du resultat
	if( lParamSort == HDF_SORTUP ) //Trie croissant
	{
		if( chiffre1<chiffre2 )
		{
			return 1;
		}
		else
		{
			if( chiffre1==chiffre2 )
			{
				return 0;
			}
			else
			{
				return -1;
			}
		}
	}
	else //trie decroissant
	{	
		if( chiffre1<chiffre2 )
		{
			return -1;
		}
		else
		{
			if( chiffre1==chiffre2 )
			{
				return 0;
			}
			else
			{
				return 1;
			}
		}
	}
}

int CALLBACK CompareStringFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
//Fonction de comparaison de chaine de caracteres
{
	//Lecture des items de la liste
	HWND hListView = GetDlgItem(mainDlg,IDC_LIST_FICHIER);
	char chaine1[1024];
	ListView_GetItemText(hListView,lParam1,0,chaine1,1024);
	char chaine2[1024];
	ListView_GetItemText(hListView,lParam2,0,chaine2,1024);

	//Resultat de la comparaison
	int cmpResult = strcmp(chaine1,chaine2);
	if( lParamSort == HDF_SORTUP )
	{
		cmpResult*=-1;
	}

	return cmpResult;
}

void OnListViewColumnClick(HWND hDlg,LPARAM lParam)
//Gestion de l'evenement de clique sur une colonne.
{
	//Indique la collonne precedemment selectionnee
	static int collonneSelectionne = -1;
	static int sensTrie;

	LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
												
	//Recuperation de l'header (pnmv->iSubItem contient le numero de la collone 
                          cliquee)
	HDITEM hdi;
	hdi.mask = HDI_FORMAT;
	HWND hListView = GetDlgItem(hDlg,IDC_LIST_FICHIER);
	HWND header = ListView_GetHeader(hListView);
	Header_GetItem(header, pnmv->iSubItem, &hdi);

	if( collonneSelectionne!=-1 ) //Une colonne deja selectionnee
	{
		if( collonneSelectionne==pnmv->iSubItem ) //Meme colonne
		{
			if( sensTrie == HDF_SORTDOWN ) //Trie decroissant en cours
			{
				sensTrie = HDF_SORTUP; //inversion du trie
				hdi.fmt &= ~HDF_SORTDOWN;
				hdi.fmt |= HDF_SORTUP;
			}
			else //Trie croissant en cours
			{
				sensTrie = HDF_SORTDOWN; //inversion du trie
				hdi.fmt &= ~HDF_SORTUP;
				hdi.fmt |= HDF_SORTDOWN;
			}

			//On modifie l'header
			Header_SetItem(header, pnmv->iSubItem, &hdi);
		}
		else //Colonne differente et donc raz de l'header
		{
			//Suppression de la fleche de trie
			Header_GetItem(header, collonneSelectionne, &hdi);
			hdi.fmt &= ~HDF_SORTUP & ~HDF_SORTDOWN;
			Header_SetItem(header, collonneSelectionne, &hdi);

			//On affiche la nouvelle fleche
			collonneSelectionne = pnmv->iSubItem;
			Header_GetItem(header, collonneSelectionne, &hdi);
			hdi.fmt |= HDF_SORTDOWN;
			sensTrie = HDF_SORTDOWN;
			Header_SetItem(header, collonneSelectionne, &hdi);
		}
	}
	else //Nouvelle collonne
	{
		collonneSelectionne = pnmv->iSubItem;
		Header_GetItem(header, collonneSelectionne, &hdi);
		hdi.fmt |= HDF_SORTDOWN;
		sensTrie = HDF_SORTDOWN;
		Header_SetItem(header, collonneSelectionne, &hdi);
	}

	//Lancement du trie
	ListView_SortItemsEx(hListView,
                                      collonneSelectionne==1?CompareNumberFunc:CompareStringFunc,
                                      sensTrie);
}

LRESULT CALLBACK DlgMainProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
//Fonction de traitement de nos messages
{
	switch(uMsg)
	{
	case WM_INITDIALOG: //Premier message recu avant affichage du dialogue
		initListView(hDlg); //Initialisation des listviews
		fillListView(hDlg); //Met des donnees dans la listview
		return TRUE;
	case WM_NOTIFY: //Notification d'evenement (ex: listview)
		switch(wParam)
		{
			case IDC_LIST_FICHIER:
			{
				switch (((NM_LISTVIEW*)lParam)->hdr.code)
				{
				case LVN_COLUMNCLICK : //Evenement de clique 
                                                                                                            sur une colonne
					OnListViewColumnClick(hDlg,lParam);
					return TRUE;
				}
			}
		}
	case WM_COMMAND:
		switch(wParam)
		{
		case WM_DESTROY:
		case WM_CLOSE:
			EndDialog(hDlg,0); //Fermeture du dialogue principal
			PostQuitMessage(0); //Fin de l'application
			return TRUE;
		}
	}
	return FALSE;
}
  
int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpCmdLine,
int nCmdShow)
//Point d'entree du programme
{     
	//Instance de notre appli
	hInst = hInstance;

	//Initialisation des controles utilises
	INITCOMMONCONTROLSEX initControl;
	initControl.dwSize = sizeof(initControl);
	initControl.dwICC = ICC_LISTVIEW_CLASSES;//Classe a charger
	InitCommonControlsEx(&initControl);

	//Creation du dialogue principal
	mainDlg=CreateDialog(hInstance,MAKEINTRESOURCE(IDD_MAIN),NULL,
                                                              (DLGPROC)DlgMainProc);
	ShowWindow(mainDlg,SW_SHOW);
	
	//traitement des messages
	MSG msg;
	while(GetMessage(&msg,NULL,0,0)==TRUE)
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return 0;
}

Conclusion :


j'ai mis initié mais c pas du code tres difficile si on connait deja un peu la prog windows.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.