- PR -

ProgressBarについてC++版

1
投稿者投稿内容
ネーブル
常連さん
会議室デビュー日: 2006/08/26
投稿数: 27
投稿日時: 2006-09-17 12:35
お世話になります、過去スレで「ProgressBarについて」という投稿があり、コピー中にProgressBarを表示する方法を質問されていました
その回答として 「バイト配列を使ってコピー処理を行いながら、その進行状況をProgressBarで表現する方法」として、Jubeiさんが答えられていました
その回答を元に若干の変更を加えC++に移植しようと思ったのですがデリゲートに関係する部分でエラーが出てしまいます、どのように修正したらよいか
ご教示お願いできないでしょうか。

[元スレッド]
件名:ProgressBarについて
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=16832&forum=7

[エラーの状況]
コード:
 gcnew ProgressBarIncrementEvent(&driveinfo::Form1::MyProgressBarIncrementEvent)))
 


error C3867: 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&driveinfo::Form1::MyProgressBarIncrementEvent' を使用してください
error C3350: delegate コンストラクタには 2 つの引数が必要です
ここで
コード:
 gcnew ProgressBarIncrementEvent(&driveinfo::Form1::MyProgressBarIncrementEvent)))
 


こうすると
error C3352: 'void driveinfo::Form1::MyProgressBarIncrementEvent(System::Object,bool)' : 指定された関数は delegate の型 'void (System::Object,bool)' と一致しません。

コード:
 
 private:
   System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
     {
       FileCopy(foo.txt, hoge.txt);
 
      // ファイルコピー
      private:
        void FileCopy( String^ SourceFileName, String^ DestFileName )
        {
          try
          {
            progressBar1->Minimum = 0;
            progressBar1->Maximum = 100;
            progressBar1->Value = 0;
            progressBar1->Step = 1;

            FileInfo^ fi = gcnew FileInfo( SourceFileName );
            UInt64 incSize = 0;
            if (fi->Length > 100) incSize = fi->Length / 100;
            else
            {
                progressBar1->Maximum = (int)fi->Length;
                incSize = 1;
            }

            if (MyFileCopy(SourceFileName, DestFileName, incSize,
              gcnew ProgressBarIncrementEvent(driveinfo::Form1::MyProgressBarIncrementEvent)))    // この部分でエラーが発生
              MessageBox::Show("ファイルのコピーが終了しました");
            else
              MessageBox::Show("ファイルのコピーに失敗しました");
          }
          finally
          {
            this->Enabled = true;
          }
        }

      private:
        delegate void ProgressBarIncrementEvent(System::Object^ sender, bool% AbortFlg);

      private:
        void MyProgressBarIncrementEvent(System::Object^ sender, bool AbortFlg)
        {
          progressBar1->PerformStep();
          Application::DoEvents();
        }

      private:
        bool MyFileCopy(String^ ASourceFile, String^ ADestFile, int AInvokeSize, ProgressBarIncrementEvent^ AIncEvent)
        {
          bool AbortFlg = false;
          array<Byte> Buffer = gcnew array<Byte>(AInvokeSize);
            FileStream^ srcFile = File::OpenRead( ASourceFile );
            BinaryReader^ binReader = gcnew BinaryReader( srcFile );

            FileStream^ dstFile = File::OpenWrite( ADestFile );
            BinaryWriter^ binWriter = gcnew BinaryWriter( dstFile );

            int readSize = 0;
            while((readSize = srcFile->Read(Buffer, 0, Buffer->Length)) != 0)
            {
              dstFile->Write(Buffer, 0, readSize);
              AIncEvent(this, AbortFlg);
              if (AbortFlg) break;
            }
        }
      }
 


ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-09-17 14:43
引用:

gcnew ProgressBarIncrementEvent(&driveinfo::Form1::MyProgressBarIncrementEvent)))

ここで
gcnew ProgressBarIncrementEvent(&driveinfo::Form1::MyProgressBarIncrementEvent)))

こうすると


って前と同じ内容じゃん。
つーか、コンパイルエラーの内容の意味わかってる?
それが答えなんだが。それを知ろうと思うことが先なんじゃねーのかな。
_________________
質問する前にググレカス
ネーブル
常連さん
会議室デビュー日: 2006/08/26
投稿数: 27
投稿日時: 2006-09-17 15:55
ぶさいくろうさん、どうもです
引用:

って前と同じ内容じゃん。


間違えてました正しくは
コード:

if (MyFileCopy(SourceFileName, DestFileName, incSize,
gcnew ProgressBarIncrementEvent(MyProgressBarIncrementEvent)))


こうすると
: error C3867: 'driveinfo::Form1::MyProgressBarIncrementEvent': 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&driveinfo::Form1::MyProgressBarIncrementEvent' を使用してください

: error C3350: 'driveinfo::Form1::ProgressBarIncrementEvent' : delegate コンストラクタには 2 つの引数が必要です
となるので、下記のようにすると
コード:

if (MyFileCopy(SourceFileName, DestFileName, incSize,
gcnew ProgressBarIncrementEvent(&driveinfo::Form1::MyProgressBarIncrementEvent)))


: error C3352: 'void driveinfo::Form1::MyProgressBarIncrementEvent(System::Object ^,bool)' : 指定された関数は delegate の型 'void (System::Object ^,bool %)' と一致しません。
となります。
引用:

つーか、コンパイルエラーの内容の意味わかってる?


関数の呼び出し方がまずいと思うのですが、
MyProgressBarIncrementEvent関数の
引数に何をどのように設定したら良いのかわかりません、本やMSDNも読みましたが分かりませんでした。


[ メッセージ編集済み 編集者: ネーブル 編集日時 2006-09-17 16:07 ]
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-09-17 16:10
引用:

ネーブルさんの書き込み (2006-09-17 15:55) より:
関数の呼び出し方がまずいと思うのですが、引数に何をどのように設定したら良いのかわかりません、本やMSDNも読みましたが分かりませんでした。


待て。俺はコンパイルエラーに書かれてあるもの意味はわかるか?と聞いている。
それを「思うのですが」→「わかりません」で片付けてしまうのはおかしいだろ。
意味がわかるかと聞いているんだから「思うのですが」ではいけないし。
思っている部分があまりに適当すぎて意味のないやりとりになったぞ。

自分の起こしたエラーくらいもっと読み取る努力をしてくれ。
VisualStudioさんもかわいそうだ。

それと本当に本を読んだだのMSDNを見ただのであれば結局なにを調べたのか書いてくれ。
リンクくらい貼れるだろ。
_________________
質問する前にググレカス
Blue
大ベテラン
会議室デビュー日: 2005/09/12
投稿数: 230
お住まい・勤務地: 知っている人は知っている
投稿日時: 2006-09-17 16:14
引用:

ネーブルさんの書き込み (2006-09-17 12:35) より:
コード:
      private:
        delegate void ProgressBarIncrementEvent(System::Object^ sender, bool% AbortFlg);
      private:
        void MyProgressBarIncrementEvent(System::Object^ sender, bool AbortFlg)
 




エラーメッセージのとおり、型が一致していません。
コード:
      private:
        delegate void ProgressBarIncrementEvent(System::Object^ sender, bool% AbortFlg);
      private:
        void MyProgressBarIncrementEvent(System::Object^ sender, bool% AbortFlg)
 

Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2006-09-17 16:33
諸農です。

最小限のサンプルです。
フォームにボタンとプログレスバーを配置し、以下のコードを実行してください。
動作原理とコーディングの内容が判れば、後は応用だけだと思います。

コード:
private: int cnt;
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
             {
             cnt = 0;
             int leng = 100;
             progressBar1->Step=1;
             progressBar1->Minimum=0;
             progressBar1->Maximum = 100;
             PBIncEvt^ evt = gcnew PBIncEvt(this,&Form1::MyPBIncEvt);
             DoCopy(leng,evt);
             }
private: delegate void PBIncEvt(Object^ , bool&);
private: void MyPBIncEvt(Object^ sender, bool& AbortFlg)
             {
             progressBar1->PerformStep();
             Application::DoEvents();
             if (cnt > 40) AbortFlg = true;
             cnt++;
             }
private: bool DoCopy(int Leng, PBIncEvt^ evt)
             {
             bool AbortFlg = false;
             for (int i = 0;i<Leng;i++)
                 {
                 evt(this, AbortFlg);
                 System::Threading::Thread::Sleep(10);
                 if (AbortFlg) return false;
                 }
             return true;
             }



#この程度のサンプルならMSDNのサンプルの方が良いかもしれません。

引用:

error C3867: 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&driveinfo::Form1::MyProgressBarIncrementEvent' を使用してください
error C3350: delegate コンストラクタには 2 つの引数が必要です
ここで
コード:
 gcnew ProgressBarIncrementEvent(&driveinfo::Form1::MyProgressBarIncrementEvent)))
 


こうすると




皆さんからもコメントが付いていますが、コンパイルエラーレベルであれば、エラーの内容をドキュメントで調査し、エラーが何故発生しているのか、そのエラーはどうやれば解決できるのか、をある程度自力で片付けるようにしなければ、思わぬところで落とし穴にハマると思います。


_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
ネーブル
常連さん
会議室デビュー日: 2006/08/26
投稿数: 27
投稿日時: 2006-09-23 04:02
Blueさん
いつもお世話になります
引用:

エラーメッセージのとおり、型が一致していません。


まさにその通りです注意します(^^;

諸農さん、分かりやすいサンプルありがとうございました。
MSDNのサンプルは引数がarray<String^>^filenamesだったので、諸農さんの方がより理解できました。
引用:

皆さんからもコメントが付いていますが、コンパイルエラーレベルであれば、エラーの内容をドキュメントで調査し、エラーが何故発生しているのか、そのエラーはどうやれば解決できるのか、をある程度自力で片付けるようにしなければ、思わぬところで落とし穴にハマると思います。


コンパイルエラーはよく読むように努力はしているのですが、抽象的過ぎてよく理解できない事が、
多々ありますもう少し時間が掛かりそうです。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2006-09-23 08:43
諸農です。

引用:

ネーブルさんの書き込み (2006-09-23 04:02) より:

MSDNのサンプルは引数がarray<String^>^filenamesだったので、諸農さんの方がより理解できました。



揚げ足取りになるかも知れませんが、ここで言われている意味が私には理解できません。

引用:

ネーブルさんの書き込み (2006-09-23 04:02) より:

コンパイルエラーはよく読むように努力はしているのですが、抽象的過ぎてよく理解できない事が、多々ありますもう少し時間が掛かりそうです。



本当に申し訳ないのですが、言われている意味がよく判りません。

質問->回答->指摘がある度に同じことを言われているようですが、そのものずばりに近いコードを掲示板からコピペし、その結果プログラムが完成できたとしても、そこに出来上がったプログラムは本当の意味での完成品とは少し意味が異なると私は思っています。
今回の件に限れば、単にC++の書き方が判らないレベルだったのでは、と感じています。つまりそれはコンパイルエラーに対する説明が抽象的で理解しがたいと言う話ではなく、コンパイルエラーを読んだときにエラーの意味することが理解できるC++の基礎知識というか基礎体力が低かったと感じるべき話なのではないかと思います。

ネーブルさんが目指すところにも依りますが、これからもプログラムを作ると言うことを主眼とするなら、数多くの書籍を読み、参考にして、サンプルのコードをたくさん書き、その結果としてのプログラミング力の底上げを試みられてみるというのも、一つの方法ではないかと思います。

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
1

スキルアップ/キャリアアップ(JOB@IT)