Sortieren einer Liste (List Control)



  • Hallo!

    wie kann ich eine Liste möglichst einfach sortieren. wie zB die Prozesse beim Windows Taskmanager. d.h. ich möchte nach versch. kriterien sortieren. zb Prozessorname, Speicher, etc.
    gibt es dafür einen einfachen verständliche Algorithmus?

    danke



  • hi

    habe letzte woche grad mal so ein ding geschrieben

    ist 3 seiten gross 🙂

    brauchst du?



  • dass wäre voll nett, bitte



  • also hier unser code:

    ist nicht wirklich kommentiert und es koennten noch kommentare dranstehen die hinfaellig sind
    unser trennzeichen in unseren textdateien ist die tilde(~)

    textdatei sieht so aus:
    12345~Axel Schweiss~DuftAlee 3738430Mueffelhausen01111/32341email@Gestank.de~

    such dir bitte die wichtigen dinge raus.....bin ein wenig busy!! 😃 sorry

    CODE:

    /////////////////////////////////////////////////////////////////////////////
    // CAuftragswahl dialog

    CAuftragswahl::CAuftragswahl(CWnd* pParent /=NULL/)
    : CDialog(CAuftragswahl::IDD, pParent)
    {
    //{{AFX_DATA_INIT(CAuftragswahl)
    m_sicht = _T("");
    //}}AFX_DATA_INIT
    CString m_MsgOben = "Fehler";
    CString m_MsgText ="Speicher voll! Neustart erfolderlich!\r\nBitte Applikation nach Arbeitstag beenden!";
    int zeilen=100,spalten=15;
    m_SuchMatrix = new CString *[zeilen];
    if (!m_SuchMatrix)
    {
    CAuftragswahl::MessageBox(m_MsgText,m_MsgOben,MB_ICONWARNING | MB_OK);
    }
    for (int i=0;i<15;i++)
    {
    m_SuchMatrix[i] = new CString[spalten];
    if (!m_SuchMatrix[i])
    {
    CAuftragswahl::MessageBox(m_MsgText,m_MsgOben,MB_ICONWARNING | MB_OK);
    }
    }
    }

    void CAuftragswahl::DoDataExchange(CDataExchange* pDX)
    {
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CAuftragswahl)
    DDX_Control(pDX, IDC_COMBOSUCH, m_CComboBox);
    DDX_Control(pDX, IDC_AUFTARGSBOX, m_ControllList);
    DDX_Text(pDX, IDC_INFOFELD, m_sicht);
    //}}AFX_DATA_MAP
    }

    BEGIN_MESSAGE_MAP(CAuftragswahl, CDialog)
    //{{AFX_MSG_MAP(CAuftragswahl)
    ON_LBN_DBLCLK(IDC_AUFTARGSBOX, OnDblclkAuftargsbox)
    ON_CBN_SELCHANGE(IDC_COMBOSUCH, OnSelchangeCombosuch)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CAuftragswahl message handlers

    void CAuftragswahl::OnOK()
    {
    CString m_MsgOben = "Fehler";
    CString m_MsgText ="Erst Auswahl treffen";
    CString m_MsgOben1 = "INFO";
    CString m_MsgText1 ="Artikelnummer " + m_SuchMatrix[m_zahl][0];
    if ( m_zahl <0)
    {
    CAuftragswahl::MessageBox(m_MsgText,m_MsgOben,MB_ICONWARNING | MB_OK);
    UpdateData(false);
    }
    else
    {
    CAuftragbeab set;
    UpdateData(false);
    set.m_AufNr = m_SuchMatrix[m_zahl][0];
    set.m_SuchMatrix1 = m_SuchMatrix;
    UpdateData(true);
    set.DoModal();
    UpdateData(true);
    /* ///// LÖSCHEN //// drüber nachdenken
    for (int i=0;i<m_AnzahlAuftraege;i++)
    {
    delete []m_SuchMatrix[i];
    }
    delete[] m_SuchMatrix;
    */
    }
    CDialog::OnOK();

    }

    /////////////////////////// Initialisierung //////////////////////////////////////////
    BOOL CAuftragswahl::OnInitDialog() // Beim Starten des Fensters wird Listbox gefüllt
    {
    CDialog::OnInitDialog();
    int i=0,j=0,zahl=0;
    CString mail[100];
    char *Dateien[100]; // Aufnahme für 100 Datensätze
    char *pointer;
    CString ExistDateien ="ExistDateien.txt"; // Alle erzeugten oder bestehenden Autragsdateinamen!!
    CFile ExDatei(ExistDateien,CFile::modeRead);// Datei zum "kopieren" vorbereiten
    char token[1000]; // Aufnahme Array für Dateiinhalt
    char delimiter[] ="~"; // Trennzeichen
    ExDatei.Read(token, sizeof(token)); // Dateiinhalt in kopiert nach Token bis 1000 Zeichen
    pointer = strtok(token, delimiter); // strtok auf Trennzeichen
    Dateien[i] = pointer; // jeder getrennte Satz in ein Dateien [String]
    m_Dateien[i] = Dateien[i]; // übergabe an Membervariabel zur späteren Filterung

    while(pointer=strtok(NULL, delimiter)) // solange strtok bis Dateieiende erreicht
    {
    i++;
    Dateien[i] = pointer; // jeder getrennte Satz in ein Dateien [String]
    m_Dateien[i] = Dateien[i]; // übergabe an Membervariabel zur späteren Filterung
    }
    m_AnzahlAuftraege =i; // zahl = aktuelle Anzahl der verschiedenen Datensätze

    for (i=0;i<m_AnzahlAuftraege;i++) // Schleife zum Einlesen der jeweiligen Komponenten
    {
    char str[1000]; // Array jeweils befüllen
    CString end; // Name für Dateikennzeichnung
    end.Format('%.i',i); // Casten der Inkrementiervariabeln
    CString dat = Dateien[i]; // jeweiliger Datename
    // dat ="C:\\Daten\" +dat;
    CFile datei(dat, CFile::modeRead); // jeweilige Datei zum "kopieren" vorbereiten
    datei.Read(str, sizeof(str)); // Aufnahme Array für Dateninhalte
    char delimiter1[] ="~"; // Trennzeichen der Attributer der Dateien
    char *pointer1; // pointer auf die jeweils nächste Komponente
    char *satzkomp[8]; // Array zur Aufnahmer der einzelnden Komponenten
    pointer1 = strtok(str, delimiter1); //strtok auf Trennzeichen
    int k=0;
    satzkomp[k] = pointer1; // Inhalt vorm 1. Trennzeichen ins KompArray
    while(pointer1=strtok(NULL, delimiter1))// solange strtok bis Dateieiende erreicht
    {
    k++; // Komponenteninkrementiervariabel hochzählen
    satzkomp[k] = pointer1; // jeweilige Komponente vorm Trennzeichen ins KompArray
    }
    m_SuchMatrix[i][0] = satzkomp[0];
    m_SuchMatrix[i][1] = satzkomp[1]; // nötige Komponenten in Auffangstrings
    m_SuchMatrix[i][2] = satzkomp[2];
    m_SuchMatrix[i][3] = satzkomp[3];
    m_SuchMatrix[i][4] = satzkomp[4];
    m_SuchMatrix[i][5] = satzkomp[5];
    m_SuchMatrix[i][6] = satzkomp[6];

    m_ControllList.AddString( "ANr: " + m_SuchMatrix[i][0] +
    " Name: " + m_SuchMatrix[i][1] +
    " PLZ: " + m_SuchMatrix[i][3] );
    j++; // Ausgabe in der Listbox
    datei.Close(); // datei Schliessen
    m_sicht = "Doppelklick für Infos\r\nZur Zeit keine Filterung!";
    }
    UpdateData(false); // Aktualisieren
    return TRUE; // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
    }
    //////////////////// Doppelklick in Listbox ////////////////////////////////////
    void CAuftragswahl::OnDblclkAuftargsbox()
    {
    m_zahl = m_ControllList.GetCurSel(); // Cursorposition holen
    m_sicht =""; // Editfeld leeren
    // Formatierte Ausgabe im Editfeld
    m_sicht=( ">>>>>>>>> Ausgewählter Datenatz! <<<<<<<<<<<\r\nAufNr :\t" + m_SuchMatrix[m_zahl][0]+"\r\n"
    +"Name :\t" + m_SuchMatrix[m_zahl][1]+"\r\n"
    +"Str :\t" + m_SuchMatrix[m_zahl][2]+"\r\n"
    +"PLZ :\t" + m_SuchMatrix[m_zahl][3]+"\r\n"
    +"Ort :\t" + m_SuchMatrix[m_zahl][4]+"\r\n"
    +"Tel. :\t" + m_SuchMatrix[m_zahl][5]+"\r\n"
    +"E-Mail:\t" + m_SuchMatrix[m_zahl][6]+"\r\n");
    UpdateData(false);
    }
    /////////////////// ComboBox //////////////////////////////////////////////////
    void CAuftragswahl::OnSelchangeCombosuch()
    { //////////////// AN DIE FIXWERTE DENKEN!!!!!!
    m_CComboBox.GetLBText(
    m_CComboBox.GetCurSel(),m_SuchKrit); // Ausgewählter String übergeben
    m_ControllList.ResetContent(); //Listbox löschen
    m_sicht = "Gefiltert nach " +m_SuchKrit +"\r\n";//Ausgabe im Editfeld

    ///////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////
    CAuftragswahl::FilterKundendaten(m_SuchKrit); // Filtermethode aufrufen
    UpdateData(false);
    m_ControllList.ResetContent();
    for (int i=0;i< m_AnzahlAuftraege;i++) // HIER EVTL FEHLER!!!!!!!!!!!!!!!
    { // Listbox mit Matrixwerten ausgeben
    if ( m_kritkomp ==0)
    {
    m_ControllList.AddString(m_SuchMatrix[i][m_kritkomp] +"---"+ m_SuchMatrix[i][1] +"---"+ m_SuchMatrix[i][2] );
    }
    if ( m_kritkomp ==1)
    {
    m_ControllList.AddString(m_SuchMatrix[i][m_kritkomp] +"---"+ m_SuchMatrix[i][0] +"---"+ m_SuchMatrix[i][2] );
    }
    if ( m_kritkomp ==2)
    {
    m_ControllList.AddString(m_SuchMatrix[i][m_kritkomp] +"---"+ m_SuchMatrix[i][0] +"---"+ m_SuchMatrix[i][1] );
    }
    if ( m_kritkomp ==3)
    {
    m_ControllList.AddString(m_SuchMatrix[i][m_kritkomp] +"---"+ m_SuchMatrix[i][4] +"---"+ m_SuchMatrix[i][0] );
    }
    if ( m_kritkomp ==4)
    {
    m_ControllList.AddString(m_SuchMatrix[i][m_kritkomp] +"---"+ m_SuchMatrix[i][3] +"---"+ m_SuchMatrix[i][0] );
    }
    if ( m_kritkomp ==5)
    {
    m_ControllList.AddString(m_SuchMatrix[i][m_kritkomp] +"---"+ m_SuchMatrix[i][0] +"---"+ m_SuchMatrix[i][1] );
    }
    }
    // CString Ausgabe =m_SuchMatrix[i][m_kritkomp] +"---"+ m_SuchMatrix[i][1] +"---"+ m_SuchMatrix[i][2];
    // m_ControllList.AddString( Ausgabe-1); /// ZUM TEST

    UpdateData(false);
    }
    ///////////////////////Filterung der Kundendaten///////////////////////////////
    void CAuftragswahl::FilterKundendaten(CString mein_m_SuchKrit)
    {
    if ( mein_m_SuchKrit == "Auftragsnummer")
    {
    m_kritkomp =0;
    }
    if ( mein_m_SuchKrit == "Kundenname")
    {
    m_kritkomp =1;
    }
    if ( mein_m_SuchKrit == "Strasse")
    {
    m_kritkomp =2;
    }
    if ( mein_m_SuchKrit == "Ort")
    {
    m_kritkomp =4;
    }
    if ( mein_m_SuchKrit == "Postleitzahl")
    {
    m_kritkomp =3;
    }
    if ( mein_m_SuchKrit == "Telefonnummer")
    {
    m_kritkomp =5;
    }
    int a=0;
    do /// GEAENDERT !!!!!!!!!!!!!!!!!!!
    {
    if ((m_SuchMatrix[a][m_kritkomp]) >( m_SuchMatrix[a+1][m_kritkomp]))
    {
    for (int i=0;i< m_AnzahlAuftraege;i++)
    {
    m_HilfsMatrix[0][i] = m_SuchMatrix[a][i] ;
    m_SuchMatrix[a][i] = m_SuchMatrix[a+1][i] ;
    m_SuchMatrix[a+1][i] = m_HilfsMatrix[0][i];
    }
    a=0;
    }
    else
    {
    if (a<5)
    {
    a++;
    }
    }
    }while (!(a==5 && ((m_SuchMatrix[a][m_kritkomp]) <= ( m_SuchMatrix[a+1][m_kritkomp]))));
    UpdateData(false);

    }



  • Danke!
    aber so ganz hab ich das ganze noch nicht durchschaut, vielleicht darf ich dir meinen code mal zeigen. kannst mir vielleicht sagen wo ich was einfügen muss, das wäre echt nett. dieser code ist nämlich auch nicht von mir, muss ihn aber um diese funktion erweitern.

    // TasksProcessesPage.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "SystemMonitor.h"
    #include "SystemMonitorDlg.h"
    #include "TasksProcessesPage.h"
    #include "Tlhelp32.h"
    #include <Winbase.h>
    #include <windows.h>
    #include "psapi.h"
    
    // CTasksProcessesPage dialog
    
    IMPLEMENT_DYNAMIC(CTasksProcessesPage, CDialogEx)
    CTasksProcessesPage::CTasksProcessesPage()
    	: CDialogEx(CTasksProcessesPage::IDD)
    {
    }
    
    CTasksProcessesPage::~CTasksProcessesPage()
    {
    }
    
    void CTasksProcessesPage::DoDataExchange(CDataExchange* pDX)
    {
    	CDialogEx::DoDataExchange(pDX);
    	DDX_Control(pDX, IDC_LIST1, m_processes);
    	DDX_Control(pDX, IDC_LIST2, m_modules);
    }
    
    BEGIN_MESSAGE_MAP(CTasksProcessesPage, CDialogEx)
    	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, OnLvnItemchangedList2)
    	ON_MESSAGE(WM_WORKERTHREAD_UPDATE, OnWorkerThreadUpdate)
    	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, OnLvnItemchangedList1)
    END_MESSAGE_MAP()
    
    // CTasksProcessesPage message handlers
    
    BOOL CTasksProcessesPage::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    	m_processes.InsertColumn(0,"Process name");
    	m_processes.InsertColumn(1,"ID");
    	m_processes.InsertColumn(2,"Threads");
    	m_processes.InsertColumn(3,"Priority");
    	m_processes.InsertColumn(4,"CPU Time");
    	m_processes.InsertColumn(5,"Memory Usage");
    	m_processes.InsertColumn(6,"Main Window Title");
    
    	m_processes.SetColumnWidth(0,120);
    	m_processes.SetColumnWidth(1,40);
    	m_processes.SetColumnWidth(2,60);
    	m_processes.SetColumnWidth(3,50);
    	m_processes.SetColumnWidth(4,60);
    	m_processes.SetColumnWidth(5,100);
    	m_processes.SetColumnWidth(6,200);
    
    	m_modules.InsertColumn(0,"Name");
    	m_modules.InsertColumn(1,"Path");
    
    	m_modules.SetColumnWidth(0,120);
    	m_modules.SetColumnWidth(1,310);
    
    	return TRUE;
    }
    
    LONG CTasksProcessesPage::OnWorkerThreadUpdate(WPARAM wParam, LPARAM lParam)
    {
    	CWorkerThreadData data=m_Parent->GetWorkerThreadData();
    
    	CArray<bool,bool> valid; // array if item on position is still valid
    	for (int i=0; i<m_processes.GetItemCount(); i++) {
    		valid.Add(false);
    	}
    
    	POSITION pos=data.m_processList.GetHeadPosition();
    	for(int i=0;i<data.m_processList.GetCount();i++)
    	{
    		CProcessInformation pi=data.m_processList.GetNext(pos);
    
    		int pos;
    		// check if item is already in the list
    		bool found=false;
    		for (int j=0; j<m_processes.GetItemCount(); j++) {
    			if (pi.id==m_processes.GetItemData(j)) {
    				pos=j;
    				found=true;
    				break;
    			}
    		}
    
    		if (!found) {
    			// add the new item
    			m_processes.InsertItem(valid.GetCount(),pi.m_processName);
    			pos=valid.GetCount();
    			valid.Add(true); 
    		}
    
    		// update the item data
    		m_processes.SetItemData(pos,pi.id);
    		m_processes.SetItemText(pos,0,pi.m_processName);
    		m_processes.SetItemText(pos,1,pi.m_processId);
    		m_processes.SetItemText(pos,2,pi.m_processCntThreads);
    		m_processes.SetItemText(pos,3,pi.m_processPriority);
    		CString temp;
    		int mins=pi.m_processCPUTime/60;
    		int secs=pi.m_processCPUTime%60;
    		temp.Format("%2.2d:%2.2d",mins,secs);
    		m_processes.SetItemText(pos,4,temp);
    		m_processes.SetItemText(pos,5,pi.m_processMemoryUsage);
    		m_processes.SetItemText(pos,6,pi.m_windowTitle);
    		valid[pos]=true; 
    	}
    
    	// remove all items which are no longer present
    	for (int i=valid.GetCount()-1; i>=0; i--) {
    		if (!valid[i]) {
    			m_processes.DeleteItem(i);
    		}
    	}
    
    	return 0;
    }
    
    void CTasksProcessesPage::OnLvnItemchangedList2(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    	// TODO: Fügen Sie hier Ihren Kontrollbehandlungscode für die Benachrichtigung ein.
    	*pResult = 0;
    }
    
    void CTasksProcessesPage::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    	HANDLE hModuleSnap;
    	MODULEENTRY32 mEntry;
    	char help[200]; //18.6.
    	CList<MODULEENTRY32,MODULEENTRY32> m_moduleList;
    
    	if (pNMLV->uNewState&LVIS_SELECTED) {
    		//get the process the user has clicked
    		int changed=pNMLV->iItem;
    		DWORD id=m_processes.GetItemData(changed); 
    
    		//remove elements from m_moduleList
    		m_moduleList.RemoveAll();
    		//delete modules in list
    		m_modules.DeleteAllItems();
    
    		//take a snapshot of the current process' modules
    		hModuleSnap=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,id);	
    		//store modules in m_moduleList
    		if(Module32First(hModuleSnap, &mEntry))
    		{
    			do
    			{
    				m_moduleList.AddTail(mEntry);
    			}
    			while(Module32Next(hModuleSnap,&mEntry));
    		}
    		CloseHandle(hModuleSnap);
    
    		if(m_moduleList.IsEmpty())
    		{
    			//insert dummy element
    			sprintf(help,"%s","DummyItem");
    			m_modules.InsertItem(0,help);
    			m_modules.SetItemText(0,0,"Keine Module geladen");
    		} else {
    			//run through m_moduleList
    			POSITION pos=m_moduleList.GetHeadPosition();
    			for(int i=0;i<m_moduleList.GetCount();i++)
    			{
    				mEntry=m_moduleList.GetNext(pos);
    				sprintf(help,"%d",mEntry.th32ModuleID);
    				m_modules.InsertItem(i,help);				
    				sprintf(help,"%s",mEntry.szModule);
    				m_modules.SetItemText(i,0,mEntry.szModule);
    				m_modules.SetItemText(i,1,mEntry.szExePath);
    			}
    		}		
    	}
    	*pResult = 0;
    }
    

Log in to reply