Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   

Die mobilen Seiten von c++.de:
http://m.c-plusplus.de
Infos hier [BETA]

  
c++.de :: VCL (C++ Builder) ::  StringGrid und Scrollprobleme     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
elektroniker_lehrling
Mitglied

Benutzerprofil
Anmeldungsdatum: 15.11.2006
Beiträge: 28
Beitrag elektroniker_lehrling Mitglied 18:15:59 11.07.2012   Titel:   StringGrid und Scrollprobleme            Zitieren

Hallo...

Folgendes Problem. Habe ein Programm, in dem zwei Tabellen miteinander verglichen werden. Weicht die Spalte A eines Datensatzes der Tabelle A von dem mit Tabelle B ab, wird die Linie rot, weicht die Spalte B ab, wird die Linie gelb und wenn alles identlisch ist, dann wird die Zeile grau. Soweit so gut, funktioniert alles.

Des weiteren habe ich eine Funktion, bei der, wenn in Tabelle A gescrollt wird, auch Tabelle B gescrollt wird.

Den Code verwende ich wie hier: http://codezentrale.bplaced.net/dcz/?p=2142

Arbeitet man mit den Auf-Ab-Pfeilen im Scrollbalken funktioniert auch das. Doch jetzt kommt der Haken: Scrollt man mit dem MouseWheel oder mit den Auf-Ab-Pfeil-Tasten (Tastatur) treten Schönheitsfehler auf:

Ab und zu wechselt der Fokus der Tabelle den String Grid (also von SG1 auf SG2 oder umgekehrt). Dadurch springt dann die Position von SG1 unten auf SG2 oben und die nächsten Moves beim Scrollen haben kein Effekt, bis der Curser wider unten angekommen ist.

Je nachdem wiviele farbige Zeilen dass existieren und wiviele Rows mit verschieden hohen Zeilen exisiteren, passiert das ganze sehr häufig. Ein wirkliches Muster ist jedoch nicht erkennbar.

Folgende Lösungsansätze würde ich gerne probieren:

1. nach dem Scrollereigniss den Focus auf die Tabelle setzen, die vorher aktiv war. Das Problem dabei:
C++:
StringGrid2TopLeftChanged(TObject *Sender)

ändert auch bei der Tabelle, die nur auf das Scrollereigniss reagiert. So wie im Beispiel von codezentrale wird beim scrollen in SG1 zuerst
C++:
void __fastcall TForm1::StringGrid1TopLeftChanged(TObject *Sender)
aufgerufen, danach
C++:
void __fastcall TForm1::StringGrid2TopLeftChanged(TObject *Sender)
. Jedoch nur im Normalfall. Bei unterschiedlichen Tabellen kann es sein, dass dann SG2 gar keine Veränderung der Eigenschaft TopLeftChanged machen muss und daher der Fokus nicht mehr zurückgesetzt wird auf SG1. Besser währe hier nur auf das Scrollereigniss zu reagieren(anstatt auf TopLeftChanged). Doch ich finde keine Eigenschaft OnScrollDown oder so...

2. kann man den Fokus ganz von einer Tabelle wegnehmen? Vielleicht kann er dann auch nicht mehr am falschen Ort hängen bleiben.

Vielleicht gehts ja auch ganz anders... Für Ideen danke ich im Voraus!

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void __fastcall TForm1::StringGrid1TopLeftChanged(TObject *Sender)
{
if(Form1->Scroll_On_Both->Checked){
   // vertikale ScrollBarposition von StringGrid1 ermitteln
   int iScrollPosV = GetScrollPos(StringGrid1->Handle, SB_VERT);
 
   // vertikale ScrollBarposition von StringGrid2 setzen
   SetScrollPos(StringGrid2->Handle, SB_VERT, iScrollPosV, true);
 
   // Anzeige des Inhalts von StringGrid2 an die akt. ScrollBarposition anpassen
   StringGrid2->Perform(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, iScrollPosV), 0);
 
//   StringGrid1->Selection.Top=iScrollPosV;
   }
 
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::StringGrid2TopLeftChanged(TObject *Sender)
{
 
if(Form1->Scroll_On_Both->Checked){
   // vertikale ScrollBarposition von StringGrid1 ermitteln
   int iScrollPosV = GetScrollPos(StringGrid2->Handle, SB_VERT);
 
   // vertikale ScrollBarposition von StringGrid2 setzen
   SetScrollPos(StringGrid1->Handle, SB_VERT, iScrollPosV, true);
 
   // Anzeige des Inhalts von StringGrid2 an die akt. ScrollBarposition anpassen
   StringGrid1->Perform(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, iScrollPosV), 0);
 
//   StringGrid2->Selection.Top=iScrollPosV;
   }
 
 
}
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
void __fastcall TForm1::StringGrid2DrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{  int RowHt, BiggestColWidth;
// Titelzeile: Nicht farbig bemahlen
if(ARow!=0){
   // Nur wenn der Vektor geladen ist, darf direkt darauf zugegriffen werden, ansonsten Acces Violation
   if(StringGrid2IsFilled==true){
      if(ArtStueli2[ARow-1].OnlyOnThisStueli==true){
         if(Form1->PaintDifferentArtRed->Checked==true){
            Form1->StringGrid2->Canvas->Brush->Color = clRed;
            StringGrid2->Canvas->Font->Color = clBlack;
            StringGrid2->Canvas->FillRect(Rect);
            }
         else{
            //ohne das Redrawing entstehen Pixelfehler
            Form1->StringGrid2->Canvas->Brush->Color = clWhite;
            StringGrid2->Canvas->Font->Color = clBlack;
            StringGrid2->Canvas->FillRect(Rect);
            }
         }
         else if(ArtStueli2[ARow-1].DiffDesig==true){
         if(Form1->PaintDifferentDesigYellow->Checked==true){
            Form1->StringGrid2->Canvas->Brush->Color = clYellow;
            StringGrid2->Canvas->Font->Color = clBlack;
            StringGrid2->Canvas->FillRect(Rect);
            }
            else{
            //ohne das Redrawing entstehen Pixelfehler
            Form1->StringGrid2->Canvas->Brush->Color = clWhite;
            StringGrid2->Canvas->Font->Color = clBlack;
            StringGrid2->Canvas->FillRect(Rect);
            }
         }
         else{
         if(Form1->PaintSameGrey->Checked==true){
            Form1->StringGrid2->Canvas->Brush->Color=clBtnFace;
            StringGrid2->Canvas->Font->Color = clBlack;
            StringGrid2->Canvas->FillRect(Rect);
            }
            else{
            //ohne das Redrawing entstehen Pixelfehler
            Form1->StringGrid2->Canvas->Brush->Color = clWhite;
            StringGrid2->Canvas->Font->Color = clBlack;
            StringGrid2->Canvas->FillRect(Rect);
            }
         }
 
      RowHt=DrawText(StringGrid2->Canvas->Handle, StringGrid2->Cells[ACol][ARow].c_str(), -1, &Rect, DT_WORDBREAK | DT_VCENTER | DT_LEFT | DT_CALCRECT );
      if ((RowHt + 3) > StringGrid2->DefaultRowHeight){
         StringGrid2->RowHeights[ARow] = RowHt + 3;
         }
 
      DrawText(StringGrid2->Canvas->Handle, StringGrid2->Cells[ACol][ARow].c_str(), -1, &Rect, DT_WORDBREAK | DT_VCENTER | DT_LEFT );   //  | DT_NOCLIP
      }
   }
   else{
   //Head Row
   Form1->StringGrid2->Canvas->Brush->Color = clBtnFace;
   StringGrid2->Canvas->Font->Color = clBlack;
   StringGrid2->Canvas->FillRect(Rect);
   DrawText(StringGrid2->Canvas->Handle, StringGrid2->Cells[ACol][ARow].c_str(), -1, &Rect, DT_WORDBREAK | DT_VCENTER | DT_LEFT ); // | DT_NOCLIP
   }
   //bugbehebungsversuch für scrolling fehler. problem: jedes mal bei focused() giebt es einen redraw.
/*if(FocusedGrid==1){
   Form1->StringGrid1->Focused();
   }
   else if(FocusedGrid==2){
   Form1->StringGrid2->SetFocus();
   }*/

}


Zuletzt bearbeitet von elektroniker_lehrling am 07:53:29 13.07.2012, insgesamt 1-mal bearbeitet
elektroniker_lehrling
Mitglied

Benutzerprofil
Anmeldungsdatum: 15.11.2006
Beiträge: 28
Beitrag elektroniker_lehrling Mitglied 08:33:51 13.07.2012   Titel:   Lösung gefunden!            Zitieren

Habe mittlerweile die Lösung gefunden. Am Ende wars ganz einfach... Das Problem wird behoben, in dem nicht die Position des Scrollbalkens verändert wird, sondern die Eigenschaft TopRow. Die Darstellung ist danach zwar minim anders, (Bei unterschiedlich hohen Rows wird jetzt nicht mehr gleich viele % gescrollt, sondern in beiden Tabellen einfach bis zum nächsten Row) jedoch ist das für meinen Fall nicht wirklich störend, eher etwas besser.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void __fastcall TForm1::StringGrid1TopLeftChanged(TObject *Sender)
{
if(Form1->Scroll_On_Both->Checked){
   if(Form1->StringGrid2->RowCount>Form1->StringGrid1->TopRow){
      Form1->StringGrid2->TopRow=Form1->StringGrid1->TopRow;
      }
   }
 
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::StringGrid2TopLeftChanged(TObject *Sender)
{
 
if(Form1->Scroll_On_Both->Checked){
   if(Form1->StringGrid1->RowCount>Form1->StringGrid2->TopRow){
      Form1->StringGrid1->TopRow=Form1->StringGrid2->TopRow;
      }
   }
 
 
}


Soweit ich das nachvolziehen kann, treten die Scroll-Probleme mit der Routine von Codezetrale dann auf, wenn Tabellen mit unterschiedlich hohen Zeilen gescrollt werden.


Zuletzt bearbeitet von elektroniker_lehrling am 08:38:06 13.07.2012, insgesamt 1-mal bearbeitet
c++.de :: VCL (C++ Builder) ::  StringGrid und Scrollprobleme   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.