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;
}
}
精彩评论