Is there any way to embed a vb.net form to another vb.net form. What I am trying to do is to make Form-A semi-transparent and Form开发者_运维百科-B as the embedded main form. So that the final application has a semi transparent border around it . Also I don't want to use a MDI form.
Edit: How to make the border of a vb.net form semi-transparent without using MDI form.
I've simplified the code a bit and hooked up most of the events to a single method. There is no longer a Form-A, just a Form-B. Form-B now creates it's own Form-A on the fly without any need to actually make a code file. I moved the border size to a variable so it would be easy to adjust it.
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
Let me know if this works for you.
You should check this out. It is in C# but you could try to get help translating it. Extending Form with Non-Client Area Painting. It is way above my head and since you are new to, it might be pretty tricky.
First of, since you did not specify, I am assuming you are using winforms and not WPf or Asp.net, both of which I have next to no experience with. I have a method that is just messing with a bunch of winforms property's. It is kinda glitchy on my winxp, box but it works :). Here is the code for the two forms, I have included th property's in code to simplify things.
The Main form
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
The Background Form
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
And it turns out something like this.
This code still has some issues with focus but is mostly functional. Also keep in mind this is not the most "elegant" way to solve this problem, there is most likely a better way to do this with some system dll. You also might try WPF, as I hear you have much more control over look then in winforms.
精彩评论