读书人

请问 Delphi 多线程切换输入法后程序假

发布时间: 2013-07-11 15:38:46 作者: rapoo

请教 Delphi 多线程切换输入法后程序假死了
最近遇到程序开启线程后,在主界面编辑框中切换输入法,程序就卡住,只有强制关闭了
线程里只有一个ADODataSet和一个ADOCommand,创建后从设备取数据存入数据库中。
以前类似的线程运行都没问题,现在问题出现后重装输入法,换电脑没能解决。
网上说因为线程中创建了窗口,消息死锁了,但在接收设备数据的时候,没有数据是等待状态 ,循环也处于等待中,执行不了消息解除死锁的过程。
不明白的是类似线程用过不少次了,为什么同样的环境 ,同样的方式 ,现在就出现了这情况了呢?
请高手指点指点!
Delphi? 多线程切换输入法? 假死 消息死锁
[解决办法]
线程里不要操作窗体,如果需要使用消息的方式。
[解决办法]

function TCFADODBStorage.OpenConnection: Boolean;

//线程里打开ADOConnection,在XP下切换输入法程序会死掉
//原因:ADO自动创建一个ADODB.AsyncEventMessenger窗口,然后会有一个对应的IME窗口,但线程里没有消息循环
// XP下输入法切换时会SendMessage给IME窗口并等待返回,IME窗口并不会处理消息,造成死锁
//这个函数把线程里的IME窗口释放掉,切换输入法时就不会有消息过来了
procedure _FreeIMEWindow;
const
IME_WINDOW_CLASS = 'IME';
IME_WINDOW_TEXT = 'Default IME';
var
h : HWND;
pid : DWORD;
dh : HWND;
begin
h := FindWindow(IME_WINDOW_CLASS, IME_WINDOW_TEXT);
while IsWindow(h) do
begin
if GetWindowThreadProcessId(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;

begin
try
FConnection.ConnectionString := ConnectionString;
FConnection.Connected := True;


if GetCurrentThreadId <> Global.MainThreadID{全局的主线程ID,如果是主线程,不需要Free} then
_FreeIMEWindow;
except on E: Exception do
FLastErrorMessage := e.Message;
end;
Result := FConnection.Connected;
end;


[解决办法]
线程中要加入消息条件退出语句,这样才不能无限循环(假死)。

读书人网 >.NET

热点推荐