4

I have a simple windows form with no border and several label controls (nothing that needs to be clicked). I needed to be able to allow the user to move the form by clicking anywhere on it, so I found this question, and used the following code found there.

    private const int WM_NCHITTEST = 0x84;
    private const int HTCLIENT = 0x1;
    private const int HTCAPTION = 0x2;

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg) {
            case WM_NCHITTEST:
                base.WndProc(ref m);

                if ((int)m.Result == HTCLIENT) {
                    m.Result = (IntPtr)HTCAPTION;
                    return;
                } else {
                    return;
                }
                break;
        }
        base.WndProc(ref m);            
    }

This works well...to a point. If I click anywhere on the form itself (the background), WM_NCHITTEST is HTCLIENT, so I can move my form as expected. However, if I click on a label control itself, the message is something different, and I can't tell what it is.

I found this article about the various possible values for WM_NCHITTEST but none of them seem to be what I need.

I realize I could disable all my label controls and that would allow me to click "on" them as if it was the form itself, but I'm wondering if there's a better/different way to do this.

Thanks for the help!

Community
  • 1
  • 1
Mansfield
  • 14,445
  • 18
  • 76
  • 112
  • Why can't you tell what the message is (IE does it error or just return something you aren't expecting)? http://msdn.microsoft.com/en-us/library/windows/desktop/ms645618(v=vs.85).aspx documents the values you can expect - are you getting something else? – Rob P. Sep 12 '12 at 16:19
  • @RobP. Good question! I thought I'd go into debug mode and try to look at what the message was when I clicked on a control - but unfortunately the breakpoint keeps being hit when I mouse over the form. I then have to hit f5 in visual studio to run, and move the mouse back over the form, etc, etc. I tried debug.writeline on m.Result but it constantly prints 1 and nothing else, no matter what the event actually is. – Mansfield Sep 12 '12 at 16:23
  • Debugging of windows messages can by tricky. Spy++ is a must have tool for that sort of thing. http://msdn.microsoft.com/en-us/library/aa264396(v=VS.60).aspx – dkackman Sep 12 '12 at 17:03

1 Answers1

5

You are overriding the WndProc for the form, but when the cursor is over a label the WM_NCHITTEST message is sent to the label.

You could create your own label control derived from Label and override its WndProc. This should always return HTTRANSPARENT in response to WM_NCHITTEST. Something like:

private const int HTTRANSPARENT = -1;

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case WM_NCHITTEST:
            m.Result = (IntPtr)HTTRANSPARENT;
            return;
    }
    base.WndProc(ref m);
}

Also note that there's a small bug in your WndProc. If the message is WM_NCHITTEST but the region isn't HTCLIENT then you call the base class twice.

arx
  • 16,686
  • 2
  • 44
  • 61
  • I've fixed the bug in the code (or at least I think I have). I'll try your idea with the custom label and get back to you. – Mansfield Sep 12 '12 at 16:27
  • How do I represent -1 as hexadecimal? I tried `0x-1` but that didn't seem to work...(invalid number) I also tried just `-1` which gave no error, but didn't seem to match the `WM_NCHITTEST`. – Mansfield Sep 12 '12 at 16:40
  • I don't want to set the result to be `HTTRANSPARENT` though, I want to change it to `HTCLIENT`. To clarify, testing `m.Result` never seems to equal `HTTRANSPARENT`. – Mansfield Sep 12 '12 at 16:59
  • 1
    Don't test `m.Result` in the label control WndProc, just set the result to `HTTRANSPARENT` as the code above illustrates. Windows will then forward the message to the form, and you'll return `HTCAPTION` as before. If you return `HTCAPTION` for the label Windows will ignore it. – arx Sep 12 '12 at 17:22
  • Ahh, I misunderstood you originally. Just tested it and it works great - thanks a lot! – Mansfield Sep 12 '12 at 17:23