Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WM_移动处理程序中更改窗口边界而不触发空气动力学抖动_C#_Windows_Winforms - Fatal编程技术网

C# 在WM_移动处理程序中更改窗口边界而不触发空气动力学抖动

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

我的问题是,如果我更改WM_移动消息的LParam以使我的表单保持在某个位置,这是合法的,Windows Aero Shake功能将被触发,所有其他窗口将最小化。可以通过在Visual Studio中创建Windows窗体项目并将以下代码粘贴到窗体中来复制该行为:

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对我的情况不起作用,因为它只在移动开始时触发一次,我需要的是在移动的同时改变窗口的边界,我刚刚编译了你的代码,看到窗口一直保持在相同的位置,所以我决定——这就是你想要实现的。我再举一个例子。。。