You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现Chrome窗口禁用MinimizeBox、MaximizeBox及SizeBox问题求助

解决方案

Chrome的多进程架构导致它的窗口创建逻辑和记事本这类单进程程序不同——Chrome启动后会先初始化后台进程,再由子进程创建实际的主窗口,直接修改启动后的进程初始窗口无法生效。以下是可行的实现步骤和代码:

核心思路

  • 等待Chrome主窗口完全创建后再修改样式
  • 通过窗口枚举找到Chrome的主窗口句柄(而非进程的初始空窗口)
  • 调用Windows API强制移除窗口的最小化、最大化及可调尺寸样式

代码实现

首先在WinForms项目中添加以下代码:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

public partial class MainForm : Form
{
    // Windows API 声明
    private const int GWL_STYLE = -16;
    private const uint WS_MINIMIZEBOX = 0x00020000;
    private const uint WS_MAXIMIZEBOX = 0x00010000;
    private const uint WS_SIZEBOX = 0x00040000;

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

    [DllImport("user32.dll")]
    private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    [DllImport("user32.dll")]
    private static extern int GetWindowTextLength(IntPtr hWnd);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

    private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

    private IntPtr _chromeMainWindowHandle = IntPtr.Zero;

    public MainForm()
    {
        InitializeComponent();
    }

    private void btnStartChrome_Click(object sender, EventArgs e)
    {
        // 启动Chrome,可根据实际安装路径修改
        Process chromeProcess = Process.Start(@"C:\Program Files\Google\Chrome\Application\chrome.exe");
        if (chromeProcess == null) return;

        // 等待Chrome进程初始化
        chromeProcess.WaitForInputIdle(5000);
        // 额外等待确保窗口创建完成
        Thread.Sleep(2000);

        // 枚举窗口找到Chrome主窗口
        EnumWindows(EnumWindowsCallback, (IntPtr)chromeProcess.Id);

        if (_chromeMainWindowHandle != IntPtr.Zero)
        {
            // 获取当前窗口样式
            IntPtr currentStyle = GetWindowLongPtr(_chromeMainWindowHandle, GWL_STYLE);
            uint styleValue = (uint)currentStyle.ToInt64();

            // 移除最小化、最大化、可调尺寸样式
            styleValue &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX);
            SetWindowLongPtr(_chromeMainWindowHandle, GWL_STYLE, (IntPtr)styleValue);
        }
    }

    private bool EnumWindowsCallback(IntPtr hWnd, IntPtr lParam)
    {
        uint processId;
        GetWindowThreadProcessId(hWnd, out processId);

        // 匹配Chrome进程ID
        if (processId == (uint)lParam)
        {
            // 判断是否为主窗口(窗口标题长度大于0)
            int textLength = GetWindowTextLength(hWnd);
            if (textLength > 0)
            {
                StringBuilder windowTitle = new StringBuilder(textLength + 1);
                GetWindowText(hWnd, windowTitle, windowTitle.Capacity);
                // 匹配Chrome主窗口标题特征
                if (windowTitle.ToString().Contains("Google Chrome"))
                {
                    _chromeMainWindowHandle = hWnd;
                    return false; // 找到后停止枚举
                }
            }
        }
        return true;
    }
}

关键说明

  1. 窗口枚举逻辑:通过EnumWindows遍历所有顶层窗口,匹配Chrome进程ID并判断窗口标题,确保找到的是实际的主窗口而非后台进程的空窗口。
  2. 等待机制:WaitForInputIdle结合Thread.Sleep确保Chrome有足够时间创建主窗口,避免过早修改样式导致无效。
  3. 样式修改:直接通过SetWindowLongPtr移除目标窗口样式,测试环境下Chrome不会自动重置这些样式。

注意事项

  • 确保Chrome的路径正确,默认64位路径为C:\Program Files\Google\Chrome\Application\chrome.exe
  • 若Chrome版本更新后窗口标题变化,需调整EnumWindowsCallback中的标题判断逻辑

内容的提问来源于stack exchange,提问作者Sergio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:21:16