Balken in der Scrollbar automatisch nachführen



  • Hallo zusammen,

    ich gebe eine Liste aus.
    Wenn diese entsprechend lang wird, gibts auch die entsprechende Scrollbar.
    Und die funktioniert auch.
    Nun sortiere ich diese Liste aber auch.
    Dabei könnte es sein, dass mein Scrollbalken irgendwo in der Mitte oder am Ende oder sonstwo steht.

    Wenn ich da aber meine Sortierung ändern will, soll die Liste wieder von vorne anfangen.
    Meine Liste macht das zwar, aber der Scrollbalken verbleiibt an seiner aktuellen Possition.

    Wie kann ich den über meinen Quellcode an den Anfang setzen?
    Folgendes habe ich probiert:

    if((m_wSortKritOld != m_wSortKrit) || (m_wSortKritUpDownOld != m_wSortKritUpDown)){
            m_ScreenPosY.m_wReadZeile = 0;
            SCROLLINFO info;
            ZeroMemory(&info, sizeof(info));
            info.cbSize = sizeof(SCROLLINFO);
            info.fMask = SIF_TRACKPOS;
            HWND hwnd = ::GetForegroundWindow();
            ::GetScrollInfo(hwnd, SB_VERT, &info);
            ::SetScrollPos(hwnd, SB_VERT, 0, TRUE);
        }
    

    Ich weiss, mit der ScrollInfo mache ich eigentlich gar nix. ...

    Grüsse
    Helmut


  • |  Mod

    Ist das eine eigene Klasse?
    Wieso führst Du GetScrollInfo aus, wenn Du es doch nicht benutzt?
    Zudem macht SIF_TRACKPOS wohl keinen Sinn, wenn Du die Position meinst ist das SIF_POS.



  • @martin-richter
    Meine Anwendung hat nur ein Fenster.
    Es handelt sich auch nicht um ein Controll. Es wird einfach in dad Fenster geschrieben.
    Das macht dann seine Scrollbar.
    Und an dieser will ich nun den Balken auf den Anfang setzen.

    Ansonsten fällt mir leider nicht ein, ob ich die SCROLLINFO brauche.


  • |  Mod

    Also es ist ein eigenes Fenster? Und Du sorgst selbst für die Anzeige, und besorgst Dir beim Zeichen die Top-Row?

    D.h. wenn eine Zeile hinzukommt veränderst Du den Range des Scrollbars und setzt den auf das Ende?
    Zeig mal mehr Code.



  • Hast Du mal mit dem Debugger versucht einen Breakpoint zu setzen, um zu sehen ob das if-statement überhaupt erfüllt wird (Ob die Anwendung ins "Scope" nach dem if-statement gelangt?).



  • Hallo Martin,

    viel mehr relevanten Code habe ich eigentlich nicht.
    Ich habe kein Scrollbar Objekt dort definiert.
    Der ganze Teil hat eine "Draw()"-Fktn und darin wird "DrawZeilen(..)" , also die Fktn, die diesen Codeausschnitt enthält, aufgerufen.
    Es werden nur Rechtecke berechnet, mit denen Die Zeilen u. Spalten zusammengesetzt werden.

    Es gibt doch eine Scrollbar-Fktn! Ich war wohl doch zu früh verzweifelt.

    BOOL CViewGrafikListeStd::CheckScrollBar()
    {
    
    #ifdef PC_TABELLEN
    	BOOL bRet = TRUE;
    	BOOL bH = GlobalIsScrollBarAktiv(SCROLL_H);
    	BOOL bV = GlobalIsScrollBarAktiv(SCROLL_V);
    
    	if(m_pDC->IsPrinting())
    		return FALSE;
    
    
    	if((int)m_ScreenPosY.m_wReadZeilenMax>m_ScreenPosY.m_dwZeilenOnScreenMax || m_ScreenPosY.m_wErsteZeile>0 ){
    		if(!bV)GlobalShowScrollBar(SCROLL_V,SW_SHOW);
    		GlobalSetScrollRange(SB_VERT,0,((m_ScreenPosY.m_wReadZeilenMax-m_ScreenPosY.m_dwZeilenOnScreenMax) <=0) ? m_ScreenPosY.m_wErsteZeile:m_ScreenPosY.m_wReadZeilenMax-m_ScreenPosY.m_dwZeilenOnScreenMax,TRUE);
    		GlobalSetScrollPos(SB_VERT,m_ScreenPosY.m_wErsteZeile);
    		bRet = ((bV) ? FALSE:TRUE);
    	}
    	else {
    		if(bV) GlobalShowScrollBar(SCROLL_V,SW_HIDE);
    		bRet = ((!bV) ? FALSE:TRUE);
    	}
    	if(/*m_ScreenPosX.m_wReadSpaltenMax*/GetMaxSpalten()>m_ScreenPosX.m_dwSpaltenOnScreenMax || m_ScreenPosX.m_wErsteSpalte>0) {
    		if(!bH) GlobalShowScrollBar(SCROLL_H,SW_SHOW);
    		DWORD dwX=((m_ScreenPosX.m_wReadSpaltenMax-m_ScreenPosX.m_dwSpaltenOnScreenMax)<=0)? m_ScreenPosX.m_wErsteSpalte:m_ScreenPosX.m_wReadSpaltenMax-m_ScreenPosX.m_dwSpaltenOnScreenMax;
    		GlobalSetScrollRange(SB_HORZ,0,dwX+2 ,TRUE);
    		GlobalSetScrollPos(SB_HORZ,m_ScreenPosX.m_wErsteSpalte);
    		bRet |= ((bH) ? FALSE:TRUE);
    	}
    	else {
    		if(bH) GlobalShowScrollBar(SCROLL_H,SW_HIDE);
    		bRet |= ((!bH) ? FALSE:TRUE);
    	}
    	return bRet;
    #else
    	return FALSE;
    #endif
    }
    

    Und das wäre die "Draw()"-Fktn:

    BOOL CViewProdukteListe::Draw(CDC* pDC,pCBaseAnlage pAnlage,DWORD dwLastAutoPrintListeTime)
    {
        DWORD wZeilenPos;
        WORD wSpaltenPos;
        CString csPath;
        CString cProgrammName;
    
    	if(!pAnlage) 
    		return FALSE;
    
    	m_pDC					= pDC;
    	m_pAnlage				= pAnlage;
    	m_cFormatVar.SetAnlage(pAnlage);
    	wZeilenPos	= m_ScreenPosY.m_wErsteZeile;
    	wSpaltenPos	= m_ScreenPosX.m_wErsteSpalte;
    	if(m_pDC->IsPrinting()) {
    		m_ScreenPosY.m_wErsteZeile	= 0;
    		m_ScreenPosX.m_wErsteSpalte = 0;
    	}
    
    	m_bUseTabellenPos=FALSE;
    
        CString csFile = GetProdukteListeFileFromBackupPath();// HP, 17.04.18: Legt fehlendes Verzeichnis an, wenn Netzwerk verfügbar.
    	BOOL bIsExisting = IsExisting(&csFile);
    	if(m_bInitData>0) {// HP, 20.04.18: Siehe hierzu "CViewGrafListeWerte::Draw(..)"
    	    AppBeginWaitCursor();
    	    if(m_bInitData == 3) {
    		    m_bInitData = 2;
    		    m_bPrintSelectedOnly=TRUE;
    	    }
    	    else
    		    m_bPrintSelectedOnly=FALSE;
    
    	    ResetZoom();
    	    GetFaktor();				// Faktoren und Zoom bestimmen (Berücksichtigt Drucker)
    	    InitWerte();				 
    	    InitAusgabeBereiche();
            if(bIsExisting){
                BuildProdukteMaps();
    	        GetZeilenNoOfUndSpaltenbreite();// Jetzt sind alle Faktoren bestimmt um zu berechnen, was ausgegeben werden muss
    		    if(m_bInitData != 2)
    			    InitSelectArray();
    	        BerechneSpalten(FALSE);
            }
    	    SetMaxZeilenOnScreen();
    	    SetMaxSpaltenOnScreen();
    	    SetAnzahlSeiten(TRUE);
    	    SetSeite(FALSE);
    	    AppEndWaitCursor();
        }
    
    	CBrush* pOldBrush = SetBkColorAndMode();
    	CopySpaltenBeschreibung();
    	m_ScreenPosX.m_wFixFirstXSpalten=2;
    	SetSpaltenBeschreibung();
    	if(!CheckScrollBar()) {
    		DrawHeader();
    		DrawSpalten();
            if(bIsExisting)
    		    DrawZeilen();
    	}
    	ReSetSpaltenBeschreibung();
    	if(m_pDC->IsPrinting()) {
    		m_ScreenPosY.m_wErsteZeile	= wZeilenPos;
    		m_ScreenPosX.m_wErsteSpalte = wSpaltenPos;
    	}
    
    	if(pOldBrush) 
    		m_pDC->SelectObject(pOldBrush);
    	m_Brush.DeleteObject();
    	SetInitData(-1);
    
        return TRUE;
    }
    


  • @martin-richter sagte in Balken in der Scrollbar automatisch nachführen:

    Also es ist ein eigenes Fenster? Und Du sorgst selbst für die Anzeige, und besorgst Dir beim Zeichen die Top-Row?

    D.h. wenn eine Zeile hinzukommt veränderst Du den Range des Scrollbars und setzt den auf das Ende?
    Zeig mal mehr Code.

    Sorry!
    Drüber schlafen hilft meist.
    Und Dein Hinweis auf mehr Code, hat noch mehr geholfen.
    Ich habe dadurch dann doch noch mein Scrollbar-Objekt gefunden "if(!CheckScrollBar()) {"

    Vielen Dank an alle!
    Helmut