Hiding the mouse cursor
a) Hide the mouse cursor
Change it (very temporarily) to something else while performing an action
I suspect I need a DLL call?
DllCall("ShowCursor","Uint",0)
Interestingly, the showcount is not reset to zero once the cursor is made visible again by moving the mouse. It stays at it's negative value and can be decremented further by repeatedly executing this call. The reverse of this call seems to have no effect on making the cursor visible again.
DllCall("ShowCursor","Uint",0) does not do anything in my laptop (XP SP2). Even calling it in a loop hundreds of times does not hide a cursor (in 2-3 minutes).
Yeah, I think you're right.
It was only working for me because I had my cursor over a vim window and triggering a hotkey to hide the cursor also tells vim to hide the cursor. It hides the cursor when you start typing | press a key.
An unfortunate false positive.
loop, 13 ToggleSystemCursor( A_Index, true ) MsgBox, Just in time for Halloween ... loop, 13 ToggleSystemCursor( A_Index ) return ToggleSystemCursor( p_id, p_hide=false ) { /* OCR_NORMAL IDC_ARROW 32512 1 OCR_IBEAM IDC_IBEAM 32513 2 OCR_WAIT IDC_WAIT 32514 3 OCR_CROSS IDC_CROSS 32515 4 OCR_UP IDC_UPARROW 32516 5 OCR_SIZENWSE IDC_SIZENWSE 32642 6 OCR_SIZENESW IDC_SIZENESW 32643 7 OCR_SIZEWE IDC_SIZEWE 32644 8 OCR_SIZENS IDC_SIZENS 32645 9 OCR_SIZEALL IDC_SIZEALL 32646 10 OCR_NO IDC_NO 32648 11 OCR_HAND IDC_HAND 32649 12 OCR_APPSTARTING IDC_APPSTARTING 32650 13 */ static system_cursor_list if system_cursor_list= system_cursor_list = |1:32512|2:32513|3:32514|4:32515|5:32516|6:32642|7:32643|8:32644|9:32645|10:32646|11:32648|12:32649|13:32650| ix := InStr( system_cursor_list, "|" p_id ) ix := InStr( system_cursor_list, ":", false, ix )+1 StringMid, id, system_cursor_list, ix, 5 ix_b := ix+6 ix_e := InStr( system_cursor_list, "|", false, ix )-1 SysGet, cursor_w, 13 SysGet, cursor_h, 14 if ( cursor_w != 32 or cursor_h != 32 ) { MsgBox, System parameters not supported! return } if ( p_hide ) { if ( ix_b < ix_e ) return h_cursor := DllCall( "LoadCursor", "uint", 0, "uint", id ) h_cursor := DllCall( "CopyImage", "uint", h_cursor, "uint", 2, "int", 0, "int", 0, "uint", 0 ) StringReplace, system_cursor_list, system_cursor_list, |%p_id%:%id%, |%p_id%:%id%`,%h_cursor% VarSetCapacity( AndMask, 32*4, 0xFF ) VarSetCapacity( XorMask, 32*4, 0 ) h_cursor := DllCall( "CreateCursor" , "uint", 0 , "int", 0 , "int", 0 , "int", cursor_w , "int", cursor_h , "uint", &AndMask , "uint", &XorMask ) } else { if ( ix_b > ix_e ) return StringMid, h_cursor, system_cursor_list, ix_b, ix_e-ix_b+1 StringReplace, system_cursor_list, system_cursor_list, |%p_id%:%id%`,%h_cursor%, |%p_id%:%id% } result := DllCall( "SetSystemCursor", "uint", h_cursor, "uint", id ) }
It took me a bit of time to work out exactly what the script was doing.
I could not resist, but modified your script a bit: At the first call all the blank cursors are created and saved along to the current cursors, in two static arrays. Later only the desired set has to be loaded in a loop. It should be faster and easier to understand.
The script is extended further: with a Toggle parameter: change On/Off; there is a parameter value "Init" or "I" to force re-initialization (after the system cursors changed).
Edit: see the script in my next post.
Thanks, Shimanov! That's great!
Did you notice the "ghost" effect when moving or hovering over controls while the cursors are hidden?
Kind of cool and appropriate on this, the day of All Hallow's Eve.
It is cool! What are the appropriate system calls to make me invisible, too, but still be able to press buttons and pop up balloon texts?the "ghost" effect when moving or hovering over controls while the cursors are hidden
This script is perfect candidate for the standard library, which when it gets launched will be distributed with the program as a set of includable files.
Thanks for sharing it.
What are the appropriate system calls to make me invisible, too, but still be able to press buttons and pop up balloon texts?
This knowledge has eluded all of us since time immemorial. Though enlightenment will be ours in the end.
Loop 9 { x := !x SystemCursor(x) MsgBox CURSOR VISIBLE = %x% } SystemCursor(OnOff=1) ; INIT = "I","Init"; OFF = 0,"Off"; TOGGLE = -1,"T","Toggle"; ON = others { static AndMask, XorMask, $, h_cursor ,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13 ; system cursors , b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13 ; blank cursors , h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13 ; handles of default cursors if (OnOff = "Init" or OnOff = "I" or $ = "") ; init when requested or at first call { $ = h ; active default cursors VarSetCapacity( h_cursor,4444, 1 ) VarSetCapacity( AndMask, 32*4, 0xFF ) VarSetCapacity( XorMask, 32*4, 0 ) system_cursors = 32512,32513,32514,32515,32516,32642,32643,32644,32645,32646,32648,32649,32650 StringSplit c, system_cursors, `, Loop %c0% { h_cursor := DllCall( "LoadCursor", "uint",0, "uint",c%A_Index% ) h%A_Index% := DllCall( "CopyImage", "uint",h_cursor, "uint",2, "int",0, "int",0, "uint",0 ) b%A_Index% := DllCall("CreateCursor","uint",0, "int",0, "int",0 , "int",32, "int",32, "uint",&AndMask, "uint",&XorMask ) } } if (OnOff = 0 or OnOff = "Off" or $ = "h" and (OnOff < 0 or OnOff = "Toggle" or OnOff = "T")) $ = b ; use blank cursors else $ = h ; use the saved cursors Loop %c0% { h_cursor := DllCall( "CopyImage", "uint",%$%%A_Index%, "uint",2, "int",0, "int",0, "uint",0 ) DllCall( "SetSystemCursor", "uint",h_cursor, "uint",c%A_Index% ) } }Another question: when the pointer becomes a hand sign, it becomes visible even when other cursors are not. Is it a bug or a feature?
Edit: make a copy of the cursor before SetSystemCursor, which destroyes it.
It looks like the size of the standard Windows cursors (even the extra large pointer set) is always 32 pixels. The invisible cursors can be made just 1 pixel large, so we could drop acquiring the cursor parameters.
That may be true, but it isn't documented as such. If it works, then great.
The nWidth and nHeight parameters must specify a width and height that are supported by the current display driver, because the system cannot create cursors of other sizes. To determine the width and height supported by the display driver, use the GetSystemMetrics function, specifying the SM_CXCURSOR or SM_CYCURSOR value.
although ...
Windows 95/98/Me: The width and height of the cursor must be the values returned by the GetSystemMetrics function for SM_CXCURSOR and SM_CYCURSOR.
when the pointer becomes a hand sign, it becomes visible even when other cursors are not. Is it a bug or a feature?
Maybe neither. The "hand sign" cursor could be assigned to appear in multiple contexts. Furthermore, it is possible that each window assigns a custom cursor or, at least, reinstates the original cursor.