Page 1 of 1
SetSystemCursor()
Posted: Wed Aug 08, 2012 9:04 pm
by IdeasVacuum
I have an app where the User would occasionally want to toggle the system cursor to match the app cursor (special cross-hair)
I have the app cursor loaded and a standard arrow cursor loaded:
Code: Select all
Global ighSysDefaultCursorNORMAL.i = LoadCursor_(1, #IDC_ARROW)
Global ighCrossCursor.i = LoadCursor_(GetModuleHandle_(0), "Cursor01") ;app cursor (special cross-hair)
The User chooses to toggle the system cursor:
Code: Select all
SetSystemCursor_(ighCrossCursor,#OCR_NORMAL)
The app's cross-hair cursor now appears anywhere on the desktop where the normal arrow would appear - good. If I check the Control Panel/Mouse Pointer/Windows Default Scheme, the cross-hair cursor is indeed shown - good good.
Now the User chooses to toggle the normal arrow cursor back on:
Code: Select all
SetSystemCursor_(ighSysDefaultCursorNORMAL,#OCR_NORMAL)
Not good. The cross-hair cursor persists. Yet, in the Control Panel, the normal arrow is shown as restored.
It seems that I'm nearly there, but nowhere near the correct solution.........

Re: SetSystemCursor()
Posted: Wed Aug 08, 2012 9:58 pm
by RASHAD
Hi
MSDN says that SetSystemCursor_() destroy the cur resources after loading it
So you got to use CopyCursor_() to create a duplicate cur
Then use the copy in SteSystemCursor_() to keep the original intact to use it later
Good luck
Re: SetSystemCursor()
Posted: Wed Aug 08, 2012 10:55 pm
by IdeasVacuum
Hi Rashad - I have in fact done that in the code above, though not by using CopyCursor(), which I shall try.
Re: SetSystemCursor()
Posted: Thu Aug 09, 2012 12:40 am
by IdeasVacuum
This compiles, but the exe crashes:
Code: Select all
If OpenLibrary(0, "user32.dll")
Prototype CopyCursor(hCursor.i)
Global CopyCursor.CopyCursor = GetProcAddress_(GetModuleHandle_("user32.dll"),"CopyCursor")
igSysDefaultCursorNORMAL = CopyCursor(#OCR_NORMAL)
igSysDefaultCursorIBEAM = CopyCursor(#OCR_IBEAM)
CloseLibrary(0)
EndIf
Same crash with this:
Code: Select all
Global CopyCursor.CopyCursor = GetFunction(0,"CopyCursor")
Interestingly, MS published a method to do it - the very method I used. Strangely, it doesn't work for them either!
http://support.microsoft.com/kb/160041
Re: SetSystemCursor()
Posted: Thu Aug 09, 2012 12:46 am
by RASHAD
There is no CopyCursor() in User32.dll I just discovered that
I am running Win 7 x64 ,I do not know what is going on?
I think you should use in this case CopyIcon()
I will see what I can do to help(If I can

)
Re: SetSystemCursor()
Posted: Thu Aug 09, 2012 6:50 am
by RASHAD
CopyCursor_() Not available
CopyIcon_() did not work
Only CopyImage_()
Check
Code: Select all
currenthcurs = LoadCursor_(0,#IDC_ARROW)
tempcurs = CopyImage_(currenthcurs,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
;************** Works with Win 7 Only ********************
; newhcurs = LoadCursorFromFile_(@"hourglas.ani")
; SetSystemCursor_(newhcurs, #OCR_NORMAL)
;***********************************************************
SetSystemCursor_(LoadCursor_(0,#IDC_CROSS ), #OCR_NORMAL)
For x = 0 To 10000
Delay(1)
Next
SetSystemCursor_(tempcurs, #OCR_NORMAL)
For x = 0 To 10000
Delay(1)
Next
Re: SetSystemCursor()
Posted: Thu Aug 09, 2012 11:44 am
by IdeasVacuum
Hi Rashad
Tested on XP 32bit.
Well, when MS say the cursor is destroyed, they mean it lol. It practically prevents the 'toggle cursor' solution I wish to deliver, though given that cursors are so small, I think I can store a few of them in an array if necessary. Your method above does work - but only once. Try this as an exe:
Code: Select all
currenthcurs = LoadCursor_(0,#IDC_ARROW)
tempcurs = CopyImage_(currenthcurs,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
;HandCurs = LoadCursor_(0, #IDC_HAND)
;CrossCurs = LoadCursor_(1,#IDC_CROSS)
MessageRequester("Start","Set to Cross")
SetSystemCursor_(LoadCursor_(0,#IDC_CROSS), #OCR_NORMAL)
For x = 0 To 1000
Delay(1)
Next
MessageRequester("","Set to Normal")
SetSystemCursor_(tempcurs, #OCR_NORMAL)
For x = 0 To 1000
Delay(1)
Next
MessageRequester("","Set to Cross")
SetSystemCursor_(CrossCurs, #OCR_NORMAL)
For x = 0 To 1000
Delay(1)
Next
MessageRequester("END","Set to Normal")
SetSystemCursor_(tempcurs, #OCR_NORMAL)
End
Edit: In fact it's not safe on XP. Even though tempcurs sounds like a full copy of the original cursor data, it seems it is just a pointer to the original. I have to reset the system cursors via control panel to get the cross cursor back.
Re: SetSystemCursor()
Posted: Thu Aug 09, 2012 12:45 pm
by RASHAD
SetSystemCursor_() destroy it's cursor handle
Try next
Code: Select all
ArroCur = LoadCursor_(0,#IDC_ARROW)
temparrow = CopyImage_(ArroCur,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
CrossCur = LoadCursor_(0,#IDC_CROSS )
tempcross = CopyImage_(CrossCur,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
;HandCurs = LoadCursor_(0, #IDC_HAND)
;CrossCurs = LoadCursor_(1,#IDC_CROSS)
MessageRequester("Start","Set to Cross")
tempcross1 = CopyImage_(tempcross,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
SetSystemCursor_(tempcross1, #OCR_NORMAL)
For x = 0 To 1000
Delay(1)
Next
MessageRequester("","Set to Normal")
temparrow1 = CopyImage_(temparrow,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
SetSystemCursor_(temparrow1, #OCR_NORMAL)
For x = 0 To 1000
Delay(1)
Next
MessageRequester("","Set to Cross")
tempcross2 = CopyImage_(tempcross,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
SetSystemCursor_(tempcross2, #OCR_NORMAL)
For x = 0 To 1000
Delay(1)
Next
MessageRequester("END","Set to Normal")
temparrow2 = CopyImage_(temparrow,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
SetSystemCursor_(temparrow2, #OCR_NORMAL)
For x = 0 To 1000
Delay(1)
Next
MessageRequester("","Set to Cross")
tempcross1 = CopyImage_(tempcross,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
SetSystemCursor_(tempcross1, #OCR_NORMAL)
For x = 0 To 1000
Delay(1)
Next
MessageRequester("END","Set to Normal")
temparrow1 = CopyImage_(temparrow,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
SetSystemCursor_(temparrow1, #OCR_NORMAL)
End
Re: SetSystemCursor()
Posted: Thu Aug 09, 2012 12:54 pm
by IdeasVacuum
Hi Rashad
Yep, that does indeed work.
