Listboxen - synchron scrollbar ?



  • es verwirrt mich wo ich das nutzen kann zum scrollen


  • Mod

    Fange WM_VSCROLL ab.
    Führe den Default durch.
    Besorge die den neuen Top Index (GetTopIndex), setzte den neuen top Index in dem anderen Control.



  • tut mir leid, aber ich versteh das nicht

    was meinst du mit "fuehre default durch" ?
    so wie ich das hab find ich das logisch, wenn zeile hoch, dann an beiden listboxen ein lineup senden, genauso mit linedown



  • @Mr Evil,

    meintest du so etwas ???
    http://ramveg1.100webspace.net
    download: test_clistbox.rar

    Eingaben/Bewegungen an der internen Scrollbar der linken Listbox werden an die rechte Listbox weitergegeben !!!

    cu veganza



  • genau - ohne das ich eine eigene progressbar erstellen muss - so hab ich das bisher geloest



  • und wo genau hast du jetzt die Probleme ???

    ich habe einfach ein neue Klasse erstellt, diese von CListBox abgeleitet und darin dann die OnVScroll() überschrieben und reagiere auf momentan 3 Messages ( SB_LINEDOWN, SB_LINEUP, SB_THUMBTRACK ).

    In der abgeleiteten Klasse habe ich dann nur noch eine Funktion implementiert mit der du ein CWnd* übergeben kannst ( für die zweite Listbox ), um auf die andere ( die rechte ) Listbox zugreifen zu können.

    die linke Listbox ist "ge-subclassed" mit der abgeleiteten CListBox Klasse, die rechte Listbox ist eine "normale" CListBox.

    benutze mal Spy++ um zu schauen was da genau abgeht ( MESSAGES )... denn Dein Dialog bekommt von den Bewegungen an der "internen Scrollbar" nur sehr bedingt was mit !!!

    du mußt also eine eigene Klasse von CListBox ableiten und darin Deine Auswertung/Funktionen implementieren...

    versuchs mal selbst zu implementieren... wenn Du Probleme hast melde dich wieder 😉

    cu veganza



  • irgendwie kapier ich das nicht

    also

    ich hab mal ein testdialog gemacht, da zwei listboxen erstellt, und die beim oninitidialog fuellen lassen sodass man scrollen kann

    dann eine klasse erstellt:

    #pragma once
    #include "afxwin.h"
    
    class OwnListBoxes : public CListBox
    {
    protected:
    	DECLARE_MESSAGE_MAP()
    
    	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar);
    };
    

    und dann die entsprechende cpp dazu:

    #include "stdafx.h"
    #include "TestProj.h"
    #include "TestProjDlg.h"
    #include "OwnListBoxes.h"
    
    BEGIN_MESSAGE_MAP(OwnListBoxes, CListBox)
    	ON_WM_VSCROLL()
    END_MESSAGE_MAP()
    
    void OwnListBoxes::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar)
    {
    	int i=0;
    }
    

    bei int i=0; hab ich n haltepunkt gesetzt, und ich seh das egal was ich mach das programm nie dahin kommt
    als wenn den die klasse voellig egal ist

    ich hab auch schon probiert das ich rechtsklick auf die listbox, add class - von CDialog abgeleitet {besseres war ne zur auswahl} dann ne eigene klasse erstellt und da diese neue klasse abgeleitet - in beiden hab ich auch versucht das VScroll abzufangen - ging alles nicht }=



  • ha, ich habs

    mein problem war die variable die ich zum fuellen benutzt hatte, das war ne eigene

    void CTestProjDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	DDX_Control(pDX, IDC_LIST1, m_myListBox);
    	DDX_Control(pDX, IDC_LIST2, m_List2);
    }
    

    da hab ich es von "m_List1" auf "m_myListBox" geaendert und in meiner haupt dialogklasse

    public:
    	CTestProjDlg(CWnd* pParent = NULL);	// standard constructor
    	enum { IDD = IDD_TESTPROJ_DIALOG };
    
    	COwnListBoxes m_myListBox;
    


  • nu stellt sich mir die frage wie ich die neue scrollposition in der zweiten liste setz, du hast etwas von einer funktion mit *Wnd geschrieben - da bin ich grad etwas ratlos was ich da zu tun habe

    mein erster versuch war, das ich bei ListA::OnVScroll gleich den aufruf zu ListB::OnVScroll mach, das problem hierbei ist der pointer auf die scrollbar, ich braeuchste ja den pointer auf die zweite liste

    ps. die zweite liste hab ich auch das OnVScroll ueberschrieben da ich es auch umgekehrt abhaengig machen moechte

    dazuedit

    ich hab nu in der scroll klasse A eine funktion die die pointer auf die scrollbars annehmen sodass ich das senden kann

    aber die sind immer null, auch die in der ersten OnVScroll (pScrollBar) sind immer null, im prinzip isses da egal wie ich es aufruf /=

    void OwnListBoxesA::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar) 
    { 
        CListBox::OnVScroll(nSBCode, nPos, pScrollBar); // pScrollBar ist immer NULL
    }
    


  • naja eigentlich ganz einfach:

    1. lege in Deiner abgeleiteten ListBox Klasse eine private Membervariable vom Type CWnd* an

    2. implementiere eine Funktion damit diese CWnd* Variable "von außen" gesetzt werden kann

    void CMyListbox::SetSlaveLB_Handle(CWnd *pWnd)
    {
    	m_hLB = pWnd;  //m_hLB ist die Membervariable in Deiner CListBox Klasse ( siehe Punkt 1. )
    }
    

    3. in der OnitDialog() von Deiner Dialoganwendung übergibst du dann den Pointer in die abgeleitete Klasse und kannst dann in der Klasse selbst darauf zugreifen !!!

    m_cMyListbox.SetSlaveLB_Handle( GetDlgItem( IDC_LIST1 ) ); // eine Überprüfung ob das Handle "valid" ist wäre nicht schlecht !!!
    

    alternativ kannst du Dir natürlich auch über:

    AfxGetMainWnd()->GetDlgItem(IDC_LIST1);
    

    direkt in Deiner abgeleiteten Klasse Zugriff auf die ListBox holen !!!

    hoffe das hilft Dir weiter 😉

    cu veganza



  • Kurze Zwischenfrage

    Falls du möchtest, dass man Elemente aus zwei Spalten glichzeitig sieht, kann man doch drei andere einfachere Wege gehen:

    • Man nehme CListView und fertig - ohne irgendwelche weiteren tiefgehenden Codes
    • eine Listbox und CListBox::DrawOwnItem verändern, so dass es zwei Spalten einzeigt
    • Diesmal werden drei Steuerelemente benötigt: 2 Listboxen, die keine Scrollbar haben, und eine externe Scrollbar (als Steuerelement direkt auf den Dialogfeld oder sonstwo) dazwischen. (ganz grob, im etwa, in der nähe von dem was ihr hier macht)

    Mit freudlichen Grüßen
    Rhombicosidodecahedron



  • Rhombicosidodecahedron schrieb:

    Kurze Zwischenfrage
    Falls du möchtest, dass man Elemente aus zwei Spalten glichzeitig sieht, kann man doch drei andere einfachere Wege gehen:

    das muß Mr Evil beantworten...

    die Problemstellung war das zwei Listboxen über die interne Scrollbar synchron scrollbar sein sollen !!!

    cu veganza



  • veganza schrieb:

    Rhombicosidodecahedron schrieb:

    Kurze Zwischenfrage
    Falls du möchtest, dass man Elemente aus zwei Spalten glichzeitig sieht, kann man doch drei andere einfachere Wege gehen:

    das muß Mr Evil beantworten...

    die Problemstellung war das zwei Listboxen über die interne Scrollbar synchron scrollbar sein sollen !!!

    Ich meine ja nur, dass man flexibel sein sollte (vor allem beim Lösen von Problemen) und nicht bis "Teufel-komm-raus" einen für einem zu schwierigen Problem sitzt und nicht weiterkommt.

    Mit freundlichen Grüßen und hoffend veganza nicht weiter zu verärgern
    Rhombicosidodecahedron



  • Rhombicosidodecahedron schrieb:

    Ich meine ja nur, dass man flexibel sein sollte (vor allem beim Lösen von Problemen) und nicht bis "Teufel-komm-raus" einen für einem zu schwierigen Problem sitzt und nicht weiterkommt.

    hast schon recht... ich hätte Mr Evil mal am Anfang fragen sollen was er genau vor hat ( so wie ich es sonst eigentlich immer mache ). Ich "denke" aber er kennt das CListCtrl ( hoffentlich ) !!!

    Rhombicosidodecahedron schrieb:

    Mit freundlichen Grüßen und hoffend veganza nicht weiter zu verärgern
    Rhombicosidodecahedron

    du hast mich nicht verärgert... und sorry wenn es so rübergekommen ist... war nicht meine Absicht 😮

    cu veganza



  • also um es mal ein bissl zu verdeutlichen

    ich benutz die listboxen um den inhalt eines vectors aufzulisten, dieser ist ein CString vector und pro zeile steht ein text, diesen muss ich einzeln handeln koennen und auhc in der listbox anklicken sodass ich diesen angeklickenten holen kann

    zugriffe hab ich solche:

    void CFileRenamerDlg::SetListBevoreItems()
    {
    	int iPos = m_ListBevore.GetCurSel();
    	m_ListBevore.ResetContent();
    	CString csTemp = _T("");
    	for(size_t i=0; i<m_vcsListComplete.size(); i++){
    		if(m_CBPath.GetCheck() == TRUE)
    			csTemp += m_vcsListPath[i];
    		csTemp += m_vcsListFile[i];
    		if(m_CBExtension.GetCheck() == TRUE)
    			csTemp += m_vcsListExtension[i];
    		m_ListBevore.AddString(csTemp);
    		csTemp = _T("");
    	}
    	m_ListBevore.SetCurSel(iPos);
    	SetListBevoreScrollBar();
    }
    

    desweiteren hier und da noch ein paar get item usw

    CListCtrl war auch mein erster gedanke, nur da find ich kein addstring oder sonstiges

    ich hab mal mein testpeoject wegen den synchronen scrollen hochgeladen, das sind meine bisherigen versuche mit dem ueberschriebenen OnVScroll

    Klick
    Klick
    das zweite, da hatte ich vor die erste ebenfals abhaengig vom zweiten zu machen

    btw: das eigentliche problem hatte ich ja schon geloest mit einer zusaetzlichen scrollbar siehe seite 1 - nur das ich das mitlerweile alles auf dieses SetTopIndex geaendert hab
    {vielen dank auch dafuer an den ideen-schubser} {=

    ich hab kein abgabetermin usw, darum kann ich mir zeit lassen und an diesem problem rumprobieren

    diese anderen ideen, zb zwei reihen geht nicht, da die listen fast immer unterschiedlichen inhalt haben werden, und auch horizontal scrollbar {einzeln} sein muessen


  • Administrator

    Ehm, kein AddString in einem CListCtrl und du gibst schon auf? ^^
    Hier mal ein kleines Beispiel wie man ein CListCtrl füllen kann:

    CListCtrl* pMyListCtrl; // Dein ListCtrl, welches auch auf etwas zeigen sollte :D
    
    // Zuerst mal, falls schon was drin wäre, leeren wir das CListCtrl komplett, samt den Kolonnen
    // Zuerst alle Items raus.
    pMyListCtrl->DeleteAllItems();
    
    // Danach alle Kolonnen.
    while(pMyListCtrl->GetHeaderCtrl()->GetItemCount() > 0)
    { pMyListCtrl->DeleteColumn(0); }
    
    // Wir fügen nun 3 Kolonnen ein.
    pMyListCtrl->InsertColumn(0, _T("Kolonne 1"), LVCFMT_LEFT, 100);
    pMyListCtrl->InsertColumn(1, _T("Kolonne 2"), LVCFMT_LEFT, 110);
    pMyListCtrl->InsertColumn(2, _T("Kolonne 3"), LVCFMT_LEFT, 50);
    
    // Wir haben nun ein Array arObject. Jedes Objekt hat 3 CStrings: strA, strB, strC
    for(int i = 0; i < nCount; ++i)
    {
        pMyListCtrl->InsertItem(i, arObject[i].strA);
        pMyListCtrl->SetItemText(i, 1, arObject[i].strB);
        pMyListCtrl->SetItemText(i, 2, arObject[i].strC);
    }
    

    Ich hoffe das hilft dir beim Verständnis des CListCtrls und hilft dir bei der Lösung deines Problems.
    Edit: Das CListCtrl sollte natürlich dann im Report Style sein! ^^

    Referenzen
    CListCtrl Overview
    CListCtrl::DeleteAllItems
    CListCtrl::GetHeaderCtrl
    CListCtrl::DeleteColumn
    CListCtrl::InsertColumn
    CListCtrl::InsertItem
    CListCtrl::SetItemText
    CHeaderCtrl Overview
    CHeaderCtrl::GetItemCount

    Grüssli



  • ich hab grad nochmal geschaut und dann ists mir wieder eingefallen

    CListCtrl hab ich bereits versucht und befuellt gehabt, dort war mein problem das er die items sobald es in der hoehe voll war in einer zweiten reihe angefangen hat und nur horizontal scrollen liess {hattes auf list gestellt}

    es muss aber alles nur untereinander - direkt wie in einer listbox, und das egal wieviele items {koennen bis ueber 10000 gehen}

    //dazuedit - ausserdem hat die funktion ebenfals kein OnVScroll welches ich direkt in der dialog klasse ueberschreiben kann
    {editbox hat des}


  • Administrator

    Mr Evil schrieb:

    CListCtrl hab ich bereits versucht und befuellt gehabt, dort war mein problem das er die items sobald es in der hoehe voll war in einer zweiten reihe angefangen hat und nur horizontal scrollen liess {hattes auf list gestellt}

    es muss aber alles nur untereinander - direkt wie in einer listbox, und das egal wieviele items {koennen bis ueber 10000 gehen}

    Du musst den Style auf LVS_REPORT setzen. Dann ist es so, wie in einem Windows-Ordner, welcher in der Ansicht auf Details gesetzt wurde. Da kannst du zig Millionen untereinander auflisten 😉

    Mr Evil schrieb:

    //dazuedit - ausserdem hat die funktion ebenfals kein OnVScroll welches ich direkt in der dialog klasse ueberschreiben kann
    {editbox hat des}

    CListCtrl hat aber die Nachricht WM_VSCROLL und WM_HSCROLL, welche man abfangen kann und dann hast du deine Funktionen OnVScroll und OnHScroll. Allerdings ist dann die Frage, ob du dies noch brauchst, wenn du ja in einem ListCtrl mehrere Kolonnen hast. Die Scrollen ja bereits alle zusammen 😉

    Grüssli



  • Dravere schrieb:

    Du musst den Style auf LVS_REPORT setzen. Dann ist es so, wie in einem Windows-Ordner, welcher in der Ansicht auf Details gesetzt wurde. Da kannst du zig Millionen untereinander auflisten 😉

    das is bloed, dann hab ich ja oben diese leiste, die brauch ich gar nicht

    Dravere schrieb:

    CListCtrl hat aber die Nachricht WM_VSCROLL und WM_HSCROLL, welche man abfangen kann und dann hast du deine Funktionen OnVScroll und OnHScroll. Allerdings ist dann die Frage, ob du dies noch brauchst, wenn du ja in einem ListCtrl mehrere Kolonnen hast. Die Scrollen ja bereits alle zusammen 😉

    Grüssli

    das ist ganz und gar ausgeschlossen das ich beide listen zu einer fasse, es muessen definitiv zwei getrennte listen bleiben, kolonnen sind hier voellig fehl am platz

    WM_VSCROLL und HSCROLL, kann ich die direkt in der dialog klasse ueberschreiben ? oder muss ich da wieder eine neue klasse erstellen wo ich CListCtrl ableite - das ist dann genau das selbe wie bei den normalen listboxen, und da bekomms ich mit der hilfe hier ja immernoch nicht hin /=

    // dazuedit - nope, des ON_WM_VSCROLL in der dialog klasse faengt das dieser liste nicht ab, also im prinzip genau das selbe problem wie bei der normalen listbox, da kann ich gleich lassen was ich hab mit der zusaetzlichen scrollbar


  • Administrator

    Mr Evil schrieb:

    das is bloed, dann hab ich ja oben diese leiste, die brauch ich gar nicht

    Kannst du abstellen mit dem Style LVS_NOCOLUMNHEADER.

    Mr Evil schrieb:

    das ist ganz und gar ausgeschlossen das ich beide listen zu einer fasse, es muessen definitiv zwei getrennte listen bleiben, kolonnen sind hier voellig fehl am platz

    Sicher? Sicher dass du nicht einfach zu verbohrt auf eine Lösung bist? Es wurde ja schon mal gesagt, dass man vielleicht auch andere Wege in betracht ziehen sollte.

    Mr Evil schrieb:

    WM_VSCROLL und HSCROLL, kann ich die direkt in der dialog klasse ueberschreiben ? oder muss ich da wieder eine neue klasse erstellen wo ich CListCtrl ableite - das ist dann genau das selbe wie bei den normalen listboxen, und da bekomms ich mit der hilfe hier ja immernoch nicht hin /=

    // dazuedit - nope, des ON_WM_VSCROLL in der dialog klasse faengt das dieser liste nicht ab, also im prinzip genau das selbe problem wie bei der normalen listbox, da kann ich gleich lassen was ich hab mit der zusaetzlichen scrollbar

    Mr Evil schrieb:

    //dazuedit - ausserdem hat die funktion ebenfals kein OnVScroll welches ich direkt in der dialog klasse ueberschreiben kann
    {editbox hat des}

    Klar musst du von CListCtrl eine Klasse ableiten, um auf die entsprechenden Nachrichten reagieren zu können. Allerdings ist das bei einem CEdit nicht anderst. CEdit hat soweit ich weiss keine öffentlichen OnVScroll oder OnHScroll Funktionen.

    Hmm willst du vielleicht mal erklären was du machen willst? Also nicht die Lösung, welche du anstrebst, sondern das Problem! Was willst du darstellen, wie und wieso? Würde mich nämlich auch langsam wunder nehmen, wieso es nur diesen Lösungsweg gibt ^^

    Grüssli


Anmelden zum Antworten