show_Mouse()

Post your working scripts, libraries and tools for AHK v1.1 and older
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

show_Mouse()

02 Oct 2017, 11:28

Original (2008) taken from here: https://autohotkey.com/board/topic/3260 ... em-cursor/ by Serenity.
I have rewritten the function, so that I can understand the code. I share my result with you, maybe this helps someone out there.

Code: Select all

;-------------------------------------------------------------------------------
show_Mouse(bShow := True) { ; show/hide the mouse cursor
;-------------------------------------------------------------------------------
    ; WINAPI: SystemParametersInfo, CreateCursor, CopyImage, SetSystemCursor
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648385.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648031.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648395.aspx
    ;---------------------------------------------------------------------------
    static BlankCursor
    static CursorList := "32512, 32513, 32514, 32515, 32516, 32640, 32641"
        . ",32642, 32643, 32644, 32645, 32646, 32648, 32649, 32650, 32651"
    local ANDmask, XORmask, CursorHandle

    If bShow ; shortcut for showing the mouse cursor

        Return, DllCall("SystemParametersInfo"
            , "UInt", 0x57              ; UINT  uiAction    (SPI_SETCURSORS)
            , "UInt", 0                 ; UINT  uiParam
            , "Ptr",  0                 ; PVOID pvParam
            , "UInt", 0                 ; UINT  fWinIni
            , "Cdecl Int")              ; return BOOL

    If Not BlankCursor { ; create BlankCursor only once
        VarSetCapacity(ANDmask, 32 * 4, 0xFF)
        VarSetCapacity(XORmask, 32 * 4, 0x00)

        BlankCursor := DllCall("CreateCursor"
            , "Ptr", 0                  ; HINSTANCE  hInst
            , "Int", 0                  ; int        xHotSpot
            , "Int", 0                  ; int        yHotSpot
            , "Int", 32                 ; int        nWidth
            , "Int", 32                 ; int        nHeight
            , "Ptr", &ANDmask           ; const VOID *pvANDPlane
            , "Ptr", &XORmask           ; const VOID *pvXORPlane
            , "Cdecl Ptr")              ; return HCURSOR
    }

    ; set all system cursors to blank, each needs a new copy
    Loop, Parse, CursorList, `,, %A_Space%
    {
        CursorHandle := DllCall("CopyImage"
            , "Ptr",  BlankCursor       ; HANDLE hImage
            , "UInt", 2                 ; UINT   uType      (IMAGE_CURSOR)
            , "Int",  0                 ; int    cxDesired
            , "Int",  0                 ; int    cyDesired
            , "UInt", 0                 ; UINT   fuFlags
            , "Cdecl Ptr")              ; return HANDLE

        DllCall("SetSystemCursor"
            , "Ptr",  CursorHandle      ; HCURSOR hcur
            , "UInt", A_Loopfield       ; DWORD   id
            , "Cdecl Int")              ; return BOOL
    }
}
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: show_Mouse()

02 Oct 2017, 11:48

Helgef wrote:[...] uses the WINAPI calling convention
, which is defined as stdcall
, which is the default for DllCall
, hence, cdecl should be omitted.
Thank you for sharing valuable information. :thumbup:

Code: Select all

;-------------------------------------------------------------------------------
show_Mouse(bShow := True) { ; show/hide the mouse cursor
;-------------------------------------------------------------------------------
    ; WINAPI: SystemParametersInfo, CreateCursor, CopyImage, SetSystemCursor
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648385.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648031.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648395.aspx
    ;---------------------------------------------------------------------------
    static BlankCursor
    static CursorList := "32512, 32513, 32514, 32515, 32516, 32640, 32641"
        . ",32642, 32643, 32644, 32645, 32646, 32648, 32649, 32650, 32651"
    local ANDmask, XORmask, CursorHandle

    If bShow ; shortcut for showing the mouse cursor

        Return, DllCall("SystemParametersInfo" ; returns BOOL
            , "UInt", 0x57              ; UINT  uiAction    (SPI_SETCURSORS)
            , "UInt", 0                 ; UINT  uiParam
            , "Ptr",  0                 ; PVOID pvParam
            , "UInt", 0)                ; UINT  fWinIni

    If Not BlankCursor { ; create BlankCursor only once
        VarSetCapacity(ANDmask, 32 * 4, 0xFF)
        VarSetCapacity(XORmask, 32 * 4, 0x00)

        BlankCursor := DllCall("CreateCursor" ; returns HCURSOR
            , "Ptr", 0                  ; HINSTANCE  hInst
            , "Int", 0                  ; int        xHotSpot
            , "Int", 0                  ; int        yHotSpot
            , "Int", 32                 ; int        nWidth
            , "Int", 32                 ; int        nHeight
            , "Ptr", &ANDmask           ; const VOID *pvANDPlane
            , "Ptr", &XORmask)          ; const VOID *pvXORPlane
    }

    ; set all system cursors to blank, each needs a new copy
    Loop, Parse, CursorList, `,, %A_Space%
    {
        CursorHandle := DllCall("CopyImage" ; returns HANDLE
            , "Ptr",  BlankCursor       ; HANDLE hImage
            , "UInt", 2                 ; UINT   uType      (IMAGE_CURSOR)
            , "Int",  0                 ; int    cxDesired
            , "Int",  0                 ; int    cyDesired
            , "UInt", 0)                ; UINT   fuFlags

        DllCall("SetSystemCursor" ; returns BOOL
            , "Ptr",  CursorHandle      ; HCURSOR hcur
            , "UInt", A_Loopfield)      ; DWORD   id
    }
}
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: show_Mouse()

02 Oct 2017, 11:51

Thanks for sharing wolf_II.
Some of my non-working code tries to hide the cursor using the ShowCursor (msdn), but that only works for the calling application. This works great!
Note that you should always have an onExit routine turning on the cursor again. The hiding persits on application exit if not restored. You could add one of those {__delete:cleanUp} static variables ;)
Edit: Re: cdecl, specifying "Ptr" for the return is still correct for the cursor handles, this probably doesn't matter though, but I like having it.
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: show_Mouse()

02 Oct 2017, 12:17

Thanks for the suggestion, Helgef, very useful!

This is an example that does not explicitly show the cursor. (done by commenting the respective line)
But since the function now takes care of it, exiting the script will no longer leave the system in an undesired state of interference.

Code: Select all

;-------------------------------------------------------------------------------
; this example hides the mouse cursor for 5 seconds, then omits to show it again
;-------------------------------------------------------------------------------
    show_Mouse(False)
    Sleep, 5000
    ;~ show_Mouse(True)

ExitApp ; end of auto-execute section



;-------------------------------------------------------------------------------
show_Mouse(bShow := True) { ; show/hide the mouse cursor
;-------------------------------------------------------------------------------
    ; WINAPI: SystemParametersInfo, CreateCursor, CopyImage, SetSystemCursor
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648385.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648031.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648395.aspx
    ;---------------------------------------------------------------------------
    static BlankCursor, CleanUp := {base: {__Delete: "show_Mouse"}}
    static CursorList := "32512, 32513, 32514, 32515, 32516, 32640, 32641"
        . ",32642, 32643, 32644, 32645, 32646, 32648, 32649, 32650, 32651"
    local ANDmask, XORmask, CursorHandle

    If bShow                    ; shortcut for showing the mouse cursor
    Or Not IsObject(CleanUp)    ; always reset mouse on exit

        Return, DllCall("SystemParametersInfo" ; dll returns BOOL
            , "UInt", 0x57              ; UINT  uiAction    (SPI_SETCURSORS)
            , "UInt", 0                 ; UINT  uiParam
            , "Ptr",  0                 ; PVOID pvParam
            , "UInt", 0)                ; UINT  fWinIni

    If Not BlankCursor { ; create BlankCursor only once
        VarSetCapacity(ANDmask, 32 * 4, 0xFF)
        VarSetCapacity(XORmask, 32 * 4, 0x00)

        BlankCursor := DllCall("CreateCursor" ; dll returns HCURSOR
            , "Ptr", 0                  ; HINSTANCE  hInst
            , "Int", 0                  ; int        xHotSpot
            , "Int", 0                  ; int        yHotSpot
            , "Int", 32                 ; int        nWidth
            , "Int", 32                 ; int        nHeight
            , "Ptr", &ANDmask           ; const VOID *pvANDPlane
            , "Ptr", &XORmask)          ; const VOID *pvXORPlane
    }

    ; set all system cursors to blank, each needs a new copy
    Loop, Parse, CursorList, `,, %A_Space%
    {
        CursorHandle := DllCall("CopyImage" ; dll returns HANDLE
            , "Ptr",  BlankCursor       ; HANDLE hImage
            , "UInt", 2                 ; UINT   uType      (IMAGE_CURSOR)
            , "Int",  0                 ; int    cxDesired
            , "Int",  0                 ; int    cyDesired
            , "UInt", 0)                ; UINT   fuFlags

        DllCall("SetSystemCursor" ; dll returns BOOL
            , "Ptr",  CursorHandle      ; HCURSOR hcur
            , "UInt", A_Loopfield)      ; DWORD   id
    }
}
I highly appreciate your input. :D :thumbup: :clap:
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: show_Mouse()

02 Oct 2017, 12:40

Great :thumbup: .
Minor comment, in this case Or Not IsObject(CleanUp) is not needed, because when __delete is called, the object (cleanUp) is passed as the first parameter, i.e., bShow, and if object is true.
For visualisation purposes, you can try this,

Code: Select all

static CleanUp := {base: {__Delete: "show_Mouse"}, name:"cleanUp" }
; ...
If bShow                    ; shortcut for showing the mouse cursor
{		
	msgbox % isObject(bShow) "`n" bshow.name
        Return, DllCall("SystemParametersInfo" ; dll returns BOOL
            , "UInt", 0x57              ; UINT  uiAction    (SPI_SETCURSORS)
            , "UInt", 0                 ; UINT  uiParam
            , "Ptr",  0                 ; PVOID pvParam
            , "UInt", 0)                ; UINT  fWinIni
}
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: show_Mouse()

02 Oct 2017, 12:45

Re: cdecl

I understand/interpret the Helpfile and your various posts as follows:
  • if return TYPE is (BOOL, int or nothing at all) -> omit cdecl
  • else (e.g. HANDLE = "UInt") -> use cdecl
I should not omit them 4x or use them 4x (as I did previously), I should use them where appropriate. Did I get that right?

I still have to mentally process your most recent post ... please stand by ...
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: show_Mouse()

02 Oct 2017, 13:08

With all the suggestions implemented:

Code: Select all

;-------------------------------------------------------------------------------
; this example hides the mouse cursor for 5 seconds, then omits to show it again
;-------------------------------------------------------------------------------
    show_Mouse(False)
    Sleep, 5000
    ;~ show_Mouse(True)

ExitApp ; end of auto-execute section



;-------------------------------------------------------------------------------
show_Mouse(bShow := True) { ; show/hide the mouse cursor
;-------------------------------------------------------------------------------
    ; WINAPI: SystemParametersInfo, CreateCursor, CopyImage, SetSystemCursor
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648385.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648031.aspx
    ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms648395.aspx
    ;---------------------------------------------------------------------------
    static BlankCursor, CleanUp := {base: {__Delete: "show_Mouse"}}
    static CursorList := "32512, 32513, 32514, 32515, 32516, 32640, 32641"
        . ",32642, 32643, 32644, 32645, 32646, 32648, 32649, 32650, 32651"
    local ANDmask, XORmask, CursorHandle

    If bShow ; shortcut for showing the mouse cursor, also RESETS MOUSE on exit
             ; https://autohotkey.com/boards/viewtopic.php?p=173756#p173756

        Return, DllCall("SystemParametersInfo" ; dll returns BOOL
            , "UInt", 0x57              ; UINT  uiAction    (SPI_SETCURSORS)
            , "UInt", 0                 ; UINT  uiParam
            , "Ptr",  0                 ; PVOID pvParam
            , "UInt", 0)                ; UINT  fWinIni

    If Not BlankCursor { ; create BlankCursor only once
        VarSetCapacity(ANDmask, 32 * 4, 0xFF)
        VarSetCapacity(XORmask, 32 * 4, 0x00)

        BlankCursor := DllCall("CreateCursor" ; dll returns HCURSOR
            , "Ptr", 0                  ; HINSTANCE  hInst
            , "Int", 0                  ; int        xHotSpot
            , "Int", 0                  ; int        yHotSpot
            , "Int", 32                 ; int        nWidth
            , "Int", 32                 ; int        nHeight
            , "Ptr", &ANDmask           ; const VOID *pvANDPlane
            , "Ptr", &XORmask           ; const VOID *pvXORPlane
            , "Ptr")                    ; return HCURSOR
    }

    ; set all system cursors to blank, each needs a new copy
    Loop, Parse, CursorList, `,, %A_Space%
    {
        CursorHandle := DllCall("CopyImage" ; dll returns HANDLE
            , "Ptr",  BlankCursor       ; HANDLE hImage
            , "UInt", 2                 ; UINT   uType      (IMAGE_CURSOR)
            , "Int",  0                 ; int    cxDesired
            , "Int",  0                 ; int    cyDesired
            , "UInt", 0                 ; UINT   fuFlags
            , "Ptr")                    ; return HANDLE

        DllCall("SetSystemCursor" ; dll returns BOOL
            , "Ptr",  CursorHandle      ; HCURSOR hcur
            , "UInt", A_Loopfield)      ; DWORD   id
    }
}
Edit: I replaced both occurrences of "cdecl Ptr" with "Ptr" only.
Last edited by wolf_II on 03 Oct 2017, 04:01, edited 1 time in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: show_Mouse()

03 Oct 2017, 01:13

wolf_II wrote:Re: cdecl
I understand/interpret the Helpfile and your various posts as follows
I mean you can still have "ptr" for the return, even when omitting cdecl. You should omit cdecl because the functions use the WINAPI (stdcall) calling convention, not cdecl. There was a brief discussion recently, in particular, just me's links might interest you.
Cheers.
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: show_Mouse()

03 Oct 2017, 03:58

OMG, what have I done? I clearly have got no idea what is involved, apart from having no idea how stuff works (which I knew already).
I mean, not only do I not know things, I also do not know the extend of my ignorance. :oops: :o :facepalm:

Second attempt at cdecl: I should leave the "cdecl" out altogether from WINAPI calls. But I should put "Ptr" or similar, when return TYPE is not (BOOL, int or nothing at all).

I will edit the most recently posted function above accordingly.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: show_Mouse()

03 Oct 2017, 07:47

wolf_II wrote: not only do I not know things, I also do not know the extend of my ignorance.
Once realised and accepted, life gets so much easier :angel:
wolf_II wrote:Second attempt at cdecl:
Perfect :clap:
Cheers.
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: show_Mouse()

03 Oct 2017, 09:37

Helgef wrote:Once realised and accepted, life gets so much easier :angel:
LOL :lol:

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: fiendhunter and 228 guests