![]() |
Probleme mit TStrings.IndexOfName unter Vista
Folgender Sachverhalt:
ich habe eine Liste mit einer Reihe von Name= Wert Paaren: blabla=1 dd=2 .... huebn=32 ... hübn=8763 ... usw=hjsd Wenn ich unter Windows XP und früher liste.indexOfName('hübn') aufrufe, erhalte ich wie erwartet den Index dieses Namens. Mache ich das ganze unter Vista, bekommen ich den Index von 'huebn' :shock: Folgender Code zeigt die betreffenden Quellen von Delphi 6
Delphi-Quellcode:
Ich schätze mal CompareString mit LOCALE_USER_DEFAULT ist der Übeltäter.
function TStrings.CompareStrings(const S1, S2: string): Integer;
begin Result := AnsiCompareText(S1, S2); end; function AnsiCompareText(const S1, S2: string): Integer; begin {$IFDEF MSWINDOWS} Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PChar(S1), Length(S1), PChar(S2), Length(S2)) - 2; {$ENDIF} {$IFDEF LINUX} Result := WideCompareText(S1, S2); {$ENDIF} end; Hat jemand so ein Verhalten schon einmal beobachtet? Was kann ich da machen? Sie der betreffende Quelltext von Delphi in späteren Versionen evtl. anders aus? MSDN hat mich auch noch nicht weiter gebracht. |
Re: Probleme mit TStrings.IndexOfName unter Vista
uih, gut zu wissen, habs auch gleich mal getestet ... das kann ja wirklich böse folgen haben sowas ...
hab gerade mal in VCL von D2006 geguckt, die sieht ganz gleich aus [edit] wharscheinlich haben die das feature eingebaut, damit man deutsche wörter besser sortieren kann, dann macht es sinn, das ae und ä gleichwertig sind ... |
Re: Probleme mit TStrings.IndexOfName unter Vista
Hm, schön für die Sortierung und dieses neue "Feature". Nur leider entgegen der bisherigen Funktionsweise.
Ich werd morgen mal die verschiedenen Parameter für CompareString prüfen. Vielleicht betrifft es ja nur AnsiSameText und mit AnsiSameStr funktioniert es. Würde heissen, TString geht so dann nicht mehr, TStringList müsste dann auf CaseSensitive = true gesetzt werden. Mal gucken. |
Re: Probleme mit TStrings.IndexOfName unter Vista
Push :duck:
Ich weiß, dass das erst nach 24 Stunden erlaubt ist, aber bei der Brisanz des Themas musste ich mal. Das rumprobieren mit den verschiedenen Flags von ![]() Folgendes unter Vista sollte eigentlich keine MessageBox bringen, bringt es aber
Delphi-Quellcode:
Selbst wenn es ein Problem der Funktionsparameter ist, wäre das ja echt grass. Dann müsste ich ja die Delphi-Quellen anpassen. :shock:
if (CompareStringW(LOCALE_USER_DEFAULT, 0, 'HÜBNER', Length('HÜBNER'),
'HUEBNER', Length('HUEBNER')) - 2) = 0 then ShowMessage('Fehler'); Hat jemand eine Idee, was man da tun sollte? |
Re: Probleme mit TStrings.IndexOfName unter Vista
Wie sehen die Ländereinstellungen unter XP und Vista aus?
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Auf den ersten Blick gleich.
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Habs zwar noch nicht ganz verstanden was die im
![]() |
Re: Probleme mit TStrings.IndexOfName unter Vista
Falls jemand das Plattform-SDK hat, könnte der mal die Werte von
Zitat:
|
Re: Probleme mit TStrings.IndexOfName unter Vista
#define NORM_IGNORECASE 0x00000001 // ignore case
#define NORM_IGNORENONSPACE 0x00000002 // ignore nonspacing chars #define NORM_IGNORESYMBOLS 0x00000004 // ignore symbols #define LINGUISTIC_IGNORECASE 0x00000010 // linguistically appropriate 'ignore case' #define LINGUISTIC_IGNOREDIACRITIC 0x00000020 // linguistically appropriate 'ignore nonspace' #define NORM_IGNOREKANATYPE 0x00010000 // ignore kanatype #define NORM_IGNOREWIDTH 0x00020000 // ignore width #define NORM_LINGUISTIC_CASING 0x08000000 // use linguistic rules for casing //Edit die neuem Parameter als Flag bringen keine Besserung des Ergebnisses. |
Re: Probleme mit TStrings.IndexOfName unter Vista
Also aus meiner Sicht gäbe es nur folgende Lösungen.
1. Kein Vista benutzen bzw. die Einstellung finden, die den Mist verzapft 2. Einen API-Hook für CompareString,CompareStringA,CompareStringW schreiben und auf StrICompW, StrCompW umbiegen, die es in vielen Unicode-Bibliotheken gibt (JCL, Unicode.pas von Mike Lischke) Ansi-Variante bietet Delphi mit SameText und SameStr Wäre 2. sinnvoll? Ist das unter Vista mit Benutzerrechten möglich? Vielleicht langt es ja schon, wie bei TNTs InstallTntSystemUpdates die Delphi-Functionen zu patchen. |
Re: Probleme mit TStrings.IndexOfName unter Vista
Zitat:
Damit wäre ja der erste TNT-Fork da ;-) |
Re: Probleme mit TStrings.IndexOfName unter Vista
Zitat:
|
Re: Probleme mit TStrings.IndexOfName unter Vista
wir nutzen keine DLL's, von daher...
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Zitat:
Der Fehler das Problem kann ja durch unerwartete Daten auf API-Ebene schon auftreten. Und irgendwelche (System-)DLL's läd auch ein Hello-World-Programm. |
Re: Probleme mit TStrings.IndexOfName unter Vista
Also heisst das was? API-Hook?
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Zitat:
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Ja sicher, die Funktion CompareString in kernel32.dll. Ob mir da MS einen Patch macht? :gruebel:
Ansonsten nutzen wir zwangsweise nur System-Dlls. Eigentlich müsste es ja ausreichen, den Einsprungscode in Delphi umzubiegen. Ich möchte ja nur, das WideSameText und WideSameStr (TStringList) wieder richtig arbeiten. Was ein CompareString-Aufruf in irgend einer gelinkten dll zurück bekommt, ist mir eigentlich relativ Schnitte. Betrifft schlimmstenfalls irgend eine GUI-Komponente, aber das ist zu verkraften. |
Re: Probleme mit TStrings.IndexOfName unter Vista
Hallo,
den eigentlichen "Fehler" haben leider die VCL-Macher verbrochen. Sie hätten, auch nach dem seinerzeit aktuellen PSDK, einen eigenen Aufruf von CompareString() mit LOCALE_INVARIANT verwenden müssen, anstatt auf ihre lokalisierte Funktion AnsiSameText() zurückzugreifen. Das Thema gehört jetzt wohl nach Delphi-Bugs ... Grüße vom marabu |
Re: Probleme mit TStrings.IndexOfName unter Vista
Hast Du mal eben den Wert von LOCALE_INVARIANT bei der Hand? Bin grad unter XP und hab da das SDK nicht drauf.
Wieso muss ich immer der Erste sein, bei dem so was passiert. |
Re: Probleme mit TStrings.IndexOfName unter Vista
Zitat:
is ja gar keine Konstante. wird mit (MAKELCID(MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT)) erzeugt. ![]() //EDIT Aber leider bringt das nicht wirklich was - immer noch falsch:
Delphi-Quellcode:
function MAKELCID(LangId, SortId: WORD): DWORD;
begin Result := (DWORD(SortId) shl 16) or DWORD(LangId); end; function MAKELANGID(PrimaryLang, SubLang: Word): WORD; begin Result := (SubLang shl 10) or PrimaryLang; end; procedure TForm1.TntButton3Click(Sender: TObject); const NORM_LINGUISTIC_CASING = $08000000; LINGUISTIC_IGNORECASE = $10; LANG_INVARIANT = $7F; begin if (CompareStringW((MAKELCID(MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT)), 0, 'HÜBNER', Length('HÜBNER'), 'HUEBNER', Length('HUEBNER')) - 2) = 0 then ShowMessage('Fehler'); end; |
Re: Probleme mit TStrings.IndexOfName unter Vista
Zitat:
Würde sonst wohl in der aktuellen ![]() MS hat ja schon öfters mal API-Funktionalität umdefiniert. |
Re: Probleme mit TStrings.IndexOfName unter Vista
Der Wert LOCALE_INVARIANT wird im aktuellen SDK vom Februar in der WinNT.h mittels (MAKELCID(MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT)) erzeugt. Also keine Konstante.
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Zitat:
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Tss, klappt sogar unter .NET
Delphi-Quellcode:
Das muss ich anders lösen.
if (String.Compare("HÜBNER", "HUEBNER") == 0)
{ MessageBox.Show("Gleich"); } |
Re: Probleme mit TStrings.IndexOfName unter Vista
Hallo Bernhard,
Zitat:
Win32 SDK : Topic CompareString : Section Remarks Notice that if the return value is 2, the two strings are "equal" in the collation sense, though not necessarily identical. Ich denke der für TStrings verantwortliche Entwickler ist einfach ein Opfer seiner Code-Reuse-Praxis geworden. Zitat:
Für den Fall, dass es sich dabei um einen special value handeln sollte: Ich habe das jetzt nicht ausprobiert. Freundliche Grüße |
Re: Probleme mit TStrings.IndexOfName unter Vista
[Offtopic]
Hey ein Radebeuler. Ist ja gleich um die Ecke. *wink* aus Dresden. :D [/Offtopic] |
Re: Probleme mit TStrings.IndexOfName unter Vista
Zitat:
Delphi-Quellcode:
Selbst wenn Vista unter einer deutschen Locale Umlaute erkennen kann, sollte das mit englischen Spracheinstellungen mit Sicherheit nicht so sein.
if (CompareStringW(MAKELCID(2057, 0), NORM_IGNORECASE, 'HÜBNER', Length('HÜBNER'), 'HUEBNER', Length('HUEBNER')) - 2) = 0 then
begin ShowMessage('Fehler'); end; Die Unterschiede zwischen Vista und XP sind übrigens nicht auf deutsche Umlaute beschränkt. Bspw. wird chinesischer Text bei gleichen Einstellungen und gleicher Locale komplett anders sortiert. |
Re: Probleme mit TStrings.IndexOfName unter Vista
Hallo NetSpy.
Also einen API-Hook für CompareStringW habe ich nicht geschrieben, sondern nur eine Überladung von Delphi-Funktionen. D.h. genauer nutze ich sie jetzt aber nicht, da mir beides wegen der unbekannten Nebenwirkungen zu unsicher ist. Einige unserer Komponenten sind nicht im Quelltext verfügbar. Und was weiss ich, was da passiert. Wir haben jetzt alle betreffenden Funktionen (z.B. TStringList.IndexOf) noch mal gekapselt. Die Sortierung haben wir sowieso schon immer selbst gemacht. Hier aber trotzdem das Beispiel zum Überladen einer Funktion:
Delphi-Quellcode:
procedure OverwriteProcedure(OldProcedure, NewProcedure: pointer; Data: POverwrittenData = nil);
{ OverwriteProcedure originally from Igor Siticov } { Modified by Jacques Garcia Vazquez } var x: PAnsiChar; y: integer; ov2, ov: cardinal; p: pointer; begin if Assigned(Data) then if (Data.Location <> nil) then exit; { procedure already overwritten } // need six bytes in place of 5 x := PAnsiChar(OldProcedure); if not VirtualProtect(Pointer(x), 6, PAGE_EXECUTE_READWRITE, @ov) then RaiseLastOSError; // if a jump is present then a redirect is found // $FF25 = jmp dword ptr [xxx] // This redirect is normally present in bpl files, but not in exe files p := OldProcedure; if Word(p^) = $25FF then begin Inc(Integer(p), 2); // skip the jump // get the jump address p^ and dereference it p^^ p := Pointer(Pointer(p^)^); // release the memory if not VirtualProtect(Pointer(x), 6, ov, @ov2) then RaiseLastOSError; // re protect the correct one x := PAnsiChar(p); if not VirtualProtect(Pointer(x), 6, PAGE_EXECUTE_READWRITE, @ov) then RaiseLastOSError; end; if Assigned(Data) then begin Move(x^, Data.OldCode, 6); { Assign Location last so that Location <> nil only if OldCode is properly initialized. } Data.Location := x; end; x[0] := AnsiChar($E9); y := integer(NewProcedure) - integer(p) - 5; x[1] := AnsiChar(y and 255); x[2] := AnsiChar((y shr 8) and 255); x[3] := AnsiChar((y shr 16) and 255); x[4] := AnsiChar((y shr 24) and 255); if not VirtualProtect(Pointer(x), 6, ov, @ov2) then RaiseLastOSError; end; function MyWideSameText(const S1, S2: WideString): Boolean; begin Result := false; end; procedure TForm1.FormCreate(Sender: TObject); begin OverwriteProcedure(@SysUtils.WideSameText, @MyWideSameText); end; |
Re: Probleme mit TStrings.IndexOfName unter Vista
Danke für die Antwort. Das bringt mich aber leider nicht weiter. Ich brauche schon die echte CompareString-Funktion, da ich die für die jeweilige Spracheinstellung passende Sortierung brauche und das für alle möglichen Sprachen selbst zu programmieren ist wohl ein Ding der Unmöglichkeit.
Wenn ich die Antwort in microsoft.public.win32.programmer.international auf deine Frage sehe, dass wohl die "collation tables" grundlegend geändert wurden, dann sieht es aber schlecht mit einer einheitlichen Lösung aus. |
Re: Probleme mit TStrings.IndexOfName unter Vista
Zitat:
Ich arbeite mich grad zu diesem Thema durch MSDN und dem Blog desjenigen, der geantwortet hat ![]() |
Re: Probleme mit TStrings.IndexOfName unter Vista
Mit Michael S. Kaplan scheint das Thema zumindest von Microsoft-Seite Beachtung geschenkt zu bekommen. Mal sehen, was daraus wird...
![]() |
Re: Probleme mit TStrings.IndexOfName unter Vista
Schön das deine Anfrage da doch noch Beachtung bekommen hat. Mal sehen, ob da irgendwann noch was vernünftiges rauskommt und die Leute einsehen, dass das jetzige Verhalten absolut buggy ist.
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Hallo netspy,
falls Deine Sortierungsprobleme unter Vista mit chinesisch gut nachvollziehbar sind, könntest Du ja in der Newsgroup in meinem Thread auch Dein Kommentar abgeben. Die beiden von MS bekommen wir schon noch zum schwitzen :-D |
Re: Probleme mit TStrings.IndexOfName unter Vista
Gut nachvollziehbar ist so eine Sache. Ich weiß, dass anders sortiert wird - ob es dabei aber solche Fehler wie bei den deutschen Umlauten gibt oder ob es vielleicht in XP und kleiner sogar falsch war, kann ich leider nicht sagen. Auf jeden Fall können die sich drehen und wenden wie sie wollen, 'ü' ist nicht gleich 'ue' und wenn das nicht geändert wird, wird es noch einigen Ärger mit fehlerhaften Progammen und Datenbanken gebeb.
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Michael S. Kaplan [MSFT]:
Zitat:
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Cool
|
Re: Probleme mit TStrings.IndexOfName unter Vista
Ich habe nun den Vista SP1 RC1 auf meinem System installiert um zu sehen, ob das Problem nun behoben wurde. Schlechte Nachricht!!! Geht noch immer nicht.
CompareString(LOCALE_USER_DEFAULT, 0, 'HÜBNER', Length('HÜBNER'),'HUEBNER', Length('HUEBNER')); Das liefert noch immer CSTR_EQUAL (2) retour. :wall: |
Re: Probleme mit TStrings.IndexOfName unter Vista
Zitat:
Evtl. wäre eine Hook der API-Funktion sinnvoll bei dem man den Zeichenvergleich selbst macht und damit auf allen Windows-Versionen das gewünschte richtige Verhalten erhält und hier nicht auch noch Versionsabhänigkeiten bekommt. |
Re: Probleme mit TStrings.IndexOfName unter Vista
Habe eben eine Antwort auf meine Anfrage betreffs Fix in SP1 für diese Problem bekommen. Dabei hat mich Herr Kaplan auf diesen Bolgeintrag verwiesen:
![]() Soweit ich das da verstanden habe wird es keinen Fix dafür geben. :wall: :wall: Ich könnte kotzen!!! Meine DBISAM3 Application läuft auf Vista nicht richtig und der Grund ist ziemlich sicher genau dieses Problem. Die Tabellen haben bei mir German(Swiss) als Sprache eingestellt. Teilweise funktionieren die Filter nun nicht mehr unter Vista. Wenn ich die Tabellen auf ANSI-Language umstelle geht alles problemlos, nur ist dann halt die Sortierung nicht mehr so wie es meine Kunden erwarten. Wie soll ich dieses Problem blos lösen? Ich weiss nicht mehr weiter und bin am verzweifeln!!!! Wie habt ihr das Problem denn nun gelöst? Da meine DB-Applikation die jeweilige Sprache des Systems nimmt und die Tabellen zu erstellen, ist das mit einer eigenn Routinee über einen Hook nicht machbar. Was MS hier verbrochen hat und dabei noch schreibt, man wollle es nicht ändern, wegen der Programmkompatibiltät (???), geht auf keine Kuhhaut. Dass genau diese Änderung in Vista aber nun eben die Programmkompatibiltät komplett gebrochen hat, wollen die nicht begreiffen. :wall: |
Re: Probleme mit TStrings.IndexOfName unter Vista
Z.B die Datenbank wechseln. TurboDB etwa hat seine eigenen Compare-Methoden (wenn es denn eine Desktopdatenbank sein soll).
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz