Jump to content

Rotating Circle


Recommended Posts

I want to know if it is possible to rotate a window a number of degrees (will be with mouse wheel in future). I found a script to rotate a window around the mouse, but it doesn't actually rotate the window, the window just revolves around the point.

#include <GUIConstants.au3>
 #include <WindowsConstants.au3>
 Global Const $pi = 3.14159265358979
 HotKeySet("{ESC}", "_Bye")
 
 $iCircleR = 20; <=== Edit this for different circle radius (in pixels)
 $iCircleD = $iCircleR * 2
 Global $radius = 100;radius of movement of the blob mouse cursor to centre of circle blob
 Global $angle = 0
 Global $incr = 3
 $pt = MouseGetPos()
 $GUI = GUICreate("test", $iCircleD, $iCircleD, $pt[0] - $iCircleR, $pt[1] - $iCircleR, $WS_POPUP, $WS_EX_TOPMOST)
 GUISetBkColor(0xFF0000)
 
 $a = _CreateRoundRectRgn(0, 0, $iCircleD, $iCircleD, $iCircleD, $iCircleD)
 
;Remove comments on Next To lines To have the cirle instead of a disc
;~ $b = _CreateRoundRectRgn(4, 4, ($iCircleD - 8), ($iCircleD - 8), ($iCircleD - 4), ($iCircleD - 4))
;~ _CombineRgn($a, $b)
 
 _SetWindowRgn($GUI, $a)
 
 GUISetState()
 GUISetState(@SW_DISABLE)
 AdlibEnable("setangle", 20)
 
 While 1
     Sleep(10)
     $pt = MouseGetPos()
     If Not @error Then MoveBlob($pt)
 WEnd
 
 
 Func _CreateRoundRectRgn($l, $t, $w, $h, $e1, $e2)
     $ret = DllCall("gdi32.dll", "long", "CreateRoundRectRgn", "long", $l, "long", $t, "long", $l + $w, "long", $t + $h, "long", $e1, "long", $e2)
     Return $ret[0]
 EndFunc ;==>_CreateRoundRectRgn
 
 Func _CombineRgn(ByRef $rgn1, ByRef $rgn2)
     DllCall("gdi32.dll", "long", "CombineRgn", "long", $rgn1, "long", $rgn1, "long", $rgn2, "int", 3)
 EndFunc ;==>_CombineRgn
 
 Func _SetWindowRgn($h_win, $rgn)
     DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $h_win, "long", $rgn, "int", 1)
 EndFunc ;==>_SetWindowRgn
 
 Func _bye()
     Exit
 EndFunc ;==>_bye
 
 Func Setangle()
     $angle = Mod($angle + $incr, 360);degrees
 EndFunc ;==>Setangle
 
 Func MoveBlob($mousePos)
     $radAng = $angle * $pi / 180
     Local $x = $mousePos[0] + $radius * Cos($radAng) - $iCircleR
     Local $y = $mousePos[1] + $radius * Sin($radAng) - $iCircleR
     WinMove($GUI, "", $x, $y)
 EndFunc ;==>MoveBlob

A circular window will be fine for the example. If it is easier to use GDI+, that's OK too. Thanks in advance!

Edited by dantay9
Link to comment
Share on other sites

This can't be made as you want. If you know a prog named TopDesk, so it nothing do with windows - its illusion, program make screenshots of each window and then using DirectX do with them rotations and the various transformations. In theory it can be made in Autoit, of course using DirectX, by for what?...

Edited by Vitas

_____________________________________________________________________________

Link to comment
Share on other sites

I made the topic broader than it really is. All I want to do is make a circle that rotates on a certain point. Is there any way to do that. The circle can also be made in GDI+ so it won't be a window.

Here is a quick modification to a post made by monoceres.

#include <GDIPlus.au3>
#include <windowsconstants.au3>
Global $Startx, $Starty, $Endx, $Endy, $aM_Mask, $aMask, $nc, $rangle
Global $cx = 400, $cy = 400, $wrad = 250
Opt("GuiOnEventMode", 1)
$hwnd = GUICreate("Test", 300, 300, $cx - 150, $cy - 150 - $wrad, $WS_POPUP)
GUISetState()
GUISetBkColor(0x123456)
GUISetOnEvent(-3, "close")
_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(300, 300, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$pen = _GDIPlus_PenCreate(0xFF00FF00, 2)

InetGet("http://msp5.photobucket.com/albums/y196/dannydude182/smiley-300x300.png", @ScriptDir & "\smiley.png")

$image = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\smiley.png")

$matrix = _GDIPlus_MatrixCreate()

_GDIPlus_MatrixTranslate($matrix, 150, 150);True)

setTrans($hwnd)
$inc = 0
$rangle = 90
Do
    _GDIPlus_GraphicsClear($backbuffer, 0xFF123456)

    _GDIPlus_MatrixRotate($matrix, 1)

    _GDIPlus_GraphicsSetTransform($backbuffer, $matrix)

    _GDIPlus_GraphicsDrawImageRect($backbuffer, $image, -150, -150, 300, 300);-150,-150)


    _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, 300, 300)
    $rangle += 1
    If $rangle > 360 Then $rangle -= 360

    WinMove($hwnd, "", $cx + $wrad * Sin($rangle * ATan(1) / 45) - 150, $cy - $wrad * Cos($rangle * ATan(1) / 45) - 150)
    Sleep(20)
Until 0


Func close()
    Exit
EndFunc  ;==>close


Func _GDIPlus_MatrixTranslateB($hMatrix, $nOffsetX, $nOffsetY, $fOrder = True)
    $aResult = DllCall($ghGDIPDll, "int", "GdipTranslateMatrix", "ptr", $hMatrix, "float", $nOffsetX, "float", $nOffsetY, "int", $fOrder)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc  ;==>_GDIPlus_MatrixTranslateB


Func setTrans($hW)

    $aM_Mask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 460, "long", 460)

    $rct = DllStructCreate("int;int;int;inr", $aM_Mask[0])

    For $y = 0 To 300
        $x = Abs((150 * 150 - (150 - $y) * (150 - $y)) ^ 0.5)
        $Startx = 150 + $x
        $Endx = 300
        addRegion($Startx, $y, $Endx, $y)
        $Startx = 0
        $Endx = 150 - $x
        addRegion($Startx, $y, $Endx, $y)
    Next

    DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hW, "long", $aM_Mask[0], "int", 1)
EndFunc  ;==>setTrans

Func addRegion($a, $b, $c, $d)
    $aMask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $a, "long", $b, "long", $c + 1, "long", $d + 1)
    DllCall("gdi32.dll", "long", "CombineRgn", "long", $aM_Mask[0], "long", $aMask[0], "long", $aM_Mask[0], "int", 3)
EndFunc  ;==>addRegion
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

I saw that but it wasn't exactly what I wanted. I am not very good at GDI+. I want the picture to rotate on its center point. The x and y coordinates of the picture shouldn't move, but the orientation of the picture will. Also, is there a way to make a plain circle and use that instead of having to use a picture loaded from a file? If not, that's fine, just wondering.

Changing the winmove function to WinMove($hwnd, "", 150, 150) will make the picture stay in place right?

Edited by dantay9
Link to comment
Share on other sites

I saw that but it wasn't exactly what I wanted. I am not very good at GDI+. I want the picture to rotate on its center point. The x and y coordinates of the picture shouldn't move, but the orientation of the picture will. Also, is there a way to make a plain circle and use that instead of having to use a picture loaded from a file? If not, that's fine, just wondering.

You didn't "saw that" because I have only just written it!

But monoceres original post did just what you describe. I just made the window outside of the circle transparent so you have a circular window, which is what I thought you wanted, and I made the whole window move round in a circle so that the picture always pointed to the centre, whichj is what I thought you wanted.

EDIT

Changing the winmove function to WinMove($hwnd, "", 150, 150) will make the picture stay in place right?

Just comment that line out and the window won't move at all, just rotate.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

That is what I wanted. Thank you. I meant I saw monoceres original post when I was searching the forum. I also wanted to know if a circle can be drawn in GDI+. If not, what you gave me is great. I just don't like to have more files connected to a script than I need.

Edited by dantay9
Link to comment
Share on other sites

That is what I wanted. Thank you. I meant I saw monoceres original post when I was searching the forum. I also wanted to know if a circle can be drawn in GDI+. If not, what you gave me is great. I just don't like to have more files connected to a script than I need.

OK.

A circle can be drawn with GDI+, but I don't really understand what you want as I suppose has been obvious.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Can you replace the _GDIPlus_ImageLoadFromFile function with a function to draw a circle so that the circle that was drawn rotates? I know this is probably easy, but I have never used GDI+ before so I am clueless.

Link to comment
Share on other sites

Can you replace the _GDIPlus_ImageLoadFromFile function with a function to draw a circle so that the circle that was drawn rotates? I know this is probably easy, but I have never used GDI+ before so I am clueless.

If you just want a circle with a uniform color to rotate how will you know its rotating? You can see I'm not understanding again. Or do you mean this small mod to your first post

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
Global Const $pi = 3.14159265358979
HotKeySet("{ESC}", "_Bye")

$iCircleR = 20; <=== Edit this for different circle radius (in pixels)
$iCircleD = $iCircleR * 2
Global $radius = 100;radius of movement of the blob mouse cursor to centre of circle blob
Global $angle = 0
Global $incr = 3
$pt = MouseGetPos()
$GUI = GUICreate("test", $iCircleD, $iCircleD, $pt[0] - $iCircleR, $pt[1] - $iCircleR, $WS_POPUP, $WS_EX_TOPMOST)
GUISetBkColor(0xFF0000)

$a = _CreateRoundRectRgn(0, 0, $iCircleD, $iCircleD, $iCircleD, $iCircleD)
$b = _CreateRoundRectRgn(10, 10, $iCircleD-20, $iCircleD-20, $iCircleD-20, $iCircleD-20)
;Remove comments on Next To lines To have the cirle instead of a disc
;~ $b = _CreateRoundRectRgn(4, 4, ($iCircleD - 8), ($iCircleD - 8), ($iCircleD - 4), ($iCircleD - 4))
_CombineRgn($a, $b)

_SetWindowRgn($GUI, $a)

GUISetState()
GUISetState(@SW_DISABLE)
AdlibEnable("setangle", 20)

While 1
     Sleep(10)
     $pt = MouseGetPos()
     If Not @error Then MoveBlob($pt)
WEnd


Func _CreateRoundRectRgn($l, $t, $w, $h, $e1, $e2)
     $ret = DllCall("gdi32.dll", "long", "CreateRoundRectRgn", "long", $l, "long", $t, "long", $l + $w, "long", $t + $h, "long", $e1, "long", $e2)
     Return $ret[0]
EndFunc;==>_CreateRoundRectRgn

Func _CombineRgn(ByRef $rgn1, ByRef $rgn2)
   $res =  DllCall("gdi32.dll", "long", "CombineRgn", "long", $rgn1, "long", $rgn1, "long", $rgn2, "int", 3)
   return $res[0]
EndFunc;==>_CombineRgn

Func _SetWindowRgn($h_win, $rgn)
     DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $h_win, "long", $rgn, "int", 1)
EndFunc;==>_SetWindowRgn

Func _bye()
     Exit
EndFunc;==>_bye

Func Setangle()
     $angle = Mod($angle + $incr, 360);degrees
EndFunc;==>Setangle

Func MoveBlob($mousePos)
     $radAng = $angle * $pi / 180
     Local $x = $mousePos[0] + $radius * Cos($radAng) - $iCircleR
     Local $y = $mousePos[1] + $radius * Sin($radAng) - $iCircleR
     WinMove($GUI, "", $x, $y)
EndFunc;==>MoveBlob
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Here's the end product in for anyone else searching the forum for something similar.

#include <GDIPlus.au3>
#include <windowsconstants.au3>

Global Const $WM_MOUSEWHEEL = 0x020A
Global Const $Angle = 10
Global Const $tagMSLLHOOKSTRUCT = $tagPOINT & ';dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo'
Global $aM_Mask

Opt("GuiOnEventMode", 1)

$hwnd = GUICreate("Test", 300, 300, 150, 150, $WS_POPUP)
GUISetOnEvent(-3, "close")
_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics(300, 300, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$pen = _GDIPlus_PenCreate(0xFF00FF00, 2)

$image = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\smiley.png")
$matrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($matrix, 150, 150)

SetTrans($hwnd)
GUISetState()

_GDIPlus_GraphicsSetTransform($backbuffer, $matrix)
_GDIPlus_GraphicsDrawImageRect($backbuffer, $image, -150, -150, 300, 300)
_GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, 300, 300)

$hFunc = DllCallbackRegister("Mouse_LL", "long", "int;wparam;lparam")
$hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hFunc), _WinAPI_GetModuleHandle(0))

While 1
    Sleep(20)
WEnd

Func Rotate_Matrix($hmatrix, $nangle)
    _GDIPlus_GraphicsClear($backbuffer, 0xFF123456)

    _GDIPlus_MatrixRotate($matrix, $nangle)

    _GDIPlus_GraphicsSetTransform($backbuffer, $matrix)

    _GDIPlus_GraphicsDrawImageRect($backbuffer, $image, -150, -150, 300, 300)

    _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, 300, 300)
EndFunc  ;==>Rotate_Matrix

Func close()
    Exit
EndFunc  ;==>close

Func OnAutoItExit()
    _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hFunc)
EndFunc  ;==>OnAutoItExit

Func Mouse_LL($iCode, $iwParam, $ilParam)
    Local $tMSLLHOOKSTRUCT = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam)

    If $iCode < 0 Then
        Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    EndIf

    If $iwParam = $WM_MOUSEWHEEL Then
        Local $iValue = DllStructGetData($tMSLLHOOKSTRUCT, 'mouseData') / 2 ^ 16
        If BitAND($iValue, 0x8000) Then $iValue = BitOR($iValue, 0xFFFF0000)
        If Abs($iValue) = $iValue Then
            Rotate_Matrix($matrix, $Angle)
        Else
            Rotate_Matrix($matrix, -($Angle))
        EndIf
    EndIf

    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
EndFunc  ;==>Mouse_LL

Func _GDIPlus_MatrixTranslateB($hmatrix, $nOffsetX, $nOffsetY, $fOrder = True)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipTranslateMatrix", "ptr", $hmatrix, "float", $nOffsetX, "float", $nOffsetY, "int", $fOrder)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc  ;==>_GDIPlus_MatrixTranslateB

Func SetTrans($hW)
    Local $rct, $y, $x, $Startx, $Endx
    $aM_Mask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 460, "long", 460)

    $rct = DllStructCreate("int;int;int;inr", $aM_Mask[0])

    For $y = 0 To 300
        $x = Abs((150 * 150 - (150 - $y) * (150 - $y)) ^ 0.5)
        $Startx = 150 + $x
        $Endx = 300
        addRegion($Startx, $y, $Endx, $y)
        $Startx = 0
        $Endx = 150 - $x
        addRegion($Startx, $y, $Endx, $y)
    Next

    DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hW, "long", $aM_Mask[0], "int", 1)
EndFunc  ;==>SetTrans

Func addRegion($a, $b, $c, $d)
    Local $aMask
    $aMask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $a, "long", $b, "long", $c + 1, "long", $d + 1)
    DllCall("gdi32.dll", "long", "CombineRgn", "long", $aM_Mask[0], "long", $aMask[0], "long", $aM_Mask[0], "int", 3)
EndFunc  ;==>addRegion
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...