Как мне создать WideString с диакратией в не-юникодной версии Delphi? - PullRequest
4 голосов
/ 11 августа 2011

Я пытаюсь построить (тест) WideString из:

á ( U + 00E1 Строчная латинская буква A с острым )

но используя разложенную форму:

ЛАТИНСКОЕ МАЛЕНЬКОЕ ПИСЬМО A ( U + 0061 ) КОМБИНИРОВАННОЕ ОСТРОЕ АКЦЕНТ ( U + 0301 )

Итак, у меня есть фрагмент кода:

var
    test: WideString;
begin
   test := #$0061#$0301;
   MessageBoxW(0, PWideChar(test), 'Character with diacratic', MB_ICONINFORMATION or MB_OK);
end;

За исключением того, что он не работает:

enter image description here

Это может быть ошибкой в ​​MessageBox, но я собираюсь сказать, что более вероятно, что ошибка в моем код.

Некоторые другие варианты, которые я пробовал:

test := WideString(#$0061#$0301);


const
    SmallLetterLatinAWithAcuteDecomposed: WideString = #$0061#$0301;
test := SmallLetterLatinAWithAcuteDecomposed


test := #$0061+#$0301;  (Doesn't compile; incompatible types)


test := WideString(#$0061)+WideString(#$0301);  (Doesn't compile; crashes compiler)


test := 'a'+WideString(#$0301);  (Doesn't compile; crashes compiler)


//Arnauld's thought:
test := #$0301#$0061;

Бонусная болтовня

Ответы [ 3 ]

10 голосов
/ 11 августа 2011

Лучший ответ:

const
    n: WideString = '';  //n=Nothing

s := n+#$0061+#$0301;

Это исправляет все случаи, которые у меня есть ниже, в противном случае происходит сбой.


Единственный работающий вариант - объявить его константой:

AccentAcute: WideString = #$0301;
AccentAcute: WideString = WideChar($0301);
AccentAcute: WideString = WideChar(#$0301);
AccentAcute: WideString = WideString(#$0301);

Пример использования:

s := 'Pasta'+AccentAcute;

Константы на основе синтаксиса, которые не работают

  • AccentAcute: WideString = $0301;
    несовместимые типы
  • AccentAcute: WideString = #0301;
    дает enter image description here
  • AccentAcute: WideString = WideString($0301);
    недопустимый тип
  • AccentAcute: WideString = WideString(#$0301);
    недопустимый тип
  • AccentAcute: WideChar = WideChar(#0301); т Pastai
  • AccentAcute: WideChar = WideChar($0301); т Pasta´

Другие синтаксисы, которые терпят неудачу

  • 'Pasta'+WideChar($0301)
    т Pasta´
  • 'Pasta'+#$0301
    дает Pasta´
  • WideString('Pasta')+#$0301
    дает enter image description here

Сводка всех найденных констант синтаксисов, придуманных:

AccentAcute: WideString =            #$0301;   //works
AccentAcute: WideString =   WideChar(#$0301);  //works
AccentAcute: WideString = WideString(#$0301);  //works
AccentAcute: WideString =             $0301;   //incompatble types
AccentAcute: WideString =    WideChar($0301);  //works
AccentAcute: WideString =  WideString($0301);  //invalid typecast

AccentAcute: WideChar =            #$0301;     //fails, gives Pasta´
AccentAcute: WideChar =   WideChar(#$0301);    //fails, gives Pasta´
AccentAcute: WideChar = WideString(#$0301);    //incompatible types
AccentAcute: WideChar =             $0301;     //incompatible types
AccentAcute: WideChar =    WideChar($0301);    //fails, gives Pasta´
AccentAcute: WideChar =  WideString($0301);    //invalid typecast

Перестановка WideChar может работать, если вы добавляете только переменную

//Works
t := '0123401234012340123';
t := t+WideChar(#$D840);
t := t+WideChar(#$DC00);

//fails
t := '0123401234012340123'+WideChar(#$D840);
t := t+WideChar(#$DC00);

//fails
t := '0123401234012340123'+WideChar(#$D840)+WideChar(#$DC00);

//works
t := '0123401234012340123';
t := t+WideChar(#$D840)+WideChar(#$DC00);

//works
t := '';
t := t+WideChar(#$D840)+WideChar(#$DC00);

//fails; gives junk
t := ''+WideChar(#$D840)+WideChar(#$DC00);

//crashes compiler
t := WideString('')+WideChar(#$D840)+WideChar(#$DC00);

//doesn't compile
t := WideChar(#$D840)+WideChar(#$DC00);

Определенно удар по чепухе компилятора; случаи, которые не были проверены, проверены полностью. Да, я знаю Дэвида, мы должны обновить.

2 голосов
/ 11 августа 2011

Это работает в Delphi 5/7:

var
  test: WideString;
begin

   test := WideChar($0061);
   test := test + WideChar($0301);

   MessageBoxW(0, PWideChar(test), 'Character with diacratic', MB_ICONINFORMATION or MB_OK);
end;

Короче говоря:

  • В delphi 5 и delphi 7 не похоже, что объединение WideChars с WideString работает с использованием #$xxxx литералов формы.
  • # не работает так, как вы ожидаете для литералов Unicode.

  • Вы не можете просто добавить два или более символа в одном выражении, например:

    test := WideChar(a)+WideChar(b);  // won't compile in D5/D7.
    
0 голосов
/ 11 августа 2011

Вы пробовали # $ 0301 # $ 0061 (то есть сначала диакритическое)?

ОК.

Так # $ .... в этой версии обрабатывает только 8-битные константы ASCII.

Вы можете просто использовать обходной путь, используя уровень памяти:

type
    TWordArray  = array[1..MaxInt div SizeOf(word)-2] of word;
    // start at [1], just as WideStrings
    // or: TWordArray  = array[0..MaxInt div SizeOf(word)-1] of word;
    PWordArray = ^TWordArray;

var
  test: WideString;
begin
  test := '12'; // or SetLength(test,2);
  PWordArray(test)[1] := $61; 
  PWordArray(test)[2] := $301;
  MessageBoxW(0, pointer(test), 'Character with diacratic', MB_ICONINFORMATION or MB_OK);
end;

Это всегда будет работать, поскольку вы не играете с символами / широкими символами и т. Д.

И это также будет работатькак и ожидалось с версией Delphi для Unicode.

...