Page 1 of 1

Big Cross Mouse Cursor [Windows]

Posted: Thu Aug 23, 2012 7:44 pm
by RASHAD
Tested with PB v4.61 x86 Windows XP x86 -Windows 7 x64
Escape to quit

Code: Select all

Global hWnd_0,hWnd_1,hhkLLMouse,Width,Height

ExamineDesktops()
Width = DesktopWidth(0)
Height = DesktopHeight(0)

Procedure MouseHook(nCode, wParam, lParam)
      Select wParam
         Case #WM_LBUTTONDOWN
            Debug "OK"
                     
         Case #WM_MOUSEMOVE
            GetCursorPos_(p.POINT)
            MoveWindow_(hWnd_0,0,p\y+2,Width,2,1)
            MoveWindow_(hWnd_1,p\x+2,0,2,Height,1)
            SetWindowPos_(hWnd_0, #HWND_TOPMOST, 0, 0, 0, 0,#SWP_NOSIZE|#SWP_NOMOVE| #SWP_SHOWWINDOW|#SWP_NOACTIVATE)
            SetWindowPos_(hWnd_1, #HWND_TOPMOST, 0, 0, 0, 0,#SWP_NOSIZE|#SWP_NOMOVE| #SWP_SHOWWINDOW|#SWP_NOACTIVATE)
      
      EndSelect
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, lParam)
EndProcedure

hWnd_0 = OpenWindow(0,0,Height/2,Width,1,"",#PB_Window_BorderLess)
hWnd_1 = OpenWindow(1,Width/2,0,1,Height,"",#PB_Window_BorderLess,WindowID(0))
SetWindowColor(0,$0000FF)
SetWindowColor(1,$0000FF)

hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE_LL, @MouseHook(), GetModuleHandle_(0), 0)

Repeat
    Select WaitWindowEvent()      
       
    EndSelect
   
Until GetAsyncKeyState_(#VK_ESCAPE) & 1
UnhookWindowsHookEx_(hhkLLMouse)


Re: Big Cross Mouse Cursor [Windows]

Posted: Thu Aug 23, 2012 10:19 pm
by IdeasVacuum
Hi Rashad

Well, I really need a good cross hair cursor, my attempts so far either not good on XP or not good on Win7, or not good on both :cry:

Anything with the word MouseHook sounds lower-level to me (= more likely to be successful) but compiled as an exe, I see graphics problems with your cursor: Cursor on XP 32bit

Edit: In another post on this subject System-wide cross hair cursor
I linked to this solution by Mike Lin: CrossHair. This one works perfectly on XP and Win7 here and I think perhaps it does so by using a mouse-hook technique.

Re: Big Cross Mouse Cursor [Windows]

Posted: Fri Aug 24, 2012 1:45 am
by IdeasVacuum
Well, I have made one that works here on both XP 32bit and Win7 64bit, compiled as a 32bit exe.

LoadImage() will allow a large file to be used - so I have simply created a giant bitmap. It's only 1 bit, but is still a large file at 1MB. That's an issue because it takes 4 or 5 seconds to load. I'm wondering if it would be possible to include it in a data section and if that would reduce the start-up time.

Code: Select all

Global ighBigCursor.i = LoadImage_(GetModuleHandle_(0),"BigCursor01",#IMAGE_CURSOR,0,0,0)

SetSystemCursor_(ighBigCursor,#OCR_NORMAL)

Repeat

Until GetAsyncKeyState_(#VK_ESCAPE) & 1

;### Reset Cursor Pointers Set
SystemParametersInfo_(#SPI_SETCURSORS,0,#Null,#Null)
                Delay(1)

End

;
;GlobalCursor.rc
;BigCursor01 CURSOR "C:\PROJECTS_DrvC\GlobalCursor\BigCursor01.cur"
;
Link to download the cursor file: BigCursor01

Re: Big Cross Mouse Cursor [Windows]

Posted: Fri Aug 24, 2012 3:14 am
by IdeasVacuum
...tried drawing the cursor instead of loading from Resource.
Two problems -
(1) Really simple image but I can't get the mask to work :oops:
(2) It is just as slow as loading from Resource

Code: Select all

#CursorMask01 = 1
#CursorImage02 = 2

CreateImage(#CursorMask01,2048,2048,24)
CreateImage(#CursorImage02,2048,2048,24)

If StartDrawing(ImageOutput(#CursorMask01))

                ;x1  ;y1  ;x2  ;y2
            Box(   0,    0, 2048, 2048, RGB(255,255,255))
         LineXY(1024,    0, 1024, 2048, RGB(0,0,255))
         LineXY(   0, 1024, 2048, 1024, RGB(0,0,255))
    StopDrawing()
EndIf

If StartDrawing(ImageOutput(#CursorImage02))

                 ;x1  ;y1  ;x2  ;y2
            Box(   0,    0, 2048, 2048, RGB(255,255,255))
         LineXY(1024,    0, 1024, 2048, RGB(0,0,0))
         LineXY(   0, 1024, 2048, 1024, RGB(0,0,0))
    StopDrawing()
EndIf

icoInf.ICONINFO
icoInf\fIcon = #False
icoInf\xHotspot = 1024
icoInf\yHotspot = 1024
icoInf\hbmMask = ImageID(#CursorMask01)
icoInf\hbmColor = ImageID(#CursorImage02) 

ighBigCursor = CreateIconIndirect_(icoInf)

SetSystemCursor_(ighBigCursor,#OCR_NORMAL)

Repeat

Until GetAsyncKeyState_(#VK_ESCAPE) & 1

;### Reset Cursor Pointers Set
SystemParametersInfo_(#SPI_SETCURSORS,0,#Null,#Null)
                Delay(1)

End

Re: Big Cross Mouse Cursor [Windows]

Posted: Fri Aug 24, 2012 3:38 am
by RASHAD
Hi

Code: Select all

ExamineDesktops()
Width = DesktopWidth(0)
Height = DesktopHeight(0)

CreateImage(0, Width*2,Height*2)
CreateImage(1,  Width*2,Height*2)
 
StartDrawing(ImageOutput(0))
  Box(0,0,Width*2,Height*2,#White)
  LineXY(0,Height,Width*2,Height,#Red)
  LineXY(Width,0,Width,Height*2,#Red)
  Circle(Width,Height,10,#Red)
  Circle(Width,Height,7,#White)
StopDrawing()

StartDrawing(ImageOutput(1))
  Box(0,0,Width*2,Height*2,#Red)
StopDrawing()

iinf.ICONINFO
iinf\fIcon = #False
iinf\xHotspot = Width
iinf\yHotspot = Height
iinf\hbmMask = ImageID(0)
iinf\hbmColor = ImageID(1)

curHnd = CreateIconIndirect_(iinf)

SetSystemCursor_(curHnd,#OCR_NORMAL)

Repeat

Until GetAsyncKeyState_(#VK_ESCAPE) & 1

SystemParametersInfo_(#SPI_SETCURSORS,0,#Null,#Null)
 Delay(1)

End

Edit :Modified for enhancement

Re: Big Cross Mouse Cursor [Windows]

Posted: Fri Aug 24, 2012 1:02 pm
by IdeasVacuum
Hi Rashad

Well, without the circle, the mask does not work properly :cry:
.... and still the issue is the slow loading.

I think Mike Lin must be doing something like this though because his app is so small. Perhaps a slow load is disguised by loading during PC boot-up.

Re: Big Cross Mouse Cursor [Windows]

Posted: Fri Aug 24, 2012 1:12 pm
by Kwai chang caine
The first code works fine on VISTA :D
It's crazy to see what you can do, with two windows :lol:
Thanks RASHAD 8)

Re: Big Cross Mouse Cursor [Windows]

Posted: Fri Aug 24, 2012 1:41 pm
by RASHAD
Hi KCC thanks

Hi IdeasVucuum
There is no way to speed the loading time(I did my best)
I still prefer the first solution(until now :mrgreen: )
Updated the code for XP check and for your information PB is using the Low Level Hook
See yourself
About the mask I have a doubt that Your PC needs some cleaning
What is your configuration mate?

Code: Select all

Global hWnd_0,hWnd_1,hhkLLMouse,Width,Height

ExamineDesktops()
Width = DesktopWidth(0)
Height = DesktopHeight(0)

Procedure MouseHook(nCode, wParam, lParam)
      
      Select wParam
         Case #WM_MBUTTONDOWN
            UnhookWindowsHookEx_(hhkLLMouse)
            SystemParametersInfo_(#SPI_SETCURSORS,0,0,0)               
            End
            
            
         Case #WM_LBUTTONDOWN,#WM_LBUTTONUP
              SHChangeNotify_($8000000, $1000, 0, 0)             
          
                     
         Case #WM_MOUSEMOVE
              GetCursorPos_(p.POINT)              
              SetWindowPos_(hWnd_0, #HWND_TOPMOST, 0,p\y+2,Width,1,#SWP_NOSIZE|#SWP_DRAWFRAME)
              SetWindowPos_(hWnd_1, #HWND_TOPMOST, p\x+2,0,1,Height,#SWP_NOSIZE|#SWP_DRAWFRAME)
              SHChangeNotify_($8000000, $10000, 0, 0)
              
     
      EndSelect
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, lParam)
EndProcedure

hWnd_0 = OpenWindow(0,0,Height/2,Width,1,"",#PB_Window_BorderLess)
hWnd_1 = OpenWindow(1,Width/2,0,1,Height,"",#PB_Window_BorderLess)
SetWindowColor(0,#Yellow)
SetWindowColor(1,#Yellow)

hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE_LL, @MouseHook(), GetModuleHandle_(0), 0)

Repeat
    Select WaitWindowEvent()     
       
    EndSelect   
Until GetAsyncKeyState_(#VK_ESCAPE) & 1




PB style :

Code: Select all

Global hWnd_0,hWnd_1,Width,Height,Quit

ExamineDesktops()
Width = DesktopWidth(0)
Height = DesktopHeight(0)

hWnd_0 = OpenWindow(0,0,Height/2,Width,1,"",#PB_Window_BorderLess)
hWnd_1 = OpenWindow(1,Width/2,0,1,Height,"",#PB_Window_BorderLess,WindowID(0))
SetWindowColor(0,$0000FF)
SetWindowColor(1,$0000FF)

SetSystemCursor_(curHnd,#OCR_NORMAL)

Repeat
    MoveWindow_(hWnd_0,0,DesktopMouseY()+2,Width,2,1)
    MoveWindow_(hWnd_1,DesktopMouseX()+2,0,2,Height,1)
    ;SetWindowPos_(hWnd_0, #HWND_TOPMOST, 0, 0, 0, 0,#SWP_NOSIZE|#SWP_NOMOVE| #SWP_SHOWWINDOW|#SWP_NOACTIVATE)
    ;SetWindowPos_(hWnd_1, #HWND_TOPMOST, 0, 0, 0, 0,#SWP_NOSIZE|#SWP_NOMOVE| #SWP_SHOWWINDOW|#SWP_NOACTIVATE)
Until GetAsyncKeyState_(#VK_ESCAPE) & 1


Re: Big Cross Mouse Cursor [Windows]

Posted: Fri Aug 24, 2012 1:52 pm
by IdeasVacuum
I have noticed something interesting with the app loading time - it is not LoadImage_ that is taking that time. As an experiment, I loaded 6 giant cursors (different colours). The time from app start to cursor on screen is the same as with one giant cursor being loaded. Once the app is running, switching between the different cursors is instant.

Concerning the mask issue, I don't think that is system/hardware persay. I do think it might be the rendering of the cursor image, where having the line start right at the edge of the cursor image border might break the transparency - I will test that later, unfortunately I have to drive the Mrs to town :mrgreen:

Re: Big Cross Mouse Cursor [Windows]

Posted: Fri Aug 24, 2012 10:36 pm
by IdeasVacuum
OK, hunch about the cursor lines start/finish right at the edge of the image boundary was correct - just nipping them in a few pix removes the mask problem, which did have a wrinkle in it and that's fixed too in the code below:

Code: Select all

Enumeration
#CursorMask
#CursorImage
EndEnumeration

CreateImage(#CursorMask,2048,2048,24)
CreateImage(#CursorImage,2048,2048,24)

If StartDrawing(ImageOutput(#CursorMask))

                 ;x1  ;y1  ;x2  ;y2
            Box(   0,    0, 2048, 2048, RGB(255,255,255))
         LineXY(1014,   10, 1014, 2038, RGB(0,0,0))
         LineXY(  10, 1014, 2038, 1014, RGB(0,0,0))
    StopDrawing()

EndIf

;### Cursor 1
If StartDrawing(ImageOutput(#CursorImage))

                ;x1   ;y1   ;x2   ;y2
            Box(   0,    0, 2048, 2048, RGB(0,0,0))
         LineXY(1014,   10, 1014, 2038, RGB(255,0,0)) ;<-- Change this value for different colour cursor
         LineXY(  10, 1014, 2038, 1014, RGB(255,0,0)) ;<-- Change this value for different colour cursor
    StopDrawing()

EndIf

Cursor.ICONINFO
   Cursor\fIcon = #False
Cursor\xHotspot = 1024
Cursor\yHotspot = 1024
 Cursor\hbmMask = ImageID(#CursorMask)
Cursor\hbmColor = ImageID(#CursorImage) 
   ighBigCursor = CreateIconIndirect_(Cursor)

;### display cursor
SetSystemCursor_(ighBigCursor,#OCR_NORMAL)

;### Escape to Quit
Repeat : Until GetAsyncKeyState_(#VK_ESCAPE) & 1

;### Exit: Reset Cursor Pointers Set
SystemParametersInfo_(#SPI_SETCURSORS,0,#Null,#Null)
                Delay(1)

End

Re: Big Cross Mouse Cursor [Windows]

Posted: Sat Aug 25, 2012 2:37 am
by RASHAD
There is a good news for you mate :mrgreen:
The loop is the problem

Try the next

Code: Select all

Enumeration
#CursorMask
#CursorImage
EndEnumeration

CreateImage(#CursorMask,2048,2048,24)
CreateImage(#CursorImage,2048,2048,24)

If StartDrawing(ImageOutput(#CursorMask))

                 ;x1  ;y1  ;x2  ;y2
            Box(   0,    0, 2048, 2048, RGB(255,255,255))
         LineXY(1014,   10, 1014, 2038, RGB(0,0,0))
         LineXY(  10, 1014, 2038, 1014, RGB(0,0,0))
    StopDrawing()

EndIf

;### Cursor 1
If StartDrawing(ImageOutput(#CursorImage))

                ;x1   ;y1   ;x2   ;y2
            Box(   0,    0, 2048, 2048, RGB(0,0,0))
         LineXY(1014,   10, 1014, 2038, RGB(255,0,0)) ;<-- Change this value for different colour cursor
         LineXY(  10, 1014, 2038, 1014, RGB(255,0,0)) ;<-- Change this value for different colour cursor
    StopDrawing()

EndIf

Cursor.ICONINFO
   Cursor\fIcon = #False
Cursor\xHotspot = 1024
Cursor\yHotspot = 1024
 Cursor\hbmMask = ImageID(#CursorMask)
Cursor\hbmColor = ImageID(#CursorImage)
   ighBigCursor = CreateIconIndirect_(Cursor)

;### display cursor
SetSystemCursor_(ighBigCursor,#OCR_NORMAL)
end

Re: Big Cross Mouse Cursor [Windows]

Posted: Sat Aug 25, 2012 4:03 am
by Josh
RASHAD wrote:There is a good news for you mate :mrgreen:
The loop is the problem

Try the next

Code: Select all

.....
LineXY(1014,   10, 1014, 2038, RGB(0,0,0))
LineXY(  10, 1014, 2038, 1014, RGB(0,0,0))
.....
If you use 1024 instead of 1014, the hotspot will be shown correctly.

Any idea, that the shadow isn't shown for this cursor?

tested win7/64, PB 4.60

Re: Big Cross Mouse Cursor [Windows]

Posted: Sat Aug 25, 2012 4:36 am
by IdeasVacuum
Hi Rashad

Yep, I actually fixed it 'accidentally' by adding a window front-end for choosing the cursor colour!

Josh, thanks for that note - had not noticed that the hotspot was out, at the time I was trying to ensure that the transparency always worked.

In my early days using computers, cross-hairs were all we had. I'm not sure how they fell out of favour so much that the OS does even have them as an option - they really are very handy at times!

Re: Big Cross Mouse Cursor [Windows]

Posted: Sat Aug 25, 2012 5:06 am
by RASHAD
Another trick

Ctrl + 1 Load Big Cursor
Ctrl + 2 Load Normal Cursor
Ctrl + 3 Exit

Tested with XP x86 Win 7 x64
Compile it as EXE file and you have the best application for the big cursor :)
And that is the beauty of Pure Basic (you can see your work as fast as you can)

Code: Select all

ExamineDesktops()
Width = DesktopWidth(0)
Height = DesktopHeight(0)

CreateImage(0, Width*2,Height*2)  
StartDrawing(ImageOutput(0))
  Box(0,0,Width*2,Height*2,#White)
  LineXY(0,Height,Width*2,Height,#Red)
  LineXY(Width,0,Width,Height*2,#Red)
  LineXY(Width-20,Height,Width+20,Height,#Yellow)
  LineXY(Width,Height-20,Width,Height+20,#Yellow)  
  ;Circle(Width,Height,10,#Red)
  ;Circle(Width,Height,7,#White)
StopDrawing()
;  
CreateImage(1,Width*2,Height*2)
StartDrawing(ImageOutput(1))
   Box(0,0,Width*2,Height*2,#Red)
   LineXY(Width-20,Height,Width+20,Height,#Yellow)
   LineXY(Width,Height-20,Width,Height+20,#Yellow)
StopDrawing()

iinf.ICONINFO
iinf\fIcon = #False
iinf\xHotspot = Width
iinf\yHotspot = Height
iinf\hbmMask = ImageID(0)
iinf\hbmColor = ImageID(1)

curHnd = CreateIconIndirect_(iinf)

temparrow    = CopyImage_(curHnd,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
SetSystemCursor_(temparrow,32650)
 
temparrow    = CopyImage_(curHnd,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
SetSystemCursor_(temparrow,32512)

Repeat
  Delay(1)
    If GetAsyncKeyState_(#VK_CONTROL) & $8000 = 32768 And GetAsyncKeyState_(#VK_1) & $8000 = 32768
       temparrow    = CopyImage_(curHnd,#IMAGE_CURSOR,0,0,#LR_COPYFROMRESOURCE)
       SetSystemCursor_(temparrow,#OCR_NORMAL)
    ElseIf GetAsyncKeyState_(#VK_CONTROL) & $8000 = 32768 And GetAsyncKeyState_(#VK_2) & $8000 = 32768
       SystemParametersInfo_(#SPI_SETCURSORS,0,#Null,#Null)
    ElseIf GetAsyncKeyState_(#VK_CONTROL) & $8000 = 32768 And GetAsyncKeyState_(#VK_3) & $8000 = 32768
       SystemParametersInfo_(#SPI_SETCURSORS,0,#Null,#Null)
       End
    EndIf
ForEver