SetSystemCursor()

Windows specific forum
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

SetSystemCursor()

Post 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......... :|
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4997
Joined: Sun Apr 12, 2009 6:27 am

Re: SetSystemCursor()

Post 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
Egypt my love
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: SetSystemCursor()

Post by IdeasVacuum »

Hi Rashad - I have in fact done that in the code above, though not by using CopyCursor(), which I shall try.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: SetSystemCursor()

Post 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
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4997
Joined: Sun Apr 12, 2009 6:27 am

Re: SetSystemCursor()

Post 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 :mrgreen: )
Egypt my love
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4997
Joined: Sun Apr 12, 2009 6:27 am

Re: SetSystemCursor()

Post 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
Egypt my love
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: SetSystemCursor()

Post 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.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4997
Joined: Sun Apr 12, 2009 6:27 am

Re: SetSystemCursor()

Post 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

Egypt my love
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: SetSystemCursor()

Post by IdeasVacuum »

Hi Rashad

Yep, that does indeed work. 8)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Post Reply