应用程序卡在全屏?

Cod*_*per 12 c# winforms

要重现我的问题,请执行以下操作:

  1. 在C#中创建一个新的Windows窗体应用程序.
  2. 在Form 1的属性窗口中设置FormBorderStyleNone.
  3. 启动程序并按Windows+ Up.
  4. 现在你陷入全屏.

在默认FormBorderStyle设置中,MaximizeBox属性为false将禁用Windows+ Up全屏快捷方式.

如果FormBorderStyle设置为NoneMicrosoft,则决定禁用除向上箭头之外的所有Windows +箭头键快捷键,然后禁用该MaximizeBox属性的禁用.

这是一个小故障吗?禁用此快捷方式的任何简单方法都是在所有其他FormBorderStyles上禁用的同一方式吗?

Han*_*ant 7

Windows通过调用SetWindowPos()来改变窗口的位置和大小.可以通过侦听WM_WINDOWPOSCHANGING消息并覆盖设置来通知窗口.你可以做很多事情,比如通过根据自己的喜好调整大小和位置来保持操作意义.你可以通过打开NOSIZE和NOMOVE标志来完全阻止它.

将此代码粘贴到您的表单中:

    private bool AllowWindowChange;

    private struct WINDOWPOS {
        public IntPtr hwnd, hwndInsertAfter;
        public int x, y, cx, cy;
        public int flags;
    }

    protected override void WndProc(ref Message m) {
        // Trap WM_WINDOWPOSCHANGING
        if (m.Msg == 0x46 && !AllowWindowChange) {
            var wpos = (WINDOWPOS)System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, typeof(WINDOWPOS));
            wpos.flags |= 0x03; // Turn on SWP_NOSIZE | SWP_NOMOVE
            System.Runtime.InteropServices.Marshal.StructureToPtr(wpos, m.LParam, false);
        }
        base.WndProc(ref m);
    }
Run Code Online (Sandbox Code Playgroud)

如果要自己更改窗口,只需将AllowWindowChange字段暂时设置为true即可.


Jef*_*Son 1

检查此解决方案 - 它通过 API 调用删除最大化/最小化/标题栏/边框。

public partial class Form1 : Form
{
    // import necessary API functions to get and set Windows styles for P/Invoke
    [DllImport("user32.dll")]
    internal extern static int SetWindowLong(IntPtr hwnd, int index, int value);

    [DllImport("user32.dll")]
    internal extern static int GetWindowLong(IntPtr hwnd, int index);

    // define constants like they are named in SDK in order to make source more readable
    const int GWL_STYLE = -16;
    const int GWL_EXSTYLE = -20;
    const int WS_MINIMIZEBOX = 0x00020000;
    const int WS_MAXIMIZEBOX = 0x00010000;
    const int WS_CAPTION = 0x00C00000;
    const int WS_THICKFRAME = 0x00040000;
    const int WS_EX_DLGMODALFRAME = 0x00000001;
    const int WS_EX_CLIENTEDGE = 0x00000200;
    const int WS_EX_STATICEDGE = 0x00020000;

    // this replaces MinimizeBox=false and MaximizeBox=false
    void HideMinimizeAndMaximizeButtons()
    {
        // read current style
        int style = GetWindowLong(Handle, GWL_STYLE);
        Debug.WriteLine("0x{0:X}", style);
        // update style - remove flags for MinimizeBox and MaximizeBox
        style = style & ~WS_MINIMIZEBOX & ~WS_MAXIMIZEBOX;
        Debug.WriteLine("0x{0:X}", style);
        SetWindowLong(Handle, GWL_STYLE, style);
    }

    // part of removing the whole border
    void HideTitleBar()
    {
        // read current style
        int style = GetWindowLong(Handle, GWL_STYLE);
        Debug.WriteLine("0x{0:X}", style);
        // update style - remove flag for caption
        style = style & ~WS_CAPTION;
        Debug.WriteLine("0x{0:X}", style);
        SetWindowLong(Handle, GWL_STYLE, style);
    }

    // hide the border
    void HideBorder()
    {
        // read current style
        int style = GetWindowLong(Handle, GWL_STYLE);
        Debug.WriteLine("0x{0:X}", style);
        // update style - remove flag for border (could use WS_SIZEBOX which is the very same flag (see MSDN)
        style = style & ~WS_THICKFRAME;
        Debug.WriteLine("0x{0:X}", style);
        SetWindowLong(Handle, GWL_STYLE, style);

        // read current extended style
        style = GetWindowLong(Handle, GWL_EXSTYLE);
        Debug.WriteLine("0x{0:X}", style);
        // update style by removing some additional border styles -
        // may not be necessary, when current border style is not something exotic,
        // i.e. as long as it "normal"
        style = style & ~WS_EX_DLGMODALFRAME & ~WS_EX_CLIENTEDGE & ~WS_EX_STATICEDGE;
        Debug.WriteLine("0x{0:X}", style);
        SetWindowLong(Handle, GWL_EXSTYLE, style);
    }

    public Form1()
    {
        InitializeComponent();

        // hide those unwanted properties - you can try to leave out one or another to see what it does
        HideMinimizeAndMaximizeButtons();
        HideTitleBar();
        HideBorder();
    }
}
Run Code Online (Sandbox Code Playgroud)

这按预期工作。通过设置 WindowState 来最大化/最小化也可以。

人们可以在源代码中分析该框架做了什么以及它做了什么“错误”(或不太正确)。

编辑:我添加了样式值的调试输出。请在 Form1 构造函数中尝试以下命令序列:

MaximizeBox = false;
FormBorderStyle = FormBorderStyle.Sizable;
HideMinimizeAndMaximizeButtons();
FormBorderStyle = FormBorderStyle.None;
MaximizeBox = true;
MaximizeBox = false;
HideMinimizeAndMaximizeButtons();
FormBorderStyle = FormBorderStyle.None;
HideMinimizeAndMaximizeButtons();
Run Code Online (Sandbox Code Playgroud)

您将看到,设置 FormBorderStyle.None 启用 WS_MAXIMIZEBOX 样式。这不能被另一个“纠正” MaximizeBox = false。看来需要调用API函数了。