如何实现像rar的拖放功能,要拖放后解压数据的
注意:是把程序里的数据拖到桌面或文件夹的,内部拖放的答案就别来浪费时间了很简单的,
光拖放也很简单也不用来乱了,
具体:用户拖放后左 键弹起时开始出来解压进度条,数据解压后存放到临时文件夹,然后拖放完成,解压后文件复制到用户拖放的目标文件夹
最好是C#的解决方法哈,
网上搜了无数,实在是找不到这类方法的解了,英文不大好,CSDN里没搜到...找到的都是拖进控件的...
研究了好久,高手们别笑啊,我就分享下拖放出去的经验,如果不存在解压,把文件拖放到桌面是很简单的,直接用DoDragDrop,然后把数据填成WINDOWS的文件类型,系统就自动完成拖放了,不过中间有个解压问题就来了,希望高手们不吝给个法子哈,,搞了几天了,,累死了
[解决办法]
下面是转贴的代码,主要说明Drag Drop过程需要处理的事项。
其实lz已经找到了方法,只是很多案例是拖放到控件,而不是进行目录和文件操作的。其实是一样的,只是修改拖放所激发的过程就行了!
再简单一些,可以通过执行带参数的命令行解压文件到指定的目录即可。
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace DragDrop
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.ListBox listBox2;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.listBox1 = new System.Windows.Forms.ListBox();
this.listBox2 = new System.Windows.Forms.ListBox();
this.SuspendLayout();
//
// listBox1
//
this.listBox1.ItemHeight = 12;
this.listBox1.Location = new System.Drawing.Point(32, 24);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(120, 280);
this.listBox1.TabIndex = 0;
this.listBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDown);
//
// listBox2
//
this.listBox2.ItemHeight = 12;
this.listBox2.Location = new System.Drawing.Point(248, 24);
this.listBox2.Name = "listBox2";
this.listBox2.Size = new System.Drawing.Size(120, 280);
this.listBox2.TabIndex = 0;
this.listBox2.DragDrop += new System.Windows.Forms.DragEventHandler(this.listBox2_DragDrop);
this.listBox2.DragEnter += new System.Windows.Forms.DragEventHandler(this.listBox2_DragEnter);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(408, 333);
this.Controls.Add(this.listBox1);
this.Controls.Add(this.listBox2);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
this.listBox1.AllowDrop = true;
this.listBox2.AllowDrop = true;
this.listBox1.Items.Add("a");
this.listBox1.Items.Add("b");
this.listBox1.Items.Add("c");
}
private void listBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
this.listBox1.DoDragDrop(this.listBox1.Items[this.listBox1.SelectedIndex],DragDropEffects.Move);
}
private void listBox2_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
if(e.Data.GetDataPresent("Text"))
{
e.Effect = DragDropEffects.Move;
}
}
private void listBox2_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
this.listBox2.Items.Add(e.Data.GetData("Text"));
this.listBox1.Items.Remove(e.Data.GetData("Text"));
}
}
}
{$R *.TLB}
{$R *.RES}
begin
end.
将文件保存为 CopyHook.dpr。再在Delphi菜单中选File|New选项,选择其中的Unit图标,按Ok键建立一个Pas文件,在其中加入以下代码:
unit CopyMain;
interface
uses Windows, ComObj, ShlObj;
type
TCopyHook = class(TComObject, ICopyHook)
protected
function CopyCallback(Wnd: HWND; wFunc, wFlags: UINT; pszSrcFile: PAnsiChar;
dwSrcAttribs: DWORD; pszDestFile: PAnsiChar; dwDestAttribs: DWORD): UINT; stdcall;
end;
TCopyHookFactory = class(TComObjectFactory)
protected
function GetProgID: string; override;
procedure ApproveShellExtension(Register: Boolean; const ClsID: string);
virtual;
public
procedure UpdateRegistry(Register: Boolean); override;
end;
implementation
uses ComServ, SysUtils, Registry;
{ TCopyHook }
file://当/Windows外壳程序执行文件夹或者打印机端口操作时,CopyCallBack
file://方/法就会被调用。
function TCopyHook.CopyCallback(Wnd: HWND; wFunc, wFlags: UINT;
pszSrcFile: PAnsiChar; dwSrcAttribs: DWORD; pszDestFile: PAnsiChar;
dwDestAttribs: DWORD): UINT;
const
FO_COPY = 2;
FO_DELETE = 3;
FO_MOVE = 1;
FO_RENAME = 4;
var
sOp:string;
begin
Case wFunc of
FO_COPY: sOp:=format(’你确定要将 %s 拷贝到 %s 吗?’,[pszSrcFile,pszDestFile]);
FO_DELETE: sOp:=format(’你确定要将 %s 删除吗?’,[pszSrcFile]);
FO_MOVE: sOp:=format(’你确定要将 %s 转移到 %s 吗?’,[pszSrcFile,pszDestFile]);
FO_RENAME: sOp:=format(’你确定要将 %s 重命名为 %s 吗?’,[pszSrcFile,pszDestFile]);
else
sOp:=format(’无法识别的操作代码 %d’,[wFlags]);
end;
// 提示,让用户决定是否执行操作
Result := MessageBox(Wnd, PChar(sOp),
’文件挂钩演示’, MB_YESNOCANCEL);
end;
{ TCopyHookFactory }
function TCopyHookFactory.GetProgID: string;
begin
Result := ’’;
end;
procedure TCopyHookFactory.UpdateRegistry(Register: Boolean);
var
ClsID: string;
begin
ClsID := GUIDToString(ClassID);
inherited UpdateRegistry(Register);
ApproveShellExtension(Register, ClsID);
if Register then
file://将/clsid 加入到注册表的CopyHookHandlers中
CreateRegKey(’directory\shellex\CopyHookHandlers\’ + ClassName, ’’,
ClsID)
else
DeleteRegKey(’directory\shellex\CopyHookHandlers\’ + ClassName);
end;
procedure TCopyHookFactory.ApproveShellExtension(Register: Boolean;
const ClsID: string);
const
SApproveKey = ’SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved’;
begin
with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
if not OpenKey(SApproveKey, True) then Exit;
if Register then WriteString(ClsID, Description)
else DeleteValue(ClsID);
finally
Free;
end;
end;
const
CLSID_CopyHook: TGUID = ’{66CD5F60-A044-11D0-A9BF-00A024E3867F}’;
LIBID_CopyHook: TGUID = ’{D2F531A0-0861-11D2-AE5C-74640BC10000}’;
initialization
TCopyHookFactory.Create(ComServer, TCopyHook, CLSID_CopyHook,
’CR_CopyHook’, ’文件操作挂钩演示’,ciMultiInstance, tmApartment);
end.
将文件保存为CopyMain.Pas文件,然后编译程序为CopyHook.Dll文件,然后注册CopyHook.Dll文件,你可以使用Windows提供的RegSvr32.exe来注册,注册的方法是在Dos窗口中进入Windows的System子目录,然后在其中输入Regsvr32 x:\xxx\xxx\copyhook.dll ,其中x:\xxx\xxx\是编译的CopyHook.dll所在的全路径名。也可以在Run菜单中选择Register ActiveX Server来注册。
当文件注册成功之后,在Windows的Explore中任意改变一个文件夹的名字或者移动一个目录,就会有一个提示框弹出,提示用户是否确定执行操作。如图所示:
按“是”将执行文件夹操作,按“否”或者“取消”将取消相应的文件夹操作。
上面介绍的只是Delphi实现Windows外壳扩展的一种,参照上面的程序和Delphi关于Windows的COM组件模型的编程,就可以编写出十分专业化的Windows外壳扩展程序。
[解决办法]
哈哈, 这个问题我也遇到过
后来搜的结果就是需要加一个 explorer 的扩展, 应该就是 3 楼的答案
[解决办法]
我可以说上面的答案都错,人家要的答案是要从里面拖出来,上面的答案都是从外面拖进去嘀
[解决办法]
楼主的问题可能需要利用钩子技术来解决吧
简单一点的处理就是在程序中直接浏览文件夹,然后完成所有的功能。楼主一定要用拖放技术吗?
[解决办法]
How to drag a virtual file from your app into Windows Explorer
http://www.codeproject.com/KB/tips/ExplorerDelayDrop.aspx
这个应该是想要的东西!我已经实现了!