[GDI] unerklärliches (negatives) Phänomen

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von ~blaze~.

    [GDI] unerklärliches (negatives) Phänomen

    Hallo,

    machen wirs kurz und knapp: ich will mit GDI etwas an eine bestimmte Position zeichnen, welche ausgerechnet wird. Jedoch wirds nicht an die Position gezeichnet (Position: (Höhe - 10) - 10) stattdessen in die Mitte, bzw. nicht weiter unten.

    VB.NET-Quellcode

    1. Imports System.Threading
    2. Public Class LineRunnerGameEngine
    3. Private RunnerPos As Point = New Point(0, (Me.Height - 10) - 10)
    4. Private Sub LineRunnerGameEngine_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    5. MyBase.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
    6. MyBase.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    7. End Sub
    8. Private Sub LineRunnerGameEngine_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    9. Form1.Text = e.Location.ToString
    10. End Sub
    11. Private Sub LineRunnerGameEngine_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    12. Dim basePen As Pen = New Pen(Brushes.Black, 20)
    13. With e.Graphics
    14. .DrawLine(basePen, New Point(0, Me.Height - 10), New Point(Me.Width, Me.Height - 10))
    15. .FillRectangle(Brushes.Red, New Rectangle(RunnerPos, New Size(10, 10)))
    16. End With
    17. End Sub
    18. Sub StartRunning()
    19. Timer1.Start()
    20. End Sub
    21. Sub StopRunning()
    22. Timer1.Stop()
    23. End Sub
    24. Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
    25. ' RunnerPos.Offset(2, 0)
    26. Me.Invalidate()
    27. End Sub
    28. End Class
    Naja, ein Control halt :P

    Ich hoffe, jemand kann mir helfen.
    Grüße

    * Topic verschoben *

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „der_Kurt“ ()

    Hi
    Ich würde für Controlinterne Berechnungen immer ClientSize statt Size verwenden, da es z.B. bei einer Form zu einem oft nicht erwünschten Verhalten kommt. RunnerPos würde ich nach der Änderung der Form-Größe setzen.

    VB.NET-Quellcode

    1. Private Sub LineRunnerGameEngine_SizeChanged(ByVal sender As Object, ByVal e As EventArgs) Handles Me.SizeChanged
    2. Static previousHeight As Integer = 0
    3. If previousHeight <> ClientSize.Height Then
    4. RunnerPos = New Point(RunnerPos.X, RunnerPos.Y + ClientSize.Height - previousHeight)
    5. previousHeight = ClientSize.Height
    6. End If
    7. End Sub

    Die Dekaration kann so stehen bleiben. Diese Vorgehensweise hilft beim Ableiten anderer Controls von der eigenen Klasse. (Ich persönlich würde das Programm übrigens ohne Zugriff auf Controls gestalten und mit einem gepufferten bösen CreateGraphics bepinseln. Mit AddHandler würde ich dann einen Handler für das Paint-Event abonnieren, in dem ich dann den Puffer in e.Graphics rüberschiebe.)

    Gruß
    ~blaze~
    Hallo,
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Threading
    2. Public Class LineRunnerGameEngine
    3. Private RunnerPos As Point = New Point(0, ClientSize.Height)
    4. Private Sub LineRunnerGameEngine_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    5. MyBase.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
    6. MyBase.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    7. End Sub
    8. Private Sub LineRunnerGameEngine_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    9. Form1.Text = e.Location.ToString
    10. End Sub
    11. Private Sub LineRunnerGameEngine_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    12. Dim basePen As Pen = New Pen(Brushes.Black, 20)
    13. With e.Graphics
    14. .DrawLine(basePen, New Point(0, Me.Height - 10), New Point(Me.Width, Me.Height - 10))
    15. .FillRectangle(Brushes.Red, New Rectangle(RunnerPos, New Size(10, 10)))
    16. End With
    17. End Sub
    18. Private Sub LineRunnerGameEngine_SizeChanged(ByVal sender As Object, ByVal e As EventArgs) Handles Me.SizeChanged
    19. Static previousHeight As Integer = 0
    20. If previousHeight<> ClientSize.Height Then
    21. ' RunnerPos = New Point(RunnerPos.X, RunnerPos.Y + ClientSize.Height - previousHeight)
    22. ' previousHeight = ClientSize.Height
    23. End If
    24. End Sub
    25. Sub StartRunning()
    26. Timer1.Start()
    27. End Sub
    28. Sub StopRunning()
    29. Timer1.Stop()
    30. End Sub
    31. Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
    32. ' RunnerPos.Offset(2, 0)
    33. Me.Invalidate()
    34. End Sub
    35. End Class


    wird es halt in der Mitte positioniert. Ich habe vorerst den Snippet von ~blaze~ auskommentiert.

    So siehts dann aus:
    Wenn ich ein neues UserControl erstelle, dann hat dies die Abmessungen 150;150.
    Zufällig genau die Größe, die ClientSize.Height in deinem Beispiel hat, wenn man einen Haltepunkt setzt.

    ~blaze~ schrieb:

    RunnerPos würde ich nach der Änderung der Form-Größe setzen.

    /Sign

    Siehe Veränderung im Beispiel...

    VB.NET-Quellcode

    1. Private RunnerPos As Point
    2. Private Sub LineRunnerGameEngine_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    3. MyBase.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
    4. MyBase.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    5. RunnerPos = New Point(30, ClientSize.Height - 30)
    6. End Sub