1

So going back to the beginning of this issue. I have using System.Windows.Forms to create a text editor. The textbox control by default accepts an event when its contained text is double-clicked and highlights the entire row of text. I wanted to override this behavior with something different. It turns out this requires that I intercept the windows message that kicks off this event and prevent it from ever getting triggered. Here is a link I found on Stackoverflow that explains almost verbatim what I am doing: Is it possible to disable textbox from selecting part of text through double-click

But this explanation is incomplete! Notice that DoubleClickEvent inherits from EventArgs. It should be inheriting from MouseEventArgs. This is because PreviewDoubleClick is going to need information from the windows message about where the screen was clicked. So that's the task I set off to accomplish: override the doubleclick event but still send it all of the click information from the windows message.

If I set up breakpoints in the code, I begin to see where my information is stored. Message m contains a couple properties, one of which is called LParam. As I understand, this is a pointer to the click information I want to retrieve. But this isn't C++... I cannot just dereference the pointer. .NET conveniently provides the Message.GetLParam method to help me out. I am having trouble getting this method to work.

Here is my code:

    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);
    }
}

As you can see it, looks a lot like the sample. The crazy casting I did to get it to compile on this line DoubleClickEventArgs e = (DoubleClickEventArgs) m.GetLParam(typeof(MouseEventArgs)); is obviously causing the crash. We get the error: No parameterless constructor defined for this object.

That makes sense. DoubleCLickEventArgs do require parameters to be created. But the parameters are defined by the lParam pointer... Can anyone give me a little guidance here? I'm struggling.

4

1 回答 1

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);
}
于 2013-10-03T13:54:39.743 回答