首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WPF:使窗口不可调整,但保留框架吗?

WPF:使窗口不可调整,但保留框架吗?
EN

Stack Overflow用户
提问于 2010-08-02 09:26:30
回答 4查看 5.4K关注 0票数 8

我有一个没有标题栏(WindowStyle == WindowStyle.None)的窗口。整个窗口使用航空玻璃效果。当我使窗口不可调整大小(ResizeMode == ResizeMode.NoResize)时,玻璃效果就消失了,我的控制装置就挂在半空中。(从本质上说,窗口本身消失了,但却留下了内容。)

有什么办法可以让我的窗户在不摆脱窗框的情况下不能调整大小?

我读过https://stackoverflow.com/questions/1324398/enable-vista-glass-effect-on-a-borderless-wpf-window的问题,但这并不完全是我想要的--我想保留窗口的边框。关于我希望我的窗口是什么样子的一个例子,点击Alt+Tab并启用Aero。

为了澄清,不希望调整大小的游标在窗口边框上悬停时显示。这基本上就是我想让我的窗户看起来的样子:

解决方案不必严格使用WPF--为了实现这一点,我不介意使用Win32 API进行黑客操作。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-08-11 20:54:05

您可以挂起wndproc并拦截温道普昌消息。不是严格意义上的WPF,但可能是你最好的选择。

如果您想隐藏调整大小的游标,那么最好的方法是拦截尼特泰斯特。调用DefWindowProc (获取默认行为)并测试返回值;如果是HTBOTTOM、HTBOTTOMLEFT、HTBOTTOMRIGHT、HTTOP、HTTOPLEFT或HTTOPRIGHT,则将返回值更改为HTBORDER。

票数 13
EN

Stack Overflow用户

发布于 2010-08-26 03:26:47

根据儿科学的答案。

代码语言:javascript
运行
复制
public partial class MainWindow : Window
{
    [DllImport("DwmApi.dll")]
    public static extern int DwmExtendFrameIntoClientArea(
        IntPtr hwnd,
        ref MARGINS pMarInset);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr DefWindowProc(
        IntPtr hWnd,
        int msg,
        IntPtr wParam,
        IntPtr lParam);

    private const int WM_NCHITTEST = 0x0084;
    private const int HTBORDER = 18;
    private const int HTBOTTOM = 15;
    private const int HTBOTTOMLEFT = 16;
    private const int HTBOTTOMRIGHT = 17;
    private const int HTLEFT = 10;
    private const int HTRIGHT = 11;
    private const int HTTOP = 12;
    private const int HTTOPLEFT = 13;
    private const int HTTOPRIGHT = 14;

    public MainWindow()
    {
        InitializeComponent();

        this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        try
        {
            // Obtain the window handle for WPF application
            IntPtr mainWindowPtr = new WindowInteropHelper(this).Handle;
            HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
            mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);
            mainWindowSrc.AddHook(WndProc);

            // Set Margins
            MARGINS margins = new MARGINS();
            margins.cxLeftWidth = 10;
            margins.cxRightWidth = 10;
            margins.cyBottomHeight = 10;
            margins.cyTopHeight = 10;

            int hr = DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
            //
            if (hr < 0)
            {
                //DwmExtendFrameIntoClientArea Failed
            }
        }
        // If not Vista, paint background white.
        catch (DllNotFoundException)
        {
            Application.Current.MainWindow.Background = Brushes.White;
        }
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        // Override the window hit test
        // and if the cursor is over a resize border,
        // return a standard border result instead.
        if (msg == WM_NCHITTEST)
        {
            handled = true;
            var htLocation = DefWindowProc(hwnd, msg, wParam, lParam).ToInt32();
            switch (htLocation)
            {
                case HTBOTTOM:
                case HTBOTTOMLEFT:
                case HTBOTTOMRIGHT:
                case HTLEFT:
                case HTRIGHT:
                case HTTOP:
                case HTTOPLEFT:
                case HTTOPRIGHT:
                    htLocation = HTBORDER;
                    break;
            }

            return new IntPtr(htLocation);
        }

        return IntPtr.Zero;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
    }
}

[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
    public int cxLeftWidth;      // width of left border that retains its size
    public int cxRightWidth;     // width of right border that retains its size
    public int cyTopHeight;      // height of top border that retains its size
    public int cyBottomHeight;   // height of bottom border that retains its size
};

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="150" Width="200" 
    Background="Transparent"
    WindowStyle="None"
    ResizeMode="CanResize"
>
    <Grid Background="White" Margin="10,10,10,10">
        <Button Content="Go Away" Click="Button_Click" Height="20" Width="100" />
    </Grid>
</Window>
票数 11
EN

Stack Overflow用户

发布于 2010-08-02 15:55:02

一种常见的方法是设置MinWidth/MaxWidth和MinHL.8/MaxHeight属性,从而有效地使其不可调整大小。当然,问题是您仍然会在边界上获得调整大小的游标。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3386486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档