c# - 创建可以通过在背景区域中的任意位置拖动来移动的非矩形表单

标签 c# .net windows winforms winapi

我想通过左键单击并按住背景区域来移动我的表单窗口,就像我们通常使用标题栏所做的那样。

然后我还想将应用程序的窗体窗口(即矩形窗口)更改为自定义设计的图形窗口。我在许多其他应用程序中看到过这种类型的窗口,所以我相信这是可能的。

最佳答案

问题 1:

要允许窗体在拖动其客户区时移动,您需要告诉窗口管理器将客户区视为标题栏(标题区)。您在问题中提出了类似的建议。

这可以在 .NET 中通过覆盖 WndProc method 来完成您的表单,响应 WM_NCHITTEST 消息,并返回 HTCAPTION 以指示应将所有内容视为标题(标题)栏的一部分,而不是默认的 HTCLIENT,表示应将其视为窗体的客户区。将以下代码添加到您的表单类中:

private const int WM_NCHITTEST = 0x84;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    if (m.Msg == WM_NCHITTEST)
    {
        // Convert HTCLIENT to HTCAPTION
        if (m.Result.ToInt32() == HTCLIENT)
        {
            m.Result = (IntPtr)HTCAPTION;
        }
    }
}

问题 2:

您可以通过设置 Region property 来创建任意的非矩形形状的表单您的表格到自定义 Region你的选择。如果您有使用 Photoshop 等图形程序的经验,您可以将此视为为您的表单设置一个“剪切区域”:窗口管理器不会在您指定的边界之外绘制任何内容。描述此 Region 的形状中的像素甚至可以是不连续的。

创建区域的最简单方法可能是使用 GraphicsPath class , 然后使用 constructor for the Region class接受单个 GraphicsPath 对象作为参数。

我假设您已经知道,对于第一个问题,您必须设置 FormBorderStyle propertyNone 以确保窗口管理器绘制的默认边框消失。

不幸的是,这些区域无法消除锯齿。参见 Hans's answer to this question有关这些限制的更多详细信息。

最后,值得注意的是,后一种创建非矩形表单的方法可能会产生一些非常丑陋的用户界面,根本不会提高产品的可用性,如下所示:

Windows Media Player "alien head"

请谨慎使用此技术并运用良好的判断力。如果有疑问,矩形实际上是一种非常适合 window 的形状。

关于c# - 创建可以通过在背景区域中的任意位置拖动来移动的非矩形表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9321899/

相关文章:

c# - 正则表达式拆分包含标记的文本

windows - 批处理文件 : How can I extract the substring of a value from a FOR loop using an index variable?

python - 如何独立于父 python 脚本调用外部应用程序(基于 Windows)?

c# - 如何将字符数组的一部分转换为字符串

c# - 从 watch 或即时窗口打破无限循环

c# - 将 DTO 传递给我的 ViewModels 构造函数以映射属性

c# - 使用 PagedList.Mvc 在我的 View 中创建页面会出现构建错误

c# - 当运行时动态生成 'myType' 时,鉴别器 'myType' 不明确

windows - 使用 PowerShell 反引号执行代码片段不起作用

c# - 调整选定的 ListViewItem TextBlock 样式