CreateLink problem mit umlaute - Gelöst

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
DoorPro
Beiträge: 15
Registriert: Do 8. Mär 2012, 13:02
OS, Lazarus, FPC: Windows (L 0.9.30.2 FPC 2.4.4)
CPU-Target: 64Bit
Wohnort: Xanten
Kontaktdaten:

CreateLink problem mit umlaute - Gelöst

Beitrag von DoorPro »

Hallo Leute,

Ich verwende folgenden Code um eine Verknüfung zu erstellen.
Das funktioniert auch ganz gut so lange keine Umlaute im Spiel sind.

Code: Alles auswählen

function CreateLink(const AFilename, ALNKFilename, ADescription: string): Boolean;
var
    psl: IShellLink;
    ppf: IPersistFile;
    wsz: PWideChar;
begin
    result := false;
    if SUCCEEDED(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_inPROC_SERVER, IID_IShellLinkA, psl)) then
    begin
        psl.SetPath(PChar(AFilename));
        psl.SetDescription(PChar(ADescription));
        psl.SetWorkingDirectory(PChar(ExtractFilePath(AFilename)));
        if SUCCEEDED(psl.QueryInterface(IPersistFile, ppf)) then
        begin
            GetMem(wsz, MAX_PATH * 2);
            try
                MultiByteToWideChar(CP_ACP, 0, PChar(ALNKFilename), -1, wsz, MAX_PATH);
                ppf.Save(wsz, true);
                result := true;
            finally
                FreeMem(wsz, MAX_PATH * 2);
            end;
        end;
    end;
end;
Ich habe gelesen das man statt IShellLinkA einfach IShellLinkW schreiben soll nur leider funktioniert es nicht

Ich freue mich über eure Lösungsvorschläge :wink:
Zuletzt geändert von DoorPro am Sa 10. Mär 2012, 20:44, insgesamt 2-mal geändert.
The Door Project
Door is a Virtual Desktop System for Windows
Next Door Version 7.5

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: CreateLink problem mit umlaute

Beitrag von theo »

Wahrsch. reicht UTF8ToSys((AFilename) etc..

DoorPro
Beiträge: 15
Registriert: Do 8. Mär 2012, 13:02
OS, Lazarus, FPC: Windows (L 0.9.30.2 FPC 2.4.4)
CPU-Target: 64Bit
Wohnort: Xanten
Kontaktdaten:

Re: CreateLink problem mit umlaute

Beitrag von DoorPro »

theo hat geschrieben:Wahrsch. reicht UTF8ToSys((AFilename) etc..
Leider nicht.
Hast du vielleicht n besseres Beispiel?
The Door Project
Door is a Virtual Desktop System for Windows
Next Door Version 7.5

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: CreateLink problem mit umlaute

Beitrag von theo »

DoorPro hat geschrieben: Hast du vielleicht n besseres Beispiel?
Ich bin ein Linuxer, weiss das nicht genau.
In der IDE hast du UTF-8, entweder erwartet der Befehl ANSI (UTF8ToSys) oder WideString (UTF8Decode).
Testen!

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: CreateLink problem mit umlaute

Beitrag von Socke »

theo hat geschrieben:Testen!
Das hört sich für mich so an, als ob Zeichenkodierungen Magie wären und man nur durch Ausprobieren herausfinden könnte, was denn vorliegen könnte.
DoorPro hat geschrieben:Ich habe gelesen das man statt IShellLinkA einfach IShellLinkW schreiben soll nur leider funktioniert es nicht
Was funktioniert denn nicht? Gibt es eine Fehlermeldung? Die Windows-Funktion GetLastError() kann auch Wunder wirken.

Prinzipiell gilt unter Windows, dass die *A-Varianten einen Einzelbyte-Zeichensatz und die *W-Varianten einen Mehr-/Multibyte-Zeichensatz benötigen. Weiterhin gilt, dass der Einezlbytezeichensatz immer lokalisierungsabhängig (Spracheinstellungen) ist und als Mehrbytezeichensatz immer UTF-16 bzw. UCS-2 (zu 96% identisch) verwendet wird.

Daher:
  • Welche Kodierung verwendet dein Quelltext? (eher nebensächlich)
  • Welche Kodierung haben die Funktionsparameter AFilename, ALNKFilename, ADescription? (Hinweis: die LCL liefert immer UTF-8, die RTL immer Systemcodierung -- unter Windows ist das eine Einzelbytecodierung und damit lokalisierungsabhängig)
Weiterhin schau dir bitte nochmal die Dokumentation der Windows-API/-Interfaces an; ggf. kannst du die auch hier verlinken, damit ich nicht suchen muss (bin da gerade zu faul zu ;-))
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: CreateLink problem mit umlaute

Beitrag von mschnell »

Dateinamen (also auch Link Namen) sind in Linux-Dateisystemen (also z.B. "EXT" und "NFS" - für "FAT" "NTFS" oder "CIFS" kann anderes gelten) einfach nur Byte-Ketten. Die Kodierung ist dem Betriebssystem egal (es darf nur nicht der Byte-Wert 0x00 oder "/" vorkommen, die Sonder-Bedeutung haben, "*" und "\" sollte man wohl besser auch nicht verwenden). Wie diese Zeichenketten dargestellt werden, ist eine andere Frage.

Soweit ich weiß, verändern die entsprechenden System-Aufruf-Funktionen in Lazarus die Byte-Ketten nicht. Da Lazarus intern in Strings (zur Anzeige etc.) mit UTF-8 Darstellung arbeitet, werden also entsprechend kodierte Byte-Ketten weitergegeben. (der String 'Hünxe' - und damit der Dateiname - besteht also aus 6 Byte !!! ). Wie das dann wieder in irgendeiner Oberfläche des Betriebssystems dargestellt wird, ist dann von dieser Oberfläche abhängig (z.B. kann das Dateisystem ja per CIFS (=Samba) von einen Windows-Rechner zugegriffen werden der das ein Directory Search macht und von wer weiß welcher Kodierung ausgeht.

Bei mir klappt das ganz gut (Siehe Anhänge Win-Commander, Windows Kommandozeile und Linux Kommandozeile am Rechner (ohne "X") und Linux-Kommandozeite via Putty auf Windows).

Der CIFS-Server Dämon auf dem Linux-Rechner gibt also an den Windows-Rechner den entsprechend umkodierten Dateinamen (vermutlich UTF8->UCS2) weiter, so dass Windows das entsprechend anzeigen kann. Die Linux-Kommando-Zeilenprogramm "ls" stellt das UTF8-kodierte "ü" passend zur Code-Funktionalität des Bildschirm-Treibers (ohne X) dar und Putty ist auch passend eingestellt, um auf Windows diese Codierung darzustellen (was den Effekt hat, dass die Darstellung von z.B. Midnight-Commander schlecht ist).

Anhang 4.png zeigt die Verwaltungs-Datei des Backup Linux-Programms (Dirvish). Hier wird dieselbe Dateinamen-Kodierung ganz anders mit Fluchtsymbol '\' - Kombinationen für Leerzeichen und 'ü' dargestellt. (Warum ein kleines ü \303\274 ist, verstehe ich allerdings auch nicht.)

-Michael
Dateianhänge
4.png
4.png (8.81 KiB) 1408 mal betrachtet
1.png
1.png (2.63 KiB) 1484 mal betrachtet
3.png
3.png (1.94 KiB) 1484 mal betrachtet
2.png
2.png (3.1 KiB) 1484 mal betrachtet
Zuletzt geändert von mschnell am Sa 10. Mär 2012, 14:27, insgesamt 6-mal geändert.

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: CreateLink problem mit umlaute

Beitrag von theo »

Socke hat geschrieben: Das hört sich für mich so an, als ob Zeichenkodierungen Magie wären und man nur durch Ausprobieren herausfinden könnte, was denn vorliegen könnte.
Nö, das meinte ich nicht. Ich hatte auch gesagt, dass theoretisch UTF8ToSys((AFilename) klappen müsste.
Dieser Meinung bin ich immer noch.
Aber wenn studieren nicht hilft, muss man vielleicht zuerst probieren, und dann wieder studieren. :lol:

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: CreateLink problem mit umlaute

Beitrag von mschnell »

theo hat geschrieben:Ich hatte auch gesagt, dass theoretisch UTF8ToSys((AFilename)
Da die Strings intern UTF8 sind hört sich das plausibel an.

Auf Windows ist die "SYS"-Codierung UCS2 (oder UFT16). Dann sollte die entsprechende Codierung dabei herauskommen.

Auf Linux ist die "SYS" - Codierung doch auch UTF8. Macht dann UTF8toSys gar nichts ?

Sind IShellLink und IPerstistFile von Lazarus zur Verfügung gestellt ? Dann sollten die doch eigentlich die passend Umcodierung, die durch die von Lazarus immer erzwungene UTF-8 Codierung der Strings notwendig ist, vornehmen.

-Michael (habe hier kein laufendes Lazarus zur Hand))

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: CreateLink problem mit umlaute

Beitrag von theo »

mschnell hat geschrieben: Auf Windows ist die "SYS"-Codierung UCS2 (oder UFT16). Dann sollte die entsprechende Codierung dabei herauskommen.
UTF8ToSys wandelt auf Win nach ANSI afaik.
mschnell hat geschrieben: Auf Linux ist die "SYS" - Codierung doch auch UTF8. Macht dann UTF8toSys gar nichts ?
Nö.

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: CreateLink problem mit umlaute

Beitrag von Socke »

mschnell hat geschrieben:Da die Strings intern UTF8 sind hört sich das plausibel an.
Strings sind in Free Pascal nur Byteketten; Die Zeichenkodierung wird Eins zu Eins aus dem Quelltext übernommen.
theo hat geschrieben:
mschnell hat geschrieben: Auf Windows ist die "SYS"-Codierung UCS2 (oder UFT16). Dann sollte die entsprechende Codierung dabei herauskommen.
UTF8ToSys wandelt auf Win nach ANSI afaik.
Die Systemkodierung ist UCS-2, wobei die Einzelbytezeichensätze von dem entsprechenden Windows-API transparent konvertiert werden. Die RTL verwendet die Einzelbyte-(Ansi-)Varianten. Daher transkodiert UTF8ToSys() unter Windows auf Deutsch von UTF-8 nach Windows-1252.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

DoorPro
Beiträge: 15
Registriert: Do 8. Mär 2012, 13:02
OS, Lazarus, FPC: Windows (L 0.9.30.2 FPC 2.4.4)
CPU-Target: 64Bit
Wohnort: Xanten
Kontaktdaten:

Re: CreateLink problem mit umlaute

Beitrag von DoorPro »

So jetzt habe ichs endlich Kapiert

Lösung:

UTF8ToSys(ComboBox1.text)


Vielen Dank an alle! :oops:
The Door Project
Door is a Virtual Desktop System for Windows
Next Door Version 7.5

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: CreateLink problem mit umlaute

Beitrag von mschnell »

Socke hat geschrieben:Die RTL verwendet die Einzelbyte-(Ansi-)Varianten.
I see. Finde ich aber erstaunlich, die Wide-API wäre ja eigentlich leistungsfähiger (bei "komplizierteren" locales).

-Michael

Antworten