使用拖放下载文件的时候窗口假死的问题

lcfeng1982 2008-11-26 12:22:21
最近在做一个C/S模式的网络U盘,上传文件到服务器时网民可以通过从资源管理器中拖放文件到TListView中,下载文件时从TListView中拖放文件到本地资源管理器中,上传的时候可以使用多线程实现,但是下载的时候使用拖放,使用多线程的时候无法下载,如果不使用多线程倒是可以下载但是窗口会出现假死的情况,不知道哪位大侠可有好的解决方法?!
...全文
93 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
filec75 2008-11-27
  • 打赏
  • 举报
回复
帮顶
Waiting4you 2008-11-26
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lcfeng1982 的回复:]

void DownloadFileTo(int idx, AnsiString FileName)  //模拟从网上下载文件并保存到FileName
{
//Sleep(10000);  //花了1秒钟下载(在实际下载中,建议使用While(!完成下载) Application->ProcessMessage();代替以防止假死)
//模拟下载进度条
TfmDownload *pfm = new TfmDownload(Application);
pfm->Timer1->Enabled = true;
pfm->ShowModal();  //“这里等窗体关闭.”如果这样的话,岂不是只有窗体关闭文件才能下载,如…
[/Quote]

我说了是"模拟下载进度条",只是模拟. 下面的"我这里就随便建个文件代替"你完全可以无视,这个只是当时给你演示拖放文件时写的.
你下载几百兆的文件的下载过程是可以多线程的吧? 等窗体关闭的同时另一线程也在下载文件呀.
那么这个TfmDownload你自己可以改造一下,比如可以把构造函数改成TfmDownload( String URL, String Filename);在构造里直接生成一个线程下载这个文件,线程里可以通过PostMessage给这个窗体通信,告诉窗体现在下载到百分之多少了.(我那个Timer1就是模拟这个的) 这样当下载完成时窗体就可以关闭了.
窗体里再加一个"取消"按钮可以直接结束线程+关闭窗体,给用户一个可以取消下载的机会.
lcfeng1982 2008-11-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 dfdscx 的回复:]
下载为啥不能用多线程啊?
[/Quote]
如果是一般的下载(比如通过SelectDirectory选择下载到的目标路径)是可以用多线程的,但是如果通过拖放下载的话好像不可以使用多线程,至少我还不知道如何在多线程中实现拖放,不知道哪位大侠知道否?!!
lcfeng1982 2008-11-26
  • 打赏
  • 举报
回复

void DownloadFileTo(int idx, AnsiString FileName) //模拟从网上下载文件并保存到FileName
{
//Sleep(10000); //花了1秒钟下载(在实际下载中,建议使用While(!完成下载) Application->ProcessMessage();代替以防止假死)
//模拟下载进度条
TfmDownload *pfm = new TfmDownload(Application);
pfm->Timer1->Enabled = true;
pfm->ShowModal(); //“这里等窗体关闭.”如果这样的话,岂不是只有窗体关闭文件才能下载,如果下面的代码是下载一个大的文件(比如几百兆),还不是一样会假死??
delete pfm;

//我这里就随便建个文件代替吧-_-
TIcon *ico = new TIcon;
fmMain->ilIcons->GetIcon(idx, ico);
ico->SaveToFile(FileName);
delete ico;
}
lcfeng1982 2008-11-26
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 Waiting4you 的回复:]
引用 4 楼 lcfeng1982 的回复:

void DownloadFileTo(int idx, AnsiString FileName) //模拟从网上下载文件并保存到FileName
{
//Sleep(10000); //花了1秒钟下载(在实际下载中,建议使用While(!完成下载) Application->ProcessMessage();代替以防止假死)
//模拟下载进度条
TfmDownload *pfm = new TfmDownload(Application);
pfm->Timer1->Enabled = true;
pfm->ShowModal(); //“这里等窗体关闭.”如果这样的话…
[/Quote]
只有如此了,看样子拖放是不能点击“我的U盘”界面上的其他按钮,DoDragDrop函数就像DoModal函数一样,只有完成后才能返回
谢谢各位了,特别是毛毛,:-D
Waiting4you 2008-11-26
  • 打赏
  • 举报
回复
你说的假死是拖放操作在等你下载文件结束,你下载文件过程中没办法监控吗?比如显示下载百分比,加一个取消按钮?
我上次给你的Demo,把DownloadFileTo函数改成这样就没这个问题了



void DownloadFileTo(int idx, AnsiString FileName)  //模拟从网上下载文件并保存到FileName
{
//Sleep(10000); //花了1秒钟下载(在实际下载中,建议使用While(!完成下载) Application->ProcessMessage();代替以防止假死)
//模拟下载进度条
TfmDownload *pfm = new TfmDownload(Application);
pfm->Timer1->Enabled = true;
pfm->ShowModal(); //这里等窗体关闭.
delete pfm;

//我这里就随便建个文件代替吧-_-
TIcon *ico = new TIcon;
fmMain->ilIcons->GetIcon(idx, ico);
ico->SaveToFile(FileName);
delete ico;
}


这里的TfmDownload是一个TForm, 里面一个TProcessBar和Timer再加一个"取消"按钮.
事件代码如下:
//---------------------------------------------------------------------------
void __fastcall TfmDownload::Timer1Timer(TObject *Sender) //这个Timer是用来模拟你下载百分比进度的,完成下载以后关闭这个窗体.
{
ProgressBar1->StepIt();
if(ProgressBar1->Position>=ProgressBar1->Max) Close();
}
//---------------------------------------------------------------------------
void __fastcall TfmDownload::btnCancelClick(TObject *Sender) //按取消按钮直接关闭窗体(实际使用时可以用ModalResult代替,这样可以作为下载是否成功的指示, 上同)
{
Close();
}
//---------------------------------------------------------------------------
android2008 2008-11-26
  • 打赏
  • 举报
回复
帮顶
yumikoo 2008-11-26
  • 打赏
  • 举报
回复
看下假死阶段的代码
filec75 2008-11-26
  • 打赏
  • 举报
回复
友情up
dfdscx 2008-11-26
  • 打赏
  • 举报
回复
下载为啥不能用多线程啊?
filec75 2008-11-26
  • 打赏
  • 举报
回复
不懂,up
ilistonline 2008-11-26
  • 打赏
  • 举报
回复
使用多线程是最好的办法
jaffy 2008-11-26
  • 打赏
  • 举报
回复
什么是拖放,什么是假死?

703

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder ActiveX/COM/DCOM
社区管理员
  • ActiveX/COM/DCOM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧