How to change mouse pointer?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Renfro
Posts: 64
Joined: 15 Oct 2020, 10:19

How to change mouse pointer?

16 Mar 2021, 11:44

How can I temporarily replace the hourglass mouse pointer icon (that displays while a program is loading) with the standard mouse pointer icon?

I have background app that is scripted to load a few times a day, but whenever it starts up it causes my mouse pointer to change to the hourglass icon for at least 30 seconds (it's very slow loading, but it has no impact on system responsiveness).

I would therefore like to add code to force my mouse pointer icon to display the standard pointer icon whenever that particular app is being started (so that no hourglass is seen but there is still a normal arrow pointer) and then automatically return my pointer back to normal, so that when I manually run programs the hourglass displays as it normally would do.
Renfro
Posts: 64
Joined: 15 Oct 2020, 10:19

Re: How to change mouse pointer?

16 Mar 2021, 13:46

Thanks, but I think that's for changing an entire set of icons from one theme to another. Therefore the hourglass icon will still show (but just using one from a different icon set to the main one). That's not what I'm trying to do.
teadrinker
Posts: 4389
Joined: 29 Mar 2015, 09:41
Contact:

Re: How to change mouse pointer?

16 Mar 2021, 14:10

Try this:

Code: Select all

ReplaceSystemCursor("IDC_WAIT", "IDC_ARROW")
Return

Esc:: ExitApp

ReplaceSystemCursor(old := "", new := "")
{
   static IMAGE_CURSOR := 2, SPI_SETCURSORS := 0x57
        , exitFunc := Func("ReplaceSystemCursor").Bind("", "")
        , setOnExit := false
        , SysCursors := { IDC_APPSTARTING: 32650
                        , IDC_ARROW      : 32512
                        , IDC_CROSS      : 32515
                        , IDC_HAND       : 32649
                        , IDC_HELP       : 32651
                        , IDC_IBEAM      : 32513
                        , IDC_NO         : 32648
                        , IDC_SIZEALL    : 32646
                        , IDC_SIZENESW   : 32643
                        , IDC_SIZENWSE   : 32642
                        , IDC_SIZEWE     : 32644
                        , IDC_SIZENS     : 32645 
                        , IDC_UPARROW    : 32516
                        , IDC_WAIT       : 32514 }
   if !old {
      DllCall("SystemParametersInfo", "UInt", SPI_SETCURSORS, "UInt", 0, "UInt", 0, "UInt", 0)
      OnExit(exitFunc, 0), setOnExit := false
   }
   else  {
      hCursor := DllCall("LoadCursor", "Ptr", 0, "UInt", SysCursors[new], "Ptr")
      hCopy := DllCall("CopyImage", "Ptr", hCursor, "UInt", IMAGE_CURSOR, "Int", 0, "Int", 0, "UInt", 0, "Ptr")
      DllCall("SetSystemCursor", "Ptr", hCopy, "UInt", SysCursors[old])
      if !setOnExit
         OnExit(exitFunc), setOnExit := true
   }
}
To restore default cursors call ReplaceSystemCursor() without parameters or terminate the script.
User avatar
boiler
Posts: 17242
Joined: 21 Dec 2014, 02:44

Re: How to change mouse pointer?

16 Mar 2021, 15:52

Now you just need to wait until the app starts loading before implementing that. If the process doesn't exist until it starts loading and it eventually goes away before the next time it starts loading again, then you should be able to do something like this:

Code: Select all

loop {
	Process, Wait, MyProcess.exe
	ReplaceSystemCursor("IDC_WAIT", "IDC_ARROW")
	Sleep, 60000 ; wait 60 seconds
	ReplaceSystemCursor()
	Process, WaitClose, MyProcess.exe
}
return

Esc:: ExitApp

ReplaceSystemCursor(old := "", new := "")
{
   static IMAGE_CURSOR := 2, SPI_SETCURSORS := 0x57
        , exitFunc := Func("ReplaceSystemCursor").Bind("", "")
        , setOnExit := false
        , SysCursors := { IDC_APPSTARTING: 32650
                        , IDC_ARROW      : 32512
                        , IDC_CROSS      : 32515
                        , IDC_HAND       : 32649
                        , IDC_HELP       : 32651
                        , IDC_IBEAM      : 32513
                        , IDC_NO         : 32648
                        , IDC_SIZEALL    : 32646
                        , IDC_SIZENESW   : 32643
                        , IDC_SIZENWSE   : 32642
                        , IDC_SIZEWE     : 32644
                        , IDC_SIZENS     : 32645 
                        , IDC_UPARROW    : 32516
                        , IDC_WAIT       : 32514 }
   if !old {
      DllCall("SystemParametersInfo", "UInt", SPI_SETCURSORS, "UInt", 0, "UInt", 0, "UInt", 0)
      OnExit(exitFunc, 0), setOnExit := false
   }
   else  {
      hCursor := DllCall("LoadCursor", "Ptr", 0, "UInt", SysCursors[new], "Ptr")
      hCopy := DllCall("CopyImage", "Ptr", hCursor, "UInt", IMAGE_CURSOR, "Int", 0, "Int", 0, "UInt", 0, "Ptr")
      DllCall("SetSystemCursor", "Ptr", hCopy, "UInt", SysCursors[old])
      if !setOnExit
         OnExit(exitFunc), setOnExit := true
   }
}
Renfro
Posts: 64
Joined: 15 Oct 2020, 10:19

Re: How to change mouse pointer?

21 Mar 2021, 23:13

Thanks very much for the code @teadrinker, and thanks to @boiler for the loop to make it run.

Unfortunately it's not working for me. The hourglass icon is still visible when the process loads. This is undoubtedly due to something I've done (or perhaps omitted to mention) rather than the code itself.

I replaced MyProcess.exe in the loop section of the script with the actual name of the executable. However, when watching Windows Task Manager I can see that the main executable actually loads 4 other executables (and kills those same 4 when it exists too). Could that account for why the hourglass still shows? Do I need to reference all of the executables, or should the script work regardless? Sorry if this is a dumb question.
teadrinker
Posts: 4389
Joined: 29 Mar 2015, 09:41
Contact:

Re: How to change mouse pointer?

21 Mar 2021, 23:34

@Renfro
Try launching my script as it is.
User avatar
WeedTrek
Posts: 75
Joined: 22 Mar 2019, 14:29
Location: Cache Creek BC Canada
Contact:

Re: How to change mouse pointer?

21 Mar 2021, 23:42

Unsure if this works, not sure how to trigger a proper test, try throwing in a pointer from a .CUR file you place in your script folder... apologies if no worky

Code: Select all

; load custom pointer from file:

ThisPointer()	; calls the pointer function, use it before the hourglass appears

; bla bla script stuff while hourglass normally shows

; unload custom pointer afterwards, back to regular:
DllCall("SystemParametersInfo", UInt, 0x57, UInt, 0, UInt, 0, UInt, 0) ; sticks in normal default pointer


; function underneath somewhere
ThisPointer()	; inserts pointer from .CUR file from script dir, does not install it into system just uses it
{
	Pointer := DllCall("LoadCursorFromFile", Str, A_ScriptDir "chosenCursor.cur")	; rename this to your cursor file in script dir
	DllCall("SetSystemCursor", Uint, Pointer, Int, 32512) ; I know this replaces arrow pointer with the above pointer, not sure if it will override the hourglass
}
My Weed Trek video archive: http://weedtrek.ca
User avatar
boiler
Posts: 17242
Joined: 21 Dec 2014, 02:44

Re: How to change mouse pointer?

21 Mar 2021, 23:49

Here's a demo of my script modified to have the horizontal resize cursor (that appears when you hover over a vertical edge of a resizable window) become the regular pointer cursor for the first 10 seconds that a Notepad editor process exists. Then it reverts back until the Notepad process has closed and then exists again, at which point you won't be able to see the horizontal resize cursor for 10 seconds. Test it out so you can see that it works and how.

Code: Select all

loop {
	Process, Wait, Notepad.exe
	ReplaceSystemCursor("IDC_SIZEWE", "IDC_ARROW")
	Sleep, 10000 ; wait 10 seconds
	ReplaceSystemCursor()
	Process, WaitClose, Notepad.exe
}
return

Esc:: ExitApp

ReplaceSystemCursor(old := "", new := "")
{
   static IMAGE_CURSOR := 2, SPI_SETCURSORS := 0x57
        , exitFunc := Func("ReplaceSystemCursor").Bind("", "")
        , setOnExit := false
        , SysCursors := { IDC_APPSTARTING: 32650
                        , IDC_ARROW      : 32512
                        , IDC_CROSS      : 32515
                        , IDC_HAND       : 32649
                        , IDC_HELP       : 32651
                        , IDC_IBEAM      : 32513
                        , IDC_NO         : 32648
                        , IDC_SIZEALL    : 32646
                        , IDC_SIZENESW   : 32643
                        , IDC_SIZENWSE   : 32642
                        , IDC_SIZEWE     : 32644
                        , IDC_SIZENS     : 32645 
                        , IDC_UPARROW    : 32516
                        , IDC_WAIT       : 32514 }
   if !old {
      DllCall("SystemParametersInfo", "UInt", SPI_SETCURSORS, "UInt", 0, "UInt", 0, "UInt", 0)
      OnExit(exitFunc, 0), setOnExit := false
   }
   else  {
      hCursor := DllCall("LoadCursor", "Ptr", 0, "UInt", SysCursors[new], "Ptr")
      hCopy := DllCall("CopyImage", "Ptr", hCursor, "UInt", IMAGE_CURSOR, "Int", 0, "Int", 0, "UInt", 0, "Ptr")
      DllCall("SetSystemCursor", "Ptr", hCopy, "UInt", SysCursors[old])
      if !setOnExit
         OnExit(exitFunc), setOnExit := true
   }
}

It would be the same for your process and the first script I posted. You don't need to worry about the other processes you mentioned. As long as the one you mentioned appears (and eventually goes away), the hourglass cursor should become the pointer cursor for the first 60 seconds of that process existing, then it will be available again if an application calls for it until that process closes and reappears.

Is the only thing you changed the process name (in two places)? Can you post the script with your modifications?
Renfro
Posts: 64
Joined: 15 Oct 2020, 10:19

Re: How to change mouse pointer?

25 Mar 2021, 01:10

@boiler

I appreciate the clarification about the other subsequently loaded processes not being relevant.

Thanks also for your ready-to-go test example. I ran it and it didn't work at first (but I had my regular every-day AHK script running at the time). I therefore unloaded my script and re-ran the test example on its own, and it worked exactly as you described.

So it's clearly something in my existing script that is causing the problem.

I'll go through a process of elimination to track down the culprit code, and once it's found, if I'm still unable to fix it I'll post back here with the problem code that's causing the interference. Hopefully it will be pretty obvious what the issue is and how I can resolve it (now that I know what I'm looking for).

But for now at least, this thread is solved.

Thanks to everybody who contributed.
Renfro
Posts: 64
Joined: 15 Oct 2020, 10:19

Re: How to change mouse pointer?

25 Mar 2021, 02:02

OK, well something strange is afoot.

My first step of testing was to run the exact same example code (that had just successfully worked with notepad) and simply swap the executable name. That's all I did (apart from adding a 'run' line and hotkey to allow loading of the software without having to wait for a timer).

It didn't work (despite the fact that I ensured no other script code was running).

So when that failed, I tried switching the code back to notepad, and it worked once again. However, bear in mind that I was viewing the window border arrow cursor rather than an hourglass (which will obviously will not display for a tiny program like notepad).

So then I decided to try a couple of 'bloater' application that I have (which would allow me to check for an hourglass instead of a window border icon). I tried both Photoshop and Vegas (video editor) which are both pretty hefty and always show an hourglass during loading. In both instances the hourglass still showed as normal. The code appeared to make no difference in those instances.

Here is the exact code I used for one of the tests:

Code: Select all

!F1::

Run, "C:\Program Files\Adobe\Adobe Photoshop\Photoshop.exe"

loop {
	Process, Wait, Photoshop.exe
	ReplaceSystemCursor("IDC_SIZEWE", "IDC_ARROW")
	Sleep, 10000 ; wait 10 seconds
	ReplaceSystemCursor()
	Process, WaitClose, Photoshop.exe
}
return

Esc:: ExitApp

ReplaceSystemCursor(old := "", new := "")
{
   static IMAGE_CURSOR := 2, SPI_SETCURSORS := 0x57
        , exitFunc := Func("ReplaceSystemCursor").Bind("", "")
        , setOnExit := false
        , SysCursors := { IDC_APPSTARTING: 32650
                        , IDC_ARROW      : 32512
                        , IDC_CROSS      : 32515
                        , IDC_HAND       : 32649
                        , IDC_HELP       : 32651
                        , IDC_IBEAM      : 32513
                        , IDC_NO         : 32648
                        , IDC_SIZEALL    : 32646
                        , IDC_SIZENESW   : 32643
                        , IDC_SIZENWSE   : 32642
                        , IDC_SIZEWE     : 32644
                        , IDC_SIZENS     : 32645 
                        , IDC_UPARROW    : 32516
                        , IDC_WAIT       : 32514 }
   if !old {
      DllCall("SystemParametersInfo", "UInt", SPI_SETCURSORS, "UInt", 0, "UInt", 0, "UInt", 0)
      OnExit(exitFunc, 0), setOnExit := false
   }
   else  {
      hCursor := DllCall("LoadCursor", "Ptr", 0, "UInt", SysCursors[new], "Ptr")
      hCopy := DllCall("CopyImage", "Ptr", hCursor, "UInt", IMAGE_CURSOR, "Int", 0, "Int", 0, "UInt", 0, "Ptr")
      DllCall("SetSystemCursor", "Ptr", hCopy, "UInt", SysCursors[old])
      if !setOnExit
         OnExit(exitFunc), setOnExit := true
   }
}
Pressing the Alt + F1 hotkey combo runs the application, and I immediately see the hourglass as usual.

I'm not sure what it is that I am doing wrong.
User avatar
boiler
Posts: 17242
Joined: 21 Dec 2014, 02:44

Re: How to change mouse pointer?

25 Mar 2021, 03:50

Renfro wrote:
25 Mar 2021, 02:02
OK, well something strange is afoot.
Not really. Replace IDC_SIZEWE with IDC_WAIT so it affects the hourglass icon instead of the horizontal resize icon.
Renfro
Posts: 64
Joined: 15 Oct 2020, 10:19

Re: How to change mouse pointer?

25 Mar 2021, 06:04

Oops, I should have spotted that. :oops:

Anyway, I changed it, and it still doesn't work (for the several different large apps that I just tested).
User avatar
boiler
Posts: 17242
Joined: 21 Dec 2014, 02:44

Re: How to change mouse pointer?

25 Mar 2021, 09:12

I'm successfully able to replace the IDC_WAIT cursor with IDC_ARROW or any other pointer for 10 seconds using that script. One thing to make sure of is whether your cursor turns into simply an hourglass (hourglass is a spining blue circle on my system), or is it an arrow pointer with a small hourglass next to it? If it's the latter, then the cursor name is not IDC_WAIT but IDC_APPSTARTING. If that's the case, then change it to that and try it.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: AlFlo, Google [Bot] and 124 guests