TListView CustomSort für BCB2009
-
Für eine ListView habe ich im C++Builder V6.0 zum Sortieren der Spalten den folgenden Code erstellt und seit Jahren erfolgreich verwendet. Nach der Umstellung auf C++Builder 2009 wird bei der Sortierung nach der ersten Spalte das Caption einiger Zeile zerstört. Die Routinen für die übrigen Spalten funktionieren einwandfrei.
Weiss jemand warum ??
Oder besser, was muss ich ändern ??//--------------------------------------------------------------------------- int __stdcall TlvDialog::SortCaptionAufwaerts(long Item1, long Item2, long ParamSort) { iZahl1 = StrToInt(((TListItem *)Item1)->Caption.c_str()); iZahl2 = StrToInt(((TListItem *)Item2)->Caption.c_str()); return (iZahl1 - iZahl2); } //--------------------------------------------------------------------------- int __stdcall TlvDialog::SortCaptionAbwaerts(long Item1, long Item2, long ParamSort) { iZahl1 = StrToInt(((TListItem *)Item1)->Caption.c_str()); iZahl2 = StrToInt(((TListItem *)Item2)->Caption.c_str()); return (iZahl2 - iZahl1); } //--------------------------------------------------------------------------- //########################################################################### //### On ColumnClick-Ereignis //########################################################################### void __fastcall TlvDialog::FifoColumnClick(TObject *Sender, TListColumn *Column) { Items->BeginUpdate(); Columns->BeginUpdate(); // Sortieren switch (Column->Index) { case 0: // lfd. Nummer if ( this->Column[Column->Index]->Caption.SubString(1,1) == ">") { this->Column[Column->Index]->Caption.Delete(1,2); this->Column[Column->Index]->Caption = "< " + this->Column[Column->Index]->Caption; this->CustomSort(SortCaptionAbwaerts,0); } else { if ( this->Column[Column->Index]->Caption.SubString(1,1) == "<") this->Column[Column->Index]->Caption.Delete(1,2); this->Column[Column->Index]->Caption = "> " + this->Column[Column->Index]->Caption; this->CustomSort(SortCaptionAufwaerts,0); } break; . . . .
-
Mecki schrieb:
Weiss jemand warum ??
Ich werde mal mutmaßen.
Dein Problem dürfte darin begründet sein, daß du Properties wie Variablen verwendest. Das resultiert, obgleich der Compiler daran nichts auszusetzen hat, in undefiniertem Verhalten.
Für Properties gilt:- Sie können immer als R-Value-Werte benutzt werden.
- Sie verhalten sich in genau einem Fall wie L-Value-Werte: bei der direkten Zuweisung. Diese wird übersetzt von
obj->Property = Value;
zuobj->SetProperty (Value);
oder zuobj->FProperty = Value;
, je nachdem, ob als Property-Setter eine Funktion oder eine Membervariable angegeben ist.
Alle anderen L-Value-Zugriffe sind undefiniert. Das umfaßt sämtliche kombinierten Zuweisungsoperatoren (+=, -=, *=, /=, &=, ^=, |=, %=), unäre Operatoren wie Inkrement und Dekrement, die Übergabe per Referenz oder Zeiger (sofern nicht const) und den Aufruf nicht konstanter Memberfunktionen.
- Es gibt eine Ausnahme von obiger Regel, und zwar im Falle skalarer Typen, also für alle Typen, bei denen der Compiler kombinierte und explizite Zuweisung austauschen darf. Hat das entsprechende Property einen skalaren Typ, so ist auch die Verwendung kombinierter Zuweisungsoperatoren und unärer Operatoren erlaubt:
++ProgressBar->Position; // wird vom Compiler durch ProgressBar->Position = ProgressBar->Position + 1; ersetzt
Eine derartige Substitution ist natürlich für selbstdefinierte Typen nicht gestattet; dementsprechend können diese Operatoren für Properties nichtskalarer Typen nicht benutzt werden.
Du machst mehrfach so etwas:
this->Column[Column->Index]->Caption.Delete(1,2);
Durch das Aufrufen einer nicht konstanten Memberfunktion verstößt du gegen die Regeln zur Nutzung von Properties.
-
Zumal AnsiString.Delete den resultierenden String zurückgibt und nicht den AnsiString an sich verändert.
Nur so gehts:
AnsiString foo="foo"; foo=foo.Delete(1,1);
mfg
xXx
-
-=]xXx[=- schrieb:
Zumal AnsiString.Delete den resultierenden String zurückgibt und nicht den AnsiString an sich verändert.
?
C++Builder 2007-Dokumentation schrieb:
System::AnsiString::Delete entfernt ab der durch index bezeichneten Position count Zeichen aus dem System::AnsiString, dessen erstes Zeichen den Index 1 hat. Die Methode gibt den sich daraus ergebenden geänderten String (*this) zurück.
-
MMhhh mist ^^
Kommt davon wenn man zuviel mit Java fremd geht. Wobei ich hier aber auch mal anmerken muss, dass das in Java bescheiden gemacht ist. Objektmethoden sollten auch das Objekt ändern...
Aber das war ja gar nicht Thema...mfg
xXx