AutoHotkey Community

It is currently May 27th, 2012, 3:33 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Hiding the mouse cursor
PostPosted: October 30th, 2005, 11:45 pm 
Offline

Joined: July 20th, 2005, 4:49 am
Posts: 65
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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2005, 12:08 am 
Offline

Joined: July 20th, 2005, 4:49 am
Posts: 65
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2005, 12:30 am 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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).


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2005, 12:34 am 
Offline

Joined: July 20th, 2005, 4:49 am
Posts: 65
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2005, 1:05 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2005, 1:46 am 
Offline

Joined: July 20th, 2005, 4:49 am
Posts: 65
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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2005, 6:17 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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 )
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2005, 11:00 am 
Offline

Joined: July 20th, 2005, 4:49 am
Posts: 65
Thanks Mate. This should work well!

It took me a bit of time to work out exactly what the script was doing.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2005, 8:58 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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 November 2nd, 2005, 8:43 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2005, 11:07 pm 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2005, 11:24 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 1st, 2005, 1:03 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 1st, 2005, 1:29 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 1st, 2005, 10:54 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
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 November 2nd, 2005, 8:16 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 2nd, 2005, 1:16 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
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.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Google Feedfetcher, Wicked, Yahoo [Bot] and 13 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group