如何实现“WinForm窗体禁用关闭按钮”方法功能及源代码

更新时间:2023-05-12 20:56:34 阅读: 评论:0

如何实现“WinForm窗体禁⽤关闭按钮”⽅法功能及源代码
【实例说明】
 ⼀般情况下,在窗体的右上⾓都有最⼤化、最⼩化和关闭按钮,丹在MDI窗体中,有事为了避免重复打开同⼀个窗⼝,需要禁⽤窗⼝上⾯的“关闭”按钮,本实例就实现了这样的功能。
 说道禁⽤、有的⼈会说:直接在FormClosing处理不就得了:
<pre name="code" class="csharp">/// <summary>
/// 窗体关闭时的事件
/// </summary>
private void FrmMain_FormClosing(object nder, FormClosingEventArgs e)
{
 e.Cancel = true;    // 取消关闭操作
}
当然,这样可以,但是我们的⽬标是实现如下图所⽰的禁⽤+变灰:
运⾏效果如图所⽰:
 很神奇吧、我们知道最⼤化最⼩化按钮时可以禁⽤的、但是关闭按钮怎么禁⽤呢?请看下⾯的制作过程:
【关键技术】
 本实例主要⽤到了窗⼝处理⽅法WndProc的重写⽅法,在该⽅法的内部截获单击关闭窗⼝的消息,从⽽实现禁⽤“关闭”按钮的功能。 使⽤GetSystemMenu()和EnableMenuItem()使“关闭”按钮变灰⾊、
 其它事件的使⽤等等。
 WndProc⽅法主要⽤来处理Windows消息,语法格式如下:
1 [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
2 [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
3protected virtual void WndProc(ref Message m);
[注:详细的函数说明请参见源码中的备注说明。]
【设计过程】
 (1)打开Visual Studio,新建WinForm应⽤程序,将其命名为StopCloButton。
 (2)定义以下成员变量及API声明:
1private const int SC_CLOSE = 0xF060;    //定义关闭按钮对应的消息值
2private const int MF_ENABLED = 0x00000000;    //禁⽤
3private const int MF_GRAYED = 0x00000001;    //变灰
4private const int MF_DISABLED = 0x00000002;    //禁⽤
5private const int WM_SYSCOMMAND = 0x0112;  // 定义要截获的消息类型
6
7 [DllImport("ur32.dll", EntryPoint = "GetSystemMenu")]
8private static extern IntPtr GetSystemMenu(IntPtr hWnd, int bRevert);
9德国乙级联赛
10 [DllImport("Ur32.dll")]
11public static extern bool EnableMenuItem(IntPtr hMenu, int uIDEnableItem, int uEnable);
 (2)重写WndProc⽅法、实现当⽤户点击“关闭”按钮时⽆反应的效果:
1///<summary>
2///重写WndProc⽅法、实现当⽤户点击“关闭”按钮时⽆反应的效果
3///</summary>
4///<param name="m">要处理的Windows消息</param>
5protected override void WndProc(ref Message m)
6 {
7 if ((m.Msg == WM_SYSCOMMAND) && (int)m.WParam == SC_CLOSE)  // 当⿏标单击“关闭”按钮时
8 {
9  return; // 不进⾏任何处理直接返回
10 }
11 ba.WndProc(ref m);    // 传递下⼀条消息
12 }
文字的奥秘(3)先别急着运⾏、因为那样除了结束进程是关不掉的、
    所以、给⾃⼰留⼀条后路:放⼀个按钮、⽤于退出、在按钮的Click事件中写上退出程序的⽅法:
1private void button1_Click(object nder, EventArgs e)
2 {
3 Application.Exit();
4 }
(4)运⾏后发现,确实“关闭”按钮不能点击了、但是、他也没有变灰⾊啊、
    那是因为我们还没有调⽤EnableMenuItem()呢:
    在窗体的构造或Load事件中调⽤GetSystemMenu()和EnableMenuItem()函数以达到变灰“关闭”按钮的效果:
1private void FrmMain_Load(object nder, EventArgs e)
2 {
3 IntPtr hMenu = GetSystemMenu(this.Handle, 0);    //得到关闭按钮
4 EnableMenuItem(hMenu, SC_CLOSE, (MF_DISABLED + MF_GRAYED) | MF_ENABLED);    //设置样式(参数可⾃定义)关于青蛙的谜语
5 }
(5)到此,这个⼩程序就已经实现完毕了,细⼼的⼈会发现以下的⼩Bug:
    虽然“关闭”按钮已经禁⽤了、但是、当你点击以下最⼤化后、虽然关闭按钮依旧不能⽤、但是灰⾊效果消失了、    那么解决的⽅案就是禁⽤掉最⼤化最⼩化按钮、(*^_^*)、
    或者在窗体状态改变的事件⾥⾯再次调⽤以下变灰的函数即可。
程序主要函数注释如下:
1/**
2    * 【WndProc定义】
3    *  /// <summary>
3    *  /// <summary>
4    *  /// 使⽤窗⼝处理⽅法WndProc的重写⽅法
5    *  /// 截获单击关闭窗⼝的信息
6    *  /// </summary>
7    *  /// <param name="m">要处理的Windows消息</param>
8    *  [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
9    *  [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
10    *  protected virtual void WndProc(ref Message m);
11    * */
12
13/**
14    * 【GetSystemMenu定义】
15    *  /// <summary>
16    *  /// 该函数允许应⽤程序为复制或修改⽽访问窗⼝菜单(系统菜单或控制菜单)
17    *  /// 函数原型:HMENU GetSystemMenu(HWND hWnd,BOOL bRevert)
18    *  /// 备注:
19    *  ///    任何没有⽤函数GetSystemMenu来⽣成⾃⼰的窗⼝菜单拷贝的窗⼝将接受标准窗⼝菜单。
20    *  ///    窗⼝某单最初包含的菜单项有多种标识符值,如SC_CLOSE,SC_MOVE和SC_SIZE。/
21    *  ///    窗⼝菜单上的菜单项发送WM_SYSCOMMAND消息。
22    *  ///    所有预定义的窗⼝菜单项的标识符数⼤于OxFOOO。如果⼀个应⽤程序增加命令到窗⼝菜单,应该使⽤⼩于OxFOOO的标识符数。
23    *  ///    ⾃动变灰标准窗⼝菜单上的菜单项。应⽤程序通过响应在任何某单显⽰之前发送的WM_INITMENU消息来实现选取和变灰。
24    *  ///    Windows CE环境下,不⽀持系统菜单,但GetSyemMenu以宏的⽅式实现,以保持和已存在代码的兼容性。可以使⽤该宏的返回菜单句柄使关闭框⽆效,与在Windows桌⾯平台上⼀样。Windows CE下的返回值没有其他⽤处。参数bRevert⽆⽤。二面角定义
25    *  /// </summary>
26    *  /// <param name="hWnd">拥有窗⼝菜单拷贝的窗⼝的句柄</param>
27    *  /// <param name="bRevert">指定将执⾏的操作。如果此参数为FALSE,GetSystemMenu返回当前使⽤窗⼝菜单的拷贝的句柄。该拷贝初始时与窗⼝菜单相同,但可以被修改,如果此参数为TRUE,GetSystemMenu重置窗⼝菜单到缺省状态。如果存在先前的窗⼝菜单,将被销毁</param>
28    *  /// <returns>如果参数bRevert为FALSE,返回值是窗⼝菜单的拷贝的句柄:如果参数bRevert为TRUE,返回值是NULL</returns>
29    * [DllImport("ur32.dll", EntryPoint = "GetSystemMenu")]
30    * private static extern IntPtr GetSystemMenu(IntPtr hWnd, int bRevert);
31    * */
32
33/**爱的表白
34    * 【EnableMenuItem定义】
35    *  /// <summary>
36    *  /// 允许、禁⽌或变灰指定的菜单条⽬
37    *  /// 函数原型:
38    *  ///   BOOL EnableMenuItem(
39    *  ///    HMENUhMenu, // handle to menu
40    *  ///    UINTuIDEnableItem, // menu item to enable, disable, or gray
41    *  ///    UINTuEnable // menu item flags
员工培训记录
42    *  ///   );
43    *  /// 备注:
44    *  ///  使菜单项有效、⽆效或变灰。CreateMenu,InrtMenu,ModifyMenu和LoadMenuIndirect成员函数同时也设置菜单项的状态(有效、⽆效、或变灰)。
45    *  ///  使⽤MF_BYPOSITION的值需要应⽤恰当的CMenu对象。若菜单条的CMenu被使⽤,那么顶层菜单项(菜单条中的某项)将受影响。如果为了在弹出菜单或嵌套的弹出菜单中通过位置来设置项的状态,那么应⽤必须指定弹出菜单的CMenu。
46    *  ///  当应⽤指定了MF_BYCOMMAND标志,那么Windows将检测所有的属于CMenu的弹出菜单项。因此,除⾮当前正在复制菜单项,那么使⽤菜单条的CMenu是⾮常有效的。
最强大脑刘健47    *  /// </summary>
48    *  /// <param name="hMenu">菜单句柄</param>图书馆系统
49    *  /// <param name="uIDEnableItem">欲允许或禁⽌的⼀个菜单条⽬的标识符。如果在wEnable参数中设置了MF_BYCOMMAND标志,这个参数就代表欲改变菜单条⽬的命令ID。如设置的是MF_BYPOSITION,则这个参数代表菜单条⽬在菜单中的位置(第⼀个条⽬肯定是零)</param>
50    *  /// <param name="uEnable">参考ModifyMenu函数中的菜单常数标志定义表,其中列出了允许使⽤的所有常数。对于这个函数,只能指定下述常数:MF_BYCOMMAND,MF_BYPOSITION,MF_ENABLED,MF_DISABLED以及MF_GRAYED、具体值的含义请看下⾯的【EnableMenuItem函数中的uEnable各值的含义】</param>
51    *  /// <returns>返回值指定的先前状态菜单项。如果菜单项不存在,返回值是0xffffffff</returns>
52    *  [DllImport("Ur32.dll")]
53    *  public static extern bool EnableMenuItem(IntPtr hMenu, int uIDEnableItem, int uEnable);
54    * */
55
56/**
57    * 【EnableMenuItem函数中的uEnable各值的含义】
58    * MF_BYCOMMAND 指定参数给出已存在的菜单项的命令ID号。此为缺省值。
59    * MF_BYPOSITION 指定参数给出已存在菜单项的位置。第⼀项所在的位置是0。
60    * MF_DISABLED 使菜单项⽆效,以便它不能被选择,但不变灰。
60    * MF_DISABLED 使菜单项⽆效,以便它不能被选择,但不变灰。
61    * MF_ENABLED 使菜单项有效,以便它能够被选择,并可从变灰的状态中恢复出来。
62    * MF_GRAYED 使菜单项⽆效,以便它不能被选择并同时变灰。
63    *
64    * 注解:如指定的菜单条⽬依附了⼀个弹出式菜单,那么整个弹出式菜单都会受到影响
65    * */

本文发布于:2023-05-12 20:56:34,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/604337.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:菜单   关闭   按钮   菜单项   函数   程序
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图