How to open the system menu window by code?

I have a C # WinForms borderless window, for which I redefine WndProc and process the WM_NCHITTEST message. For the scope of this form, my result test function returns HTSYSMENU. Double-clicking on this area successfully closes the form, but when you right-click it does not display the window system menu and does not appear when you right-click on the window name in the taskbar.

This form uses these styles:

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

And it has these default values:

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

I tried to process WM_NCRBUTTONDOWN and WM_NCRBUTTONUP and send the WM_GETSYSMENU message, but this did not work.

+4
source share
3 answers

A borderless window, if I am not mistaken, is marked so that it does not offer a system menu and does not appear on the taskbar.

The fact that any given window has no border and is not displayed on the taskbar is the result of setting style flags in this window. These specific style flags can be set using the SetWindowLong API GetWindowLong and SetWindowLong . However, you have to be careful, as some styles just don't work together.

Over the years, I have written several user controls, and I constantly persuade windows to become what they were not originally.
For example, I wrote my own drop-down control in which I need a window that will behave as a pop-up window and not activate it.
The following code will do this. Notice that the code appears in the OnHandleCreated event of the OnHandleCreated . This is due to the fact that the flags must be changed immediately after installing the descriptor, which indicates that Windows has already installed what, in its opinion, 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 the source list of styles and the list of advanced styles using these two links:
Window styles
CreateWindowEx

+5
source

I have the same properties in my application, and right-clicking does not work either, so this is not your problem, it looks like window shapes react when they have no border.

If you set your border to a normal value, you can right-click on the taskbar, etc.

To right-click on other controls, you need to install ContextMenuStrip and provide your โ€œmenuโ€. But I'm not sure if this works when you have it without borders. I could not get it to work.

0
source
  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 defines the right button on the "area" application taskbar ..

Perhaps this will help?
0
source

Source: https://habr.com/ru/post/1309721/


All Articles