Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.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/4/wpf/12.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# 如何在应用程序中禁用Aero Snap?_C#_Wpf_Aero - Fatal编程技术网

C# 如何在应用程序中禁用Aero Snap?

C# 如何在应用程序中禁用Aero Snap?,c#,wpf,aero,C#,Wpf,Aero,是否可以在WPF应用程序中禁用Windows 7的自动窗口停靠功能?为了便于在“控制面板”中访问,请选择 更容易专注于任务 和滴答声 防止在移动到屏幕边缘时自动排列窗口我这里没有windows 7框,因此我无法对此进行测试,但我会尝试以下方法: 1-创建测试表单并覆盖WndProc 2-测试并记录与大小、位置和窗口状态更改相关的特定消息。 3-确定停靠时发送到窗口的消息是否是大小/位置/窗口状态的组合,或者是否存在另一条新的Windows 7消息(搜索5分钟后,我没有发现任何消息)。 4-收到消

是否可以在WPF应用程序中禁用Windows 7的自动窗口停靠功能?

为了便于在“控制面板”中访问,请选择

更容易专注于任务

和滴答声


防止在移动到屏幕边缘时自动排列窗口

我这里没有windows 7框,因此我无法对此进行测试,但我会尝试以下方法:

1-创建测试表单并覆盖WndProc
2-测试并记录与大小、位置和窗口状态更改相关的特定消息。
3-确定停靠时发送到窗口的消息是否是大小/位置/窗口状态的组合,或者是否存在另一条新的Windows 7消息(搜索5分钟后,我没有发现任何消息)。
4-收到消息后,检查是否有“独特”情况发生。
5-修改您的代码以适应这种独特的情况


如果没有其他人提出任何建议,我可能会在本周末在家里试一试。

如果您给出Win7的“便笺”示例,您可能已经注意到它没有标准的窗口边框。在此基础上,我只能告诉您,除了设置
ResizeMode=“NoResize”
并手动处理调整大小行为之外,没有直接的方法可以做到这一点。下面是一个非常基本的、非专业的解决方案,我很快创建了这个解决方案来帮助您入门,但如果您愿意,可以附加更多函数:)


您甚至可以创建一个控件(基本上是一个面板),该控件可以在其父画布中调整大小和移动。现在该控件可以填充到透明的最大化窗口中。这会给你一个错觉,你的控制是一个窗口,不响应“窗口捕捉”,不会停靠

希望这有帮助。
问候,

Mihir Gokani

对您来说,这可能不是一个完美的解决方案,但对我来说,将表单设置为不可调整大小就可以了。

这是我的解决方案。如果窗口的ResizeMode设置为ResizeMode.NoResize,窗口将不会捕捉,因此,关键在于可靠地确定拖动/移动的开始和结束时间

EDIT:alexandrud正确地指出,这只适用于“无边界”窗口(WPF术语中的WindowStyle=None)

许多博萨人为了给我们带来这些信息而牺牲了

class NoSnapWindow : System.Windows.Window
{
    public NoSnapWindow()
    {
        SourceInitialized += delegate {
            var source = HwndSource.FromVisual(this) as HwndSource;
            source.AddHook(SourceHook);
        };
    }

    private IntPtr SourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case 0x112: // WM_SYSCOMMAND
                switch (wParam.ToIn32() & ~0x0F)
                {
                    case 0xF010: // SC_MOVE
                        ResizeMode = ResizeMode.NoResize;
                        break;
                }
                break;
            case 0x2A2: // WM_MOUSELEAVE
                ResizeMode = ResizeMode.CanResize;
                break;
        }

        return IntPtr.Zero;
    }
}

我使用anthony的解决方案有一段时间了,但是如果切换ResizeMode,窗口将临时删除大小边界,这有点令人担忧。这是另一个解决方案。通过设置WS_OVERLAPPEDWINDOW标志并删除WS_THICKFRAME标志,将禁用窗口的Aero Snap功能,而不是临时删除大小边界。您可以使用样式来获得所需的确切样式,但关键是删除WS_THICKFRAME标志

        public enum WindowStyles: int
{
    WS_BORDER = 0x00800000,
    WS_CAPTION = 0x00C00000,
    WS_CHILD = 0x40000000,
    WS_CHILDWINDOW = 0x40000000,
    WS_CLIPCHILDREN = 0x02000000,
    WS_CLIPSIBLINGS = 0x04000000,
    WS_DISABLED = 0x08000000,
    WS_DLGFRAME = 0x00400000,
    WS_GROUP = 0x00020000,
    WS_HSCROLL = 0x00100000,
    WS_ICONIC = 0x20000000,
    WS_MAXIMIZE = 0x01000000,
    WS_MAXIMIZEBOX = 0x00010000,
    WS_MINIMIZE = 0x20000000,
    WS_MINIMIZEBOX = 0x00020000,
    WS_OVERLAPPED = 0x00000000,
    WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
    WS_POPUP = unchecked((int)0x80000000),
    WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
    WS_SIZEBOX = 0x00040000,
    WS_SYSMENU = 0x00080000,
    WS_TABSTOP = 0x00010000,
    WS_THICKFRAME = 0x00040000,
    WS_TILED = 0x00000000,
    WS_TILEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
    WS_VISIBLE = 0x10000000,
    WS_VSCROLL = 0x00200000,
}

int newWinLongStyle = 0;
newWinLongStyle |= (int)WindowStyles.WS_OVERLAPPEDWINDOW;
newWinLongStyle ^= (int)WindowStyles.WS_THICKFRAME; 
WindowInteropHelper helper = new WindowInteropHelper(this);
NativeMethods.SetWindowLong(helper.Handle, (int)WindowStyles.GWL_STYLE, newWinLongStyle);

我需要检测Windows 7 Aero快照/停靠,以防止WPF应用程序上的窗口大小更改。在我的搜索过程中,我偶然发现了这篇文章,并发现作者给出的答案非常有用

以下是对我有效的方法

private void DisplayWindow\u MouseMove(对象发送方,MouseEventArgs e)
{
如果(e.LeftButton==鼠标按钮状态.已释放)
{
this.ResizeMode=System.Windows.ResizeMode.CanResizeWithGrip;
}
}
私有void DisplayWindow\u位置已更改(对象发送方,事件参数e)
{
this.ResizeMode=System.Windows.ResizeMode.NoResize;
}
窗口的XAML具有
ResizeMode=“CanResizeWithGrip”
设置

编辑

我的回答是没有正确处理Windows7的Aero快照。优雅地为我解决了这个问题。

我最近需要对一个自定义的、可调整大小的
ResizeMode=CanResizeWithGrip
WPF窗口执行此操作,该窗口没有窗口装饰(没有标题栏和按钮)。我使用
DragMove()
移动窗口,当AeroSnap将其最大化时,窗口将不可移动,因此锁定到位

我试过了,虽然部分奏效,但它仍然会显示AeroSnap图形,并将应用程序调整为全屏大小。我在下面对它进行了修改,现在它可以按预期工作:仍然可以调整大小,但根本没有AeroSnap

void Window1_MouseDown(object sender, MouseButtonEventArgs e)
{
    if( e.LeftButton == MouseButtonState.Pressed )
    {
        // this prevents win7 aerosnap
        if( this.ResizeMode != System.Windows.ResizeMode.NoResize )
        {
            this.ResizeMode = System.Windows.ResizeMode.NoResize;
            this.UpdateLayout();
        }

        DragMove();
    }
}

void Window1_MouseUp( object sender, MouseButtonEventArgs e )
{
    if( this.ResizeMode == System.Windows.ResizeMode.NoResize )
    {
        // restore resize grips
        this.ResizeMode = System.Windows.ResizeMode.CanResizeWithGrip;
        this.UpdateLayout();
    }
}
编辑:

我写这篇文章已经有一段时间了,但由于人们仍然关注这篇文章,我将用我现在使用的东西更新它。我仍然使用基本相同的方法来防止边缘捕捉和移动窗口,但现在我将它们打包到自定义的
行为
类中,我可以将它们附加到
窗口
用户控件
。这使得它们很容易与MVVM一起使用(我使用Caliburn Micro)

行为类包括:

/// <summary>
/// behavior that makes a window/dialog draggable by clicking anywhere 
/// on it that is not a control (ie, button)
/// </summary>
public class DragMoveBehavior<T> : Behavior<T> where T : FrameworkElement
{
    protected override void OnAttached()
    {
        AssociatedObject.MouseLeftButtonDown += MouseDown;
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        AssociatedObject.MouseLeftButtonDown -= MouseDown;
        base.OnDetaching();
    }

    void MouseDown( object sender, EventArgs ea ) => Window.GetWindow( sender as T )?.DragMove();
}

public class WinDragMoveBehavior : DragMoveBehavior<Window> { }

public class UCDragMoveBehavior : DragMoveBehavior<UserControl> { }

/// <summary>
/// behavior that makes a window/dialog not resizable while clicked.  this prevents
/// the window from being snapped to the edge of the screen (AeroSnap).  if DragMoveBehavior
/// is also used, this must be attached first.
/// </summary>
/// <typeparam name="T"></typeparam>
public class NoSnapBehavior<T> : Behavior<T> where T : FrameworkElement
{
    ResizeMode lastMode = ResizeMode.NoResize;
    protected override void OnAttached()
    {
        AssociatedObject.MouseLeftButtonDown += MouseDown;
        AssociatedObject.MouseLeftButtonUp += MouseUp;
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        AssociatedObject.MouseLeftButtonDown -= MouseDown;
        AssociatedObject.MouseLeftButtonUp -= MouseUp;
        base.OnDetaching();
    }

    /// <summary>
    /// make it so the window can be moved by dragging
    /// </summary>
    void MouseDown( object sender, EventArgs ea )
    {
        var win = Window.GetWindow( sender as T );
        if( win != null && win.ResizeMode != ResizeMode.NoResize )
        {
            lastMode = win.ResizeMode;
            win.ResizeMode = ResizeMode.NoResize;
            win.UpdateLayout();
        }
    }

    void MouseUp( object sender, EventArgs ea )
    {
        var win = Window.GetWindow( sender as T );
        if( win != null && win.ResizeMode != lastMode )
        {
            win.ResizeMode = lastMode;
            win.UpdateLayout();
        }
    }
}

public class WinNoSnapBehavior : NoSnapBehavior<Window> { }

public class UCNoSnapBehavior : NoSnapBehavior<UserControl> { }
//
///通过单击任意位置使窗口/对话框可拖动的行为
///上面不是控件(即按钮)
/// 
公共类DragMoveBehavior:T:FrameworkElement所在的行为
{
受保护的覆盖无效附加()
{
AssociatedObject.MouseLeftButtonDown+=MouseDown;
base.onatached();
}
附加时受保护的覆盖无效()
{
AssociatedObject.MouseLeftButtonDown-=MouseDown;
base.OnDetaching();
}
void MouseDown(对象发送方,EventArgs ea)=>Window.GetWindow(发送方为T)?.DragMove();
}
公共类windragmovebhavior:dragmovebhavior{}
公共类UCDragMoveBehavior:DragMoveBehavior{}
/// 
///使窗口/对话框在单击时无法调整大小的行为。这防止了
///窗口不会被捕捉到屏幕边缘(AeroSnap)。如果拖航行为
///如果也使用了,则必须先附加此项。
/// 
/// 
公共类NoSnapBehavior:Behavior,其中T:FrameworkElement
{
ResizeMode lastMode=ResizeMode.NoResize;
P
/// <summary>
/// behavior that makes a window/dialog draggable by clicking anywhere 
/// on it that is not a control (ie, button)
/// </summary>
public class DragMoveBehavior<T> : Behavior<T> where T : FrameworkElement
{
    protected override void OnAttached()
    {
        AssociatedObject.MouseLeftButtonDown += MouseDown;
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        AssociatedObject.MouseLeftButtonDown -= MouseDown;
        base.OnDetaching();
    }

    void MouseDown( object sender, EventArgs ea ) => Window.GetWindow( sender as T )?.DragMove();
}

public class WinDragMoveBehavior : DragMoveBehavior<Window> { }

public class UCDragMoveBehavior : DragMoveBehavior<UserControl> { }

/// <summary>
/// behavior that makes a window/dialog not resizable while clicked.  this prevents
/// the window from being snapped to the edge of the screen (AeroSnap).  if DragMoveBehavior
/// is also used, this must be attached first.
/// </summary>
/// <typeparam name="T"></typeparam>
public class NoSnapBehavior<T> : Behavior<T> where T : FrameworkElement
{
    ResizeMode lastMode = ResizeMode.NoResize;
    protected override void OnAttached()
    {
        AssociatedObject.MouseLeftButtonDown += MouseDown;
        AssociatedObject.MouseLeftButtonUp += MouseUp;
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        AssociatedObject.MouseLeftButtonDown -= MouseDown;
        AssociatedObject.MouseLeftButtonUp -= MouseUp;
        base.OnDetaching();
    }

    /// <summary>
    /// make it so the window can be moved by dragging
    /// </summary>
    void MouseDown( object sender, EventArgs ea )
    {
        var win = Window.GetWindow( sender as T );
        if( win != null && win.ResizeMode != ResizeMode.NoResize )
        {
            lastMode = win.ResizeMode;
            win.ResizeMode = ResizeMode.NoResize;
            win.UpdateLayout();
        }
    }

    void MouseUp( object sender, EventArgs ea )
    {
        var win = Window.GetWindow( sender as T );
        if( win != null && win.ResizeMode != lastMode )
        {
            win.ResizeMode = lastMode;
            win.UpdateLayout();
        }
    }
}

public class WinNoSnapBehavior : NoSnapBehavior<Window> { }

public class UCNoSnapBehavior : NoSnapBehavior<UserControl> { }
<UserControl ...
  xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
  xmlns:util:="...">
  <i:Interaction.Behaviors>
    <util:UCNoSnapBehavior/>
    <util:UCDragMoveBehavior/>
  </i:Interaction.Behaviors>

  ...

</UserControl>
void Window1_MouseDown(object sender, MouseButtonEventArgs e)
{
    if( e.LeftButton == MouseButtonState.Pressed )
    {
        // this prevents win7 aerosnap
        this.ResizeMode = System.Windows.ResizeMode.NoResize;
        this.UpdateLayout();

        DragMove();

        // restore resize grips
        this.ResizeMode = System.Windows.ResizeMode.CanResizeWithGrip;
        this.UpdateLayout();
    }
}
    [DllImport("user32.dll")]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    private const int GWL_STYLE = -16;
    private const int WS_MAXIMIZEBOX = 0x10000;

    private void Window_OnSourceInitialized(object sender, EventArgs e)
    {
            var hwnd = new WindowInteropHelper((Window)sender).Handle;
            var value = GetWindowLong(hwnd, GWL_STYLE);
            SetWindowLong(hwnd, GWL_STYLE, (int)(value & ~WS_MAXIMIZEBOX));
    }