开发者

Capturing WndProc messages in Windows Vista and above using .NET

I have a .net 2.0 windows forms application.

I have overridden the WndProc method to capture the user activities on the form

Ex:

const int HTCLOSE           = 0x0014;
bool m_bCloseButtonActive   = false;

if (m.Msg == WM_NCHITTEST)
{
    base.WndProc(ref m);
    m_bCloseButtonActive = (m.Result.ToInt32() == HTCLOSE);
}

Based on the value of m_bCloseButtonActive i take further actions.

The issue now i face is my form doesn't close as it is not able to capture the Close button clicked event in the Operating systems Vista and above(even Windows 7).

i.e the condition m.Result.ToInt32() == HTCLOSE is never true and my form never closes when i click the close button.

My application works in previous OS (Windows 2000, XP, XP Embedded). Also an interesting thing is that it works when i specify

Application.VisualStyleState = System.Windows.Forms.VisualStyles.VisualStyleState.ClientAreaEnabled;

Any idea whats going on in here. Is this something related to the Desktop Windows Manager, my application is not able to trap t开发者_如何学编程he close button clicked event.

Thanks in advance


Hit test messages doesn't seem to me to be the appropriate way to do this. For example, what if the user closes the form through the system menu, or through the Alt+F4 shortcut?

I think that you should be responding to WM_SYSCOMMAND messages with wParam == SC_CLOSE.

Windows Aero is fundamentally different when it comes to the handling of the non-client area which explains why it works in 2000/XP and when you disable DWM. But using WM_SYSCOMMAND works in all versions of Windows.

Note that you need to read the MSDN documentation for WM_SYSCOMMAND quite carefully because the message parameters contain extra information that needs to be masked out. To detect the close button you need code like this:

const int WM_SYSCOMMAND = 0x0112;
const int SC_CLOSE = 0xF060;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_SYSCOMMAND)
        if ((m.WParam.ToInt32() & 0xFFF0) == SC_CLOSE)
            MessageBox.Show("close button pressed");
    }
    base.WndProc(ref m);
}

If you want to change the behaviour when the user closes the form, why don't you handle the Closing event?


This finally worked ... I used WM_NCMOUSEMOVE instead of the non client HITTEST information The WParam contained all the related events.

This link helped : http://social.msdn.microsoft.com/Forums/en/windowsuidevelopment/thread/9a8a63c8-79b5-43a8-82eb-f659be947add

const int WM_NCMOUSEMOVE = 0x00A0;

  if (m.Msg == WM_NCMOUSEMOVE)
    {
    base.WndProc(ref m);
    if ((m.WParam.ToInt32() == HTCLOSE))
    {
      m_bCloseButtonActive = true;
    }
   }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜