我有一个C#WinForms无边框窗口,我为此覆盖WndProc并处理WM_NCHITTEST消息.对于该表单的区域,我的命中测试函数返回HTSYSMENU.双击该区域可以成功关闭表单,但右键单击它不会显示窗口的系统菜单,也不会在右键单击任务栏中的窗口名称时显示.
此表单使用以下样式:
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;
我已经尝试处理WM_NCRBUTTONDOWN和WM_NCRBUTTONUP,并发送WM_GETSYSMENU消息,但它不起作用.
如果我没有弄错的话,无边框窗口会被标记为不提供系统菜单,并且它不会出现在任务栏中.
任何给定窗口没有边框但未出现在任务栏中的事实是窗口上设置的样式标志的结果.可以使用GetWindowLong
和SetWindowLong
API调用设置这些特定的Style标志.但是你必须小心,因为某些样式不能一起工作.
多年来,我已经编写了许多自定义控件,并且我一直在哄骗窗口,以成为他们原本不打算成为的东西.
例如,我已经编写了自己的下拉控件,我需要一个窗口来表现为弹出窗口而不是激活.
以下代码将执行此操作.请注意,代码出现在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
样式,所以我不能说这是否是您实现中的问题.
您可以在以下两个链接中查看原始样式列表和扩展样式列表:
窗口样式
CreateWindowEx