(by ysai)
現象:
在xp下,如果執行緒中建立了視窗而執行緒中沒有訊息迴圈,那麼可能切換輸入法時會造成程式卡死(某些xp下必現,跟安裝盤有關)
原因:
執行緒建立乙個視窗後,系統會自動建立乙個default ime視窗以便通知輸入法訊息(可能只有可以接收輸入的視窗才會建立,未證實)
xp下切換輸入法,會向所有defaultime視窗sendmessage告訴應用程式,當前輸入法改變了
而執行緒視窗如果沒有訊息迴圈,則不會處理訊息佇列,然後卡死
演示**:
ttestthread = class(tthread)
private
procedure processmessages;
protected
procedure execute; override;
end;
procedure ttestthread.execute;
begin
ttimer.create(nil); //ttimer會建立隱藏的視窗
while not terminated do
begin
dosomething;//執行緒幹活
//processmessages; //去掉這一句就可能卡死
sleep(1);
end;
end;
///內建的乙個簡單訊息迴圈
procedure ttestthread.processmessages;
var msg: tmsg;
begin
while peekmessage(msg, 0, 0, 0,pm_remove) then
begin
translatemessage(msg);
dispatchmessage(msg);
end;
end;
程式中使用上面的執行緒,則在xp下切換輸入法可能卡死
終極解決方案:
procedure freeimewindow;
const
ime_window_class ='ime';
ime_window_text = 'default ime';
var h : hwnd;
pid : dword;
dh : hwnd;
begin
if getcurrentthreadid= 主線程idthen exit; //如果是主線程,那麼它應該有訊息迴圈,可以不處理
h := findwindow(ime_window_class, ime_window_text);
while iswindow(h) do
begin
ifgetwindowthreadprocessid(h, pid) = getcurrentthreadid then
dh := h
else
dh := 0;
h:= findwindowex(0, h, ime_window_class, ime_window_text);
if dh<> 0 then
destroywindow(dh);
end;
end;
procedure ttestthread.execute;
begin
ttimer.create(nil); //ttimer會建立隱藏的視窗
freeimewindow; //釋放ime視窗
while not terminated do
begin
dosomething;//執行緒幹活
sleep(1);
end;
end;
ubuntu下如何切換輸入法
我的ubuntu下安裝了2種中文輸入法,scim,fcitx。一直在用fcitx,但是不知何故,fcitx最近不能選取第二候選詞,所以,決定換到scim下。sudo apt get install scim pinyin sudo im switch s scim z all all 因為我用的英文...
AHK 切換 獲取當前的輸入法
用ahk 實現輸入法的切換,和獲取當前的輸入法,這只是乙個示例,你可以發揮把它做成更有用的程式,例如對指定的視窗使用指定的輸入法,可以為 每個輸入法設定乙個單獨的快捷鍵等。不過有個 bug,當輸入法切換到 微軟輸入法後,再獲取當前輸入法狀態,會出錯。不知道是不是我輸入法的問題!在系統中已安裝的輸入法...
切換輸入法導致程式宕機的解決辦法
近日在開發類似qq螢幕截圖過程中,發現在輸入文字時切換輸入法 ctrl shift 時,會導致程式出現 卡死 現象。為了方便 重用,螢幕截圖模組是以動態庫方式封裝起來的。出現 卡死 現象後,只能通過任務管理器強制殺掉對應的程序才能退出程式。於是,上網搜尋了相關話題,發現原因通常是某種輸入法如紫光或搜...