2012-12-09 7 views
10

Sto utilizzando la funzione LoadKeyboardLayout per caricare e attivare il layout di tastiera in questo modo:Come utilizzare LoadKeyboardLayout in un thread in background?

procedure TfrmMain.eSearchEnter(Sender: TObject); 
begin 
    LoadKeyboardLayout('00000429', KLF_ACTIVATE); 
end; 

Funziona perfettamente, ma blocca la forma attiva per 1-2 secondi, dal momento che questo cambiamento richiede un certo tempo. Per prevenire questo, ho spostato il codice a un thread in background come questo:

type 
    FLangChangeThread = class(TThread) 
    private 
    FLang: string; 
    protected 
    procedure Execute; override; 
    public 
    property Lang: string read FLang write FLang; 
    end; 

implementation 

procedure FLangChangeThread.Execute; 
begin 
    if FLang = 'EN' then 
    LoadKeyboardLayout('00000409', KLF_ACTIVATE) 
    else 
    if FLang = 'FA' then 
    LoadKeyboardLayout('00000429', KLF_ACTIVATE); 
end; 

Questo thread in background sto poi eseguire in questo modo:

procedure TfrmMain.ChangeWritingLanguage(ALang: string); 
begin 
    with FLangChangeThread.Create(True) do 
    begin 
    FreeOnTerminate := True; 
    Lang := ALang; 
    Resume; 
    end; 
end; 

procedure TfrmMain.eSearchEnter(Sender: TObject); 
begin 
    ChangeWritingLanguage('FA'); 
end; 

Il problema è, che doesn' t cambia il layout della tastiera come previsto. Ho eseguito il debug del codice e sono state aggiunte tutte le righe; solo la funzione LoadKeyboardLayout non ha fatto il suo lavoro.

Come posso far funzionare la funzione LoadKeyboardLayout da un thread in background?

risposta

8

Prima di tutto, è necessario controllare il risultato della funzione LoadKeyboardLayout e, in caso di errore, controllare l'errore restituito dalla funzione GetLastError per determinare cosa è sbagliato.

Ma anche se questa chiamata di funzione ha esito positivo, attiverà l'identificatore locale di input, ma per il thread di lavoro. Come LoadKeyboardLayout rinvio per il flag KLF_ACTIVATE (sottolineato da me):

KLF_ACTIVATE

Se l'identificatore di impostazioni ingresso specificato non è già caricato, i carichi funzione e attiva l'identificatore di impostazioni di ingresso per il thread corrente .


Anche se, se si desidera caricare e attivare il layout della tastiera per l'intero processo, si può tentare di coniugare la bandiera KLF_ACTIVATE con l'KLF_SETFORPROCESS uno:

const 
    KLF_SETFORPROCESS = $00000100; 
begin 
    if LoadKeyboardLayout('00000429', KLF_ACTIVATE or KLF_SETFORPROCESS) = 0 then 
    RaiseLastOSError; 
end; 
+0

Grazie, dovrei indovinare! come posso risolvere questo? –

+0

Sono stato controllato il risultato e non restituisce mai NUL. come posso applicare questa funzione al controllo attivo (come un TEdit)? –

+1

Se hai intenzione di cambiare il layout della tastiera per il processo (cosa penso che fai, il thread di lavoro che hai usato da quando ci vuole molto tempo, non è vero?), Prova a combinare la bandiera 'KLF_ACTIVATE' con la funzione 'KLF_SETFORPROCESS'. – TLama