|
| Autor |
Nachricht |
Hexer Newbie

Anmeldedatum: 16.12.2010 Beiträge: 2
|
Ruckeln bei DrawReversibleFrame oder DrawFocusRect
Verfasst am: 16.12.2010, 20:36 |
|
|
Hallo erstmal.
Ich bin neu hier. Und wie das meistens so ist, haben die Neulinge erst einmal ein paar Fragen. Genau so wie meine Wenigkeit.
Ich habe folgendes Problem:
Ich versuche eine Funktion zu implementieren, bei der man ein Objekt (Block) durch drücken der linken Maustaste quasi wie bei Drag&Drop bewegen kann. Um anzuzeigen, daß der Nutzer dieses Objekt mit der Maus hält, möchte ich einen Rahmen der Form des Objektes unter dem Mauszeiger auf dem Bildschirm bewegen. Das Problem ist, wenn ich die Funktion ControlPaint.DrawReversibleFrame verwende, ruckelt dieser Rahmen unendlich stark. Da dieser Rahmen ja nur auf dem Screen/Desktop gezeichnet wird, habe ich etwas rumprobiert und bin auf ein merkwürdiges Phänomen gestoßen. Verwende ich die alte GDI-Funktion DrawFocusRect auf dem DeviceContext der Parent-Form, so kann dieser Frame flüssig auf der Form bewegt werden. Verwende ich die Funktion DrawFocusRect allerdings auf dem DeviceContext des Desktop (genau wie es ja bei der DrawReversibleFrame-Funktion ja üblich ist) so ruckelt der Rahmen bei Bewegung des Mauszeigers (im selbstgebastelten Drag-Modus).
Hier der Test-Quelltext:
| Code: | Imports System.Drawing
Public Class Form1
Dim Block As clBlock
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'erst einmal einen neuen Block erstellen, wenn dies noch nicht geschehen ist
If Block Is Nothing Then
Block = New clBlock(Me)
Block.Left = 20
Block.Top = 20
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
'Wenn der Block bereits existiert, die Farbe des Rahmens ändern
If Not (Block Is Nothing) Then
Block.FrameColor = Color.Red
End If
End Sub
End Class
Public Class clBlock
Inherits Control
Private Declare Function DrawFocusRect Lib "user32" Alias "DrawFocusRect" (ByVal hDC As Integer, ByRef lpRect As RECT) As Integer
Private Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hWnd As Integer) As Integer
Private Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (ByVal hWnd As Integer, ByVal DC As Integer) As Integer
Private Structure RECT
Dim Left As Integer
Dim Top As Integer
Dim Right As Integer
Dim Bottom As Integer
End Structure
'Lokale Variablen
Private FramePen As Pen
Private DrawArea As Graphics
Private MouseDwn As Boolean
Private Frame As RECT
Private SrcPt As Point
Private DrawOnClient As Boolean
Private Dragging As Boolean
'Eigenschaften
Public Property FrameColor()
Get
Return (FramePen.Color)
End Get
Set(ByVal value)
FramePen.Color = value
Me.Refresh()
End Set
End Property
'Konstruktor
Sub New(ByVal AParent As Control)
If Not (AParent Is Nothing) Then
Me.Parent = AParent
End If
FramePen = New Pen(Color.Black, 1)
'eine Standardgröße von 40x40 festlegen
Me.Width = 40
Me.Height = 40
DrawArea = Me.CreateGraphics
DrawOnClient = False
End Sub
Private Sub clBlock_Paint(ByVal Sender As Object, ByVal e As PaintEventArgs) Handles Me.Paint
If Not (DrawArea Is Nothing) Then
If Visible Then
DrawArea.DrawRectangle(FramePen, 0, 0, Width - 1, Height - 1)
DrawArea.DrawRectangle(FramePen, 2, 2, Width - 5, Height - 5)
End If
End If
End Sub
Private Sub clBlock_MouseDown(ByVal Sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseDown
MouseDwn = True
'Quellkoordinaten des Mauszeigers festlegen (iin Client-Koordinaten!)
SrcPt = e.Location
Parent.Text = CStr(e.X) + " , " + CStr(e.Y)
End Sub
Private Sub clBlock_MouseUp(ByVal Sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseUp
MouseDwn = False
If Dragging Then
Dragging = False
'ein letztes mal das Frame zeichnen damit keine Rester des Frames auf dem Bildschirm zurückbleiben
DrawReversibleRect(Frame)
Me.Visible = True
End If
End Sub
Private Sub clBlock_MouseMove(ByVal Sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseMove
Dim dx, dy As Integer
If Dragging Then
'Veränderung zum
dx = e.X - SrcPt.X
dy = e.Y - SrcPt.Y
'Altes Frame durch neuzeichnen löschen
DrawReversibleRect(Frame)
Frame.Left = Left + dx
Frame.Top = Top + dy
Frame.Right = Frame.Left + Width
Frame.Bottom = Frame.Top + Height
DrawReversibleRect(Frame)
End If
If (MouseDwn) And Not (Dragging) Then
Dragging = True
Me.Hide()
dx = e.X - SrcPt.X
dy = e.Y - SrcPt.Y
Frame.Left = Left + dx
Frame.Top = Top + dy
Frame.Right = Frame.Left + Width
Frame.Bottom = Frame.Top + Height
DrawReversibleRect(Frame)
End If
End Sub
Private Sub DrawReversibleRect(ByRef ARect As RECT)
Dim g As Graphics = Parent.CreateGraphics
Dim DC As Integer
Dim BRect As Rectangle
Dim CRect As RECT
'Koordinaten von ARect sind Client-Koordinaten
If DrawOnClient Then
DC = g.GetHdc.ToInt32
Call DrawFocusRect(DC, ARect)
Else
'Koordinaten konvertieren in Screen-Koordinaten
DC = GetDC(0)
BRect = New Rectangle(ARect.Left, ARect.Top, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top)
BRect = Parent.RectangleToScreen(BRect)
CRect.Left = BRect.Left
CRect.Top = BRect.Top
CRect.Right = BRect.Right
CRect.Bottom = BRect.Bottom
Call DrawFocusRect(DC, CRect)
ReleaseDC(0, DC)
End If
g.Dispose()
End Sub
End Class |
(Die Form enthält nur zwei Taster [Button1, Button2], wobei nur Button1 zum Test gebraucht wird.)
Zum Test einfach die DrawOnClient = True setzen, damit der Rahmen auf der Form gezeichnet wird und wenn DrawOnClient = False so wird der Rahmen auf dem Desktop gezeichnet.
Nun die Frage:
Was kann der Grund für das Ruckeln, beim Zeichnen auf dem DC des Screen/Desktop sein? Ich habe auch schon die DoubleBuffering-Option auf True gesetzt.
Zusätzliche (vielleicht nützliche) Informationen:
Ich programmiere die Anwendung mit VisualBasic.NET 2008 Express Edition auf Windows 7.
Aero Peek ist aktiviert.
Vielen Dank für die Hilfe schon im Voraus.
Gruß,
Der Hexer. |
|
| |
|
 |
|
|