|
■No79951 (魔界の仮面弁士 さん) に返信 > ■No79947 (とっちゃん さん) に返信
お世話になっております。 昨日、なぜだかサイトにアクセスできなかったので、お返事が遅くなりました。 こちらで、いろいろと検証をしていった結果をまとめます。
手前の仕様はユーザーコントロールでPictureBoxを継承し、ユーザーコントロールにイベント足していた事を忘れていました。 現在、起こる現象としてピクチャーボックスをクリックまたはマウスムーブし、カラーパレット表示ボタンを押下するとカラーパレットがfromの裏に行き、フリーズしているように見える。というものです。 alt + tabを押せば表に出て来て表示されます。
ユーザーコントロールには4つイベントを加えており、PaintEventHandler,MouseEventHandler(アップ、ダウン、ムーブ)それぞれあります。 最初に4つのメソッドをコメントアウトして、アプリケーションを起動したところ、ピクチャーボックスをクリックした後にカラーパレットを表示するボタンを押下したら正常に期待通り表示されました。 そこで、ひとつづずメソッドをコメントオン、オフして行ったところ、マウスムーブイベントが原因だと判明しました。
以下切り分けした事
1 マウスムーブイベント全てをコメントアウト ピクチャーボックスをクリックしてカラーボックス表示ボタンを押下 期待の場所にカラーボックスが表示される ただし、penや消しゴムでの描画ができなくなってしまう。 (本末転倒)
2 マウスムーブイベント左クリック内の座標取得部分をコメントアウト ピクチャーボックスをクリックしてカラーボックス表示ボタンを押下 カラーパレットがFromの後ろに行く Alt +Tabで表示可能 ペンや消しゴムを使えない上に表示もできない。 3 マウスムーブイベントのrefresh()部分だけをコメントアウト ピクチャーボックスをクリックしてカラーボックス表示ボタンを押下 期待の場所にカラーボックスが表示される ただし、penや消しゴムでの描画ができなくなってしまう。 (本末転倒)
切り分け結果 開始点と終了点の間にrefresh()をしているのですが、このrefresh()が原因でカラーパレットが表示されない(Fromの後ろに行く) 事が判明しました。 しかし、refreshしないとpenや消しゴムが使えなくなるので ためしにApplication.DoEvents(); をstripBtn_Click直後に置いてみましたが、結果はカラーパレット表示ボタンを押下後はすぐに表示されず、一度、PictureBoxをクリックしないとカラーパレットは表示されませんでした。 ステップ実行をすると、カラーパレットボタン押下後にすぐDoEventに入るのですが、そこで処理が止まり、pictureBoxをクリックするとその後の処理が行われるという物でした。
以上が昨日までにやった事でしたが、まだ解決には至りませんでした。。 お忙しいところお手数ですが、なにとぞご教授をよろしくお願いします。
実際のコード private const float INIT_POINT = 99999.9f; /// 開始:X座標、Y座標 private PointF _st = new PointF(INIT_POINT, INIT_POINT); /// 終了:X座標、Y座標 private PointF _ed = new PointF(INIT_POINT, INIT_POINT); //画像取り込み用ビットマップ public Bitmap bmp;
ボタン押下処理 private void stripBtn_Click(object sender, EventArgs e) { Application.DoEvents(); 追加しました // PictureBox の左上隅にダイアログボックスの座標を合わせて表示する using(var dlg = new ColorDialogEx()) { Point p = this.PointToScreen(new Point(PictureBox.Left + 20, PictureBox.Top + 30)); dlg.Position = p; dlg.AllowFullOpen = false; if (dlg.ShowDialog(this) == DialogResult.OK) this.StripSelectColorBtn.BackColor = dlg.Color; } }
//マウスムーブイベント private void MouseMove(object sender, MouseEventArgs e) { // 左クリック押下中 if (e.Button == MouseButtons.Left) { // ZOOM率に合わせたサイズを取得 SizeF size = this.getZoomSize(); //// コントロール側の座標値と描画用BITMAP座標値の計算:終点 this._ed.X = e.X - (((float)this.ClientSize.Width - size.Width) / 2); this._ed.X = this._ed.X * ((float)this.bmp.Width / size.Width); this._ed.Y = e.Y - (((float)this.ClientSize.Height - size.Height) / 2); this._ed.Y = this._ed.Y * ((float)this.bmp.Height / size.Height); //// 再描画 this.Refresh(); //// コントロール側の座標値と描画用BITMAP座標値の計算:始点 this._st.X = e.X - (((float)this.ClientSize.Width - size.Width) / 2); this._st.X = this._st.X * ((float)this.bmp.Width / size.Width); this._st.Y = e.Y - (((float)this.ClientSize.Height - size.Height) / 2); this._st.Y = this._st.Y * ((float)this.bmp.Height / size.Height); } }
//画面サイズの取得 public SizeF getZoomSize() { float img_w = this.bmp.Width; float img_h = this.bmp.Height; float pic_w = this.ClientSize.Width; float pic_h = this.ClientSize.Height;
float mag_w = pic_w / img_w; float mag_h = pic_h / img_h; SizeF zoomSize;
if (mag_w < mag_h) { zoomSize = new SizeF(img_w * mag_w, img_h * mag_w); } else { zoomSize = new SizeF(img_w * mag_h, img_h * mag_h); }
return zoomSize; }
別クラス internal class ColorDialogEx : ColorDialog { private Point FPosition; public Point Position { set { FPosition = value; } }
public ColorDialogEx() : base() { }
protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam) { if (msg == 0x110) { // WM_INITDIALOG{ RECT r = new RECT();
// ダイアログボックスの位置とサイズを取得する GetWindowRect(hWnd, ref r);
// ダイアログボックスの位置を変更する MoveWindow(hWnd, FPosition.X, FPosition.Y, r.right - r.left, r.bottom - r.top, true);
return IntPtr.Zero; // HookProc メソッドでメッセージを処理済みにする }
// WM_INIDIALOG 以外のメッセージに対しては元のコントロールにまかせる return base.HookProc(hWnd, msg, wparam, lparam); }
[DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern bool GetWindowRect(IntPtr hWnd, [In, Out] ref RECT lpRect);
[DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[StructLayout(LayoutKind.Sequential)] private struct RECT { public int left; public int top; public int right; public int bottom; }
|