C#でパネルのマウスイベントが取得できない

このQ&Aのポイント
  • C#のパネルにbitmapを描画し続けるサンプルプログラムで、描画中にパネルのマウスイベントが取得できない問題が発生しています。マウスの位置から補助線を引きたいのですが、解決策を教えてください。
  • OpenNI(キネクトセンサー)のサンプルプログラムを使用しています。C#のパネルにbitmapを描画している途中で、マウスイベントを取得できない問題が発生しています。描画中にマウスの位置から補助線を引きたいのですが、どのような方法で解決できますか?
  • C#のパネルにbitmapを描画し続けるサンプルプログラムで、描画中にパネルのマウスイベントが取得できない問題が生じています。マウスの位置から補助線を引くためには、どのような手法やアプローチを使用すればよいですか?
回答を見る
  • ベストアンサー

C# でパネルのマウスイベントが取得できない

OpenNI(キネクトセンサー)のサンプルプログラムは、C#のパネルにbitmapを描画し続けるのですが、 描画中、そのパネルのマウスイベントが生じない(無視されている?)ようです。マウスの位置から 補助線を引いたりしたいのですが、描画中にマウスイベントが取得できる方法をご存知の方、お願いします。以下サンプルソースそのままです。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Text; using System.Windows.Forms; using OpenNI; using System.Threading; using System.Drawing.Imaging; namespace SimpleViewer.net { private unsafe void ReaderThread() { DepthMetaData depthMD = new DepthMetaData(); while (this.shouldRun) { try { this.context.WaitOneUpdateAll(this.depth); } catch (Exception) { } this.depth.GetMetaData(depthMD); lock (this) { Rectangle rect = new Rectangle(0, 0, this.bitmap.Width, this.bitmap.Height); BitmapData data = this.bitmap.LockBits(rect, ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); ushort* pDepth = (ushort*)this.depth.DepthMapPtr.ToPointer(); // set pixels for (int y = 0; y < depthMD.YRes; ++y) { byte* pDest = (byte*)data.Scan0.ToPointer() + y * data.Stride; for (int x = 0; x < depthMD.XRes; ++x, ++pDepth, pDest += 3) { byte pixel = (byte)this.histogram[*pDepth]; pDest[0] = 0; pDest[1] = pixel; pDest[2] = pixel; } } this.bitmap.UnlockBits(data); } this.Invalidate(); } } private readonly string SAMPLE_XML_FILE = @"../../../Data/SamplesConfig.xml"; private Context context; private ScriptNode scriptNode; private DepthGenerator depth; private Thread readerThread; private bool shouldRun; private Bitmap bitmap; private int[] histogram; } }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

求めていることの解答にはなりませんが, とりあえず,いま,Kinect for Windows SDK 1.5で試してみたら, Panelに深度画像を表示し続けても 普通にマウスイベントは取得できました. ご参考まで.

goropapa
質問者

お礼

ありがとうございます。 private void panelView_Click(object sender, EventArgs e) { textBox1.Text = System.Windows.Forms.Cursor.Position.X.ToString(); } センサーはXtionProLive なのですが、それとは関係ないですよね。 たったこれだけのコードで、ファイルに書き出したら、、、、同じ、ためしに このイベントの中にブレークポイントを置いてみると、デバッガが停止もしません。 つまりマウスイベントが起きていないかどこかにいってしまっている。これを 確認できる知識は持っていません。 同じフォームに描画されている以外のパネルを設置してみると ちゃんとマウス座標が取得できるのでなにか描画に特別な部分があるのかと 思ったのです。すみませんが、お使いのソースを教えていただけませんか? 同じことを試してみたいです。

goropapa
質問者

補足

解決しました!!!! ( 多少疑問は残りますが。) サンプルのPanelView のマウスイベントは受け取れませんが、フォームのマウスイベント は機能しました。toro_nekomataさんはフォームのClickイベントを使いましたか? DockがFillの設定でフォームいっぱいだったので気づきませんでした。 イベントの発生を勉強しないといけませんね。ありがとうございました。

関連するQ&A

  • C#のGraphicsクラスについて(GDI+)

    以下のようにgraphicsクラスをつかった画像の描画をおこないました。 Graphics gr = Graphics.FromImage(mapObj); というふうにからのリソースからGraphicsオブジェクトをつくる方法です。 using System; using System.IO; using System.Windows.Forms; using System.Drawing; using System.Web; using System.Net; using System.Text; using System.Threading; using System.ComponentModel; public class MainClass{ public static void Main(string [] args){ NewForm formObj = new NewForm(); formObj.RenderMethod(); Application .Run(formObj); } } public class NewForm : Form{ public NewForm(){ this.Width = 500; this.Height = 500; } public void RenderMethod(){ Bitmap mapObj = new Bitmap(500,500); Graphics gr = Graphics.FromImage(mapObj); Image imageObj = Image.FromFile("C:\\test.jpg"); gr .DrawImage(imageObj, 0,0,150,150); this.BackgroundImage = mapObj; } } このほかに、フォームコントロールの thisl.CreateGraphics()という メソッドを使っても画像を描画できるとききました。 あるサンプルをみると public class NewForm : Form{ public NewForm(){ this.Width = 500; this.Height = 500; } public void RenderMethod(){ Graphics gr = this.CreateGraphics(); Image imageObj = Image.FromFile("C:\\test.jpg"); gr .DrawImage(imageObj, 0,0,150,150); } } とこのようにthis.CreateGraphics()をつかっていましたが 実際にはこれが描画されないのです。 Graphics gr = Graphics.FromImage(mapObj); というGraphicsクラスの静的メソッドを使う方法ではなく コントロールのCreateGraphicsメソッドをつかって描画するにはどうしたらよいのですか? 識者のかた、ご教授ください。

  • C#での画像ファイルをドラッグアンドドロップで描画

    C#で画像ファイルをドラッグアンドドロップで描画させるプログラムを作りたいのですが、うまくできません。 ドラッグしたファイル名を読み取る部分までは動作確認できています。このファイル名の画像ファイルをForm1に描画させる部分でエラーになってしまいます。 どのように修正したらよいのかわからないのでお助けください。 ----- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Drag {   public partial class Form1 : Form   {     public Form1()     {       InitializeComponent();     }     private void Form1_DragEnter(object sender, DragEventArgs e)     {       e.Effect = DragDropEffects.All;     }     private void Form1_DragDrop(object sender, DragEventArgs e)     {       Graphics g = e.Graphics;   // <------ エラーになる。       if (e.Data.GetDataPresent(DataFormats.FileDrop))       {         foreach (string fileName             in (string[])e.Data.GetData(DataFormats.FileDrop))         {           g.DrawImage(new Bitmap(fileName, new PointF(10F, 50F)));           // Console.WriteLine(fileName); // 動作確認         }       }     }   } }

  • C#のGraphicsクラスについてです。

    C#のGraphicsクラスを用いて画像をフェードインで表示させよとしています。 まず以下のコードをごらんください。 ただ、フェードインで画像は表示されるものの、フォームの操作が一切できなくなってしまいます。 そのためマルチスレッドにしようとしたのですが using System; using System.IO; using System.Windows.Forms; using System.Drawing; using System.Web; using System.Net; using System.Text; using System.Threading; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Diagnostics; public class MainClass{ public static void Main(string [] args){ NewForm formObj = new NewForm(); Application .Run(formObj); } } public class NewForm : Form { //インスタンス変数の宣言 public Graphics g ; public Bitmap mapObj ; public Image imageObj; public ImageAttributes ia; public ColorMatrix cm; public Thread th ; public ParameterizedThreadStart ts; public PaintEventArgs e; public Rectangle rec; public int flag = 0; public delegate void TestDelegate(); public TestDelegate deleObj; public NewForm(){ Button buttonObj = new Button(); buttonObj.Width=100; buttonObj.Height = 30; //フェードさせるためのイベント発行用ボタンの設置 buttonObj.Click += new EventHandler(this.SetMethod); this.Controls.Add(buttonObj); } public void SetMethod(object sender , EventArgs e){ this.Paint += new PaintEventHandler(this.ThreadMethod); //フォームコントロールの再描画を促す this.Invalidate(); } public void ThreadMethod(object sender ,PaintEventArgs eventObj){ this.ts = new ParameterizedThreadStart(this.ThreadRenderMethod); this.th = new Thread(this.ts); this.th.Start(eventObj); MessageBox.Show("ThreadMethod実行後"); MessageBox.Show(InvokeRequired.ToString()); this.th.Join(); } public void ThreadRenderMethod(object paintObj){ MessageBox.Show(InvokeRequired.ToString()); this.deleObj =delegate(){ //無現ループしてしまうので、再描画イベント後イベントハンドラーを削除 this.Paint -= new PaintEventHandler(this.ThreadMethod); PaintEventArgs e = (PaintEventArgs)paintObj; try{ Console.WriteLine("paint メソッド発生"); this. g = e.Graphics; this.mapObj = new Bitmap(this.Width,this.Height); this.imageObj = Image.FromFile("C:\\c#\\test.jpg"); //this.g = Graphics.FromImage(this.mapObj); this.cm = new ColorMatrix(); this.cm.Matrix00 = 1; this.cm.Matrix11 = 1; this.cm.Matrix22 = 1; this.cm.Matrix33 = 0.0F; this.cm.Matrix44 = 1; this.ia = new ImageAttributes(); this.ia.SetColorMatrix(this.cm); this.rec = new Rectangle(0, 0, this.Width, this.Height); this.g.DrawImage(this.imageObj,rec,0,0,this.imageObj.Width,imageObj.Height,GraphicsUnit.Pixel,this.ia); this.BackgroundImage = mapObj; for(double i = 0.0; i <= 1.0; i = i + 0.001){ this.cm.Matrix33 = (float) i; this.ia.SetColorMatrix(this.cm); this.g.DrawImage(this.imageObj,rec,0,0,this.imageObj.Width,imageObj.Height,GraphicsUnit.Pixel,this.ia); this.BackgroundImage = this.mapObj; Thread.Sleep(100); } //this.imageObj.Dispose(); //this.g.Dispose(); }catch(Exception ex){ Console.WriteLine(ex.ToString()); } Console.WriteLine("paint end"); }; this.deleObj(); //this.Invoke(this.deleObj); this.BackgroundImage = Image.FromFile("C:\\c#\\test.jpg"); } } 上記コードでも、フェードは動作するものの、やはりフォームの操作ができなくなります。 どう対処したらよいでしょうか? 識者の方、よろしくご教授ください お願いいたします

  • C# フォームを閉じてもプログラムが終了しない

    前略 ・C#の初心者です。 ・下記のようなプログラムを作りたいと思っています。プログラムは<作りたいプログラム>の仕様どうりに動作していますが、Form1のFormClosingイベントに Application.Exit()を追加しないと フォーム1で "X"(閉じる)をクリックしても(フォームは非表示になりますが)プログラムが終了しません。プログラムでどこかおかしな部分があると思っています。Application.Exit()を追加しないでもプログラムを終了する方法を教えてください。 <作りたいプログラム> (1)Form1 のbutton1をクリックすると新しいForm2が作成され表示される。Form2が表示されるとForm1は非表示となる。 (2)Form2 のbutton1をクリックするとForm2が非表示となりForm1が表示される。 (3)Form1 の "X"(閉じる)をクリックしてプログラムを終了する。 //Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace formClose { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Form2 form2 = new Form2(); form2.Show(); //フォーム2を表示 this.Hide(); //フォーム1を非表示 } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { Application.Exit(); //アプリケーション終了 } } } //Form2.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace formClose { public partial class Form2 : Form { Form1 form1 = new Form1(); public Form2() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { this.Close(); //フォーム2を閉じる } private void Form2_FormClosing(object sender, FormClosingEventArgs e) { form1.Show(); //フォーム1を表示する } } } 以上

  • フォーム間のデータ受け渡し

    現在VIsual Studio 2005のフォームアプリケーションを使ってプログラミングしています。ボタンを押すことで新たな子フォームを作成し、親フォームから子フォームへグローバル関数で宣言しているbmp[],picture[],red[]などのデータを渡したいのですがどうすればいいのかわからず困っております。子フォームから親フォームへテキストボックスなどの値を渡す方法などはわかったのですが、それをどう応用していいのかもわからない状況です。最終的には親フォームのbmp[0]におけるred[0]が1(画像処理されている)なら子フォームでbmp[0]を表示させたいと思っています。わかる方がいましたらどうかご教授ください。よろしくお願いします。以下がプログラムとなっております。 *** 親フォーム *** #pragma once #include "pic2.h" namespace pic { 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; // 省略 // public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: ここにコンストラクタ コードを追加します // bmp = nullptr; Array::Resize( bmp, 20 ); Array::Resize( picture, 20 ); Array::Resize( bmpr, 20 ); this->red = gcnew array<int>(20); } // 省略 // private: System::Windows::Forms::PictureBox^ pictureBox1; private:array< Bitmap^>^ bmp; // 原画像格納 // private:array< Bitmap^>^ bmpr; // 処理画像格納 // private:array< PictureBox^>^ picture; private:array< int>^ red; // 処理:1 不処理:0 // // 省略 // #pragma endregion private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { bmp[0] = gcnew Bitmap("ファイル名",true); } private: System::Void button1_Click_1(System::Object^ sender, System::EventArgs^ e) { pic2 ^p2 = gcnew pic2(); p2->ShowDialog();     /* ボタンを押すことで新たなフォーム作成 */ } private: System::Void pictureBox1_Click(System::Object^ sender, System::EventArgs^ e) { int x,y; int w = bmpr[0]->Width; int h = bmpr[0]->Height; if(red[0] == 1){ bmp[0] = gcnew Bitmap("ファイル名",true); pictureBox1->Image = bmp[0]; red[0] = 0; return; } if(red[0] == 0){ // 画像処理 // pictureBox1->Image = bmpr[0]; red[0] = 1; } } }; *** 子フォーム *** #pragma once //#include "Form1.h" #include "pic3.h" using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; namespace pic { /// <summary> /// pic2 の概要 /// public ref class pic2 : public System::Windows::Forms::Form { public: pic2(void) { InitializeComponent(); // //TODO: ここにコンストラクタ コードを追加します // } // 省略 // } #pragma endregion private: System::Void pic2_Load(System::Object^ sender, System::EventArgs^ e) { if(親フォームのred[0]==1ならば){ pictureBox1->Image = bmp[0] } } private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {   // 新たな子フォームpic3作成 // } private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { this->Close(); } }; }

  • 配列を使ったビットマップクラス

    VC++を使ったフォームアプリケーションでビットマップなどの画像を表示させ、ピクセル処理を施せるプログラムを作りました。このプログラム上ではピクチャボックスを1つ用意していますが、今後もっと多くのピクチャボックスが必要になってきます。以下のプログラムではBitmapクラスのbmpをピクチャボックス1の画像に入れています。単純にBitmapクラスのbmpを増やせば(例:bmp1)、ピクチャボックスが増えても平気ですが、処理の関係上配列を使いたいと思っています。なので下に書いてあるプログラムのbmp->という部分をbmp[0]->というふうに変えたいと考えています。自分なりに調べて(1)、(2)の部分を変えればいいと思うのですがどうもうまくいきません。わかる方がいたらご教授ください、おねがいします。 #pragma once namespace bmp { 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::Text; using namespace System::Collections::Generic; /// <summary> /// Form1 の概要 /// /// 警告: このクラスの名前を変更する場合、このクラスが依存するすべての .resx ファイルに関連付けられた /// マネージ リソース コンパイラ ツールに対して 'Resource File Name' プロパティを /// 変更する必要があります。この変更を行わないと、 /// デザイナと、このフォームに関連付けられたローカライズ済みリソースとが、 /// 正しく相互に利用できなくなります。 /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: ここにコンストラクタ コードを追加します // bmp = nullptr; ……… (1) //Bitmap^ bmp[300]; }      //省略// #pragma endregion //private: array<Bitmap^>^ bmp = gcnew array<Bitmap^>(300); ……… (2) private: Bitmap^ bmp; private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { bmp = gcnew Bitmap("C:/Documents and Settings/Owner/デスクトップ/lena.bmp",true); pictureBox1->Image = bmp; } private: System::Void pictureBox1_Click(System::Object^ sender, System::EventArgs^ e) { /*bmp = gcnew Bitmap("C:/Documents and Settings/Owner/デスクトップ/lena.bmp",true);*/ int x,y; int w = bmp->Width; int h = bmp->Height; for(x = 0; x < w; x++){ for(y = 0; y < h; y++){ if(x < (w * 0.05) || y < (h * 0.05) || (y > (h - (h*0.05)))&&(y < h) || (x > (w - (w*0.05)))&&(x < w)){ Color pixelColor = bmp->GetPixel( x, y ); Color newColor = Color::FromArgb( 255, 0, 0 ); bmp->SetPixel( x, y, newColor ); } } } pictureBox1->Image = bmp; } private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { } }; }

  • C# タスク非表示でタイトルバーは表示する

    前略 ・C#の初心者です。 ・タスクバーは下記のプログラムで非表示とすることができますが、同時にタイトルバーも消えてしまいます。タスクバーは非表示で、右端に閉じる・最大化・最小化アイコン("X"、 "□"、"_")のないタイトルバーを表示したいのですが、その方法をおしえてください。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace noTaskbar { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.FormBorderStyle = FormBorderStyle.None;//タイトルバー&タスクバー非表示 this.WindowState = FormWindowState.Maximized;// } } } 以上、よろしくお願いします

  • C#でstop()が使えない。

    http://kana-soft.com/tech/sample_0012_3.htm#WebBrowser_Stop このHPを参考にstop()メソッドを使おうとしたのですがSTOP()に下記のエラーが出ます。 'System.Windows.Forms.WebBrowser' に 'stop' の定義が含まれておらず、型'System.Windows.Forms.WebBrowser' の最初の引数を受け付ける拡張メソッドが見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。 VS2010を使用し、.NETは4なので問題なく使えると思うのですが原因不明です。 以下ソースです。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace busywait4 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { webBrowser1.Navigate("http://yahoo.co.jp");//もう一度、アクセスしなおす。 } int i; private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { webBrowser1.stop(); }

  • バイナリ読み込みについて

    お世話になります。バイナリファイルの読み込みについて質問させてください。 バイナリファイルはC#で出力したものでushort型(符号無し16bit)で書き込んでいます。 //C#でushort型データのバイナリ書き込み例 private static void WriteBinary(){  ushort data=5000;   BinaryWriter bw = new BinaryWriter(new FileStream(@"C:\Binary.txt", FileMode.Create, FileAccess.Write)); bw.Write(data); bw.Close(); } これをJavaで読んで、書き込んだ値5000を取得したいのですが、 C#のushortは符号無しの2Byteなんので、Javaでそれに相当するように readUnsignedShortで読み込んだのですがうまくいきません。どなたかご教授ください。 //Javaでushort型データのバイナリ読み込み private static void ReadBinary(){  DataInputStream dis = new DataInputStream(new FileInputStream("C:\\Binary.txt"));  int data = dis.readUnsignedShort();  System.out.println(data);  } すると「34835」と表示されます。その他、readShort()→-30701 read(byte[2])として byteに格納してbyte[0]と[1]を足しても-101になり取得できませんでした。 保存されたデータは符号なしの16ビットなのでreadUnsignedShort()で取得できると 思ったのですが、何か根本的に考え方が違うのでしょうか?? ※もちろんC#でReadInt16で読み取ると正常に5000を取得できした。

    • ベストアンサー
    • Java
  • C#で派生クラスから描画処理を行う

    C#を勉強しているのですが、GUIを作り初めて描画処理で分からない所があり、質問させて頂きます。 基本クラスの方で「Hello, world!」という文字列をDrawStringで表示させる事は出来たのですが、それを基本クラスを継承した派生クラスのメソッドで行うと何も表示されないんです。 以下が試したコードです。 //基本クラスSample1 using System; using System.Drawing; using System.Windows.Forms; public class Sample1 : Form {   protected Bitmap image; protected Graphics g; protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Sample2 s = new Sample2(); s.helloworld(); e.Graphics.DrawImage(image, 0, 0); } public Sample1() { SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); image = new Bitmap(600, 400); g = Graphics.FromImage(image); } static void Main() { Form form = new Sample1(); form.Text = "sample"; form.ClientSize = new Size(600, 400); form.BackColor = Color.FromArgb(0xff, 0xff, 0xff); Application.Run(form); } } //派生クラスSample2 using System; using System.Drawing; using System.Windows.Forms; public class Sample2 : Sample1 { Brush brush = new SolidBrush(Color.Black); public void helloworld() { g.DrawString("Hello, world!", this.Font, brush, 10, 10); } } なぜ表示されないのか分かる方いらしたら、ご教授願えないでしょうか。是非お願いします。