2009-11-20 15 views
16

Per ottenere le impostazioni locali, ad es. formato di breve data, abbiamo sempre utilizzato GetLocaleFormatSettings con GetThreadLocale. Questo ha sempre funzionato senza problemi fino ad ora.GetThreadLocale restituisce un valore diverso da GetUserDefaultLCID?

Un paio dei nostri utenti sono sempre valori diversi per GetThreadLocale che non corrispondono a quello che hanno configurato nelle impostazioni internazionali di Windows 7. Siamo stati in grado di riprodurre questo non importa quello che cerchiamo, ma ho mandato un utente un programma di test per ottenere le informazioni sulla locale, e in modo sicuro GetThreadLocale restituisce un LCID diverso (1033) rispetto a GetUserDefaultLCID (2057). Quindi, invece di ottenere le impostazioni internazionali del Regno Unito, finiscono con le impostazioni internazionali degli Stati Uniti.

Stiamo ottenendo le informazioni locali in modo errato? Dovremmo utilizzare GetUserDefaultLCID anziché GetThreadLocale?

Grazie

+0

Stai effettivamente utilizzando più thread o stai semplicemente chiamando GetThreadLocale dal thread principale? –

risposta

15

Non sei il solo. Ho visto questo anche con Windows 7 qui in Nuova Zelanda e sembra solo far saltare le applicazioni Delphi per qualche ragione, per quanto posso dire.

La cosa strana che abbiamo trovato è che il passaggio a un diverso impostazioni internazionali tramite il Pannello di controllo e poi tornando alla NZ risolve il problema. Sarei curioso di sapere se la stessa soluzione ti risolve solo per verificare che stiamo assistendo allo stesso fenomeno.

Mi chiedo se la selezione di impostazioni internazionali non statunitensi tramite il processo di installazione di Windows 7 non stia 'facendo la cosa giusta' in qualche modo sottile che solo per le applicazioni di Delphi si interrompe per qualche motivo.

Sono arrivato a un codice di test simile a quello di JP nel tentativo di rintracciare e trovare una soluzione alternativa al software ma il nostro addetto al controllo qualità ha trovato la soluzione alternativa di "impostazioni internazionali switcheroo" e non ha voluto reinstallare completamente Windows 7 di nuovo per tornare allo stato originale funky per qualche motivo :-)

+3

Passare a una diversa impostazione regionale tramite il Pannello di controllo e quindi tornare indietro sembra funzionare. Grazie! – Mick

6

ho notato lo stesso problema, quando ho iniziato ad usare nuovi computer Windows 7. Ho passato un po 'di tempo a cercare di scoprire cosa causa questo, ma non ho trovato nulla. Quindi ho aggiunto queste due righe alla sezione di inizializzazione di alcune unità.

initialization 
    SetThreadLocale(LOCALE_USER_DEFAULT); 
    GetFormatSettings; 

strana è che questo comportamento si verifica solo nel mio computer come abbiamo pochi altri computer Win7 in carica anche.

+0

Passare a una diversa impostazione regionale e quindi tornare sembra anche risolvere il problema come suggerito da Paul Heinz. Quindi potrebbe essere qualcosa sul processo di installazione di Windows 7. Tutti i programmi che ho trovato hanno avuto questo problema sono state le applicazioni Delphi. Strano anche se DatetimePicker aveva il formato datetime corretto. –

+0

Questo risolve il problema solo per il thread corrente? Quindi per le app multi-threaded devo aggiungerlo attentamente ad ogni inizializzazione del thread se nel thread sono usate alcune funzioni dipendenti dalla locale. ... – mjn

1

Ho appena testato una nuova installazione di Windows 7 Starter Edition e ho avuto lo stesso problema, ma ho trovato che le impostazioni locali che GetThreadLocale restituisce erano esattamente la localizzazione suggerita dal programma di installazione di Windows, ma l'ho modificata durante l'installazione in un'altra, che è quella che ottiene GetUserDefaultLCID, anche quella che volevo usare, (ho fatto un piccolo programma solo per questo). Quindi, le impostazioni internazionali sono state modificate per l'utente, ma da qualche parte è stata ancora specificata la prima versione locale ed è stata restituita da GetThreadLocale. Come ha commentato JP, c'è davvero un problema con l'installazione, non cambia le impostazioni locali in tutti i punti in cui può essere trovato. Sembra che cambiare la localizzazione tramite il Pannello di controllo faccia il lavoro bene, e che potrebbe spiegare come cambiarlo come proposto, a proposito, spiega perché gli altri computer non potrebbero avere lo stesso problema (se non hai cambiato le impostazioni durante installazione). Spero che questo aiuto.

18

Per alcune informazioni di dare un'occhiata qui:

http://www.siao2.com/2010/03/19/9980203.aspx

Quindi sembra che questo problema si manifesta su Vista e Windows 7.Si verifica perché Microsoft sembra essere in procinto di deprecare l'ID internazionale in favore del Nome Locale .

Per riepilogare: Le chiamate API pertinenti operano tutte sui valori di registro che è possibile trovare su HKCU\Control Panel\International. Il valore "Locale" viene mantenuto per ragioni di compatibilità con le versioni precedenti e in circostanze normali viene mantenuto sincronizzato con la sua controparte più recente denominata "LocaleName". Questo processo di sincronizzazione tuttavia non funziona in alcune circostanze.

In ogni caso, la chiamata API GetThreadLocale prende il suo valore di ritorno dalla voce del Registro "Locale" di cui sopra, mentre gli altri (GetUserDefaultLCID, GetSystemDefaultLCID, etc) utilizzano la voce di registro "localename".

Da qui la confusione.

A proposito, la soluzione fornita dal JP in a previous post dovrebbe probabilmente essere esteso a

initialization 
    SetThreadLocale(GetUserDefaultLCID); 
    GetFormatSettings; 

perché (se sto leggendo correttamente!) In base al Docco la chiamata GetUserDefaultLCID rappresenterà le personalizzazioni degli utenti.

Dopo un po 'più di ricerca, Vista non ne risente affatto. Ho un po 'più in dettaglio troppo ...

L'API in questione chiama tutti operano su valori di registro che si possono trovare a HKCU\Control Panel\International. Il valore "Locale" viene mantenuto per ragioni di compatibilità con le versioni precedenti e in circostanze normali viene mantenuto sincronizzato con la sua controparte più recente denominata "LocaleName". Almeno in Windows 7, questo processo di sincronizzazione tuttavia non funziona dove i processi vengono eseguiti come un altro utente (ad es. RunAs o Impersonation). Questo sembra essere il caso durante l'installazione, in cui il programma di installazione viene avviato da una sessione Windows esistente. Tuttavia sembra funzionare correttamente se è stato avviato dal CD di installazione.

  • GetThreadLocale prende il suo valore a partire da fili blocchi Informazioni o filo di Ambiente Block (TIB o TEB) Vedi: http://en.wikipedia.org/wiki/Thread_Environment_Block Sia per Vista e Windows 7, il TIB viene inizializzato con l'entrata HKCU\Control Panel\International\Locale Registro all'accesso. Questo diventa l'impostazione internazionale predefinita per tutti i thread creati durante la sessione. La modifica di questo valore di registro durante una sessione non ha alcun effetto sul valore restituito dalla chiamata API GetThreadLocale. L'utente deve disconnettersi e accedere di nuovo per vedere una modifica. Questa è la chiamata API che Delphi utilizza come base per inizializzare tutte le sue stringhe di formato locale (vedere il metodo SysUtils.GetFormatSettings), da cui vengono formattati tutti i campi di data.

  • GetUserDefaultLCID: in Vista, basa il suo valore di ritorno sulla voce di registro HKCU\Control Panel\International\Locale. In Windows 7, basa il suo valore di ritorno sulla voce di registro HKCU\Control Panel\International\LocaleName. La relativa voce del Registro di sistema può essere modificata durante una sessione e il risultato viene immediatamente riflesso in questo valore di ritorno della chiamata API.

  • SetThreadLocale aggiorna il TIB per riflettere le impostazioni locali fornite nel parametro per questa chiamata. Si noti che questo ha sempre effetti sul thread da cui viene eseguita la chiamata API. L'API chiama SetThreadLocale(LOCALE_USER_DEFAULT) e SetThreadLocale(GetUserDefaultLCID) sono funzionalmente equivalenti. Entrambi derivano le impostazioni locali di origine come descritto nella chiamata API GetUserDefaultLCID precedente.

1

A new post in the RTL forum suggerisce questa correzione in SysUtils-> InitSysLocale:

SetThreadLocale(LOCALE_USER_DEFAULT); 
SysLocale.DefaultLCID := LOCALE_USER_DEFAULT; 
GetFormatSettings; 

e spiega ulteriormente:

deve essere impostato di default per LOCALE_USER_DEFAULT e non a 0x409! Questo bug è nel 2010, XE e XE2

Problemi correlati