How can I open a window's system menu by code?

后端 未结 3 919
-上瘾入骨i
-上瘾入骨i 2021-01-06 06:13

I have a C# WinForms borderless window, for which I override WndProc and handle the WM_NCHITTEST message. For an area of that form, my hit test function returns HTSYSMENU. D

相关标签:
3条回答
  • 2021-01-06 06:42
        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())));
            }}
    

    This detects rightclick on the applications taskbar "area"..

    maybe it will help ?

    0 讨论(0)
  • 2021-01-06 06:53

    A borderless window, if I am not mistaken, is flagged such that it offers no system menu, and that it does not appear in the taskbar.

    The fact that any given window does not have a border and does not appear in the taskbar is the result of the style flags set on the window. These particular Style flags can be set using the GetWindowLong and SetWindowLong API calls. However you have to be careful as certain styles just don't work together.

    I have written a number of custom controls over the years and I am constantly coaxing windows to become something they weren't originally intended to be.
    For example I have written my own dropdown control where I needed a window to behave as a popup and not to activate.
    The following code will do that. Note that the code appears in the OnHandleCreated event handler. This is because the flags need to be changed just after the handle is setup which indicates that Windows has already set what it thinks the flags should be.

    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,
        }
    }
    

    Unfortunately the SysMenu style cannot be set without using the Caption style, so I can't say if this is a problem in your implementation.

    You can check out the original style list and the extend style list at these two links:
    Window Styles
    CreateWindowEx

    0 讨论(0)
  • 2021-01-06 06:58

    I have the same properties in my application and Right click doesn't work either, so this is not your problem, it appears to be the way windows forms respond when they have no border.

    If you set your border to the normal value, you will be able to have right click in the taskbar and such.

    For right click on other controls, you'll need to set the ContextMenuStrip and provide your "menu". But I'm not sure if this works when you have it without border. I have been unable to make it work.

    0 讨论(0)
提交回复
热议问题