2012-12-09 17 views
10

我使用的LoadKeyboardLayout功能加載和激活鍵盤佈局是這樣的:如何在後臺線程中使用LoadKeyboardLayout?

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

它完美,但它凍結1-2秒的活性形式,因爲這種變化需要一定的時間。爲了防止這一點,我搬到這個代碼到後臺線程這樣的:

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; 

這個後臺線程我那麼這種方式運行:

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; 

的問題是,它不」按預期更改鍵盤佈局。 我已經調試了代碼,所有的行都被拒絕了。只是LoadKeyboardLayout功能還沒有完成它的工作。

我怎樣才能使LoadKeyboardLayout函數從後臺線程工作?

回答

8

首先,您應該檢查LoadKeyboardLayout函數的結果,如果失敗,您應該檢查GetLastError函數返回的錯誤以確定錯誤。

但即使此函數調用成功,它將激活輸入語言環境標識符,但對於您的工作線程。至於KLF_ACTIVATE標誌(由我強調)的LoadKeyboardLayout參考狀態:

KLF_ACTIVATE

如果指定的輸入區域設置標識符尚未加載,則 函數加載並激活輸入區域設置標識符爲 當前線程


儘管如此,如果要加載和激活鍵盤佈局整個過程中,你可以嘗試將KLF_ACTIVATE標誌和KLF_SETFORPROCESS一個結合:

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

謝謝,我應該猜!我如何解決這個問題? –

+0

我檢查了結果,它永遠不會返回NUL。我如何將此功能應用於主動控制(如TEdit)? –

+1

如果您要更改流程的鍵盤佈局(我想你會這樣做,因爲它需要很長時間,因此您使用的工作線程,是嗎?),嘗試將「KLF_ACTIVATE」標誌與'KLF_SETFORPROCESS'一個。 – TLama

相關問題