代码之家  ›  专栏  ›  技术社区  ›  Martin Plante

如何通过代码打开窗口的系统菜单?

  •  4
  • Martin Plante  · 技术社区  · 16 年前

    此表单使用以下样式:

    this.SetStyle( ControlStyles.AllPaintingInWmPaint, true );
    this.SetStyle( ControlStyles.UserPaint, true );
    this.SetStyle( ControlStyles.OptimizedDoubleBuffer, true );
    this.SetStyle( ControlStyles.ResizeRedraw, true );
    

    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
    this.KeyPreview = true;
    this.MaximizeBox = false;
    this.MinimizeBox = false;
    

    3 回复  |  直到 16 年前
        1
  •  5
  •   Jimi    6 年前

    如果我没有弄错的话,一个无边界窗口会被标记为不提供系统菜单,并且不会出现在任务栏中。

    任何给定的窗口都没有边框,并且不会出现在任务栏中,这是在窗口上设置的样式标志的结果。可以使用 GetWindowLong SetWindowLong API调用。但是,你必须小心,因为某些样式不能一起工作。

    这些年来,我已经编写了许多自定义控件,我一直在哄骗windows,使其成为它们原本不打算成为的东西。
    例如,我编写了自己的下拉控件,其中需要一个窗口作为弹出窗口,而不是激活。
    下面的代码将实现这一点。请注意,代码显示在 OnHandleCreated 事件处理程序。这是因为标志需要在句柄设置后立即更改,这表明Windows已经设置了它认为标志应该是什么。

    using System.Runtime.InteropServices;
    
    protected override void OnHandleCreated(EventArgs e) {
        uint dwWindowProperty;
    
        User32.SetParent(this.Handle, IntPtr.Zero);
    
        dwWindowProperty = User32.GetWindowLong( this.Handle, User32.GWL.EXSTYLE );
        dwWindowProperty = dwWindowProperty | (uint)User32.WSEX.TOOLWINDOW | (uint)User32.WSEX.NOACTIVATE;
        User32.SetWindowLong( this.Handle, User32.GWL.EXSTYLE, dwWindowProperty );
    
        dwWindowProperty = User32.GetWindowLong( this.Handle, User32.GWL.STYLE );
        dwWindowProperty = ( dwWindowProperty & ~(uint)User32.WS.CHILD ) | (uint)User32.WS.POPUP; 
        User32.SetWindowLong( this.Handle, User32.GWL.STYLE, dwWindowProperty );
        base.OnHandleCreated (e);
    }
    
    
    //this is a fragment of my User32 library wrapper needed for the previous code segment.
    class User32 
    {
        [DllImport("user32.dll", SetLastError = true)]
       static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
    
        [DllImport("user32.dll", CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall )]
        public  static extern int SetWindowLong( IntPtr hWnd, User32.GWL gwlIndex, uint dwNewLong); 
    
        [DllImport("user32.dll", CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall )]
        public static extern uint GetWindowLong( IntPtr hWnd, User32.GWL gwlIndex );
    
        [FlagsAttribute] 
        public enum WS: uint { 
            POPUP = 0x80000000,
            CHILD = 0x40000000,
        }
    
        public enum GWL {
            STYLE   = -16,
            EXSTYLE = -20
        }
    
        [FlagsAttribute]
        public enum WSEX: uint {
            TOP        = 0x0,
            TOPMOST    = 0x8,
            TOOLWINDOW = 0x80,
            NOACTIVATE = 0x08000000,
        }
    }
    

    不幸的是 SysMenu Caption 样式,所以我不能说这是否是实现中的问题。


    Window Styles
    CreateWindowEx

        2
  •  0
  •   Martin Marconcini    16 年前

    我的应用程序中有相同的属性,右键单击也不起作用,所以这不是 你的问题 ,这似乎是windows窗体在没有边框时的响应方式。

    如果将边框设置为正常值,则可以右键单击任务栏等。

    要右键单击其他控件,需要设置ContextMenuStrip并提供“菜单”。但我不确定如果你没有边界的话这是否有效。我一直无法使它工作。

        3
  •  0
  •   chris chris    16 年前
        protected override void WndProc( ref System.Windows.Forms.Message m )
        { // RightClickMenu
            if ( m.Msg == 0x313 )
            {
                this.contextMenuStrip1.Show(this, this.PointToClient(new Point(m.LParam.ToInt32())));
            }}
    

    这会检测到右键单击应用程序任务栏的“区域”。。

    也许会有帮助?