3

GDI+ を使用して描画しているカスタム UserControl があります。親コントロールの上に小さな図形を描画する透明なコントロールです。

親ウィンドウが行うことは、コントロールを作成し、それ自体を描画する Rectangle を与えることだけです。次に、ユーザーが非透明領域をクリックすると、イベントを受け取ります。

描画部分は完全に機能しますが、今私がする必要があるのは、MouseMove、MouseClick などのすべてのイベントを可能な限りシームレスに親コントロールに転送することです。これらのイベントが形状の外で発生した場合。

図形は GraphicsPath を使用して描画され、GraphicsPath.IsVisible() を使用して、マウスの位置が図形の上にあるかどうかを既に検出できます。

親にゼロまたは最小限の余分なコードを必要とする方法でこれを行いたいです。親は、MouseMove イベントが子コントロールから転送されたかどうかを必ずしも知る必要はなく、それらすべてを同等に扱う必要があります。

これを行うには、pinvoke/SendMessage() する必要がありますか? または、.NET フレームワークを使用するより簡単な方法はありますか?

4

1 に答える 1

7

これは winapi で可能です。WM_NCHITTEST メッセージはウィンドウ マネージャーによって送信され、マウスがコントロールのどの部分の上にあるかを尋ねます。できることは HTTRANSPARENT を返すことで、親ウィンドウに尋ねます。これを実装する UserControl のサンプルを次に示します。メッセージをキャッチするには、WndProc() をオーバーライドする必要があります。

public partial class UserControl1 : UserControl {
    public UserControl1() {
        InitializeComponent();
        paths = new List<GraphicsPath>();
        GraphicsPath example = new GraphicsPath();
        example.AddEllipse(new Rectangle(10, 10, 50, 30));
        paths.Add(example);
    }
    List<GraphicsPath> paths;

    protected override void OnPaint(PaintEventArgs e) {
        foreach (var path in paths) e.Graphics.FillPath(Brushes.Blue, path);
        base.OnPaint(e);
    }

    protected override void WndProc(ref Message m) {
        base.WndProc(ref m);
        // Trap WM_NCHITTEST on the client area
        if (m.Msg == 0x84 && m.Result == (IntPtr)1) {
            Point pos = new Point(m.LParam.ToInt32());
            pos = this.PointToClient(pos);
            bool oncurve = false;
            foreach (var path in paths)
                if (path.IsVisible(pos)) oncurve = true;
            if (!oncurve) m.Result = (IntPtr)(-1);  // HTTRANSPARENT
        }
    }
}

次の形式のテスト コード:

    private void userControl11_MouseMove(object sender, MouseEventArgs e) {
        Console.WriteLine("On shape {0}", e.Location);
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e) {
        Console.WriteLine("On form  {0}", e.Location);
    }
于 2011-10-07T20:21:44.323 に答える