2012-09-09 23 views
6

mi aplicación es una aplicación no Unicode escrito en Delphi 7.WideString de conversión de cadenas en Delphi 7

me gustaría convertir cadenas Unicode a ANSI con esta función:

function convertU(ws : widestring) : string; 
begin 
    result := string(ws); 
end; 

utilizo también este código para configurar la página de códigos correcta para convertir.

initialization 
    SetThreadLocale(GetSystemDefaultLCID); 
    GetFormatSettings; 

Funciona muy bien en el hilo principal de VCL pero no en una TThread, donde consigo algunos signos de interrogación '?' como resultado de la función convertU.

¿Por qué no en un TThread?

+0

En primer lugar, no necesita una función o encasillado para hacer esto; un simple 'stringVar: = wideStringVar;' funcionará. Segundo, el problema es que no todos los WideChars son directamente convertibles a AnsiString; algunos tienen más de un carácter de ancho, y algunos tienen valores de caracteres que no son representables en un AnsiChar, y algunas fuentes no contienen todos los valores Unicode posibles. Si está * viendo * '?', Significa que los está mostrando, lo que podría ser el tercer problema: los hilos no deberían acceder a los controles de la GUI sin usar 'Sychronize'. Como no ha publicado el código de visualización, es difícil decir si eso es todo. –

+0

La pregunta es: ¿por qué recibo los signos de interrogación cuando se usa en un TThread? – user382591

+2

Repito: ** Si está viendo '?', Está mostrando el texto. ** Ha proporcionado ** código cero o información ** con respecto a cómo se muestra. –

Respuesta

5

Llamar a SetThreadLocale() dentro de un bloque initialization no tiene ningún efecto en TThread. Si desea establecer la configuración regional de un subproceso, debe llamar al SetThreadLocale() dentro del método TThread.Execute().

Una mejor opción es no confiar en SetThreadLocale() en absoluto. Haga su propia conversión llamando directamente al WideCharToMultiByte() para que pueda especificar la página de códigos Ansi a convertir.

+0

Gracias por su ayuda. Funciona !!! – user382591

+0

Si usted es el autor de todo el código de su aplicación, las llamadas explícitas a WideCharToMultiByte son una opción viable. Si incluye un código de terceros, entonces la configuración de la configuración regional en todo el subproceso puede ser el mejor compromiso. –

+0

sí. Gracias. Uso una combinación de ambos ahora: WideCharToMultiByte AND SetThreadLocale() – user382591

6

yo sepa SetThreadLocale no cambia el sistema actual página de códigos, por lo que no afectará a la conversión widestringansistring en Delphi 7, que se basan en GetACP llamada a la API, es decir, el sistema de página de códigos.

La Página de códigos del sistema está configurada p. en Windows Seven en el Panel de control, luego Lenguajes regionales/pestaña Administrativa/Página de códigos para aplicaciones que no sean Unicode. Esto necesita un reinicio del sistema.

Delphi 7 utiliza esta página de códigos del sistema, que proporciona 0 a todas las llamadas a la API de conversión. Por lo tanto, AFAIR SetThreadLocale no afectará la conversión widestring a ansistring en Delphi 7. Cambiará la configuración regional (por ejemplo, fecha/hora y formato de moneda), no la página de códigos utilizada por el sistema para su Ansi < -> conversión Unicode.

Las versiones más nuevas de Delphi tienen una función SetMultiByteConversionCodePage(), pueden establecer la página de códigos que se utilizará para todo el manejo de AnsiString.

Pero llamadas a la API (es decir, todas las funciones en ....A()windows.pas que se asigna por ...() en Delphi 7) usarán esta página de códigos del sistema. Por lo tanto, tendrá que llamar a la API amplia ...W() después de una conversión a Unicode si desea manejar otra página de códigos. Es decir, Delphi 7 VCL solo funcionará con la página de códigos del sistema, no con el valor especificado por SetThreadLocale.

bajo Delphi 7, mi consejo es:

  • Uso WideString todas partes, y llamadas a la API específicas "ancho" - hay varias conjunto de componentes para Delphi 7 que manejar WideString;
  • Utilice sus propios tipos, con un conjunto de caracteres dedicado, pero necesitará una conversión explícita antes de usar las llamadas a la API VCL/RTL o "Ansi", p. MyString = type AnsiString (esto es lo que hacemos en mORMot, mediante la definición de un tipo personalizado RawUTF8 para el proceso interno UTF-8).

Esto es mucho mejor manejado con Delphi 2009 y hasta, ya que se puede especificar una página de códigos para cada tipo AnsiString, y manejar apropiadamente la conversión de/a Unicode, por llamadas a la API o proceso de VCL.

+0

+1 Creo que esto es correcto. –

+0

Solo quiero manejar la página de códigos predeterminada del sistema. Lo que he notado, es que para la conversión Ansi Unicode <->, la página de códigos utilizada es el LCID del usuario POR DEFECTO y no el LCID del sistema POR DEFECTO y eso es un problema. – user382591

Cuestiones relacionadas