4

In my media player application, I hid the cursor using SetCursor(NULL) and to make sure that Windows does not reset the cursor state, I handled WM_SETCURSOR in my WndProc method.

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case WM.SETCURSOR:
            base.WndProc(ref m);
            int lowWord = (m.LParam.ToInt32() << 16) >> 16;
            if (lowWord == HTCLIENT && FullScreen)
            {
                SetCursor(IntPtr.Zero); // hides cursor
                m.Result = (IntPtr)1; // return TRUE; equivalent in C++
            }
            return;
    }
}

However when the cursor is in the client area (aka LOWORD(lParam) == HTCLIENT), WM_SETCURSOR is never triggered in WndProc. So I never actually get the WM_SETCURSOR message when the cursor is in the client area and only get it when LOWORD(lParam) != HTCLIENT.

However in Spy++, it clearly shows that the application received the WM_SETCURSOR and WM_MOUSEMOVE messages.

Where is the message getting lost/handled? What do I have to do in order to receive the WM_SETCURSOR message in C#?

godly-devotion
  • 177
  • 3
  • 15
  • 2
    I don't know the answer off the top of my head. But why can't you just set the form's cursor? – Jonathan Wood Aug 16 '13 at 18:38
  • I don't know why it can't work for you. I've tested a simple code and it works like a charm. – King King Aug 16 '13 at 18:39
  • Are you sure the `HTCLIENT = 1`? – King King Aug 16 '13 at 18:39
  • Looks like that the `Fullscreen` is false? Your code should work because I've tested. BTW, you should be sure `WM_SETCURSOR = 0x20` and `HTCLIENT = 1`. – King King Aug 16 '13 at 18:45
  • @King Strange, when I put a breakpoint on the line after `case WM.SETCURSOR`, it only breaks once, during application startup. It doesn't break after that, even if the mouse is moving on top of the form. – godly-devotion Aug 16 '13 at 18:49
  • @azian.otaku I think you should make a totally new demo, just add the code above. You don't need breakpoint here, especially in a `WndProc`, you can use `System.Diagnostics.Debug.Print` instead to see if it jumps in the case block. – King King Aug 16 '13 at 19:00
  • @King okay I can confirm that it does send in a demo project I created. Now I have no idea why it isn't firing in my own project. – godly-devotion Aug 16 '13 at 19:34
  • @azian.otaku does your form have any other control covering its surface, such as a `Panel` with `Dock = DockStyle.Fill`? – King King Aug 16 '13 at 19:43
  • 1
    @King I have multiple `Panel`'s covering my application, although I thought that `WndProc` captures messages from the entire application? – godly-devotion Aug 16 '13 at 19:56

1 Answers1

1

My application has several panels covering the application. So another user pointed out to me kindly that since every control has its own WndProc, the WM_SETCURSOR method wasn't being passed on to the form underneath it. In order to receive those messages, I would have to override each of those panels with its own WndProc method.

However the above code does work if there are no controls covering the form where the cursor is.

godly-devotion
  • 177
  • 3
  • 15