C#/WPF中彻底消除隐藏关闭按钮,及自定义最大化最小化关闭按钮

您所在的位置:网站首页 最小化按钮后 C#/WPF中彻底消除隐藏关闭按钮,及自定义最大化最小化关闭按钮

C#/WPF中彻底消除隐藏关闭按钮,及自定义最大化最小化关闭按钮

2023-10-19 17:09| 来源: 网络整理| 查看: 265

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情

消除隐藏关闭按钮

对关闭按钮的隐藏消除,是通过win32 API实现的。具体使用如下所示。

SetWindowLongPtr API

SetWindowLongPtr 是Windows的一个API,作用是改变窗口的属性。

LONG_PTR WINAPI SetWindowLongPtr( _In_ HWND hWnd, _In_ int nIndex, _In_ LONG_PTR dwNewLong );

第一个参数是窗口句柄。第二个参数是offset,当它的值是GWL_STYLE(-16)时,可以设置窗口风格。第三个参数是要设置的值,针对GWL_STYLE的可能取值参见Window Styles,有关 最大化(WS_MAXIMIZEBOX=0x00010000L) 、最小化按钮(WS_MINIMIZEBOX=0x00020000L) 和 窗口标题栏上的菜单(WS_SYSMENU=0x00080000L)。可以通过设置这对应的值去掉最大化、最小化和关闭按钮。

如果仅仅设置最大化或最小化按钮,将会使其禁用变灰,而不是隐藏。只有同时设置最大化和最小化按钮时,才会将两者去掉。

在调用SetWindowLongPtr之前要调用GetWindowLongPtr来获取当前Window的信息。

如果窗体数据被缓存,则在调用SetWindowLongPtr之后,需要调用SetWindowPos确保设置生效。

官网介绍SetWindowLongPtr(但,实际 在 64位Windows上的32位C#程序中引入SetWindowLongPtr会报错,需要根据位数判断使用SetWindowLongPtr还是SetWindowLong,GetWindowLongPtr同理。):

To write code that is compatible with both 32-bit and 64-bit versions of Windows, use GetWindowLongPtr. When compiling for 32-bit Windows, GetWindowLongPtr is defined as a call to the GetWindowLong function.

SetWindowLongPtr 用于替代 SetWindowLong,它可以编写 32 位和 64 位Windows兼容的代码。对于 32 位 Windows,SetWindowLongPtr 内部直接调用 SetWindowLong 函数。

SetWindowLongPtr 设置最大化最小化关闭按钮

如下,在 加载后的事件 或 激活事件 中,调用 SetWindowLongPtr API 设置隐藏最大化最小化关闭按钮。

#region 去除隐藏最大化最小化关闭按钮 private const int GWL_STYLE = -16; // 窗口标题栏上的菜单【最大最小关闭】 private const int WS_SYSMENU = 0x80000; // 最大化按钮 private const int WS_MAXIMIZEBOX = 0x10000; // 最小化按钮 private const int WS_MINIMIZEBOX = 0x20000; private const int SWP_NOMOVE = 0x0002; private const int SWP_NOSIZE = 0x0001; private const int SWP_NOZORDER = 0x0004; private const int SWP_FRAMECHANGED = 0x0020; [DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)] private static extern int GetWindowLong32(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] extern private static int GetWindowLongPtr(IntPtr hWnd, int nindex); [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)] extern private static int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll")] private static extern int SetWindowLongPtr(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags); /// /// 隐藏最小化最大化按钮,等同 ResizeMode.NoResize /// /// private static void HideMinMaxButtons(IntPtr hwnd) { if (IntPtr.Size == 4) { var currentStyle = GetWindowLong32(hwnd, GWL_STYLE); SetWindowLong32(hwnd, GWL_STYLE, currentStyle & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX); } else { var currentStyle = GetWindowLongPtr(hwnd, GWL_STYLE); SetWindowLongPtr(hwnd, GWL_STYLE, currentStyle & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX); } //call SetWindowPos to make sure the SetWindowLongPtr take effect according to MSDN SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } /// /// 隐藏最小化最大化关闭按钮 /// /// private static void HideMinMaxCloseButtons(IntPtr hwnd) { if (IntPtr.Size == 4) { var currentStyle = GetWindowLong32(hwnd, GWL_STYLE); SetWindowLong32(hwnd, GWL_STYLE, currentStyle & ~WS_SYSMENU); } else { var currentStyle = GetWindowLongPtr(hwnd, GWL_STYLE); SetWindowLongPtr(hwnd, GWL_STYLE, currentStyle & ~WS_SYSMENU); } //call SetWindowPos to make sure the SetWindowLongPtr take effect according to MSDN SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } /// /// [禁用]最小化按钮 变非常灰 /// /// private static void DisableMinButton(IntPtr hwnd) { if (IntPtr.Size == 4) { var currentStyle = GetWindowLong32(hwnd, GWL_STYLE); SetWindowLong32(hwnd, GWL_STYLE, currentStyle & ~WS_MINIMIZEBOX); } else { var currentStyle = GetWindowLongPtr(hwnd, GWL_STYLE); SetWindowLongPtr(hwnd, GWL_STYLE, currentStyle & ~WS_MINIMIZEBOX); } //call SetWindowPos to make sure the SetWindowLongPtr take effect according to MSDN SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } /// /// [禁用]最大化按钮 变非常灰 /// /// private static void DisableMaxButton(IntPtr hwnd) { if (IntPtr.Size == 4) { var currentStyle = GetWindowLong32(hwnd, GWL_STYLE); SetWindowLong32(hwnd, GWL_STYLE, currentStyle & ~WS_MAXIMIZEBOX); } else { var currentStyle = GetWindowLongPtr(hwnd, GWL_STYLE); SetWindowLongPtr(hwnd, GWL_STYLE, currentStyle & ~WS_MAXIMIZEBOX); } //call SetWindowPos to make sure the SetWindowLongPtr take effect according to MSDN SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } #endregion

隐藏按钮后,仍然可以通过 Alt+F4 关闭窗口,因此要禁用关闭操作,还需要重载OnClosing函数,或者,Closing事件中处理。

去掉最大化最小化关闭按钮的测试 隐藏最大化最小化关闭按钮 Activated += MainWindow_Activated; //Loaded += MainWindow_Loaded; /// ...... /// /// MainWindow_Loaded MainWindow_Activated 等事件中执行,会在按钮显示后再消失(隐藏) /// /// /// private void MainWindow_Activated(object sender, EventArgs e) { var hwnd = new WindowInteropHelper(this).Handle; HideMinMaxCloseButtons(hwnd); } 隐藏最大化最小化按钮 /// /// MainWindow_Loaded MainWindow_Activated 等事件中执行,会在按钮显示后再消失(隐藏) /// /// /// private void MainWindow_Activated(object sender, EventArgs e) { var hwnd = new WindowInteropHelper(this).Handle; HideMinMaxButtons(hwnd); } 禁用最大化按钮 /// /// MainWindow_Loaded MainWindow_Activated 等事件中执行,会在按钮显示后再消失(隐藏) /// /// /// private void MainWindow_Activated(object sender, EventArgs e) { var hwnd = new WindowInteropHelper(this).Handle;; DisableMaxButton(hwnd); } 禁用最小化按钮 /// /// MainWindow_Loaded MainWindow_Activated 等事件中执行,会在按钮显示后再消失(隐藏) /// /// /// private void MainWindow_Activated(object sender, EventArgs e) { var hwnd = new WindowInteropHelper(this).Handle;; DisableMinButton(hwnd); } 禁用关闭按钮(变灰)

首先引入需要的 API:

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)] private static extern IntPtr GetSystemMenu(IntPtr hWnd, UInt32 bRevert); [DllImport("USER32.DLL ", CharSet = CharSet.Unicode)] private static extern UInt32 RemoveMenu(IntPtr hMenu, UInt32 nPosition, UInt32 wFlags); private const UInt32 SC_CLOSE = 0x0000F060; private const UInt32 MF_BYCOMMAND = 0x00000000;

同样,在 加载后事件 中调用如下方法,禁用关闭按钮

var hwnd = new WindowInteropHelper(this).Handle; //获取window的句柄 IntPtr hMenu = GetSystemMenu(hwnd, 0); RemoveMenu(hMenu, SC_CLOSE, MF_BYCOMMAND); 参考 WPF中如何禁用/去除窗口右上角的关闭按钮 如何去掉WinForm或者WPF的最大化和最小化按钮


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3