程序从C# winform 移植到 C++/CLR form
中自己折腾了3天了,最后还有俩个问题。。。
之前,对线程和委托,一点也没学,概念都不清楚,只来论坛来请教这俩个问题了。
问题现象
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
C# winform 原代码
程序代码:
using System;
using System.Collections.Generic;
using using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using using System.Threading;
namespace FileCopyPlan
{
public partial class Frm_Main : Form
{
public Frm_Main()
{
InitializeComponent();
}
private System.Threading.Thread thdAddFile; //创建一个线程
private string str = "";
FormerOpen;//实例化FileStream类
FileStream ToFileOpen;//实例化FileStream类
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)//打开文件对话框
textBox1.Text = openFileDialog1.FileName;//获取源文件的路径
}
private void button2_Click(object sender, EventArgs e)
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)//打开文件夹对话框
textBox2.Text = folderBrowserDialog1.SelectedPath;//获取目的文件的路径
}
private void button3_Click(object sender, EventArgs e)
{
if (textBox1.Text.Length == 0 || textBox2.Text.Length == 0)
{
MessageBox.Show("请选择原文件路径或目的文件路径。");
return;
}
str = textBox1.Text;//记录源文件的路径
str = "\\" + str.Substring(str.LastIndexOf('\\') + 1, str.Length - str.LastIndexOf('\\') - 1);//获取源文件的名称
thdAddFile = new Thread(new ThreadStart(SetAddFile));//创建一个线程
thdAddFile.Start();//执行当前线程
}
public delegate void AddFile();//定义委托
/// <summary>
/// 在线程上执行委托
/// </summary>
public void SetAddFile()
{
this.Invoke(new AddFile(RunAddFile));//在线程上执行指定的委托
}
/// <summary>
/// 对文件进行复制,并在复制完成后关闭线程
/// </summary>
public void RunAddFile()
{
CopyFile(textBox1.Text, textBox2.Text + str, 1024, progressBar1);//复制文件
thdAddFile.Abort();//关闭线程
}
/// <summary>
/// 文件的复制
/// </summary>
/// <param FormerFile="string">源文件路径</param>
/// <param toFile="string">目的文件路径</param>
/// <param SectSize="int">传输大小</param>
/// <param progressBar="ProgressBar">ProgressBar控件</param>
public void CopyFile(string FormerFile, string toFile, int SectSize, ProgressBar progressBar1)
{
progressBar1.Value = 0;//设置进度栏的当前位置为0
progressBar1.Minimum = 0;//设置进度栏的最小值为0
FileStream fileToCreate = new FileStream(toFile, FileMode.Create);//创建目的文件,如果已存在将被覆盖
fileToCreate.Close();//关闭所有资源
fileToCreate.Dispose();//释放所有资源
FormerOpen = new FileStream(FormerFile, FileMode.Open, FileAccess.Read);//以只读方式打开源文件
ToFileOpen = new FileStream(toFile, FileMode.Append, FileAccess.Write);//以写方式打开目的文件
int max = Convert.ToInt32(Math.Ceiling((double)FormerOpen.Length / (double)SectSize));//根据一次传输的大小,计算传输的个数
progressBar1.Maximum = max;//设置进度栏的最大值
int FileSize;//要拷贝的文件的大小
if (SectSize < FormerOpen.Length)//如果分段拷贝,即每次拷贝内容小于文件总长度
{
byte[] buffer = new byte[SectSize];//根据传输的大小,定义一个字节数组
int copied = 0;//记录传输的大小
int tem_n = 1;//设置进度栏中进度块的增加个数
while (copied <= ((int)FormerOpen.Length - SectSize))//拷贝主体部分
{
FileSize = FormerOpen.Read(buffer, 0, SectSize);//从0开始读,每次最大读SectSize
FormerOpen.Flush();//清空缓存
ToFileOpen.Write(buffer, 0, SectSize);//向目的文件写入字节
ToFileOpen.Flush();//清空缓存
ToFileOpen.Position = FormerOpen.Position;//使源文件和目的文件流的位置相同
copied += FileSize;//记录已拷贝的大小
progressBar1.Value = progressBar1.Value + tem_n;//增加进度栏的进度块
}
int left = (int)FormerOpen.Length - copied;//获取剩余大小
FileSize = FormerOpen.Read(buffer, 0, left);//读取剩余的字节
FormerOpen.Flush();//清空缓存
ToFileOpen.Write(buffer, 0, left);//写入剩余的部分
ToFileOpen.Flush();//清空缓存
}
else//如果整体拷贝,即每次拷贝内容大于文件总长度
{
byte[] buffer = new byte[FormerOpen.Length];//获取文件的大小
FormerOpen.Read(buffer, 0, (int)FormerOpen.Length);//读取源文件的字节
FormerOpen.Flush();//清空缓存
ToFileOpen.Write(buffer, 0, (int)FormerOpen.Length);//写放字节
ToFileOpen.Flush();//清空缓存
}
FormerOpen.Close();//释放所有资源
ToFileOpen.Close();//释放所有资源
if (MessageBox.Show("复制完成") == DialogResult.OK)//显示"复制完成"提示对话框
{
progressBar1.Value = 0;//设置进度栏的当有位置为0
textBox1.Clear();//清空文本
textBox2.Clear();
str = "";
}
}
}
}
移植到C++/CLR form后有问题的代码
程序代码:
#pragma once
namespace FileCopyPlan {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::IO;
using namespace System::Threading;
/// <summary>
/// Frm_Main 摘要
/// </summary>
public ref class Frm_Main : public System::Windows::Forms::Form
{
public:
Frm_Main(void)
{
InitializeComponent();
//
//TODO: 在此处添加构造函数代码
//
}
protected:
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
~Frm_Main()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Label^ label1;
protected:
private: System::Windows::Forms::Label^ label2;
private: System::Windows::Forms::TextBox^ textBox1;
private: System::Windows::Forms::TextBox^ textBox2;
private: System::Windows::Forms::Button^ button1;
private: System::Windows::Forms::Button^ button2;
private: System::Windows::Forms::ProgressBar^ progressBar1;
private: System::Windows::Forms::Button^ button3;
private: System::Windows::Forms::OpenFileDialog^ openFileDialog1;
private: System::Windows::Forms::FolderBrowserDialog^ folderBrowserDialog1;
private:
/// <summary>
/// 必需的设计器变量。
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
void InitializeComponent(void)
{
this->label1 = (gcnew System::Windows::Forms::Label());
this->label2 = (gcnew System::Windows::Forms::Label());
this->textBox1 = (gcnew System::Windows::Forms::TextBox());
this->textBox2 = (gcnew System::Windows::Forms::TextBox());
this->button1 = (gcnew System::Windows::Forms::Button());
this->button2 = (gcnew System::Windows::Forms::Button());
this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
this->button3 = (gcnew System::Windows::Forms::Button());
this->openFileDialog1 = (gcnew System::Windows::Forms::OpenFileDialog());
this->folderBrowserDialog1 = (gcnew System::Windows::Forms::FolderBrowserDialog());
this->SuspendLayout();
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(11, 9);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(65, 12);
this->label1->TabIndex = 0;
this->label1->Text = L"源文件路径";
//
// label2
//
this->label2->AutoSize = true;
this->label2->Location = System::Drawing::Point(11, 66);
this->label2->Name = L"label2";
this->label2->Size = System::Drawing::Size(77, 12);
this->label2->TabIndex = 1;
this->label2->Text = L"文件保存路径";
//
// textBox1
//
this->textBox1->Location = System::Drawing::Point(13, 29);
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size(476, 21);
this->textBox1->TabIndex = 2;
//
// textBox2
//
this->textBox2->Location = System::Drawing::Point(13, 86);
this->textBox2->Name = L"textBox2";
this->textBox2->Size = System::Drawing::Size(476, 21);
this->textBox2->TabIndex = 3;
//
// button1
//
this->button1->Location = System::Drawing::Point(495, 29);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 23);
this->button1->TabIndex = 4;
this->button1->Text = L"浏览";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Frm_Main::button1_Click);
//
// button2
//
this->button2->Location = System::Drawing::Point(495, 86);
this->button2->Name = L"button2";
this->button2->Size = System::Drawing::Size(75, 23);
this->button2->TabIndex = 5;
this->button2->Text = L"浏览";
this->button2->UseVisualStyleBackColor = true;
this->button2->Click += gcnew System::EventHandler(this, &Frm_Main::button2_Click);
//
// progressBar1
//
this->progressBar1->Location = System::Drawing::Point(13, 121);
this->progressBar1->Name = L"progressBar1";
this->progressBar1->Size = System::Drawing::Size(557, 19);
this->progressBar1->TabIndex = 6;
//
// button3
//
this->button3->Location = System::Drawing::Point(254, 152);
this->button3->Name = L"button3";
this->button3->Size = System::Drawing::Size(75, 23);
this->button3->TabIndex = 7;
this->button3->Text = L"文件复制";
this->button3->UseVisualStyleBackColor = true;
this->button3->Click += gcnew System::EventHandler(this, &Frm_Main::button3_Click);
//
// openFileDialog1
//
this->openFileDialog1->FileName = L"openFileDialog1";
//
// Frm_Main
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(582, 185);
this->Controls->Add(this->button3);
this->Controls->Add(this->progressBar1);
this->Controls->Add(this->button2);
this->Controls->Add(this->button1);
this->Controls->Add(this->textBox2);
this->Controls->Add(this->textBox1);
this->Controls->Add(this->label2);
this->Controls->Add(this->label1);
this->Name = L"Frm_Main";
this->Text = L"Form1";
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
private: System::Threading::Thread^ thdAddFile; //创建一个线程
private: static String^ str = "";
FileStream^ FormerOpen;//实例化FileStream类
FileStream^ ToFileOpen;//实例化FileStream类
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
if (openFileDialog1->ShowDialog() == Windows::Forms::DialogResult::OK)//打开文件对话框
textBox1->Text = openFileDialog1->FileName;//获取源文件的路径
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
if (folderBrowserDialog1->ShowDialog() == Windows::Forms::DialogResult::OK)//打开文件夹对话框
textBox2->Text = folderBrowserDialog1->SelectedPath;//获取目的文件的路径
}
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e)
{
if (textBox1->Text->Length == 0 || textBox2->Text->Length == 0)
{
MessageBox::Show("请选择原文件路径或目的文件路径。");
return;
}
str = textBox1->Text;//记录源文件的路径
str = "\\" + str->Substring(str->LastIndexOf('\\') + 1, str->Length - str->LastIndexOf('\\') - 1);//获取源文件的名称
thdAddFile = gcnew Thread(gcnew ThreadStart(SetAddFile()));//创建一个线程
thdAddFile->Start();//执行当前线程
}
public: delegate void AddFile();//定义委托
/// <summary>
/// 在线程上执行委托
/// </summary>
public: void SetAddFile()
{
this->Invoke(gcnew AddFile(RunAddFile()));//在线程上执行指定的委托
}
/// <summary>
/// 对文件进行复制,并在复制完成后关闭线程
/// </summary>
public: void RunAddFile()
{
CopyFile(textBox1->Text, textBox2->Text + str, 1024, progressBar1);//复制文件
thdAddFile->Abort();//关闭线程
}
/// <summary>
/// 文件的复制
/// </summary>
/// <param FormerFile="string">源文件路径</param>
/// <param toFile="string">目的文件路径</param>
/// <param SectSize="int">传输大小</param>
/// <param progressBar="ProgressBar">ProgressBar控件</param>
public: void CopyFile(String^ FormerFile, String^ toFile, int SectSize, ProgressBar^ progressBar1)
{
progressBar1->Value = 0;//设置进度栏的当前位置为0
progressBar1->Minimum = 0;//设置进度栏的最小值为0
FileStream^ fileToCreate = gcnew FileStream(toFile, FileMode::Create);//创建目的文件,如果已存在将被覆盖
fileToCreate->Close();//关闭所有资源
fileToCreate->~FileStream();//Dispose();//释放所有资源
FormerOpen = gcnew FileStream(FormerFile, FileMode::Open, FileAccess::Read);//以只读方式打开源文件
ToFileOpen = gcnew FileStream(toFile, FileMode::Append, FileAccess::Write);//以写方式打开目的文件
int max = Convert::ToInt32(Math::Ceiling((double)FormerOpen->Length / (double)SectSize));//根据一次传输的大小,计算传输的个数
progressBar1->Maximum = max;//设置进度栏的最大值
int FileSize;//要拷贝的文件的大小
if (SectSize < FormerOpen->Length)//如果分段拷贝,即每次拷贝内容小于文件总长度
{
array<Byte>^buffer = gcnew array<Byte>(SectSize);//根据传输的大小,定义一个字节数组
int copied = 0;//记录传输的大小
int tem_n = 1;//设置进度栏中进度块的增加个数
while (copied <= ((int)FormerOpen->Length - SectSize))//拷贝主体部分
{
FileSize = FormerOpen->Read(buffer, 0, SectSize);//从0开始读,每次最大读SectSize
FormerOpen->Flush();//清空缓存
ToFileOpen->Write(buffer, 0, SectSize);//向目的文件写入字节
ToFileOpen->Flush();//清空缓存
ToFileOpen->Position = FormerOpen->Position;//使源文件和目的文件流的位置相同
copied += FileSize;//记录已拷贝的大小
progressBar1->Value = progressBar1->Value + tem_n;//增加进度栏的进度块
}
int left = (int)FormerOpen->Length - copied;//获取剩余大小
FileSize = FormerOpen->Read(buffer, 0, left);//读取剩余的字节
FormerOpen->Flush();//清空缓存
ToFileOpen->Write(buffer, 0, left);//写入剩余的部分
ToFileOpen->Flush();//清空缓存
}
else//如果整体拷贝,即每次拷贝内容大于文件总长度
{
array<Byte>^buffer = gcnew array<Byte>(FormerOpen->Length); //获取文件的大小
FormerOpen->Read(buffer, 0, (int)FormerOpen->Length);//读取源文件的字节
FormerOpen->Flush();//清空缓存
ToFileOpen->Write(buffer, 0, (int)FormerOpen->Length);//写放字节
ToFileOpen->Flush();//清空缓存
}
FormerOpen->Close();//释放所有资源
ToFileOpen->Close();//释放所有资源
if (MessageBox::Show("复制完成") == Windows::Forms::DialogResult::OK)//显示"复制完成"提示对话框
{
progressBar1->Value = 0;//设置进度栏的当有位置为0
textBox1->Clear();//清空文本
textBox2->Clear();
str = "";
}
}
};
}