2016-08-23 5 views
0

J'ai un code hérité (1 million de lignes) écrit en Delphi 7 Pascal qui, pour diverses raisons, ne peut pas être mis à niveau vers une version plus récente de Delphi. Le programme produit des documents dans environ 30 langues et fait un très bon travail de production des différents caractères dans toutes les langues à l'exception du turc. Le codage définit le jeu de caractères sur TURKISH_CHARSET (162). Quand il essaie d'imprimer char # 351 (ş, hex 15f), char # 285 (ğ, hex 11f) ou char # 305 (ı, hex 131), il imprime seulement "s", "g" ou "i". Il utilise un simpleImpression en turc 7 en turc

pour sortir le texte.

J'ai essayé de compiler le code sur différentes machines et de l'exécuter sur différentes versions de Windows mais toujours avec le même résultat.

+0

Insister sur l'utilisation du texte encodé ANSI en 2016 est stupide. –

+0

Quand je google TURKISH_CHARSET je trouve que cela correspond à la page de code 1254. Quand je google code page 1254, je vois une table de caractères. Il semble que les codes pour ces caractères sont $ FE, $ F0 et $ FD. –

+0

TextOut prend un paramètre de chaîne qui, dans Delphi 7, signifie "résister à l'erreur". Chaque personnage d'une interview est un octet. –

Répondre

0

Dans Delphi 7, string est un alias pour AnsiString, qui code les caractères Unicode en octets de 8 bits à l'aide de pages de code Windows. Dans certaines pages de code MBCS, les caractères Unicode peuvent nécessiter plusieurs octets (le turc n'en fait cependant pas partie).

Microsoft a plusieurs pages de code pour le turc:

  • 857 (MS-DOS)
  • 1254 (Windows)
  • 10081 (Macintosh)
  • 28599 (ISO-8859-9)

Dans les deux pages de code 1254 et 28599 (où 1254 est le plus probable que vous rencontrerez), le caractère Unicode les éléments en question sont codés en 8 bits sous la forme d'hex $FE (ş), $F0 (ğ) et $FD (ı).

Assurez-vous que votre variable de chaîne sText contient en fait ces octets pour commencer, et non octets ASCII $73 (s), $67 (g) et $69 (i) au lieu. S'il contient ce dernier, vous perdez les données turques avant même d'atteindre Canvas.TextOut(). Ce serait un problème plus tôt dans votre code.

Toutefois, si sText contient les octets corrects, le problème doit être du côté du système d'exploitation, comme TCanvas.TextOut() est juste une enveloppe mince pour l'API Win32 ExtTextOutA() fonction, où sText est transmis en l'état à l'API. Peut-être que la police que vous utilisez ne supporte pas le turc, ou au moins ces caractères particuliers. Ou peut-être qu'il y a un problème avec le pilote d'imprimante. De toute façon, vous pourriez avoir à recourir à la conversion de votre valeur sText à un WideString en utilisant MultiByteToWideChar() puis appelez ExtTextOutW() (non ExtTextOutA()) directement, par exemple:

var 
    wText: WideString; 
    size: TSize; 
begin 
    //Printer.Canvas.TextOut(x, y, sText); 
    SetLength(wText, MultiByteToWideChar(1254{28599}, 0, PAnsiChar(sText), Length(sText), nil, 0)); 
    MultiByteToWideChar(1254{28599}, 0, PAnsiChar(sText), Length(sText), PWideChar(wText), Length(wText))); 
    Windows.ExtTextOutW(Printer.Canvas.Handle, x, y, Printer.Canvas.TextFlags, nil, PWideChar(wText), Length(wText), nil); 
    size.cX := 0; 
    size.cY := 0; 
    Windows.GetTextExtentPoint32W(Printer.Canvas.Handle, PWideChar(wText), Length(wText), size); 
    Printer.Canvas.MoveTo(x + size.cX, Y); 
end; 
+0

Merci, Remy, c'est vraiment utile. J'ai écrit une petite fonction qui détourne toute tentative d'impression en turc et met le texte au format WideString avec les routines d'impression WideString (comme dans votre code ci-dessus). Tout vient bien :-) –