html form里面的选择文件对话框只能得到文件的名称,拿不到文件的全路径,只能扩展js让其去调用通用对话框的函数,例如SHBrowseForFolder。写完代码后,发现需要点击两次才能点中确定按钮的bug,一开始以为是鼠标有问题,后来发现每次都是这样,这肯定是代码的问题了。一开始我以为是SHBrowseForFolder调用有问题,认为SHBrowseForFolder产生的对话框没有获得焦点,所以用各种方法来使得对话框获得焦点,用各种方法都发现没用。针对要点击两次的问题,我还试过模拟鼠标点击来试图解决这个bug,后面发现根本无效。看来应该是webkit对鼠标消息的处理有问题,看了一下WebView.cpp里面的WebView::handleMouseEvent,发现有如下代码:
鼠标按下:
鼠标抬起:
在鼠标按下时,webkit会调用SetCapture,鼠标抬起时会调用ReleaseCapture,但是ReleaseCapture在交给webcore处理之后才调用,也就是说,js里面处理onmousedown完之后才会调用ReleaseCapture。所以如果在onmousedown或onclick中调用SHBrowseForFolder会导致对话框里面的事件会先交给webkit的窗口,但点击其他窗口或点击两次的时候才会让对话框激活。解决方法也简单,在调用SHBrowseForFolder之前先调用ReleaseCapture之前就可以了,示例代码:
如果将webview.cpp的ReleaseCapture放在调用handleMouseReleaseEvent之前,应该也可以解决这个bug,但可能会引起js对drag and drop的处理出问题,所以在进行完全测试之前不建议这么干。
在解决这个bug过程中,发现了如下技巧:
1.如何简单地设置SHBrowseForFolder所需的父窗口?调用::GetActiveWindow()方法就可以得到当前的active窗口,用其作为父窗口即可。
2. 让选择文件夹对话框里面的treeview获取焦点:
3. Window SubClassing另类运用:http://blog.youkuaiyun.com/weizhisheng/archive/2002/02/28/9258.aspx