使用 .NET 在 Windows Vista 及更高版本中捕获 WndProc 消息
我有一个 .net 2.0 Windows 窗体应用程序。
我已经重写了 WndProc 方法来捕获表单上的用户活动
Ex:
const int HTCLOSE = 0x0014;
bool m_bCloseButtonActive = false;
if (m.Msg == WM_NCHITTEST)
{
base.WndProc(ref m);
m_bCloseButtonActive = (m.Result.ToInt32() == HTCLOSE);
}
根据 m_bCloseButtonActive 的值,我采取进一步的操作。
我现在面临的问题是我的表单无法关闭,因为它无法捕获 Vista 及更高版本操作系统(甚至 Windows 7)中的“关闭”按钮单击事件。
即条件 m.Result.ToInt32() == HTCLOSE 永远不会成立,当我单击关闭按钮时,我的表单永远不会关闭。
我的应用程序可以在以前的操作系统(Windows 2000、XP、XP Embedded)中运行。 还有一件有趣的事情是,当我指定
Application.VisualStyleState = System.Windows.Forms.VisualStyles.VisualStyleState.ClientAreaEnabled;
“任何想法这里发生了什么”时它就会起作用。这是否与桌面 Windows 管理器有关,我的应用程序无法捕获关闭按钮单击事件。
提前致谢
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 the close button clicked event.
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在我看来,命中测试消息并不是执行此操作的适当方法。例如,如果用户通过系统菜单或通过 Alt+F4 快捷键关闭表单会怎样?
我认为您应该回复
WM_SYSCOMMAND
带有wParam == SC_CLOSE
的消息。Windows Aero 在处理非客户区时有着根本的不同,这解释了为什么它在 2000/XP 中以及在禁用 DWM 时工作。但使用
WM_SYSCOMMAND
适用于所有版本的 Windows。请注意,您需要非常仔细地阅读 WM_SYSCOMMAND 的 MSDN 文档,因为消息参数包含需要屏蔽的额外信息。要检测关闭按钮,您需要如下代码:
如果您想更改用户关闭表单时的行为,为什么不处理
Closing
事件?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 withwParam == 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:If you want to change the behaviour when the user closes the form, why don't you handle the
Closing
event?这终于起作用了......我使用 WM_NCMOUSEMOVE 而不是非客户端 HITTEST 信息
WParam 包含所有相关事件。
此链接有帮助:
http://social.msdn.microsoft .com/Forums/en/windowsuidevelopment/thread/9a8a63c8-79b5-43a8-82eb-f659be947add
const int WM_NCMOUSEMOVE = 0x00A0;
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;