Hilfe: Überlauf??? bei CScrollView
-
Hallo,
ich habe mit der Klasse CScrollView ein Maus-Problem und brauche eine Lösung!!!!
Ich Lese eine Datei zeilenweise ein (CStringArry) und Zeige sie an. Bei kleinen Dateien gibt es keine Probleme, aber große Dateien verursachen folgendes Problem: Klickt man rechts auf den Scrollbalken um die Position manuell mit der Maus zu verschieben, gibt es scheinbar ab einer gewissen Größe/Position einen Überlauf und das Verschieben mit der Maus funktioniert nicht mehr richtig. Wunderlich ist nur, dass alle anderen Positionierungsarten (Tastatur, Klick auf die Pfeile oder unterhalb, bzw. oberhalb des Scrollbalkens) richtig funktionieren. Nur das direkte Verschieben mit der Maus funktioniert nicht. Scheinbar gibt es irgendwo einen Überlauf.Wer kann mir helfen oder einen Tipp geben?
Schon mal vielen Dank!!!
Hier noch ein paar Details:
1. Mit dem MFC-Anwendungs-Assistenten (exe) eine neue Anwndung erstellen. Projektname SVT (ScrollViewTest).
2. MFC-Anwendungs-Assistent Schritt 1: SDI auswählen.
3. MFC-Anwendungs-Assistent Schritt 2: KEINE Datenbankunterstützung.
4. MFC-Anwendungs-Assistent Schritt 3: KEINE Verbunddokumente.
5. MFC-Anwendungs-Assistent Schritt 4: Nur STATUSLEISTE und 3D.
6. MFC-Anwendungs-Assistent Schritt 5: Keine Änderungen.
7. MFC-Anwendungs-Assistent Schritt 6: Basisklasse von CView auf CScrollView ändern.
8. Fertig stellen.So das ist der Rahmen.
Weiter gehts:
1. Der Klasse CSVTDoc die Variable dispZeilen vom Typ CStringArray hinzufügen.
2. Ebenso wird dispMaxLen vom Typ long hinzugefügt.
3. Mit den Klassen-Assistenten der Klasse CSVTView (ID: ID_FILE_OPEN) die Methode OnFileOpen erzeugen.
4. Hier der Quelltext:void CSVTView::OnFileOpen() { int rc; int lZeile; unsigned long fLenght; CString sZeile; CStdioFile fi; // TODO: Code für Befehlsbehandlungsroutine hier einfügen CFileDialog fdlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Journaldateien (*.jrn)|*.jrn|Alle Dateien (*.*)|*.*||"); CSVTDoc* pDoc = GetDocument(); rc = fdlg.DoModal(); if (rc == IDOK) { pDoc->dispZeilen.RemoveAll(); if (fi.Open(fdlg.GetFileName(), CFile::modeRead)) { fLenght = fi.GetLength(); lZeile = 0; pDoc->dispMaxLen = 10; // Initialisierung while (fi.GetPosition() < fLenght) { lZeile++; fi.ReadString (sZeile); if (sZeile.GetLength() > pDoc->dispMaxLen) pDoc->dispMaxLen = sZeile.GetLength(); pDoc->dispZeilen.Add (sZeile); } fi.Close(); Invalidate(); // erzwingt ein Zeichnen über OnDraw } } }
Weiter geht's:
1. Der Klasse CSVTView die beiden int-Variablen lineHeight und lineWidth hinzufügen.
2. Die Klasse CSVTView um die folgende Methode erweitern:void CSVTView::SetNewScrollSizes(unsigned long x, unsigned long y) { CRect cr; GetWindowRect(&cr) ; CSize sizeTotal; sizeTotal.cx = x*lineWidth+20; sizeTotal.cy = y*lineHeight+20; // Zeichenhöhe + 20 Pixel Zugabe CSize sizePage; sizePage.cx = (((cr.Width()-10)/lineWidth)-1) * lineWidth; sizePage.cy = (((cr.Height()-10)/lineHeight)-1) * lineHeight; CSize sizeLine; sizeLine.cx = lineWidth; sizeLine.cy = lineHeight; // SizePage und sizeLine muessen unbedingt gesetzt werden, sonst ist das Scrolling-Verhalten nicht vernueftig !!! SetScrollSizes(MM_TEXT, sizeTotal, sizePage, sizeLine); }
3. Die OnDraw-Methode so ergänzen:
void CSVTView::OnDraw(CDC* pDC) { // Initialisierung bool doCopy = false; CSVTDoc* pDoc = GetDocument(); // Y-Postion der Ausgabe int nYPos = 10; unsigned long nZeilen; unsigned long nZeichen; CRect rect; ASSERT_VALID(pDoc); CFont myFont; myFont.CreatePointFont(100,"Courier New"); // Schriftgroesse 10pt pDC->SelectObject(&myFont); // Zuerst Hoehe des akt. Zeichensatzes auslesen TEXTMETRIC strFontData; pDC->GetTextMetrics(&strFontData); nZeilen = pDoc->dispZeilen.GetSize(); nZeichen = pDoc->dispMaxLen; lineWidth = strFontData.tmAveCharWidth; lineHeight = strFontData.tmHeight; SetNewScrollSizes(nZeichen, nZeilen); // Ansicht abhaengig von der Position zeichnen pDC->GetClipBox(&rect); unsigned long StartPos = rect.top / strFontData.tmHeight; if (StartPos > 0) StartPos--; unsigned long EndPos = rect.bottom / strFontData.tmHeight; EndPos++; if (EndPos > nZeilen) EndPos = nZeilen; // Ausgabe for (unsigned int i = StartPos; i < EndPos; i++) pDC->TextOut(10, nYPos+i*strFontData.tmHeight, pDoc->dispZeilen.GetAt(i)); }
Fertig !!!
Das ganze funktioniert aber leider nur für kleine Dateien. Ab einer gewissen Größe klappt das Verschieben mit dem Mauszeiger nicht mehr. Alle anderen Funktionen machen keine Probleme.
Wer kann helfen?
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
Hat jemand Ideen oder Vorschläge?