如何在非unicode Delphi版本中构建具有diacratic的WideString?

时间:2011-08-11 16:12:36

标签: delphi unicode delphi-5 unicode-string widestring

我正在尝试构建一个(测试)WideString

  

á(U+00E1 Small Letter Latin A with acute

但使用它的分解形式:

  

拉丁文小写字母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;

Bonus chatter

3 个答案:

答案 0 :(得分:10)

最佳答案:

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);

绝对打击编译器废话;没有经过测试的病例完全测试。是的,我认识大卫,我们应该升级。

答案 1 :(得分:2)

这适用于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.
    

答案 2 :(得分:0)

您是否尝试#$ 0301#$ 0061(即首先是变音符号)?

行。

所以#$ ....只处理此版本中的ASCII 8位常量。

您可以使用内存级别的解决方法:

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;

这将永远有效,因为你不玩chars / widechars等。

它也将与Unicode版本的Delphi一样正常工作。