AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Hiding the mouse cursor
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
MisterW



Joined: 20 Jul 2005
Posts: 65

PostPosted: Sun Oct 30, 2005 11:45 pm    Post subject: Hiding the mouse cursor Reply with quote

How can I:

a) Hide the mouse cursor
b) Change it (very temporarily) to something else while performing an action

I suspect I need a DLL call?
Back to top
View user's profile Send private message
MisterW



Joined: 20 Jul 2005
Posts: 65

PostPosted: Mon Oct 31, 2005 12:08 am    Post subject: Reply with quote

This sort of works, but it's slow (takes a while to take effect) and the cursor appears again as soon as I move the mouse.

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.
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4425
Location: Pittsburgh

PostPosted: Mon Oct 31, 2005 12:30 am    Post subject: Reply with quote

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).
Back to top
View user's profile Send private message
MisterW



Joined: 20 Jul 2005
Posts: 65

PostPosted: Mon Oct 31, 2005 12:34 am    Post subject: Reply with quote

Laszlo wrote:
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.
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10692

PostPosted: Mon Oct 31, 2005 1:05 am    Post subject: Reply with quote

Others have had success hiding the cursor with Corrupt's nomousy.

I think there's also a way to do it with DllCall and the DirectX API, but I haven't researched it enough yet.
Back to top
View user's profile Send private message Send e-mail
MisterW



Joined: 20 Jul 2005
Posts: 65

PostPosted: Mon Oct 31, 2005 1:46 am    Post subject: Reply with quote

Chris wrote:
Others have had success hiding the cursor with Corrupt's nomousy.

Thanks Chris, I'll check it out.

Is the source for nomousy available?
Back to top
View user's profile Send private message
shimanov



Joined: 25 Sep 2005
Posts: 612

PostPosted: Mon Oct 31, 2005 6:17 am    Post subject: Reply with quote

Try the following:

Code:
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 )
}
Back to top
View user's profile Send private message
MisterW



Joined: 20 Jul 2005
Posts: 65

PostPosted: Mon Oct 31, 2005 11:00 am    Post subject: Reply with quote

Thanks Mate. This should work well!

It took me a bit of time to work out exactly what the script was doing.
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4425
Location: Pittsburgh

PostPosted: Mon Oct 31, 2005 8:58 pm    Post subject: Reply with quote

Thanks, Shimanov! That's great!

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.


Last edited by Laszlo on Wed Nov 02, 2005 8:43 pm; edited 1 time in total
Back to top
View user's profile Send private message
shimanov



Joined: 25 Sep 2005
Posts: 612

PostPosted: Mon Oct 31, 2005 11:07 pm    Post subject: Reply with quote

Laszlo wrote:
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.
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4425
Location: Pittsburgh

PostPosted: Mon Oct 31, 2005 11:24 pm    Post subject: Reply with quote

shimanov wrote:
the "ghost" effect when moving or hovering over controls while the cursors are hidden
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?
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10692

PostPosted: Tue Nov 01, 2005 1:03 am    Post subject: Reply with quote

Great script. It seems to hide the cursor very well.

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.
Back to top
View user's profile Send private message Send e-mail
shimanov



Joined: 25 Sep 2005
Posts: 612

PostPosted: Tue Nov 01, 2005 1:29 am    Post subject: Reply with quote

Laszlo wrote:
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.
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4425
Location: Pittsburgh

PostPosted: Tue Nov 01, 2005 10:54 pm    Post subject: Reply with quote

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. Is it true? If yes, we could save a few more lines of code:
Code:
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.


Last edited by Laszlo on Wed Nov 02, 2005 8:16 pm; edited 1 time in total
Back to top
View user's profile Send private message
shimanov



Joined: 25 Sep 2005
Posts: 612

PostPosted: Wed Nov 02, 2005 1:16 am    Post subject: Reply with quote

Laszlo wrote:
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.

CreateCursor wrote:
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 ...

SetCursor wrote:
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.


Quote:
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.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group