[blue]Option Explicit
Private Type XFORM
eM11 As Single
eM12 As Single
eM21 As Single
eM22 As Single
eDx As Single
eDy As Single
End Type
Private Declare Function SetGraphicsMode Lib "gdi32" (ByVal hdc As Long, ByVal iMode As Long) As Long
Private Declare Function GetGraphicsMode Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SetMapMode Lib "gdi32" (ByVal hdc As Long, ByVal nMapMode As Long) As Long
Private Declare Function GetWorldTransform Lib "gdi32" (ByVal hdc As Long, lpXform As XFORM) As Long
Private Declare Function SetWorldTransform Lib "gdi32" (ByVal hdc As Long, lpXform As XFORM) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function DrawIconEx Lib "user32" (ByVal hdc As Long, ByVal xLeft As Long, ByVal yTop As Long, ByVal hIcon As Long, ByVal cxWidth As Long, ByVal cyWidth As Long, ByVal istepIfAniCur As Long, ByVal hbrFlickerFreeDraw As Long, ByVal diFlags As Long) As Long
Private Const DI_NORMAL = &H3
Private Const GM_ADVANCED = 2
Private Const GM_COMPATIBLE = 1
Private Const MM_TEXT = 1
Private Const MM_LOENGLISH = 4
Private gOldWorld As XFORM
Private Sub Form_Load()
[green]' Initialise Picture1's device context to work with SetWorldTransform ...[/green]
SetGraphicsMode Picture1.hdc, GM_ADVANCED
SetMapMode Picture1.hdc, MM_TEXT
Timer1.Interval = 1000
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
[green]' Uncomment the two lines of code that follow this comment and comment out
' the Picture1.Cls line if you want to render the rotated image onto another
' image (e.g a hand onto a clock). The background image should be loaded into Picture2
' RotateTargetDC Picture1.hdc, 0, 0, 0
' BitBlt Picture1.hdc, 0, 0, 64, 64, Picture2.hdc, 0, 0, vbSrcCopy[/green]
Picture1.Cls
RotateTargetDC Picture1.hdc, 32, 32, (Second(Now) - 30) * 6
[green]' We coukld have used ListImages Draw method in the next line, but it is fractionally less flexible when it comes
' to mucking about with the point of origin of the source[/green]
DrawIconEx Picture1.hdc, -3, -3, ImageList1.ListImages(1).ExtractIcon.Handle, 5, 32, 0, 0, DI_NORMAL
End Sub
[green]' This particular XForm is a rotation only[/green]
Private Function buildXForm(ByVal x0 As Long, ByVal y0 As Long, ByVal q As Single) As XFORM
q = RadDeg(q)
buildXForm.eM11 = Round(Cos(q), 4)
buildXForm.eM12 = Round(Sin(q), 4) [green]' sign swapped with eM21 because y axis is downwards[/green]
buildXForm.eM21 = Round(-Sin(q), 4)
buildXForm.eM22 = Round(Cos(q), 4)
buildXForm.eDx = x0 'x0 - Cos(q) * x0 + Sin(q) * y0
buildXForm.eDy = y0 'y0 - Cos(q) * y0 - Sin(q) * x0
End Function
Private Function RadDeg(ByVal angle As Double) As Double
RadDeg = angle * Atn(1) / 45
End Function
Private Sub RotateTargetDC(ByVal hdcTarget As Long, ByVal aboutX As Long, ByVal aboutY As Long, ByVal rotate As Single)
Dim myXForm As XFORM
[green]' Build rotation transformation matrix
' In this case rotating 'rotate' degrees clockwise about point aboutX, aboutY[/green]
myXForm = buildXForm(aboutX, aboutY, rotate)
[green]' Apply the transform to our DC[/green]
SetWorldTransform hdcTarget, myXForm
End Sub[/blue]