Jump to content

Restoring the cursor after changing it with LoadCursorFromFile and SetSystemCursor?


Recommended Posts

I'm trying to restore the previous cursor after changing the cursor with the LoadCursorFromFile function I found. The problem is that I can't figure out how to restore it, and the code snippets here don't seem to work with the LoadCursorFromFile function, only LoadCursor. I found this thread here; and, using the helpful threads made before on this forum, I've gotten this much:

Global Const $OCR_NORMAL = 32512
Global Const $OCR_IBEAM = 32513
Global Const $OCR_WAIT = 32514

$GUI = GUICreate("Test")
GUISetState()
Local $hWaitCur

$hPrevCur = _CopyCursor($OCR_NORMAL)
$curPath = @WindowsDir & "\Cursors\arrow_m.cur"
$newCur = _LoadCursorFromFile($curPath)
_SetSystemCursor($newCur, $OCR_NORMAL)

While 1
    If GUIGetMsg() = -3 Then ExitLoop
    Sleep(10)
WEnd

_SetSystemCursor($hPrevCur, $OCR_NORMAL)
$hPrevCur = 0
$hWaitCur = 0

Func _LoadCursorFromFile($iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "LoadCursorFromFile", "str", $iCursor)))
EndFunc

Func _LoadCursor($iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "LoadCursorA", "hwnd", 0, "int", $iCursor)))
EndFunc  ;==>_LoadCursor

Func _SetSystemCursor($hCursor, $iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "SetSystemCursor", "int", $hCursor, "int", $iCursor)))
EndFunc  ;==>_SetSystemCursor

Func _CopyCursor($iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "CopyCursor", "hwnd", $iCursor)))
EndFunc

Func _DestroyCursor($iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "DestroyCursor", "hwnd", $iCursor)))
EndFunc

Func _API($v_ret)
    Local $err = @error
    Local $ext = @extended
    If Not $err Then
        If IsArray($v_ret) Then
            Return $v_ret[0]
        Else
            Return $v_ret
        EndIf
    EndIf
    Return SetError($err, $ext, 0)
EndFunc  ;==>_API

But it isn't working. Please help me!

Link to comment
Share on other sites

Bump :P

The line

$hPrevCur = _CopyCursor($OCR_NORMAL)

is not right because the function CopyCursor needs a handle to a cursor not an integer for a cursor. If you check the value of $hPrevCur you will find that it is 0.

You need to know where the cursor is kept as a resourse and use LoadImage to get a handle to an image resource. I don't know which dll contains the standard arrow cursor icon :unsure: (Assuming that it is saved in a dll.)

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

Maybe this?

$hPrevCur = _CopyCursor(_LoadCursor($OCR_NORMAL))
What's the point in doing all that @error stuff if you are not going to check for errors.

Try this:

Global Const $OCR_NORMAL = 32512
Global Const $OCR_IBEAM = 32513
Global Const $OCR_WAIT = 32514

;XXXXXXXXXXXXXXX
$hDefaultCursorLoad = _LoadCursor($OCR_NORMAL)

$hDefaultCursor = _CopyCursor($hDefaultCursorLoad)
If @error Then
    Exit ConsoleWrite("! Error copying cursor" & @CRLF)
EndIf
;XXXXXXXXXXXXXXX

$GUI = GUICreate("Test")
GUISetState()
Local $hWaitCur

$curPath = @WindowsDir & "\Cursors\sizenesw.ani"
$newCur = _LoadCursorFromFile($curPath)
_SetSystemCursor($newCur, $OCR_NORMAL)

While 1
    If GUIGetMsg() = -3 Then ExitLoop
    Sleep(10)
WEnd

_SetSystemCursor($hDefaultCursor, $OCR_NORMAL)
$hPrevCur = 0
$hWaitCur = 0

Func _LoadCursorFromFile($iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "LoadCursorFromFile", "str", $iCursor)))
EndFunc  ;==>_LoadCursorFromFile

Func _LoadCursor($iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "LoadCursorA", "hwnd", 0, "int", $iCursor)))
EndFunc  ;==>_LoadCursor

Func _SetSystemCursor($hCursor, $iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "SetSystemCursor", "int", $hCursor, "int", $iCursor)))
EndFunc  ;==>_SetSystemCursor

Func _CopyCursor_($iCursor); <--- check your user32.dll for CopyCursor function. Is it there?
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "CopyCursor", "hwnd", $iCursor)))
EndFunc  ;==>_CopyCursor_

Func _DestroyCursor($iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "DestroyCursor", "hwnd", $iCursor)))
EndFunc  ;==>_DestroyCursor

Func _API($v_ret)
    Local $err = @error
    Local $ext = @extended
    If Not $err Then
        If IsArray($v_ret) Then
            Return $v_ret[0]
        Else
            Return $v_ret
        EndIf
    EndIf
    Return SetError($err, $ext, 0)
EndFunc  ;==>_API


Func _CopyCursor($hCursor)

    Local $aCall = DllCall("user32.dll", "hwnd", "CopyImage", _
            "hwnd", $hCursor, _
            "dword", 2, _; IMAGE_CURSOR
            "int", 0, _; same width as the original
            "int", 0, _; same height as the original
            "dword", 16384); LR_COPYFROMRESOURCE

    If @error Or Not $aCall[0] Then
        Return SetError(1, 0, 0)
    EndIf

    Return SetError(0, 0, $aCall[0])

EndFunc  ;==>_CopyCursor

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Thanks! That code works like a charm!

Yes very good.

LoadCursorA is nowhere to be found on msdn, but if instead you use LoadCursor it still seems to work fine.

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

Yes very good.

LoadCursorA is nowhere to be found on msdn, but if instead you use LoadCursor it still seems to work fine.

Function is exported from out of user32.dll as LoadCursorA (ordinal value 440).

It seems that AutoIt is checking for existance of called function in several steps. One of those steps include adding "A" at the end of the function name.

Same thing is for LoadCursorFromFile (I would prefer LoadCursorFromFileW). SetSystemCursor is there, DestroyCursor also.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

  • 1 month later...

@ all

i use this always. it's simple:

DllCall("user32.dll", "int", "SystemParametersInfo", "int", $SPI_SETCURSORS, "int", 0, "int", 0, "int", 0)

documented in msdn

cheers j.

edit : Global Const $SPI_SETCURSORS = 0x57

Edited by jennico
Spoiler

I actively support Wikileaks | Freedom for Julian Assange ! | Defend freedom of speech ! | Fight censorship ! | I will not silence.OixB7.jpgDon't forget this IP: 213.251.145.96

 

Link to comment
Share on other sites

  • 2 years later...

What's the point in doing all that @error stuff if you are not going to check for errors.

Try this:

Global Const $OCR_NORMAL = 32512
Global Const $OCR_IBEAM = 32513
Global Const $OCR_WAIT = 32514

;XXXXXXXXXXXXXXX
$hDefaultCursorLoad = _LoadCursor($OCR_NORMAL)

$hDefaultCursor = _CopyCursor($hDefaultCursorLoad)
If @error Then
    Exit ConsoleWrite("! Error copying cursor" & @CRLF)
EndIf
;XXXXXXXXXXXXXXX

$GUI = GUICreate("Test")
GUISetState()
Local $hWaitCur

$curPath = @WindowsDir & "\Cursors\sizenesw.ani"
$newCur = _LoadCursorFromFile($curPath)
_SetSystemCursor($newCur, $OCR_NORMAL)

While 1
    If GUIGetMsg() = -3 Then ExitLoop
    Sleep(10)
WEnd

_SetSystemCursor($hDefaultCursor, $OCR_NORMAL)
$hPrevCur = 0
$hWaitCur = 0

Func _LoadCursorFromFile($iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "LoadCursorFromFile", "str", $iCursor)))
EndFunc  ;==>_LoadCursorFromFile

Func _LoadCursor($iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "LoadCursorA", "hwnd", 0, "int", $iCursor)))
EndFunc  ;==>_LoadCursor

Func _SetSystemCursor($hCursor, $iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "SetSystemCursor", "int", $hCursor, "int", $iCursor)))
EndFunc  ;==>_SetSystemCursor

Func _CopyCursor_($iCursor); <--- check your user32.dll for CopyCursor function. Is it there?
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "CopyCursor", "hwnd", $iCursor)))
EndFunc  ;==>_CopyCursor_

Func _DestroyCursor($iCursor)
    Return SetError(@error, @extended, _API(DllCall("user32.dll", "int", "DestroyCursor", "hwnd", $iCursor)))
EndFunc  ;==>_DestroyCursor

Func _API($v_ret)
    Local $err = @error
    Local $ext = @extended
    If Not $err Then
        If IsArray($v_ret) Then
            Return $v_ret[0]
        Else
            Return $v_ret
        EndIf
    EndIf
    Return SetError($err, $ext, 0)
EndFunc  ;==>_API


Func _CopyCursor($hCursor)

    Local $aCall = DllCall("user32.dll", "hwnd", "CopyImage", _
            "hwnd", $hCursor, _
            "dword", 2, _; IMAGE_CURSOR
            "int", 0, _; same width as the original
            "int", 0, _; same height as the original
            "dword", 16384); LR_COPYFROMRESOURCE

    If @error Or Not $aCall[0] Then
        Return SetError(1, 0, 0)
    EndIf

    Return SetError(0, 0, $aCall[0])

EndFunc  ;==>_CopyCursor

The above code works fine, if the current cursor is not an animated one. When I tried with an animated cursor, it was found that, after resetting the cursor is no more animated. I think LoadCursor is only meant for loading the normal(".cur") type cursors, not for animated(".ani") ones. I tried LoadImage instead, but somehow didn't got the expected result. Do any one know a hint to solve this issue?
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...