TipicIM是一款不错的基于Jabber的聊天工具客户端,。但在聊天时若要发送文件给对方,只能在聊天界面上点击Send a file按钮,然后在弹出的文件选择框中查找并选择文件。要是能象msn那样从资源管理器中直接拖一个文件过来就能发送,那多好啊!
TipicIM提供了主要的源代码,主要是HTML和JavaScript。可自行修改源码,修改后Log out TipicIM再重新Login即可生效。
TipicIM的chat.html中,接收用户输入的聊天内容是一个TEXTAREA。在网上查了一下资料,TEXTAREA尽管可以响应OnDragStart、OnDragEnter、OnDragEnd、OnDrop等事件,但拖动的源只能是在当前页面中,若源是在浏览器外(比如Windows资源管理器),那就无法获得源文件的信息。
继续搜索,找到如下一段代码:

<html>
<head>
<title>IVBDataObject Demo</title>

<style type="text/css">
fieldset{
text-align:center;
padding:2em
}

object{
width:3em;height:3em;
border:6px double activecaption;
vertical-align:middle
}

textarea{
width:60%;margin-top:1em;
word-wrap:normal;
vertical-align:middle
}

</style>
</head>
<body>

<fieldset>
<legend><strong>Drop File(s) ? </strong>

<object id="IAnimation"
classid="clsid:B09DE715-87C1-11D1-8BE3-0000F8754DA1">
<param name="OleDropMode" value="1">
</object>

&nbsp;</legend>
<label><em>output: </em></label>
<textarea id="output" cols="100" rows="10"></textarea>
</fieldset>

<script type="text/javascript">

function IAnimation::OLEDragDrop(Data){

if(Data.GetFormat(15)){
var O = "";
var e = new Enumerator(Data.Files);
while(!e.atEnd()){
O += e.item() + "\n";
e.moveNext();
}

output.value = O;
BackColor=0x80000003;}
}

// Just for visual feedback...
function IAnimation::OLEDragOver(Data, _, _, _, _, _, State){
if (State == 0){
if(Data.GetFormat(15)){Backcolor = 0x80000002;}
}

if(State == 1){Backcolor = 0x80000003;}
}

function window::onload(){
IAnimation.BackColor=0x80000003;
}

</script>
</body>
</html>

 上面这段代码中使用了一个ActiveX控件,该控件是一个 Animation对象,这个对象就可以正确地获得事件信息了。
于是修改chat.html:
1.在接受用户输入的TEXTAREA前放一个Animation对象:

<object id="IAnimation" style="width:40px;height:84px;border:6px double activecaption;" classid="clsid:B09DE715-87C1-11D1-8BE3-0000F8754DA1">
<param name="OleDropMode" value="1"></object>
 2.为该对象添加OLEDragDrop和OLEDragOver事件处理:

<SCRIPT FOR=IAnimation EVENT="OLEDragDrop(Data)">
if(Data.GetFormat(15)){
var e = new Enumerator(Data.Files);
if(!e.atEnd()){
sendfile( e.item() );
}

BackColor=0x80000003;}
</SCRIPT>

<SCRIPT FOR=IAnimation EVENT="OLEDragOver(Data, _, _, _, _, _, State)">
// Just for visual feedback...

if (State == 0){
if(Data.GetFormat(15)){Backcolor = 0x80000002;}
}

if(State == 1){Backcolor = 0x80000003;}
</SCRIPT>

3. 上面的事件中调用了sendfile,该方法的处理如下:

function sendfile ( filename )
{
  external.globals( 'cfg' )( 'location' ) = filename;

  document.getElementById( 'txt' ).focus();
  external.wnd.params[0].dial_file( external.wnd.params[1], getresource() );
}

4.sendfile调用dial_file来创建发送文件窗体,该窗体的代码在file_send.html中。当执行file_send.html中的init方法时会弹出一个文件选择框,让用户选择要发送的文件。因为在sendfile中已经知道了这个文件名,并写入到了external.globals( 'cfg' )( 'location' )中,不需要再弹出文件选择框,于是需要修改file_send.html中的pickfile方法。在pickfile方法的头部插入如下代码:

 var s = external.globals( 'cfg' )( 'location' );
 if ( s.length )
 {
    document.getElementById( 'location' ).value = document.getElementById( 'filename' ).value = s;
   if ( s.lastIndexOf( '\\' ) != -1 )
   {
    external.globals( 'cfg' )( 'downloaddir' ) = s.substr( 0, s.lastIndexOf( '\\' ) + 1 );
    document.getElementById( 'filename' ).value = s.substr( s.lastIndexOf( '\\' ) + 1 );
   }

    external.globals( 'cfg' )( 'location' ) = '';

   return true;
 }

该段代码检查external.globals( 'cfg' )( 'location' )是否已有值,有则将该值的路径和文件名分别放入external.globals( 'cfg' )( 'downloaddir' )和document.getElementById( 'filename' ).value中并清除external.globals( 'cfg' )( 'location' )后返回,否则执行原来的代码(即弹出文件选择框,分析选择的文件路径和文件名并放到external.globals( 'cfg' )( 'downloaddir' )和document.getElementById( 'filename' ).value中)
至此修改完毕,TipicIM已经具有了在聊天时直接拖放文件并发送的功能。

注:以上改动仅针对TipicIM vRC9 1.7.0(可在www.tipic.com下载),其它版本或其它使用类似技术实现的Jabber客户端可参考以上内容进行适当修改。
附:修改后的chat.html和file_send.html源码

 

 

posted on 2006-06-19 17:19  海蓝  阅读(1012)  评论(1编辑  收藏  举报