Original by Serenity - https://autohotkey.com/board/topic/32608-changing-the-system-cursor/
I touched up the code and fixed its logic.
- SetSystemCursor() - Changes all cursors to invisible. Now over 10% faster.
- SetSystemCursor("Cross") - Changes all cursors to the same resource. Now over 10% faster.
- SetSystemCursor("Working.ani") - Loads an animated cursor from a file. Now over 200% faster.
- Fix memory leaks.
- Animated Cursors on Serenity's original script never worked on AutoHotkey Unicode.
- Cursor names are consistent with AutoHotkey's A_Cursor. The IDC_ prefix can be omitted.
- Removed obsolete cursors IDC_ICON and IDC_SIZE. They were only valid on Windows 95 and earlier.
Code: Select all
; Source: Serenity - https://autohotkey.com/board/topic/32608-changing-the-system-cursor/
; Modified: iseahound - https://www.autohotkey.com/boards/viewtopic.php?t=75867
SetSystemCursor(Cursor := "", cx := 0, cy := 0) {
static SystemCursors := {APPSTARTING: 32650, ARROW: 32512, CROSS: 32515, HAND: 32649, HELP: 32651, IBEAM: 32513, NO: 32648
, SIZEALL: 32646, SIZENESW: 32643, SIZENS: 32645, SIZENWSE: 32642, SIZEWE: 32644, UPARROW: 32516, WAIT: 32514}
if (Cursor = "") {
VarSetCapacity(AndMask, 128, 0xFF), VarSetCapacity(XorMask, 128, 0)
for CursorName, CursorID in SystemCursors {
CursorHandle := DllCall("CreateCursor", "ptr", 0, "int", 0, "int", 0, "int", 32, "int", 32, "ptr", &AndMask, "ptr", &XorMask, "ptr")
DllCall("SetSystemCursor", "ptr", CursorHandle, "int", CursorID) ; calls DestroyCursor
}
return
}
if (Cursor ~= "^(IDC_)?(?i:AppStarting|Arrow|Cross|Hand|Help|IBeam|No|SizeAll|SizeNESW|SizeNS|SizeNWSE|SizeWE|UpArrow|Wait)$") {
Cursor := RegExReplace(Cursor, "^IDC_")
if !(CursorShared := DllCall("LoadCursor", "ptr", 0, "ptr", SystemCursors[Cursor], "ptr"))
throw Exception("Error: Invalid cursor name")
for CursorName, CursorID in SystemCursors {
CursorHandle := DllCall("CopyImage", "ptr", CursorShared, "uint", 2, "int", cx, "int", cy, "uint", 0, "ptr")
DllCall("SetSystemCursor", "ptr", CursorHandle, "int", CursorID) ; calls DestroyCursor
}
return
}
if FileExist(Cursor) {
SplitPath Cursor,,, Ext ; auto-detect type
if !(uType := (Ext = "ani" || Ext = "cur") ? 2 : (Ext = "ico") ? 1 : 0)
throw Exception("Error: Invalid file type")
if (Ext = "ani") {
for CursorName, CursorID in SystemCursors {
CursorHandle := DllCall("LoadImage", "ptr", 0, "str", Cursor, "uint", uType, "int", cx, "int", cy, "uint", 0x10, "ptr")
DllCall("SetSystemCursor", "ptr", CursorHandle, "int", CursorID) ; calls DestroyCursor
}
} else {
if !(CursorShared := DllCall("LoadImage", "ptr", 0, "str", Cursor, "uint", uType, "int", cx, "int", cy, "uint", 0x8010, "ptr"))
throw Exception("Error: Corrupted file")
for CursorName, CursorID in SystemCursors {
CursorHandle := DllCall("CopyImage", "ptr", CursorShared, "uint", 2, "int", 0, "int", 0, "uint", 0, "ptr")
DllCall("SetSystemCursor", "ptr", CursorHandle, "int", CursorID) ; calls DestroyCursor
}
}
return
}
throw Exception("Error: Invalid file path or cursor name")
}
RestoreCursor() {
return DllCall("SystemParametersInfo", "uint", SPI_SETCURSORS := 0x57, "uint", 0, "ptr", 0, "uint", 0)
}