【问题标题】:making the border of a vb.net form semi-transparent使 vb.net 表单的边框半透明
【发布时间】:2011-01-08 05:38:30
【问题描述】:

有没有办法将一个 vb.net 表单嵌入到另一个 vb.net 表单中。我正在尝试做的是使 Form-A 半透明和 Form-B 作为嵌入式主窗体。这样最终的应用程序周围就有一个半透明的边框。我也不想使用 MDI 表单。

编辑:如何在不使用 MDI 表单的情况下使 vb.net 表单的边框半透明。

【问题讨论】:

  • 不使用MDI,我想不出办法。缺少一些主要的winforms hacking。我有一个想法,但必须等到明天才能使用装有 Visual Studios 的计算机。
  • 谢谢,我会等到明天
  • 我现在要下载,所以今晚可能会很晚。
  • 请问您到底在做什么?我有点好奇。
  • 只是想像你一样使表单周围的边框半透明,但没有焦点问题。

标签: vb.net transparent


【解决方案1】:

我已经稍微简化了代码并将大部分事件连接到一个方法。不再有Form-A,只有Form-B。 Form-B 现在可以即时创建它自己的 Form-A,而无需实际制作代码文件。我将边框大小移到了一个变量中,以便调整它。

Imports System.Runtime.InteropServices

Public Class InnerForm
    Private borderSize As Integer = 10
    Private border As Form = New Form()

    Private Sub InnerForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        border.FormBorderStyle = Windows.Forms.FormBorderStyle.None
        border.ShowInTaskbar = False
        border.BackColor = Color.Blue
        border.Opacity = 0.5
        border.Enabled = False

        RefreshBorder()
    End Sub

Private Sub DrawRectangle()
    Dim p As New Drawing2D.GraphicsPath()
    p.StartFigure()
    p.AddArc(New Rectangle(0, 0, 40, 40), 180, 90)
    p.AddLine(40, 0, border.Width - 40, 0)
    p.AddArc(New Rectangle(border.Width - 40, 0, 40, 40), -90, 90)
    p.AddLine(border.Width, 40, border.Width, border.Height - 40)
    p.AddArc(New Rectangle(border.Width - 40, border.Height - 40, 40, 40), 0, 90)
    p.AddLine(border.Width - 40, border.Height, 40, border.Height)
    p.AddArc(New Rectangle(0, border.Height - 40, 40, 40), 90, 90)
    p.CloseFigure()
    border.Region = New Region(p)
End Sub

Private Sub RefreshBorder()
    border.Show()
    border.Size = New Size(Me.Width + borderSize * 2, Me.Height + borderSize * 2)
    border.Location = New Point(Me.Location.X - borderSize, Me.Location.Y - borderSize)
    DrawRectangle()
    SetWindowPos(border.Handle, Me.Handle, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOACTIVATE)

    Me.BringToFront()
End Sub


    Private Sub frmMAin_Refresh(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Me.GotFocus, Me.Move, Me.Activated, Me.SizeChanged, MyBase.Shown

        'dont show when maximized or minimized, else show it'
        If Me.WindowState = FormWindowState.Maximized Or Me.WindowState = FormWindowState.Minimized Then
            border.Hide()
        Else
            RefreshBorder()
        End If
    End Sub

    <DllImport("user32.dll")> _
    Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean
    End Function

    Public Const SWP_NOSIZE As Int32 = &H1
    Public Const SWP_NOMOVE As Int32 = &H2
    Public Const SWP_NOACTIVATE As Int32 = &H10
End Class

让我知道这是否适合你。

【讨论】:

  • 那么如何让边框颜色半透明呢?你可以在某处上传一个工作示例代码吗?
  • 我试过你的方法,唯一的问题是当我改变主窗体的不透明度时,子窗体也改变了它的不透明度
  • 对不起...误解了问题(不知道如何,但我做到了)。我弄乱了 giodamelio 发布的代码,我想我让它工作了。检查我更新的答案。
  • 好的,解决了焦点问题,但是新的问题是我最小化表单后,边框消失了。
  • 我稍微调整了代码,简化了一点,我认为它应该可以工作。让我知道这是否适合您。
【解决方案2】:

您应该检查一下。它在 C# 中,但您可以尝试寻求帮助来翻译它。 Extending Form with Non-Client Area Painting。这超出了我的想象,因为你是新手,所以可能会很棘手。

首先,由于您没有指定,我假设您使用的是 winforms 而不是 WPf 或 Asp.net,我几乎没有这两种经验。 我有一个方法只是弄乱了一堆 winforms 属性。在我的 winxp 盒子上有点小故障,但它可以工作:)。这是两种形式的代码,我在代码中包含了属性以简化事情。

主窗体

Public Class frmMAin
    Dim border As Form = New frmBackground()

    Private Sub frmMAin_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus
        RefreshBorder()
    End Sub
    Private Sub frmMAin_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        RefreshBorder()
    End Sub

    Private Sub RefreshBorder()
        border.Show()


        border.Size = New Size(Me.Width + 20, Me.Height + 20)
        border.Location = New Point(Me.Location.X - 10, Me.Location.Y - 10)
    End Sub

    Private Sub frmMAin_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LostFocus
        border.Hide()
    End Sub

    Private Sub frmMAin_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move
        RefreshBorder()
    End Sub
End Class

背景表单

Public Class frmBackground

    Private Sub frmBackground_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
        Me.ShowInTaskbar = False
        Me.BackColor = Color.Blue
        Me.Opacity = 0.5
    End Sub
End Class

结果是这样的。

此代码仍然存在一些焦点问题,但主要是功能性的。还要记住,这不是解决这个问题的最“优雅”的方法,很可能有更好的方法来使用一些系统 dll 来做到这一点。您也可以尝试 WPF,因为我听说您对外观的控制比在 winforms 中要多。

【讨论】:

  • 很好,谢谢。我也带来了类似的东西。我试过你的代码,效果很好。唯一的问题是焦点,当我点击背景表单时,它出现在主表单的顶部......有什么方法可以将它始终放在主表单的背景中而不使用 topmost = true ?如果可能的话,你能告诉如何在 WPF 中做到这一点。我不太喜欢这个。我昨天刚开始 vb.net :P
  • 这是我遇到的同样的问题,无法弄清楚。但它已经晚了,大约一个小时前我大脑的编程部分关闭了:|。我明天早上再试一次。
  • 我在答案顶部添加了一个链接。
  • 感谢您的努力 giodamelio。我访问了该站点并通过了链接,但不能理解太多。 @Others 有人请将此转换为 vb.net
  • @giodamelio 如果 c# 代码被翻译成 vb.net,你能帮我吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 2011-08-17
  • 2012-01-22
  • 1970-01-01
  • 2016-12-04
相关资源
最近更新 更多