- - PR -
ソケットのAsyncCallbackデリゲート内でpictureBoxに表示したい
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-03-02 13:53
C#.NETのWindowsアプリケーションで非同期ソケット通信を行っています。
読み取りコールバックメソッド内で読み取った受信データ(画像)をFormのpictureBoxに 表示させようとしています。 読み取りコールバックメソッドは静的メソッドですので、受信バッファなどの有用な情報は小さなクラスを作成してBeginRecieveメソッドのオブジェクト引数として渡しています。 読み取りコールバックメソッド内でpictureBoxを参照させる為には、そのオブジェクト引数として渡すしか思いつかなくて、でもそうするためにはFormのpictureBoxの宣言を無理矢理static宣言に修正しないとコンパイルで ”静的でないフィールドSocketServer.Form1.pictureBox1でオブジェクトの参照が必要です。” となってしまいます。 例え無理やりstatic宣言に修正してもFormのデザインを修正すると元に戻ってしまって、また上記のコンパイルエラーになってしまいます。 もっと良い方法はないでしょうか? public class Form1 : System.Windows.Forms.Form { --- 省略--- public static System.Windows.Forms.PictureBox pictureBox1; ←無理矢理static --- 省略--- private void InitializeComponent() { // this.pictureBox を無理矢理pictureBoxに修正 pictureBox1 = new System.Windows.Forms.PictureBoX(); pictureBox1.BackColor = System.Drawing.SystemColors.Desktop; this.Controls.Add(pictureBox1); } public class StateObject // BeginRecieveに渡すオブジェクト { public Socket workSocket = null; public const int BufferSize = 787496; public byte [] buffer = new byte [BufferSize]; public PictureBox pictureBox =pictureBox1; ← 上記の定義をstaticにしないとここで’SocketServer.Form1.pictureBox1でオブジェクト参照が必要です’のエラーになる } public static void AcceptCallback(IAsyncResult ar) { Socket listener = (Socket)ar.AsyncState ; Socket handler = listener.EndAccept (ar); StateObject state = new StateObject (); state.workSocket = handler; handler.BeginReceive (state.buffer , 0, StateObject.BufferSize , 0, new AsyncCallback (ReadCallback), state); } public static void ReadCallback(IAsyncResult ar) { // Retrieve the state object and the handler socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState ; Socket handler = state.workSocket ; // Read data from the client socket. int byteRead = handler.EndReceive (ar); if( byteRead > 0 ) { ---省略--- state.pictureBox.Image = bmp2; ←ここでForm1のpictureBoxに表示させたい state.pictureBox.Invalidate (); ---省略--- } } } | ||||||||||||
|
投稿日時: 2004-03-02 16:19
諸農です。
斜め読みですが、 「読み取りコールバックメソッドは静的メソッド」 とはどういうことなんでしょうか? デリゲートではないのですが?
ちょっと意味がわからないのですが、 StateObjectクラスのコンストラクタに、フォームで利用しているPictureBoxの 参照を渡せば済むのではないでしょうか?何か別途ダメな理由があるのですか? _________________ 諸農和岳 Powered by Turbo Delphi & Microsoft Visual Studio 2005 十兵衛@わんくま同盟 http://blogs.wankuma.com/jubei/ | ||||||||||||
|
投稿日時: 2004-03-02 16:45
すみません。私、なんか良く分かってないんだと思うんですが「読み取りコールバックメソッドは静的メソッド」っていうのはデリゲートなんですが、msdnで調べると
public static void AcceptCallback(IAsyncResult ar) public static void ReadCallback(IAsyncResult ar) のように static で宣言されていたものですから・・・そんな言い方はしないのかな?すみません。 こういう場合って、staticで宣言するものなのですか? アドバイスのようにStateObjectクラスのコンストラクタに、フォームで利用している PictureBoxの参照を渡そうとしてみたんですが、これもまたStateObjectのインスタンスを 作成するのも、public static void AcceptCallback()の中なので FormのpictureBoxの参照の渡し方が分からないんです。 | ||||||||||||
|
投稿日時: 2004-03-02 17:05
絶対、ってことはないでしょう。 というか、たまたまその解説ページがstaticを使っているだけでしょう。 (たぶん非同期サーバー ソケットの例の解説では?) ちなみに非同期サーバー ソケットの使用の例ではstaticでないacceptCallbackもありますし。 このケースなら、staticなんか取っ払ってもいいと思います。 [ メッセージ編集済み 編集者: ぢゃん♪ 編集日時 2004-03-02 17:10 ] | ||||||||||||
|
投稿日時: 2004-03-02 17:10
サンプルがたまたまそう作ってあるだけだと思いますが… 静的なメソッドでは駄目な場合(という言い方も語弊があって、もっと正確にはインスタンスメソッドを使う必要がある場合)は、インスタンスメソッドを使えばいいんです。 とその前に、インスタンスメンバ(静的ではないメンバ)と静的メンバの意味の違いを理解する必要があります。というか、クラス、インスタンスについてちゃんと理解する必要があると思うんですけど、その辺は大丈夫ですか?書かれてるコードを見るとちょっとだけ微妙な線な気がしますが… | ||||||||||||
|
投稿日時: 2004-03-02 18:06
諸農です。
実現方法は色々とあるとは思いますが。。 その前に、理解しておくことも色々ありますね。
_________________ 諸農和岳 Powered by Turbo Delphi & Microsoft Visual Studio 2005 十兵衛@わんくま同盟 http://blogs.wankuma.com/jubei/ | ||||||||||||
|
投稿日時: 2004-03-03 17:27
皆様ありがとうございます。
FormのPictureBoxのハンドルをFormのstaticメンバ変数にセットしておき、 そのstaticメンバ変数をStateObjectに持たせてみました。 public static IntPtr pictHandle; pictHandle = this.pictureBox1; public class StateObject { //省略 public IntPtr pictHandle = Form1.pictHandle; } public static void AcceptCallback(IAsyncResult ar) { Socket listener = (Socket)ar.AsyncState ; Socket handler = listener.EndAccept (ar); StateObject state = new StateObject (); state.workSocket = handler; handler.BeginReceive (state.buffer , 0, StateObject.BufferSize , 0, new AsyncCallback (ReadCallback), state); } public static void ReadCallback(IAsyncResult ar) { StateObject state = (StateObject)ar.AsyncState ; Socket handler = state.workSocket ; int byteRead = handler.EndReceive (ar); if( byteRead > 0 ) { ---省略--- PictureBox pictureBox = (PictureBox)FromHandle(static.pictHandle); pictureBox.Image = bmp2; pictureBox.Invalidate (); ---省略--- } } クラスとインスタンス、オブジェクト・・・C++との違いにまだまだ慣れずに 苦悩しています。 (C++も、完璧じゃないけど・・) | ||||||||||||
|
投稿日時: 2004-03-04 01:58
うーん、なんか最初のと本質的に変わってない気がするんですが…
まず、なんでこの辺をstaticにしてるんですか? Formのインスタンスにアクセスする必要があるのなら、Formのインスタンスメソッドにすればいいと思うんですが… Jubeiさんのサンプルのような流れでは出来ないですか? 単にコールバックメソッド(およびそこにアクセスする上のようなメソッド)をインスタンスメソッドにしてもいいですけど。
ていうか、C++でもおんなじです(オブジェクトの扱いにちょっと違いはありますが)。クラスとかインスタンスとかって部分はC++でも変わりません。 |