2008-09-26 42 views
3

我有一个C#WinForms无边框窗口,我重写WndProc并处理WM_NCHITTEST消息。对于这种形式的区域,我的命中测试函数返回HTSYSMENU。双击该区域可成功关闭窗体,但右键单击该窗口不会显示窗口的系统菜单,也不会在右键单击任务栏中的窗口名称时显示该窗口。如何通过代码打开窗口的系统菜单?

这种形式使用这些样式:

而且具有以下非默认属性值:

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

我已经试过处理WM_NCRBUTTONDOWN和WM_NCRBUTTONUP,并发送WM_GETSYSMENU消息,但它没有工作。

回答

5

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

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

多年来,我写了大量的自定义控件,我不断哄骗Windows成为他们原本不打算做的事情。例如,我写了自己的下拉控件,我需要一个窗口来表现为一个弹出窗口而不是激活窗口。下面的代码将做到这一点。请注意,代码出现在OnHandleCreated事件处理程序中。这是因为在设置句柄之后需要更改标志,这表明Windows已经设置了它认为标志应该设置的内容。

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", 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风格不能设置不使用字幕样式,所以我不能说,如果这是你的执行的问题。

您可以在这两个链接查看原始样式列表和扩展样式列表。 http://msdn.microsoft.com/en-us/library/ms632600(VS.85).aspx

http://msdn.microsoft.com/en-us/library/ms632680(VS.85).aspx

+1

”WS_SYSMENU:创建一个窗口,在其标题栏上有一个窗口菜单,还必须指定WS_CAPTION风格。对, 是的,就是这样。这是一个无国界和无字幕的形式。 – 2009-01-16 13:51:14

0

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

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

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

0
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()))); 
     }} 

该检测应用程序的任务栏 “区域” 上右击..

也许有帮助吗? “

+0

谢谢,但我不想伪造系统菜单,我一直在寻找关于缺少系统菜单(还原,移动,大小,最小化,最大化,关闭)的答案。 – 2009-01-16 13:49:00

相关问题