我怎样才能在vb.net中更改表单形状

时间:2009-03-28 09:38:44

标签: vb.net winforms winapi pinvoke

我曾经使用以下代码在VB 6.0中更改Form形状:

Private Declare Function CreateRoundRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long) As Long

Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

Private Sub MakeRoundObject(objObject As Object, Value As Long)
  Static lngHeight, lngLong, lngReturn, lngWidth As Long
  lngWidth = objObject.Width / Screen.TwipsPerPixelX
  lngHeight = objObject.Height / Screen.TwipsPerPixelY
  SetWindowRgn objObject.hWnd, CreateRoundRectRgn(10, 50, lngWidth, lngHeight, Value + 10, Value), True
End Sub

Private Sub Form_Load()
   Call MakeRoundObject(Form1, 50)
End Sub

以同样的方式使用VB.NET代码如下:

Imports Microsoft.VisualBasic.Compatibility

Public Class Form1
  Private Declare Function CreateRoundRectRgn Lib "gdi32" (ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer, ByVal X3 As Integer, ByVal Y3 As Integer) As Integer
  Private Declare Function ReleaseCapture Lib "user32" () As Integer
  Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Integer, ByVal hRgn As Integer, ByVal bRedraw As Boolean) As Integer

  Private Sub MakeRoundObject(ByRef objObject As Object, ByRef Value As Integer)
    Static lngLong, lngHeight, lngReturn As Object
    Static lngWidth As Integer
    lngWidth = objObject.Width / VB6.TwipsPerPixelX
    lngHeight = objObject.Height / VB6.TwipsPerPixelY
    SetWindowRgn(objObject.hWnd, CreateRoundRectRgn(0, 0, lngWidth, lngHeight, Value, Value), True)

  End Sub

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    MakeRoundObject(Me, 20)
  End Sub

End Class

但是在后一种情况下,我收到一条错误消息 - “未找到类型'Form1'上的公共成员'hWnd'。”

我做什么?

4 个答案:

答案 0 :(得分:4)

您不必使用P / Invoke来执行此操作。 Form.Region属性是为此而设计的。一个简单的例子:

Public Class Form1
  Public Sub New()
    InitializeComponent()
    Dim path As New Drawing2D.GraphicsPath()
    path.AddEllipse(0, 0, Me.Width, Me.Height)
    Me.Region = New Region(path)
  End Sub
End Class

答案 1 :(得分:0)

该属性现在是Handle,而不是hWnd。

如果你打开选项严格,那么编译器就会告诉你hWnd不再存在了。同样在.NET中,你应该使用ByVal而不是ByRef,除非你需要调用者能够看到对该参数所做的更改,传递ByVal不再有性能损失。您还应该将MakeRoundObject Sub的参数类型更改为正确的数据类型而不是Object。

答案 2 :(得分:0)

也许另一种获取非矩形表单形状的方法可能没有考虑过:在表单上设置透明背景颜色并使用它。

我经常在.NET中关于屏幕的事情做以下事情:将背景颜色设置为实际形式中未使用的颜色(如深紫色),并使用GDI +在表单边界内以您想要的颜色绘制填充形状它有。

实际上并没有将表单区域从矩形更改为其他内容,但它确实有效。对于表单而言,“脱离形状”通常更容易。

答案 3 :(得分:0)

另一种方法是将TransparencyKey设置为像Magenta或表格上未使用的任何其他颜色。然后将BackgroundImage属性设置为某个图像,品红色将代表透明区域。 通过该程序,您可以轻松地获得任何形状。