|
STDMETHODIMP CHtmlControlSite::XDocHostUIHandler::GetDropTarget(
LPDROPTARGET pDropTarget, LPDROPTARGET* ppDropTarget)
{
METHOD_PROLOGUE_EX_(CHtmlControlSite, DocHostUIHandler)
*ppDropTarget = g_pDropTarget;//将自定义的实现告知MSHTML引擎
return S_OK;
}
其中g_pDropTarget指向某个全局的IDropTarget接口的实现,我们假定为CIEDropTarget,CIEDropTarget实现了IDropTarget的几个成员函数DragEnter、DragOver、DragLeave和Drop。在DragEnter中可以决定是否接受一个Drop以及如果接受这个Drop的话该提供怎样的鼠标拖拽反馈,在持续触发的DragOver中同样可以设定鼠标拖拽反馈,从而实现在拖放不同的对象(文字、链接、图像等)时提供不同的拖拽视觉效果,实现相当简单,此处不再赘述。
但上面的实现存在一些问题。首先是选中的文字在页面内与输入框之间交互的拖放没有了。这是自然的,既然我们用自定义的DropTarget替换掉了IE的缺省实现,那这种交互的拖放理应由我们自己实现。难处并非在于不能实现,而是在于实现起来比较麻烦——光是得到鼠标下的HTML Element就够我们烦了;当输入框中有文字的时候,光标还应该随着鼠标的移动而移动——所以这个费力还不一定讨好的功能似乎没有哪个浏览器去做。其次,作为输入框文字拖放的衍生物,拖拽滚动没有了。当鼠标向某个方向拖拽时,网页应该随着将不可见的部分滚动出来,比如某个输入框,让我们有机会将文字拖拽过去。这个Feature的实现并不困难,不过一来是被忽略了(注意到拖拽滚动的人并不多),二来主要Feature都没有实现,这个滚动也意义不大了。
3、打入MSHTML内部
既然从GetDropTarget提供外部实现难以得到与输入框的交互式拖放,那就换个角度来考虑问题,让我们打入MSHTML的内部。
着手点是IHTMLDocumentX接口——操纵IE的DOM的法宝。我们注意到IHTMLDocument2有个ondragstart事件,进而想到应该也有诸如ondragenter、ondragover、ondrop之类的事件(事实上也是有的),如果响应这些事件,处理同输入框的交互式拖放应该就能够解决。因为这些拖放在MSHTML的缺省DropTarget实现中发生,因而当鼠标拖拽到某个输入框上时,肯定会触发一个ondragover事件,而在IHTMLEventObj的辅助下我们能轻松得到相关的HTML Element,其它的操作就容易进行了。再细心一点,我们还发现IHTMLEventObj2接口有个dataTransfer属性——可以得到一个IHTMLDataTransfer的指针,而IHTMLDataTransfer接口正是浏览器内部用于数据交换的重要手段之一(看看它的属性就知道会很有用了):
IHTMLDataTransfer Members
clearData——Removes one or more data formats from the clipboard through dataTransfer or clipboardData object.
上一篇:我对PMP考试的一些体会
下一篇:关于N皇后问题高效试探回溯算法的分析
|