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.
How to change mouse pointer?
Re: How to change mouse pointer?
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.
-
- Posts: 4389
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to change mouse pointer?
Try this:
To restore default cursors call ReplaceSystemCursor() without parameters or terminate the script.
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
}
}
Re: How to change mouse pointer?
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
}
}
Re: How to change mouse pointer?
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.
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.
-
- Posts: 4389
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to change mouse pointer?
@Renfro
Try launching my script as it is.
Try launching my script as it is.
Re: How to change mouse pointer?
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
Re: How to change mouse pointer?
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.
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?
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?
Re: How to change mouse pointer?
@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.
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.
Re: How to change mouse pointer?
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:
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.
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
}
}
I'm not sure what it is that I am doing wrong.
Re: How to change mouse pointer?
Oops, I should have spotted that.
Anyway, I changed it, and it still doesn't work (for the several different large apps that I just tested).
Anyway, I changed it, and it still doesn't work (for the several different large apps that I just tested).
Re: How to change mouse pointer?
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.
Who is online
Users browsing this forum: AlFlo, Google [Bot] and 124 guests