ListCtrl Zeile für Zeile füllen



  • Gut, mit dem Zeile für Zeile füllen hat sich geklärt, sieht jetzt so aus:

    void C...View::FillListCtrl()
    {
    	m_tool.SetRedraw(FALSE);
    	CString data;
    	CTime ct = CTime::GetCurrentTime();
    
    	LVITEM lvItem;
    	lvItem.mask = LVIF_TEXT;
    	lvItem.iItem = 0; lvItem.iSubItem = 0;
    	lvItem.pszText = "";
    	m_tool.InsertItem(&lvItem);
    	for (int i = 0; i < 13; i++)
    	{
    		lvItem.iItem = m_tool.GetItemCount(); lvItem.iSubItem = i;
    		m_tool.InsertItem(&lvItem);
    	}
    	m_tool.SetItemText(0, 0, "test1");
    	m_tool.SetItemText(0, 1, "test2");
            ...
    }
    

    und die Initialisierung:

    void C...View::InitListCtrl()
    {
        CRect rectListCtrl;
        m_tool.EnableToolTips(TRUE);
        m_tool.SetRedraw(FALSE);
        m_tool.GetClientRect(&rectListCtrl);
    
        m_tool.InsertColumn(0, "0", LVCFMT_LEFT, 70);
        m_tool.InsertColumn(1, "1", LVCFMT_LEFT, 60);
        ...
    
        m_tool.SetRedraw(TRUE);
        m_tool.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP);
    }
    

    Hab ich halt nur noch das Problem, die "aktuellste" Zeile am Anfang stehen zu haben, aber werde es jetzt mal mit SortItems probieren. 👍


  • Mod

    Dann setze 0 als Einfügeposition und dann steht es oben:

    lvItem.iItem = 0;
    m_tool.InsertItem(&lvItem);
    


  • Ok, stimmt, und passt !
    Danke euch !!

    Und entschuldige mich für den Ärger mit mir ! 😉



  • Es muss mich nochmal melden: Ich habe jetzt das Flicker-Problem mit meinem ListCtrl.
    Ich aktualisiere mein Control auch immer nur dann, wenn ich in jeder Spalte per SetItemText den Inhalt festgelegt habe.

    Hab jetzt schon einige Seiten und Lösungen durchgelesen, aber bin auch nur etwas schlauer geworden und es stand auch auf einigen Seiten, dass man SetRedraw(FALSE) und SetRedraw(TRUE) aufrufen soll, was ich ja tue, aber es ändert sich trotzdem nix.

    Das soll also heißen, ich muss meine Items, das "allgemeine" Layout usw. meines ListCtrl selber zeichnen ? So ist es dort erkennbar: http://www.codeproject.com/KB/GDI-plus/what_is_a_basename_.aspx. Habe auch wie es dort beschrieben ist, WM_PAINT... hinzugefügt und muss mich jetzt noch um OnPaint() kümmern.

    Nur hab ich keine Anhung wie ich da anfangen soll, hab nix weiter mit DC... gemacht !


  • Mod

    Das CListCtrl ist optimiert. Du musst gar nichts aktualisieren. Invalidate bzw. InvalidateRect ist bei einem CListCtrl unnötig genauso wie SetRedraw etc.



  • Ich weiß nicht, aber ich hab mal SetRedraw ... entfernt, aber das Flickern ist nach wie vor da !

    EDIT:
    hab auch grad gemerkt, dass manche Linien des LVS_GRIDLINES-Style nicht gezeichnet werden, wenn man in der Liste z.B. runterscrollt
    habe dazu WM_VSCROLL hinzugefügt und dort den LVS_GRIDLINES-Style nochmal gesetzt, aber das bringt auch nix



  • Martin Richter schrieb:

    Das CListCtrl ist optimiert. Du musst gar nichts aktualisieren. Invalidate bzw. InvalidateRect ist bei einem CListCtrl unnötig genauso wie SetRedraw etc.

    Das sehe ich etwas anders. Beim Hinzufügen von mehreren Einträgen nacheinander hilft ein SetRedraw schon sehr, den Vorgang zu beschleunigen. Es verhindert, dass die Listenansicht nach jedem InsertItem interne Positionen und den Scrollbereich neu berechnet.

    Gegen das Trennlinien-Problem hilft folgendes:

    // WM_HSCROLL
    //
    //	-> Horizontales Scrollen
    void CMfxListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
    {
    	// Standardverarbeitung
    	CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
    
    	// Scrollen beendet
    	//	-> Aktualisierung (Tut not, wenn bei eingeschalteten Trennlinien per Rad gescrollt wird)
    	if (SB_ENDSCROLL == nSBCode && GetExtendedStyle() & LVS_EX_GRIDLINES)
    	{
    		RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW);
    	}
    }
    
    // WM_HSCROLL
    //
    //	-> Vertikales Scrollen
    void CMfxListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
    {
    	// Standardverarbeitung
    	CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
    
    	// Scrollen beendet
    	//	-> Aktualisierung (Tut not, wenn bei eingeschalteten Trennlinien per Rad gescrollt wird)
    	if (SB_ENDSCROLL == nSBCode && GetExtendedStyle() & LVS_EX_GRIDLINES)
    	{
    		RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW);
    	}
    }
    


  • @sri:
    Ok, also ich hab den Code mal probiert, aber so wirklich hilft das nicht, die Probleme mit den Linien ist nach wie vor da, egal ob ich den Scrollbalken runterziehe oder per Mausrad scrolle.

    Und das Flickern ist natürlich auch nach wie vor da, ne Lösung hab ich auch noch nicht gefunden !

    Und als 3. Problem hab ich noch: ich muss noch einen Ansatz finden, wie ich "neue" Daten im ListCtrl auch gleich noch in ein Logfile schreiben kann, gibts vllt ne Funktion, die aufgerufen wird, wenn der Inhalt eines ListCtrls geändert wird ?? Vllt LVN_ITEMCHANGED ? 😕
    D.h. ich fülle meine Liste und will gleich danach immer die Funktion zum Schreiben ins Logfile aufrufen, muss aber irgendwas haben, dass diese ListTextToLog-Funktion erst aufruft, wenn neue Daten in der Liste stehen !
    Das Schreiben ins Logfile funktioniert, nur eben noch nicht, wie ich mir das vorstelle.

    Konnte bis jetzt diese 3 Dinge noch nicht lösen ! 😞
    Evtl kann jemand noch was dazu sagen ??



  • Die Einträge in der MessageMap für ON_WM_VSCROLL/ON_WM_HSCROLL hast Du auch gesetzt?

    Zu Problem 3: Einfach eine Wrapperfunktion schreiben, die die Einträge in die Liste einfügt und gleichzeitig ins Logfile schreibt. LVN_ITEMCHANGED ist nur für die Änderung von Stilen (Fokussierung, Auswahl) gedacht.



  • Erdtmal danke für deine Antwort.
    Ok, gut, werde das so angehen mit der Wrapperfunktion.

    Ja, das mit den Funktionen passt, sind ja mit Assistent eingefügt (aber man weiß ja nie 🙂 )
    Und die Funktionsprototypen sind:

    void CToolTip::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    

    und

    void CToolTip::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    

    und die Message Map sieht so aus:

    BEGIN_MESSAGE_MAP(CToolTip, CListCtrl)
    	ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
    	ON_WM_HSCROLL()
    	ON_WM_VSCROLL()
    END_MESSAGE_MAP()
    

    und die Funktionen werden auch aufgerufen (Breakpoint springt an!)
    Trotzdem ist dieser Fehler mit den Linien nach wie vor da, verstehe das nicht.



  • Warum nennst Du das ListCtrl CToolTip?



  • Ist ne Klasse die ich von Codeproject geladen hab und etwas verändert habe.

    Ich will in meinem ListCtrl nur in einer bestimmten Spalte ein Tooltip anzeigen lassen und hab dafür die Klasse gebraucht und auch verstanden.
    Die Klasse ist von CListCtrl abgeleitet.

    Kanns heut nicht mehr probieren, aber werde morgen mal testen, was passiert, wenn ich ohne die Klasse arbeite.

    Meld mich morgen wieder. Schönen Abend noch !



  • Hey, also ich muss mich nochmal zu dem Thema melden.
    Das Flickern ist nach wie vor, habs bis jetzt nicht hinbekommen. 👎

    Ich habe eine Wrapperfunktion, die anspringt, wenn mein Thread mir per Sendmessage mitteilt, dass neue Daten vorliegen und mir die auch gleich als LPARAM übergibt. SetRedraw wird auf false gesetzt, die ganzen 14 Spalten werden gefüllt, für 2 Spalten werden die Tooltips gesetzt und dann rufe ich wieder SetRedraw(TRUE) auf.
    Kann das Flickern natürlich verringern, wenn ich nach dem Sendmessage im Thread ein längeres Sleep einbaue, aber vollkommen verschwunden ist es da noch nicht, und ich will den User nicht unbedingt länger als 800ms warten lassen.

    Beim Scrollen ist das Flickern auch da. 😞

    Vllt hat jemand mal noch paar Tipps, komme hier einfach nicht weiter.



  • Ruf mal nach dem SetRedraw(TRUE) ein UpdateWindow() auf.



  • So wirklich hat das nix gebracht. 😞

    Krieg das irgendwie nicht hin.

    Hab selber auch keine Idee mehr.



  • Aus der Ferne ohne Code ist es leider nicht ganz so einfach, die richtigen Hinweise zu geben. Den erweiterten LVS_EX_DOUBLEBUFFER-Stil hast Du schon gesetzt?



  • Hm, hatte den Stil noch nicht gesetzt. 🙂

    Ist dadurch schon etwas besser geworden, es kommt natürlich auch drauf an, wielange das Sleep im Thread ist, will das aber nicht zu lange setzen, wobei es ganz gut mit Sleep(800) bzw Sleep(700) funktioniert.

    Ist aber noch nicht ganz verschwunden das Flickern, hab aber grad von der MSDN-Seite n Video zum Thema CustomDraw, Flicker und Drawing in a Window gefunden, werde mir das mal anschauen. 👍

    Ist da hier: http://msdn.microsoft.com/de-de/visualc/bb905516(en-us).aspx

    Mal sehn, was dabei rauskommt, werde mich dann dazu nochmal melden.



  • Wollte nochmal abschließend was dazu sagen, falls jemand auch ein Problem damit hat.

    Habe mich jetzt zwar doch nicht mit dem CustomDraw weiter auseinandergesetzt, aber das Flickern ist bei mir verschwunden, habe folgendes dazu gemacht:

    - LVS_EX_DOUBLEBUFFER-Stil ist gesetzt
    - setze CListCtrl::SetRedraw(FALSE), dann kommen die Daten ins ListCtrl und danach wird wieder SetRedraw(TRUE) aufgerufen, ich versuche aber auch immer nur das zu aktualisieren, was auch nötig ist
    - das größte Problem verursachte bei mir das Ausblenden der horizontalen Scrollbar (CListCtrl::ShowScrollBar(SB_HORZ, FALSE)), hatte das zum Test entfernt und das Flickern ist verschwunden
    - ich habe auch nach jedem Sendmessage ein "kurzes" Sleep im Thread, damit läuft es noch um einiges besser in meinem Fall

    Das nochmal als Zusammenfassung falls jemand auch damit nicht klar kommt.
    Sonst hilft wahrscheinlich doch nur noch CustomDraw 👍



  • Ein manuelles Ein-/Ausblenden des horizontalen Scrollbalkens ist völlig überflüssig, das macht die Listenansicht bei Verkleinerung/Vergrößerung der Spalten automatisch.

    Von einem CListCtrl::ShowScrollBar habe ich im ganzen Thread nichts gelesen, oder habe ich da etwas überlesen?



  • Nein, passt schon, hab das erst am Ende hinzugefügt, wieso ich das eigentlich gemacht habe verstehe ich sowieso nicht, habe mein Projekt jetzt nach längerer Zeit wieder bearbeitet. 😃

    Aber du hast recht und natürlich noch vielen Dank für die gute Hilfe. 👍


Anmelden zum Antworten