使用RotateTransformed DrawString定位鼠标

时间:2014-10-11 10:20:19

标签: vb.net graphics mouseevent gdi+

我想在显示屏中旋转文字。我试图通过拖动一个矩形来定位字符串,以说明DrawString方法的区域。

我使用的是RotateTransform和TranslateTransform,效果很好。但是,拖动时,鼠标光标不会变换为停留在被拖动矩形的底角。

我错过了什么......? ; - )

以下是一些示例代码,它可以直接粘贴到Windows窗体上,并且可以直接粘贴到Windows窗体中

Public Class Form1
Dim drawingShape As Boolean = False
Dim mDown, mPos As Point
Dim bitMap1 As Bitmap
Dim txt As String = "Hello folks, here is some text"
Dim angle As Integer = 0

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    bitMap1 = New Bitmap(Me.Width, Me.Height)
End Sub

Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
    If drawingShape Then
        e.Graphics.RotateTransform(angle, Drawing2D.MatrixOrder.Append)
        e.Graphics.TranslateTransform(mDown.X, mDown.Y, Drawing2D.MatrixOrder.Append)
        Dim rect As New Rectangle(0, 0, mPos.X - mDown.X, mPos.Y - mDown.Y)
        e.Graphics.DrawRectangle(Pens.Red, rect)
        e.Graphics.DrawString(txt, New Font("Calibri", 12), Brushes.Green, rect)
        e.Graphics.ResetTransform()
    End If
End Sub

Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
    mDown = e.Location
    drawingShape = True
End Sub

Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles MyBase.MouseMove
    mPos = e.Location
    Me.Refresh()
End Sub

Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles MyBase.MouseUp
    Dim g As Graphics = Graphics.FromImage(bitMap1)
    g.RotateTransform(angle, Drawing2D.MatrixOrder.Append)
    g.TranslateTransform(mDown.X, mDown.Y, Drawing2D.MatrixOrder.Append)
    Dim rect As New Rectangle(0, 0, mPos.X - mDown.X, mPos.Y - mDown.Y)
    g.DrawString(txt, New Font("Calibri", 12), Brushes.Blue, rect)
    'g.ResetTransform()
    g.Dispose()
    Me.BackgroundImage = bitMap1
    drawingShape = False
    angle += 45
End Sub

结束班

2 个答案:

答案 0 :(得分:0)

您可以使用'Cursor.X and ‘Cursor.Y将鼠标定位在您想要的位置。

答案 1 :(得分:0)

感谢您的投入。我最终让它工作,更新代码如下。我使用了System.Windows.Vector中的向量例程和System.Windows.Media.Matrix中的矩阵。这些提供矩阵乘法功能。不确定这是否被认为是好习惯,因为像Point这样的类与System.Drawing类发生冲突。

注意:这些矢量类要求程序引用WindowsBase

该程序通过创建一个描述自单击鼠标按钮后拖动运动的向量来工作。因为在拖动文本显示框时创建了这个向量 - 即框已被旋转以显示它 - 向量将被转换回绘制正常水平矩形时的向量。然后旋转此水平矩形(“标准化矩形”)以实现当前拖动的文本显示框。

代码只需要一个基本表单来运行

Public Class Form1
Dim drawingShape As Boolean = False                 ' True during mouse-drag
Dim mDown, mPos As Point                            ' Mouse-Button-Down, and current mouse position
Dim bitMap1 As Bitmap                               ' Background display to hold drawn items
Dim txt As String = "Hello folks, here is some text"
Dim angle As Integer = 0                            ' Angle to rotate text through (0 = along X-axis)
Dim rect As Rectangle                               ' Rectangle holding text - which is then transformed
Dim vecRectDiag As New Windows.Vector               ' Vector TopLeft-BotRight of rect holding text
Dim mxIdentWin As System.Windows.Media.Matrix       ' Identity matrix for resetting before rotating
Dim mxNegAngle As System.Windows.Media.Matrix       ' Matrix to transform mouse cursor vector back to horizontal
Dim botRight As Point                               ' Bottom-right corner of rect rectangle
Dim mVecWin As New Windows.Vector                   ' Vector showing mouse movement since mouse-button-down
Dim pen1red, pen2yel, pen3turq, pen4lime, pen5corn As Pen

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    bitMap1 = New Bitmap(Me.Width, Me.Height)
    mxIdentWin = New Windows.Media.Matrix(1, 0, 0, 1, 0, 0)         ' Identity matrix
End Sub

Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
    If drawingShape Then
        e.Graphics.TranslateTransform(-mDown.X, -mDown.Y, Drawing2D.MatrixOrder.Append)
        e.Graphics.RotateTransform(angle, Drawing2D.MatrixOrder.Append)
        e.Graphics.TranslateTransform(mDown.X, mDown.Y, Drawing2D.MatrixOrder.Append)
        e.Graphics.DrawRectangle(Pens.Red, rect)
        e.Graphics.DrawString(txt, New Font("Calibri", 12), Brushes.Green, rect)
        e.Graphics.ResetTransform()
    End If
End Sub

Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
    mDown = e.Location                  ' Location of mouse button click
    drawingShape = True
    mxNegAngle = mxIdentWin             ' Reset the negative-rotate matrix...
    mxNegAngle.Rotate(-angle)           ' ... and re-rotate with the new angle
End Sub

Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles MyBase.MouseMove
    mPos = e.Location
    mVecWin = New Windows.Vector(mPos.X - mDown.X, mPos.Y - mDown.Y)        ' Vector showing the real mouse movement
    vecRectDiag = Windows.Vector.Multiply(mVecWin, mxNegAngle)              ' Vector to the normalised horizontal rectangle - which now needs transforming
    botRight = New Point(CInt(mDown.X + vecRectDiag.X), CInt(mDown.Y + vecRectDiag.Y))      ' Bottom right of normalised horizontal rectangle
    rect = New Rectangle(mDown.X, mDown.Y, botRight.X - mDown.X, botRight.Y - mDown.Y)
    If drawingShape Then Me.Refresh()
End Sub

Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles MyBase.MouseUp
    Dim g As Graphics = Graphics.FromImage(bitMap1)
    g.TranslateTransform(-mDown.X, -mDown.Y, Drawing2D.MatrixOrder.Append)
    g.RotateTransform(angle, Drawing2D.MatrixOrder.Append)
    g.TranslateTransform(mDown.X, mDown.Y, Drawing2D.MatrixOrder.Append)
    g.DrawString(txt, New Font("Calibri", 12), Brushes.Blue, rect)
    g.ResetTransform()
    g.Dispose()
    Me.BackgroundImage = bitMap1
    drawingShape = False
    angle += 45
End Sub

End Class