拦截Windows消息和Winforms

时间:2013-10-03 13:29:26

标签: c# windows winforms windows-messages

所以回到这个问题的开头。我使用System.Windows.Forms来创建文本编辑器。默认情况下,文本框控件在双击包含的文本时接受事件,并突出显示整行文本。我想用不同的东西覆盖这种行为。事实证明,这需要我拦截启动此事件的Windows消息,并防止它被触发。这是我在Stackoverflow上找到的一个链接,它几乎逐字地解释了我在做什么:Is it possible to disable textbox from selecting part of text through double-click

但这个解释是不完整的!请注意,DoubleClickEvent继承自EventArgs。它应该继承自MouseEventArgs。这是因为PreviewDoubleClick将需要来自Windows消息的信息,该信息涉及点击屏幕的位置。这就是我要完成的任务:覆盖双击事件,但仍然从windows消息中发送所有点击信息。

如果我在代码中设置断点,我会开始查看我的信息存储位置。消息m包含一些属性,其中一个属性称为LParam。据我所知,这是一个指向我想要检索的点击信息的指针。但这不是C ++ ......我不能只是取消引用指针。 .NET方便地提供了Message.GetLParam方法来帮助我。我无法使用此方法。

这是我的代码:

    public class DoubleClickEventArgs : MouseEventArgs
{
    public DoubleClickEventArgs(MouseButtons Button, int clicks, int x, int y, int delta) : base (Button, clicks, x, y, delta) { }


    public bool Handled
    {
        get;
        set;
    }
}

public class NewTextBox : System.Windows.Forms.TextBox
{
    public event EventHandler<DoubleClickEventArgs> NewDoubleClick;
    private const int WM_DBLCLICK = 0xA3;
    private const int WM_LBUTTONDBLCLK = 0x203;

    protected override void WndProc(ref Message m)
    {
        if ((m.Msg == WM_DBLCLICK) || (m.Msg == WM_LBUTTONDBLCLK))
        {
            DoubleClickEventArgs e = (DoubleClickEventArgs) m.GetLParam(typeof(MouseEventArgs));

            if (NewDoubleClick != null)
            {
                NewDoubleClick(this, e);
            }

            if (e.Handled)
            {
                return;
            }
        }

        base.WndProc(ref m);
    }
}

正如您所看到的,看起来很像样本。我做了疯狂的演员让它在这行上编译DoubleClickEventArgs e =(DoubleClickEventArgs)m.GetLParam(typeof(MouseEventArgs));显然是造成了崩溃。我们得到错误:没有为此对象定义无参数构造函数。

这是有道理的。 DoubleCLickEventArgs确实需要创建参数。但是参数是由lParam指针定义的......有人能给我一点指导吗?我很挣扎。

1 个答案:

答案 0 :(得分:1)

要删除突出显示的文字行为并提供您自己的行为:

private const int WM_DBLCLICK = 0xA3;
private const int WM_LBUTTONDBLCLK = 0x203;

protected override void WndProc(ref Message m)
{
    if ((m.Msg == WM_DBLCLICK) || (m.Msg == WM_LBUTTONDBLCLK))
    {
        //your behavior here like for example
        //this.ForeColor = Color.Red;
        return;
    }
    base.WndProc(ref m);
}