C# 在WM_移动处理程序中更改窗口边界而不触发空气动力学抖动
我的问题是,如果我更改WM_移动消息的LParam以使我的表单保持在某个位置,这是合法的,Windows Aero Shake功能将被触发,所有其他窗口将最小化。可以通过在Visual Studio中创建Windows窗体项目并将以下代码粘贴到窗体中来复制该行为:C# 在WM_移动处理程序中更改窗口边界而不触发空气动力学抖动,c#,windows,winforms,C#,Windows,Winforms,我的问题是,如果我更改WM_移动消息的LParam以使我的表单保持在某个位置,这是合法的,Windows Aero Shake功能将被触发,所有其他窗口将最小化。可以通过在Visual Studio中创建Windows窗体项目并将以下代码粘贴到窗体中来复制该行为: using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace FormsTest { public par
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace FormsTest
{
public partial class ShakeTest : Form
{
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 16)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
public const int WM_MOVING = 0x0216;
public ShakeTest()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_MOVING:
{
RECT rec;
rec.bottom = 500;
rec.left = 100;
rec.top = 100;
rec.right = 500;
Marshal.StructureToPtr(rec, m.LParam, true);
m.Result = new IntPtr(1);
}
break;
}
base.WndProc(ref m);
}
}
}
如果您现在抓住窗口的标题栏并将鼠标移动一点,则应触发抖动手势,即使窗口根本没有移动
到目前为止,我只是在Windows10上测试了这个
所以我的问题是,我可以为某个窗口或进程禁用抖动功能吗?如果不是的话,我能不能防止Windows认为我在以其他方式摇窗户
谢谢 坦率地说,我不知道是否可以为特定窗口禁用Aero Shake。但我可以建议一种解决方法,防止空气动力震动触发 有可能将所有鼠标输入仅指向一个窗口(这也将对Aero Shake处理程序隐藏鼠标事件)。检查位于的
SetCapture
说明。我们还需要一个GetCapture
和ReleaseCapture
函数
这里有一句话:一旦您将鼠标捕捉设置为窗口,您就要负责处理所有鼠标输入。因此,为了实现这个目标,您需要实现自己的处理程序来移动窗口。幸运的是,这并不难
这是一个带有对话框的代码示例,该对话框在移动时更改其大小,并在移动完成时恢复大小。空气动力震动也不会触发
public partial class ShakeTest : Form
{
[DllImport("user32.dll")]
static extern IntPtr SetCapture(IntPtr hWnd);
[DllImport("user32.dll")]
static extern IntPtr GetCapture();
[DllImport("user32.dll")]
static extern bool ReleaseCapture();
public const int WM_LBUTTONUP = 0x0202;
public const int WM_MOUSEMOVE = 0x0200;
public const int WM_NCLBUTTONDOWN = 0x00A1;
public const int HTCAPTION = 2;
private Point _lastCursorPos;
private Size _origianlSize;
public ShakeTest()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
// We need to get the moment when the user clicked on a non-client area
case WM_NCLBUTTONDOWN:
// We are interested only in a click on a title bar
if ((int) m.WParam == HTCAPTION)
{
// Set the capture so all the mouse input will be handled by this window
SetCapture(Handle);
// Keep the current cursor position to use it during the moving.
_lastCursorPos = Cursor.Position;
// Keep the original window size.
_origianlSize = Size;
// And change the dialog size to whatever you want
Size = new Size(300, 300);
}
break;
// Once we got the capture, we need to handle mouse moving by ourself
case WM_MOUSEMOVE:
// Check that our window has the capture
if (GetCapture() == Handle)
{
// Change the position of a window
Left += Cursor.Position.X - _lastCursorPos.X;
Top += Cursor.Position.Y - _lastCursorPos.Y;
_lastCursorPos = Cursor.Position;
}
break;
// When the left mouse button is released - it's time to release the mouse capture
case WM_LBUTTONUP:
// Check that our window has the capture
if (GetCapture() == Handle)
{
// Release the mouse capture
ReleaseCapture();
// Restore the size
Size = _origianlSize;
}
break;
}
base.WndProc(ref m);
}
}
不,这不是为了阻止用户最大化表单,示例非常简单,我真正做的是将窗口捕捉到某些“停靠区”我回复的评论只是神奇地消失了检查:@SergeyShevchenko对我的情况不起作用,因为它只在移动开始时触发一次,我需要的是在移动的同时改变窗口的边界,我刚刚编译了你的代码,看到窗口一直保持在相同的位置,所以我决定——这就是你想要实现的。我再举一个例子。。。