1

I am writing a custom control in .NET Windows Forms. Consider the following code:

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    switch(m.Msg)
    {
        case WM_LBUTTONDOWN: // Yes, it's defined correctly.
            MessageBox.Show("Left Button Down");
            break;
    }
}

It works when running, but I need it to work in the designer. How can I achieve this?

NOTE:

I guess someone might say that "You can't detect clicks in the designer because the design surface captures them and processes them as part of the design process"

...Take for example the TabControl. When you add a new tab, you can click to navigate through the tabs, and then click the tab's designable area to begin designing the tab page's content. How does that work?

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
  • I might have missed something here, but how would that work? Your program is not running while you're looking at the designer. – Octopoid May 26 '15 at 20:54
  • @Octopoid - Your code still runs even in design mode - certain messages are allowed through the WndProc loop, but as per my comment, I think clicks are handled before they reach the control itself. (see update) – Matthew Layton May 26 '15 at 20:57
  • Fair enough, I don't really use the designer very much - what happens when you move `base.WndProc(ref m);` to the end of the method, after you handle your event? – Octopoid May 26 '15 at 20:59
  • @Octopoid - nothing, same issue. – Matthew Layton May 26 '15 at 21:00
  • hmm, I was hoping that the base method was just resetting the message to none. I have just found this: `if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)` - doesn't instantly help, but I wonder if that is part of the puzzle towards implementing custom designer features. I have often wondered how the `TabControl` etc. did it's thing.. – Octopoid May 26 '15 at 21:03
  • @Octopoid - I guess it's worth investigating, thanks. I've just added a logger to WndProc to tell me which messages it's parsing. – Matthew Layton May 26 '15 at 21:05

1 Answers1

1

Well, designer eats some of the messages. If you want all messages to be sent to the Control, you need to create a custom control designer and send them to the control.

Refer ControlDesigner.WndProc

public class CustomDesigner : ControlDesigner
{
    protected override void WndProc(ref Message m)
    {
        DefWndProc(ref m);//Passes message to the control.
    }
}

Then apply the DesignerAttribute to your custom control.

[Designer(typeof(CustomDesigner))]
public partial class MyUserControl : UserControl
{
    public MyUserControl()
    {
        InitializeComponent();
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        const int WM_LBUTTONDOWN = 0x0201;
        switch (m.Msg)
        {
            case WM_LBUTTONDOWN: // Yes, it's defined correctly.
                MessageBox.Show("Left Button Down");
                break;
        }
    }
}

Drag your control to the Form, click on it. Now you should see the message box in designer also :)

Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189