Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.
2010-11-04
This adventure takes place on a Panel that resides on a Form. I have a class that represents a GDI+ object (Thing). The Draw method that does the graphical representation of the object is very, very primitive, just enough to make it visible.
Public Class Thing Private m_X As Integer Private m_Y As Integer Private m_Width As Integer Private m_Height As Integer Private m_IsDragging As Boolean Public Sub New(ByVal Rnd As Random, ByVal Width As Integer, _ ByVal Height As Integer) Me.m_X = Rnd.Next(Width - 50) Me.m_Y = Rnd.Next(Height - 25) Me.m_Width = 100 Me.m_Height = 50 End Sub Public ReadOnly Property CenterX() As Integer Get Return Me.X + CType(Me.Width / 2, Integer) End Get End Property Public ReadOnly Property CenterY() As Integer Get Return Me.Y + CType(Me.Height / 2, Integer) End Get End Property Public Function GetDistance(ByVal FromX _ As Integer, ByVal FromY As Integer) As Double Dim DistX As Double = Math.Abs(Me.CenterX - FromX) Dim DistY As Double = Math.Abs(Me.CenterY - FromY) Dim Dist As Double = (DistX + DistY) If Dist = 0 Then Return 0 Else Return Dist / 2 End If End Function Public Property X() As Integer Get Return Me.m_X End Get Set(ByVal value As Integer) Me.m_X = value End Set End Property Public Property Y() As Integer Get Return Me.m_Y End Get Set(ByVal value As Integer) Me.m_Y = value End Set End Property Public Property Width() As Integer Get Return Me.m_Width End Get Set(ByVal value As Integer) Me.m_Width = value End Set End Property Public Property Height() As Integer Get Return Me.m_Height End Get Set(ByVal value As Integer) Me.m_Height = value End Set End Property Public Property IsDragging() As Boolean Get Return Me.m_IsDragging End Get Set(ByVal value As Boolean) Me.m_IsDragging = value End Set End Property Public Sub Draw(ByVal G As System.Drawing.Graphics) G.FillRectangle(Brushes.Green, Me.X, Me.Y, Me.Width, Me.Height) G.DrawRectangle(Pens.Black, Me.X, Me.Y, Me.Width, Me.Height) If Me.IsDragging Then G.DrawRectangle(Pens.Black, Me.X - 2, Me.Y - 2, Me.Width + 4, Me.Height + 4) End If End Sub Public Function HitTest(ByVal PosX As Integer, ByVal PosY As Integer) As Boolean Return (PosX >= Me.X _ AndAlso PosX <= (Me.X + Me.Width) _ AndAlso PosY >= Me.Y AndAlso PosY <= (Me.Y + Me.Height)) End Function End Class
The ThingList keeps track of all dragable objects, and makes sure that all are positioned within the visible area of the Panel.
Public Class ThingList Inherits System.Collections.CollectionBase Public Function Add(ByVal O As Thing) As Integer Return List.Add(O) End Function Default Public ReadOnly Property Item(ByVal Index As Integer) As Thing Get Return CType(List(Index), Thing) End Get End Property Public Sub Draw(ByVal G As System.Drawing.Graphics) For Each O As Thing In Me O.Draw(G) Next End Sub Public Function GetObjectAt(ByVal MouseX As Integer, ByVal MouseY As_ Integer) As Thing If Me.Count > 0 Then For Each O As Thing In Me If O.HitTest(MouseX, MouseY) Then Return O End If Next Return Nothing Else Return Nothing End If End Function Public Function GetObjectIfClose(ByVal MouseX As Integer, _ ByVal MouseY As Integer) As Thing If Me.Count > 0 Then Dim CloseIndex As Integer = -1 Dim CloseDistance As Double = 60 For I As Integer = 0 To Me.Count - 1 Dim Distance As Double = Me(I).GetDistance(MouseX, MouseY) If Distance < CloseDistance Then CloseDistance = Distance CloseIndex = I End If Next If CloseIndex >= 0 Then Return Me(CloseIndex) Else Return Nothing End If Else Return Nothing End If End Function Public Sub ResetIsDragging() For Each O As Thing In Me O.IsDragging = False Next End Sub Public Function MoveToVisibleArea(ByVal S As Size) As Boolean Dim Ret As Boolean = False For Each O As Thing In Me If O.X < 0 Then O.X += 2 Ret = True End If If O.Y < 0 Then O.Y += 2 Ret = True End If If (O.X + O.Width) > S.Width Then O.X -= 2 Ret = True End If If (O.Y + O.Height) > S.Height Then O.Y -= 2 Ret = True End If Next Return Ret End Function End Class
The form (contains a panel named Panel1) basically keeps track of mouse actions. This does not include the drag and drop events of the Control class, because that deals with dragging and dropping controls, not GDI+ objects.
Public Class Form1 Private L As ThingList Private IsDragging As Boolean Private DragObject As Thing = Nothing Private DragOffsetX As Integer Private DragOffsetY As Integer Private Sub Form1_Load(ByVal sender As _ System.Object, ByVal e As System.EventArgs) Handles MyBase.Load L = New ThingList() Dim Rnd As New Random() L.Add(New Thing(Rnd, Panel1.Width, Panel1.Height)) L.Add(New Thing(Rnd, Panel1.Width, Panel1.Height)) L.Add(New Thing(Rnd, Panel1.Width, Panel1.Height)) End Sub Private Sub Panel1_MouseDown(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown Me.DragObject = L.GetObjectIfClose(e.X, e.Y) If Not DragObject Is Nothing Then Me.DragOffsetX = e.X - Me.DragObject.X Me.DragOffsetY = e.Y - Me.DragObject.Y Me.DragObject.IsDragging = True Me.IsDragging = True Panel1.Invalidate() End If End Sub Private Sub Panel1_MouseMove(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseMove If Me.IsDragging And Not Me.DragObject Is Nothing Then Me.DragObject.X = e.X - Me.DragOffsetX Me.DragObject.Y = e.Y - Me.DragOffsetY Panel1.Invalidate() End If End Sub Private Sub Panel1_MouseUp(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseUp If Me.IsDragging Then Me.IsDragging = False L.ResetIsDragging() Me.DragObject = Nothing End If L.MoveToVisibleArea(Panel1.Size) Panel1.Invalidate() End Sub Private Sub Panel1_Paint(ByVal sender As System.Object, _ ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint e.Graphics.FillRectangle(Brushes.White, 0, 0, Me.Width, Me.Height) L.Draw(e.Graphics) End Sub Private Sub Panel1_Resize(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Resize If Not L Is Nothing Then If L.MoveToVisibleArea(Panel1.Size) Then Panel1.Invalidate() End If End If End Sub End Class
Now you can play around with three green boxes in the panel.
Categories: Visual Basic 9
Tags: GDI+
Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!
Leave a Reply