Jak wyłapać niewizualne znaki w nazwie folderu

0

Witajcie

Mam dość nietypowy problem. Mam aplikację, która używa najzwyczajniejszego w świecie

TOpenDialog

aby zwrócić FileName wskazany przez użytkownika. Na szybko przygotowałem dla was demo:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if (OpenDialog1.Execute) and (OpenDialog1.FileName <> '') then
    Label1.Caption := OpenDialog1.FileName;
end;

Taki kod zwraca to co widać na screenie. Między literami N i O nie ma nic wizualnego ALE
Jak z pod debuggera sprawdzę sobie FileName to dostaję coś takiego:

'D:\Profilometr\Duchno'#$206B'w 2015_06_25\Duchnow_2015_06_25.srw'

Chodzi o ten dziwny ciąg: '#$206B'. Rzeczywiście jak wszedłem w nazwę folderu i zacząłem naciskać backspace między literami "W" i "O" to musiałem nacisnąć 3 razy zamiast dwóch aby usunąć również ten niewizualny znak. Pytanie do was co to za dziwactwo i jak się tego pozbyć? Ten FileName wykorzystuję później np zapisując do XML co powoduje wylotem całej aplikacji. Gdyby to był jedyny przypadek to bym olał ale to już druga taka sytuacja z dziwnym znakiem w nazwie. Jakbyście się przed tym zabezpieczyli?

1

Zapewne te znaczki to jest Unicode. Jak się tego pozbyć? Moim zdaniem nowe aplikacje powinny być przygotowane na tego typu rzeczy. Nie wiem jak w Delphi, ale pod Builderem TOpenDialog.FileName jest typu string. Czyli w zależności od ustawień projektu char mapowany jest jako zwykły char albo w_char. Domyślnie w nowszych wersjach środowiska jest to wersja w_char, więc wszelkie zmienne typu string są unikodowe.

Rozwiązania masz dwa. Albo wszędzie stosować konsekwentnie typ string, albo zmienić mapowanie na zwykły char. Pierwsze rozwiązanie daje Ci obsługę unikodu w aplikacji, drugie będzie powodować, że najprawdopodobniej program po podaniu ścieżki zawierającej znaki Unicode wywali się.

0

A pod jakim konkretnie Delphi tak masz? Bo pewnie nie obsługuje Unicode i może będziesz musiał posiłkować się pakietem TNT.

0

@olesio - Delphi 2010 Professional + IDEFixPack.
@Mr.YaHooo - ja wszędzie w tej aplikacji używam string jednak później przekazywany jest on dalej i wysypuje się właśnie tam dalej.

1

To jest normalny znak Unicode, jeśli przekazujesz to do części która nie obsługuje Unicode to dostajesz tam w najlepszym razie krzaki, w najgorszym urywa tekst.
Zakładam że to Delphi co używasz obsługuje już w pełni Unicode, w związku z tym sam musisz zdecydować co zrobić z tą częścią która nie obsługuje Unicode:

  • zamienić Unicode na "Ansi" z polskim CP przy pomocy funkcji API
  • zamienić Unicode na ASCII a nie-ASCII zamienić np. na "?" - można napisać samemu
  • poprawić funkcje która się wywala (może być niełatwe, nie wiem co używasz ale JCL potrafiło inaczej obsługiwać Unicode niż TNT - chodziło chyba o uppercase/lowercase)
0

@vpiotr poszedłem za Twoim tropem i zrobiłem takie paskudstwo:

StringReplace(AnsiString(OpenDialog1.FileName),'?','',[rfReplaceAll]);

Niby zadziałało ale ... nie podoba mi się to rozwiązanie ...

0
woolfik napisał(a):

@vpiotr poszedłem za Twoim tropem i zrobiłem takie paskudstwo:

StringReplace(AnsiString(OpenDialog1.FileName),'?','',[rfReplaceAll]);

Niby zadziałało ale ... nie podoba mi się to rozwiązanie ...

To jest bardziej workaround niż rozwiązanie. Z drugiej strony jeśli użytkownikowi się "kliknęło" to można mu sforsować bardziej poprawną nazwę.
Chyba że zastosował np. "ü" - zdarzają się w Polsce w nazwiskach - wtedy nazwy plików potrafią się "sforsować" na Unicode. I wtedy właśnie mogą się dziać chece.

Edit: jak nie chcesz użytkownikowi psuć danych to zrób tak jak zrobiłeś, potem zamień z powrotem na Unicode i porównaj z oryginałem - jeśli jest różnica wyświetl że nazwa niepoprawna.

0

Dokładnie tak zrobiłem dzięki.

0
woolfik napisał(a):

@Mr.YaHooo - ja wszędzie w tej aplikacji używam string jednak później przekazywany jest on dalej i wysypuje się właśnie tam dalej.
A gdzie to przekazujesz? Do aplikacji zewnętrznej? Bo jeśli tak i musisz z nią współpracować to niestety chyba trzeba zamieniać to wszystko na AnsiStringa. Albo po wybraniu ścieżki zbadać czy jest jakiś unikod tam i ostrzegać, ze ścieżka nie powinna zawierać takich znaków.

1 użytkowników online, w tym zalogowanych: 0, gości: 1