2010-03-31 16 views
6

Tengo una forma delphi 7:Delphi 7 - ¿Por qué Windows 7 cambia la codificación de caracteres en tiempo de ejecución?

Form http://i44.tinypic.com/13ymott.jpg

y mi código:

Code http://i44.tinypic.com/x1gh9c.jpg

cuando corro esta forma en Windows 7, veo:

Windows7Form http://i41.tinypic.com/riglzl.jpg

En tiempo de diseño, la forma tenía letras polacas en abetos t etiqueta, pero no los tiene en tiempo de ejecución. Se ve bien en Vista o Windows XP. Cuando configuro la leyenda de la segunda etiqueta en el código, todo funciona bien y los caracteres están codificados correctamente.

Primeros 5 códigos de etiqueta superior en Windows 7: 65 97 69 101 83

Primeros 5 códigos de etiqueta superior en Windows Vista/XP: 165 185 202 234 140

Primeros 5 códigos de etiqueta inferior en cada sistema: 165 185 202 234 140

Windows 7 cambia la codificación, ¿por qué? La configuración de mi sistema parece estar bien. Tengo un conjunto de idiomas adecuado para aplicaciones que no sean Unicode en el panel de control.

EDITAR

Este problema no sólo está relacionada con etiquetas en las formas, sino también con FastReport (donde el cambio a EASTERN_CHARSET resuelve el problema) o con Microsoft Excel accediendo a través de la interfaz COM.

+0

No estoy familiarizado con Delphi, pero ¿es posible que el Diseñador de formularios permita especificar una codificación diferente a la de su página de códigos predeterminada (es decir, Windows-1250)? ¿Y qué versión de Delphi es esta? El soporte IIRC Unicode se ha agregado recientemente ... –

+0

@ 0xA3 Esto es Delphi 7 y no es una aplicación unicode, pero configuro el idioma polaco para aplicaciones que no son Unicode en configuraciones regionales. Es por eso que Label2 se muestra correctamente, pero el primero sigue sin funcionar. – LukLed

+0

¿Revisó cómo se definen Label1 y Label2 en el DFM? ¿Cómo se guarda Label1.caption en el DFM? –

Respuesta

1

Las respuestas a esta pregunta resolver mi problema:

GetThreadLocale returns different value than GetUserDefaultLCID?

Una solución:

Lo extraño que encontramos es que el cambio a una diferente la configuración regional a través del Panel de control y luego volver a cambiar a NZ resuelve el problema. Me gustaría saber si la misma solución lo resuelve solo para verificar que estamos viendo el mismo fenómeno.

y segundo:

initialization 
    SetThreadLocale(LOCALE_USER_DEFAULT); 
    GetFormatSettings; 

Ambas soluciones funcionan muy bien y el problema desaparece con la aplicación.

0

Compruebe la propiedad Font.Charset de la etiqueta. Si bien no sé cómo se modificó (¿se pre-creó para algún asistente?) - podría tener una configuración regional diferente a la del sistema.

+0

El formulario tiene Font.Charset establecido en DEFAULT_CHARSET y las etiquetas tienen ParentFont establecido en verdadero. – LukLed

2

Reproduje el comportamiento en Delphi 2010 en Windows XP.

procedure Button1Click(Sender : TObject); 
begin 
    ShowMessage(AnsiString(Label1.Caption)); 
end; 

En esta situación, la conversión de Label1.Caption a AnsiString se realiza a través WideCharToMultiByte (API de Windows).

La API tiene la siguiente nota:

Las páginas de códigos ANSI pueden ser diferentes en equipos diferentes, o pueden ser cambiado para un solo equipo, lo que lleva a la corrupción de datos. Para la mayoría de los resultados consistentes, aplicaciones deben utilizar Unicode, como UTF-8 o UTF-16 , en lugar de una página específica código , a menos que las normas heredadas o datos formatos impiden el uso de Unicode. Si usando Unicode no es posible, las aplicaciones deben etiquetar el flujo de datos con el nombre de codificación correspondiente cuando los protocolos lo permitan. HTML y Los archivos XML permiten el etiquetado, pero los archivos de texto no.

Por lo tanto, mi mejor estimación es que la diferencia en el comportamiento proviene del hecho de que la versión de Windows 7 que tiene tiene una página de códigos activa diferente a la de sus estaciones de vista/XP.

Todavía tengo que encontrar cómo obtener la página de códigos activa en un sistema ... Mi mejor opción es que está definida en la configuración regional en el panel de control. Pero todavía tengo que comprobar esto ...

+0

La configuración del Panel de control parece estar bien. Estoy seguro de que este es el problema de que Windows 7 tenga otro enfoque para la conversión de cadenas, pero ¿cómo lo resuelvo? – LukLed

+1

Intente llamar a GetThreadLocale desde su aplicación en los distintos sistemas, solo para asegurarse de que se devuelve el mismo valor antes de seguir investigando ... –

+0

Buena idea. Lo haré mañana. – LukLed

2

Se encontró con lo que considero un "error" en los métodos TWriter.WriteString y TWriter.ReadString. Esos dos métodos son utilizados internamente por Delphi para mover su TLabel.Caption del objeto activo real en tiempo de diseño al archivo DFM y luego de vuelta al objeto activo en tiempo de ejecución.

Si observa el código de las dos rutinas mencionadas, notará (en estado de shock asumo) que las cosas reales que entran en la secuencia se convierten a Unicode usando la página de códigos predeterminada del sistema operativo. Eso está bien, siempre y cuando la página de códigos utilizada en la máquina de desarrollo coincida exactamente con la página de códigos utilizada en la máquina de prueba, y es probable que no coincidan, y es muy probable que se deba a ese error. Tenga en cuenta que el EASTEUROPEAN_CHARSET que está configurando para el título en el formulario no tiene ningún valor, ¡porque el método TWriter.WriteString no tiene idea al respecto!

Tengo un informe de error sobre este tema en QC, ha estado allí durante muchos años ... Probablemente piensan que es "por diseño", pero no creo que sea un diseño muy bueno.

La solución que recomiendo es un cambio rápido a Delphi 2010. Soy un desarrollador de Delphi en Rumania, y he tenido muchos y muchos problemas con este tipo de cosas, pero ahora todo está en el pasado porque Delphi 2010 es UNICODE, así que ya no tengo que preocuparme por las conversiones de la página de códigos.

Si no puede cambiar a Delphi 2010, puede querer "piratear" el archivo Classes.pas y cambiar la rutina TReader.ReadString para realizar siempre la conversión utilizando la página TU código, no la predeterminada del sistema.

+0

Es bueno saberlo, pero este problema está relacionado solo con Windows 7 y ya encontré una solución. Cambiar a Delphi 2010 será muy complicado. Mi aplicación utiliza mucho JVCL 2 y otros componentes antiguos y tiene alrededor de 1000 formularios. Delphi 2010 espera en el estante para más tiempo libre. – LukLed