ListCtrl - seltsames Verhalten



  • Hallo Leute,

    also ich hab ein ListCtrl in einer PropertyPage.
    Das ListCtrl soll wie eine Lista aussehn, also am anfang ein kleines Symbol, und dann meherer Spalten mit Informationen.

    Das ist die Init von der PropertyPage wo die Liste drinnen ist

    BOOL LogPropPage::OnInitDialog()
    {
    	CPropertyPage::OnInitDialog();
    
    	//Spalten erzeugen
    	m_LogListCtrl.InsertColumn(0, _T("Typ"), LVCFMT_LEFT, -1, 1);
    	m_LogListCtrl.InsertColumn(1, _T("Datum"), LVCFMT_LEFT, -1, 2);
    	m_LogListCtrl.InsertColumn(2, _T("Ereignis"), LVCFMT_LEFT, -1, 3);
    	//Icons erzeugen	
    
    	//Testmeldung
    	theApp.netprintlog->setLogMessage(0 , "Meldung5");
    
    	return true;
    }
    

    So und in einer anderen Klasse befülle ich dieses ListCtrl dann mit:

    bool MessageLog::fillCList(CListCtrl *listctrl)
    {
    	MessageNode *tempList;
    	int insertPos = 0;	
    	HICON hListIcon[3];
    	CImageList m_listIcons;
    	int n;
    
    	if (listctrl->GetImageList(LVSIL_SMALL) == NULL)
    	{
            m_listIcons.Create(16, 16, 0, 8, 8);
    		hListIcon[0] = AfxGetApp()->LoadIcon(IDI_NPINFO);
    		hListIcon[1] = AfxGetApp()->LoadIcon(IDI_NPWARNING);
    		hListIcon[2] = AfxGetApp()->LoadIcon(IDI_NPERROR);
    		for (n = 0; n < 3; n++)
    			m_listIcons.Add(hListIcon[n]);
    		listctrl->SetImageList(&m_listIcons, LVSIL_SMALL);	
    		theApp.netprintlog->setLogMessage(0, "GetImageList == NULL");
    	}
    	//alle bisherigen Listeneinträge löschen
    	listctrl->DeleteAllItems();	
    	if(msgList->next == NULL)
    		return false;
    	else
    	{		
    		tempList = msgList;
    		listctrl->InsertItem(insertPos, msgList->szLogTime, msgList->iLogType);		
    		listctrl->SetItemText(insertPos, 1, msgList->szLogTime);
    		listctrl->SetItemText(insertPos, 2, msgList->szLogMsg);
    		msgList = msgList->next;
    		insertPos++;
    		while(msgList->next != NULL)
    		{		
    			listctrl->InsertItem(insertPos, msgList->szLogTime, msgList->iLogType);			
    			listctrl->SetItemText(insertPos, 1, msgList->szLogTime);
    			listctrl->SetItemText(insertPos, 2, msgList->szLogMsg);
    			msgList = msgList->next;
    			insertPos++;		
    		}
    		listctrl->InsertItem(insertPos, msgList->szLogTime, msgList->iLogType);
    		listctrl->SetItemText(insertPos, 1, msgList->szLogTime);
    		listctrl->SetItemText(insertPos, 2, msgList->szLogMsg);
    		listctrl->SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER);
    		listctrl->SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER);
    		listctrl->SetColumnWidth(2, LVSCW_AUTOSIZE_USEHEADER);		
    		msgList = tempList;
    		return true;
       	}
    }
    

    Was mich nur stört ist, das die Symbole zwar beim ersten Mal anklicken der PropertyPage in der Liste angezeigt werden, allerdings, wenn ich auf eine andere Page gehe und dann wieder zurück zu meiner Liste sind die Symbole weg.

    Wie schaffe ich es, das ich nicht nur den Text in der ersten Spalte anklicken und dadurch blau markieren kann, sondern die ganze Zeile?

    Ich nehm mal an, das es bei Problem 1 einfach daran liegt, das ich noch keine Windows Meldungen verarbeite. Allerdings hab ich keien Ahnung welche Meldung dafür zuständig ist, bzw. was ich dann dort machen muss?
    Hatt jemand einen Tipp für mich?

    thx. Joe





  • Problem 1 dürfte eher daran liegen, daß die ImageList lokal in deiner fillcList()-Methode "lebt", d.h. die Liste wird bei nächster Gelegenheit wieder gelöscht und dein List-Control arbeitet anschließend mit ungültigen Daten.



  • zu Problem 2. ja mit dem richtigen Befehl geht alles, versthe nur nicht warum ich den Artikel nicht schon vorher beim Forum durchsuchen gefunden hab *grübel*

    zu Problem 1. hmm, ich weiß was du meinst, aber warum stellt er dann den Text noch richtig da und löscht nur die Symbole weg?

    Hat jemand eine Idee, wie ich das eleganter Lösen kann. Also ich ahb eine Verkettete Liste und diese Liste möchte ich in dem ListCtrl darstellen.
    Es reicht mir auch, wenn das ListCtrl immer nur dann aktualisiert wieder wenn ich auf diese PropertyPage gehe oder ein neuer eintrag in der Liste dazu kommt, aber wie mach ich das?



  • Joe80 schrieb:

    zu Problem 2. ja mit dem richtigen Befehl geht alles, versthe nur nicht warum ich den Artikel nicht schon vorher beim Forum durchsuchen gefunden hab *grübel*

    Möglichkeit 1: Die Forumsuche geht nur für Beiträge seit dem Serverumzug vor ein paar Wochen.
    Möglichkeit 2: Du hast nicht in der FAQ gesucht.
    Möglichkeit 3: Ich habe eben erst den Tippfehler im Betreff korrigiert, vorher stand da "makieren". 😉



  • ok, daran könnts liegen 💡 , weil ich schreib nicht gern Foren mit Themen voll, die eh schon beplaudert worden sind. 😃



  • Joe80 schrieb:

    zu Problem 1. hmm, ich weiß was du meinst, aber warum stellt er dann den Text noch richtig da und löscht nur die Symbole weg?

    Die Texte verwaltet dein Control selber, die Icons stehen in der "CImageList m_listIcons;" - und du mußt ganz einfach dafür sorgen, daß diese ImageList so lange überlebt, wie sie benötigt wird.

    (also hol sie am besten aus der Methode raus und pack' sie stattdessen in die Dialogklasse)



  • ok, das hab ich probiert, mein Code für das Liste initialisieren sieht jetzt so aus:

    BOOL LogPropPage::OnInitDialog()
    {
    	HICON hListIcon[3];
    	CImageList m_listIcons;
    	int n;
    
    	CPropertyPage::OnInitDialog();
    
    	if (m_LogListCtrl.GetImageList(LVSIL_SMALL) == NULL)
    	{
            m_listIcons.Create(16, 16, 0, 8, 8);
    		hListIcon[0] = AfxGetApp()->LoadIcon(IDI_NPINFO);
    		hListIcon[1] = AfxGetApp()->LoadIcon(IDI_NPWARNING);
    		hListIcon[2] = AfxGetApp()->LoadIcon(IDI_NPERROR);
    		for (n = 0; n < 3; n++)
    			m_listIcons.Add(hListIcon[n]);
    		m_LogListCtrl.SetImageList(&m_listIcons, LVSIL_SMALL);	
    		theApp.netprintlog->setLogMessage(0, "GetImageList == NULL");
    	}
    	//Spalten erzeugen
    	m_LogListCtrl.InsertColumn(0, _T("Typ"), LVCFMT_LEFT, -1, 1);
    	m_LogListCtrl.InsertColumn(1, _T("Zeit"), LVCFMT_LEFT, -1, 2);
    	m_LogListCtrl.InsertColumn(2, _T("Ereignis"), LVCFMT_LEFT, -1, 3);
    	m_LogListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT);
    	//Icons erzeugen	
    
    	//Testmeldung
    	theApp.netprintlog->setLogMessage(0 , "Meldung5");
    
    	return true;
    }
    

    So hast du das doch gemeint oder?
    hat nur den Effekt, das ich jetzt überhaupt keine Symbole mehr angezeigt bekomme. Ich check einfach nicht woran das liegt?



  • Da ist sie doch noch: Zeile 4. 😕



  • Was sagt dir der Begriff "Scope" bzw. "Lebensdauer"? Die Image-List muß mindestens so lange überleben, wie dein Control existiert - das heißt du solltest dort keine lokale Variable verwenden (am Ende der zugehörigen Methode wird diese Variable freigegeben und dein Control behält einen Zeiger auf einen Speicherbereich, der bei nächster Gelegenheit von jemand anderem überschrieben werden könnte). Trag die Variable lieber als Member der Dialogklasse ein:

    class LogPropPage
    {
      ...
      CListCtrl m_LogListCtrl;
      CImageList m_listIcons;// <-Hier hin
      ...
    };
    
    BOOL LogPropPage::OnInitDialog()
    {
      HICON hListIcon[3];
      //CImageList m_listIcons; // <-Hier NICHT
      int n;
    
      CPropertyPage::OnInitDialog();
      ...
    }
    


  • ohh, ähm, ja sagst doch gleich das ich die Varialble für die Klasse global definieren muss *fg*

    Ja jetzt bin ich das Problem los.

    Aber weil ich grad so in fahrt bin, wie löse ich das, wenn ich in der PropertyPage bin und in der Liste eine neue Meldung dazu kommt, das mir diese Meldung gleich in der Liste angezeigt wird? Welche Windows Meldung muss ich da aufrufen um diese Liste zu aktualisieren?



  • Ähm, ich dachte das hätte ich:

    CStoll schrieb:

    (also hol sie am besten aus der Methode raus und pack' sie stattdessen in die Dialogklasse)

    Woher die Liste ihre Meldungen bekommt (um was für Meldungen geht es eigentlich?), mußt du selber wissen. In dein Control kannst du die neuen Werte mit einem einfachen InsertItem() eintragen.



  • ja das sind Status und Fehlermeldungen die mein Progamm ausgeben soll.

    hmm, ok, ich glaub ich weiß was du meinst 😉


Anmelden zum Antworten