possible to change cursor without GUI/OnMessage? Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jeeswg
Posts: 5430
Joined: 19 Dec 2016, 01:58
Location: UK

possible to change cursor without GUI/OnMessage?

06 Jan 2017, 22:07

Is it possible to change the cursor without using GUI/OnMessage?
I.e. methods on AutoHotkey for changing the cursor
usually rely on creating a GUI that the user hovers over.

Is it possible to change the cursor without using GUI commands first of all,
and then secondly without using OnMessage?

Btw a good example of the GUI/OnMessage method is here:
How to properly change the mouse cursor on control hovering - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/5370 ... -hovering/
x32
Posts: 85
Joined: 25 Nov 2016, 16:44

Re: possible to change cursor without GUI/OnMessage?  Topic is solved

06 Jan 2017, 22:46

You can try this library called Cursor.ahk. I have no idea who wrote it.

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     Cursor Functions     ;;;;;;;;;;;;;;;;;;;;;;;;

Cursor_Restore()
{
   SPI_SETCURSORS := 0x57
   DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
}

Cursor_Set( Cursor = "", cx = 0, cy = 0 )
{
   BlankCursor := 0, SystemCursor := 0, FileCursor := 0 ; init
   
   SystemCursors = 32512IDC_ARROW,32513IDC_IBEAM,32514IDC_WAIT,32515IDC_CROSS
   ,32516IDC_UPARROW,32640IDC_SIZE,32641IDC_ICON,32642IDC_SIZENWSE
   ,32643IDC_SIZENESW,32644IDC_SIZEWE,32645IDC_SIZENS,32646IDC_SIZEALL
   ,32648IDC_NO,32649IDC_HAND,32650IDC_APPSTARTING,32651IDC_HELP
   
   If Cursor = ; empty, so create blank cursor
   {
      VarSetCapacity( AndMask, 32*4, 0xFF ), VarSetCapacity( XorMask, 32*4, 0 )
      BlankCursor = 1 ; flag for later
   }
   Else If SubStr( Cursor,1,4 ) = "IDC_" ; load system cursor
   {
      Loop, Parse, SystemCursors, `,
      {
         CursorName := SubStr( A_Loopfield, 6, 15 ) ; get the cursor name, no trailing space with substr
         CursorID := SubStr( A_Loopfield, 1, 5 ) ; get the cursor id
         SystemCursor = 1
         If ( CursorName = Cursor )
         {
            CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )   
            Break               
         }
      }   
      If CursorHandle = ; invalid cursor name given
      {
         Msgbox,, SetCursor, Error: Invalid cursor name
         CursorHandle = Error
      }
   }   
   Else If FileExist( Cursor )
   {
      SplitPath, Cursor,,, Ext ; auto-detect type
      If Ext = ico
         uType := 0x1   
      Else If Ext in cur,ani
         uType := 0x2     
      Else ; invalid file ext
      {
         Msgbox,, SetCursor, Error: Invalid file type
         CursorHandle = Error
      }     
      FileCursor = 1
   }
   Else
   {   
      Msgbox,, SetCursor, Error: Invalid file path or cursor name
      CursorHandle = Error ; raise for later
   }
   If CursorHandle != Error
   {
      Loop, Parse, SystemCursors, `,
      {
         If BlankCursor = 1
         {
            Type = BlankCursor
            %Type%%A_Index% := DllCall( "CreateCursor"
            , Uint,0, Int,0, Int,0, Int,32, Int,32, Uint,&AndMask, Uint,&XorMask )
            CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
            DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
         }         
         Else If SystemCursor = 1
         {
            Type = SystemCursor
            CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )   
            %Type%%A_Index% := DllCall( "CopyImage"
            , Uint,CursorHandle, Uint,0x2, Int,cx, Int,cy, Uint,0 )     
            CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
            DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
         }
         Else If FileCursor = 1
         {
            Type = FileCursor
            %Type%%A_Index% := DllCall( "LoadImageA"
            , UInt,0, Str,Cursor, UInt,uType, Int,cx, Int,cy, UInt,0x10 )
            DllCall( "SetSystemCursor", Uint,%Type%%A_Index%, Int,SubStr( A_Loopfield, 1, 5 ) )         
         }         
      }
   }   
}
User avatar
jeeswg
Posts: 5430
Joined: 19 Dec 2016, 01:58
Location: UK

Re: possible to change cursor without GUI/OnMessage?

06 Jan 2017, 23:31

Wow it works! So glad I asked, many thanks for this!

Code: Select all

q::
w::
Cursor_Set("IDC_HAND")
Sleep 4000
Cursor_Restore()
Return
x32
Posts: 85
Joined: 25 Nov 2016, 16:44

Re: possible to change cursor without GUI/OnMessage?

07 Jan 2017, 00:02

Glad I (and some unnamed person) could help.

Return to “Ask For Help”

Who is online

Users browsing this forum: colt, hanslhansl, Regath, vvhitevvizard and 46 guests