gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 00:24:58 26 4
gpt4 key购买 nike

我有一个 C# WinForms 无边框窗口,我重写 WndProc 并处理 WM_NCHITTEST 消息。对于这种形式的区域,我的 HitTest 函数返回 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 消息,但没有成功。

最佳答案

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

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

这些年来我编写了许多自定义控件,并且不断地让窗口变成它们最初不想要的样子。
例如,我编写了自己的下拉控件,其中我需要一个窗口充当弹出窗口而不是激活窗口。
下面的代码将做到这一点。请注意,该代码出现在 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,
}
}

不幸的是,如果不使用 Caption 样式,就无法设置 SysMenu 样式,所以我不能说这是否是您的实现中的问题。

您可以通过这两个链接查看原始样式列表和扩展样式列表:
Window Styles
CreateWindowEx

关于winforms - 如何通过代码打开窗口的系统菜单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/139835/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com