2012年7月9日星期一

Delphi多线程自定义消息丢失

我们的程序中有一个BUG,偶尔的时候程序没有按照正常的工作流程继续,所谓卡在了某一位置。
查看代码和日志后发现,工作流程的驱动是通过PostThreadMessage消息到主线程来进行的,当程序卡在某一位置时,消息是发送出去了,但没有到达消息处理函数中。所谓消息丢失了。
PostThreadMessage确实可能会使消息丢失,函数说明中明确提到了。所以更换为PostMessage,发消息到TApplication的Handle。但是消息丢失的情况更加频繁了。
看来利用TApplication来处理消息也不是好办法;只有把消息发送到主窗体,在主窗体中处理消息应该更加可靠。
虽然Delphi的帮助里对 TApplication的Handle说明是"Provides access to the window handle of the main form (window) of the application.",但是我们应该知道,这里的main form和Delphi程序里我们的主窗体是不一样的,尽管我们在Delphi的Project属性中设置时也是称作Main form。我们的设置的主窗体,在TApplication中是MainForm,我们的主窗体的Handle也只能用MainForm.Handle来获得。
最终解决,PostMessage消息到MainForm.Handle,然后在MainForm中进行处理,终于和谐了。

2012年7月1日星期日

不同浏览器在中文输入过程的细微差别

之前在使用QtWebkit的时候发现它对中文输出控制上跟其他浏览器有一点儿小的差别。现在就Chrome、Firefox、IE9简单对比一下对中文输入过程的处理。
打开一个包含文本输入框的网页,启用中文输入法,鼠标点击输入框,输入几个字母(输入法状态栏出现待选词,但还没有确认输入),在这时以三种方式失当前输入框失去焦点,一种是点击网页上空白区域,另一种是点击地址栏,最后一种是点击其他程序的窗口。
对于第一种方式,三种浏览器的行为是一样的,都是输入框失去焦点,输入法取消输入过程。
对于第二种方式,Firefox和IE9也都是取消输入过程,而Chrome却是把输入的字母当作键的内容填到了输入框,也就是说输中文输到一半的时候,失去焦点时会把刚才键入的字母当作输入内容。
对于第三种方式,Firefox和IE9都是保留输入法状态,当再切回时,仍然可以接着刚才未完成的输入过程继续按键;但是Chrome的行为却跟第二种方式时一致,把键入的字母当作输入内容填入了输入框。
可以看到Firefox和IE的行为是一致的,而Chrome有些不同。