XP下切换输入法造成程序卡死的原因及解决方案

http://blog.csdn.net/ysai/article/details/7468961

XP下切换输入法造成程序卡死的原因及解决方案

(by ysai)

现象:

在XP下,如果线程中创建了窗口而线程中没有消息循环,那么可能切换输入法时会造成程序卡死(某些XP下必现,跟安装盘有关)

原因:

线程创建一个窗口后,系统会自动创建一个Default IME窗口以便通知输入法消息(可能只有可以接收输入的窗口才会创建,未证实)

XP下切换输入法,会向所有DefaultIME窗口SendMessage告诉应用程序,当前输入法改变了

而线程窗口如果没有消息循环,则不会处理消息队列,然后卡死

演示代码:

[delphi] view plain copy

  1. TTestThread = class(TThread)
  2. private
  3. procedure ProcessMessages;
  4. protected
  5. procedure Execute; override;
  6. end;
  7. procedure TTestThread.Execute;
  8. begin
  9. TTimer.Create(nil);  //TTimer会创建隐藏的窗口
  10. while not Terminated do
  11. begin
  12. DoSomething;//线程干活
  13. //ProcessMessages;  //去掉这一句就可能卡死
  14. Sleep(1);
  15. end;
  16. end;
  17. ///内建的一个简单消息循环
  18. procedure TTestThread.ProcessMessages;
  19. var
  20. Msg: TMsg;
  21. begin
  22. while PeekMessage(Msg, 0, 0, 0,PM_REMOVE) then
  23. begin
  24. TranslateMessage(Msg);
  25. DispatchMessage(Msg);
  26. end;
  27. end;

程序中使用上面的线程,则在XP下切换输入法可能卡死

即使线程中加入了消息循环,如果在线程工作时DoSomething占用过多时间,也会假死

终极解决方案:

如果不能避免在线程中创建窗口(比如调用了某个COM组件,但COM内部创建了窗口,如ADO会创建一个ADODB.AsyncEventMessenger窗口)

则在线程创建窗口后,执行以下代码

[delphi] view plain copy

  1. procedure FreeIMEWindow;
  2. const
  3. IME_WINDOW_CLASS =‘IME‘;
  4. IME_WINDOW_TEXT = ‘Default IME‘;
  5. var
  6. h : HWND;
  7. pid : DWORD;
  8. dh : HWND;
  9. begin
  10. if GetCurrentThreadId= 主线程IDthen exit;    //如果是主线程,那么它应该有消息循环,可以不处理
  11. h := FindWindow(IME_WINDOW_CLASS, IME_WINDOW_TEXT);
  12. while IsWindow(h) do
  13. begin
  14. ifGetWindowThreadProcessId(h, pid) = GetCurrentThreadId then
  15. dh  :=  h
  16. else
  17. dh  :=  0;
  18. h:=  FindWindowEx(0, h, IME_WINDOW_CLASS, IME_WINDOW_TEXT);
  19. if dh<> 0 then
  20. DestroyWindow(dh);
  21. end;
  22. end;
  23. procedure TTestThread.Execute;
  24. begin
  25. TTimer.Create(nil);  //TTimer会创建隐藏的窗口
  26. FreeIMEWindow;  //释放IME窗口
  27. while not Terminated do
  28. begin
  29. DoSomething;//线程干活
  30. Sleep(1);
  31. end;
  32. end;
时间: 2024-10-17 06:53:56

XP下切换输入法造成程序卡死的原因及解决方案的相关文章

最近遇到程序开启线程后,在主界面编辑框中切换输入法,程序就卡住,只有强制关闭

function TCFADODBStorage.OpenConnection: Boolean; //线程里打开ADOConnection,在XP下切换输入法程序会死掉 //原因:ADO自动创建一个ADODB.AsyncEventMessenger窗口,然后会有一个对应的IME窗口,但线程里没有消息循环 // XP下输入法切换时会SendMessage给IME窗口并等待返回,IME窗口并不会处理消息,造成死锁 //这个函数把线程里的IME窗口释放掉,切换输入法时就不会有消息过来了 proced

Delphi 多线程切换输入法后程序假死了

http://bbs.csdn.net/topics/390472740 Delphi/Pascal code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 function TCFADODBStorage.OpenConnection: Boolean;   //线程里打开ADOConnection,在XP下切换输入法程序

linux-ubuntu 下R无法安装rjava模块的原因及解决方案

错误信息: 没有 /usr/lib/jvm/default-java/jre/bin/java 原因: R找不到java作为依赖 解决方案: (1) 如果你没有安装java,请先安装java. (2) 在终端中查看java的版本. (3) 在/usr/lib/jvm下手动创建default-java文件夹 (4) 找到终端中显示的java环境的文件夹(默认在/usr/lib/jvm下,我有oraclejava和openjava, 而我使用的是oraclejava) (5) 手动复制java环境的

linux-ubuntu 下R无法安装HH包的原因及解决方案

错误信息: configure: error: GNU MP not found, or not 4.1.4 or up, see http://gmplib.org ERROR: configuration failed for package 'gmp' * removing '/home/chenyansu/R/x86_64-pc-linux-gnu-library/3.3/gmp' Warning in install.packages : installation of package

update语句执行卡死现象原因及解决方案

https://blog.csdn.net/wpz0713/article/details/51499654 原因分析: 可能在PLSQL Developer执行update时没有commit,oracle将该条记录锁住了. 解决方案: --查询锁定记录 SELECT s.sid,s.serial# FROM v$locked_object lo,dba_objects ao, v$session s WHERE ao.object_id = lo.object_id AND lo.sessio

VS2013编写的C#程序,在xp下会报错说“不是合法的win32程序”。

VS2013编写的程序,在xp下会报错说“不是合法的win32程序”. 这个用C++编写的程序可以经过设置后在XP下运行,主要的“平台工具集”里修改就可以.方法见: http://blog.csdn.net/civilman/article/details/40109685 但是,用C#编写的程序,项目属性里是没有“平台工具集”的选项的,运行时会报错说不是正常的win32程序. DotNet版本为2.0,在xp下已经安装dotnet20. 请问,有谁知道如何让VS2013编写的C#程序在XP下运

WPF 程序在 Windows XP 下报错:The image format is unrecognized.

最近做的一个 WPF 程序,在 Windows 7 或以上版本的系统中,测试都很正常,在 Windows XP 下运行时一开始就报了个错误: {     "ClassName" : "System.Windows.Markup.XamlParseException",     "Message" : "The image format is unrecognized.",     "Data" : {   

解决Qt发布的程序在xp环境下提示“无法定位程序输入点 K32GetModuleFileNameExA 于动态链接库 KERNEL32.dll 上”的错误

用Qt开发时,调用系统API函数时的问题,在win7及以上系统没什么大问题.在xp下出现了标题描述的现象,导致无法启动程序.看了下网上的解决方案如下: 这里我要讨论的是在 WinSDK v7.0中的一些不友好的错误.如果你是一名开发者,并且当前使用的是VS2010编译器自带的 WinSDK v7.0,那么个别时候当你执行程序时,可能遇到这样的错误提示:The procedure entry point K32*** could not be located in the dynamic link

qtcreator +vs2013 开发xp下使用的程序

在qtcreator 开发,使用vs2013的编辑器开发出来的exe不能在xp下使用, 只需要在pro文件添加 QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.01 即可使用