views:

1232

answers:

4

I used to change the Form shape in VB 6.0 using the following code:

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

In the same way I used VB.NET code as follows:

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

But in the latter case, I receive an error message - "Public member 'hWnd' on type 'Form1' not found."

What I do?

A: 

The property is Handle now, not hWnd.

If you turned option strict on then the compiler would have told you hWnd didn't exist anymore. Also in .NET you should use ByVal not ByRef unless you NEED the ability for the caller to see changes made to that parameter, there is no longer a performance penalty for passing ByVal. You should also change the types of your parameters for the MakeRoundObject Sub to be correct datatypes instead of Object.

pipTheGeek
Tell that parameters please. Or give some code
somu
A: 

Maybe another way of getting a non-rectangular form shape you might not have thought about: set a transparent background color on the form and work with that.

I often do the following for things like About screens in .NET: set background color to something not used in the actual form (like deep purple) and use GDI+ to draw a filled shape inside the form boundaries in the color you want it to have.

Not actually changing the form region from a rectangle to something else, but it does work. And is often easier with "disjoined shapes" for the form.

peSHIr
not understood for your answer
somu
Create new VB.NET Windows Forms application, put something on Form1 and/or draw in OnPaint(), set FormBorderStyle=None, set BackColor=Color.Purple, set TransparencyKey=Color.Purple and press F5...
peSHIr
+3  A: 

You don't have to use P/Invoke to do this. The Form.Region property was designed for this. A simple example:

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
Hans Passant
Perfect answer to the question, I guess.
peSHIr
A: 

Another way is to set TransparencyKey to a color like Magenta or any other not used on the form. Then set a BackgroundImage property to some image on which magenta color will represent transparent areas. With that procedure, you can get any shape with minimum effort.

Hugo Riley