大概是两年前做的一个项目,跟百度云盘的拖拽下载功能基本差不多。最近有人问我,我看了一下以前的代码,感觉应该写点什么记录下来,方便以后可以直接使用。记得当时网上查了好久基本没有,问了好多人,答案大多都好像无法实现。公司当时WPF就我一个人,最后没办法,只有观察琢磨百度云的拖拽下载,观察了一周左右,最后终于自己弄出来了。
说下思路:(注意将拖拽拆分为复制和粘贴,拖起为复制,到达系统中鼠标弹起为粘贴)
1.用户在软件界面拖拽了文件或者点击了复制,如果这时候用户在系统中点击了粘贴或者文件拖拽的到系统中,我们是无法捕捉这个操作的,所以这时候我们想办法找到a.用户什么时候在系统中点击了粘贴,或者拖拽到系统中鼠标弹起了(相当于在系统中点击了粘贴);b.用户在系统中哪个文件夹下,点击了粘贴或者拖拽的鼠标弹起了,即最终的我们要下载的目录。
2.至于如何判断用户的点击粘贴动作或者拖拽的鼠标弹起操作,我们需要借助系统剪切板完成。原因:系统的文件拖拽实际也是复制粘贴过程,我们是否可以用一个中间文件,我们在软件中拖起文件时,给系统一个中间文件,到系统剪切板,后面我称这个文件为标记文件,当标记被粘贴了或者被拖拽到某一文件夹,那不就是我们需要的下载目录和最终的下载时间?
3.具体实现:用户在软件中点击复制,或者拖拽了文件(鼠标没有弹起,仅仅是复制,没有粘贴),这时候,我们需要在系统的剪切板中添加一个文件(标记文件),文件路径随意,不要改动,但是一定要隐蔽,而且不要更换,一般是C盘的AppData\Local\Temp\我们的应用程序文件夹,专业一点的都懂的,这个文件夹是干嘛的。将这个文件放入系统的剪切板,剪切板有个类型选择,选剪切,不要选复制,原因:当用户在系统中点击粘贴或者拖拽的鼠标弹起时,该文件会被切剪到用户指定的文件夹中,这个文件夹就是我们需要的文件夹路径,这个事件发生的时候,就是我们需要干活的时候,我们需要干的,最重要的一步,就是监听这个C盘的AppData\Local\Temp\我们的应用程序文件夹,查看中间文件状态(是否被剪切)。
4.最后一步:监听。获取当前系统中被激活的窗口,如果当前被激活的是文件夹,那么就监听,至于怎么获取被激活的窗体,网上有,要用win32函数,我就不多说了,后续代码也可以参考。
5.被监听的文件夹中如果出现那个标记文件被剪切走(删除了),我们就发起下载过程,同时删掉标记文件,这个下载的目的地址,就是标记文件被剪切到达的文件夹。
2.至于如何判断用户的点击粘贴动作或者拖拽的鼠标弹起操作,我们需要借助系统剪切板完成。原因:系统的文件拖拽实际也是复制粘贴过程,我们是否可以用一个中间文件,我们在软件中拖起文件时,给系统一个中间文件,到系统剪切板,后面我称这个文件为标记文件,当标记被粘贴了或者被拖拽到某一文件夹,那不就是我们需要的下载目录和最终的下载时间?
3.具体实现:用户在软件中点击复制,或者拖拽了文件(鼠标没有弹起,仅仅是复制,没有粘贴),这时候,我们需要在系统的剪切板中添加一个文件(标记文件),文件路径随意,不要改动,但是一定要隐蔽,而且不要更换,一般是C盘的AppData\Local\Temp\我们的应用程序文件夹,专业一点的都懂的,这个文件夹是干嘛的。将这个文件放入系统的剪切板,剪切板有个类型选择,选剪切,不要选复制,原因:当用户在系统中点击粘贴或者拖拽的鼠标弹起时,该文件会被切剪到用户指定的文件夹中,这个文件夹就是我们需要的文件夹路径,这个事件发生的时候,就是我们需要干活的时候,我们需要干的,最重要的一步,就是监听这个C盘的AppData\Local\Temp\我们的应用程序文件夹,查看中间文件状态(是否被剪切)。
4.最后一步:监听。获取当前系统中被激活的窗口,如果当前被激活的是文件夹,那么就监听,至于怎么获取被激活的窗体,网上有,要用win32函数,我就不多说了,后续代码也可以参考。
5.被监听的文件夹中如果出现那个标记文件被剪切走(删除了),我们就发起下载过程,同时删掉标记文件,这个下载的目的地址,就是标记文件被剪切到达的文件夹。
思路证明:把百度云的文件,随意直接往qq好友面板中拖拽,会有类似的一个标记文件存在;或者下载时观察AppData\Local\baidu这个文件夹,也会有这样一个中间文件作为标记文件,在下载的目录中也存在这样一个文件。
好了,思路是思路,最终还是要验证,最简单的验证,上代码:
1.先定义一个文件类,这个没啥好纠结的
class FileName
{
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
public FileName(string name)
{
this.Name = name;
}
}
2.定义一个窗口类,也没啥好多说的
<Grid>
<ListView Name="listView" ItemsSource="{Binding}" MouseMove="listView_MouseMove" >
<ListView.View>
<GridView>
<GridViewColumn Header="文件名" Width="320">