Jump to content

Setting a giant crosshair as hardware cursor


Recommended Posts

Dialog()
GUI()

Func Dialog()
     Local $hor = @DesktopWidth*2
     Local $ver = @DesktopHeight*2
     Local $intent = MsgBox(3,"","Customize crosshair size?")
     If $intent = 2 Then Exit
     If $intent = 6 Then 
        $hor = InputBox("Width", "Enter width of crosshair", $hor)
        $ver = InputBox("Height", "Enter height of crosshair", $ver)
        If not (IsInt(Number($hor)) and IsInt(Number($ver)) and $hor>0 and $ver>0) Then 
           MsgBox(0,"Invalid dimensions","Width and height must be positive integers.")
           Exit
        EndIf
     EndIf
     Local $widthInBytes = 2*ceiling(ceiling($hor/2)/8)
     Local $totBytes = $widthInBytes*$ver
     MsgBox(0,"Be Patient","This will take a few seconds to loop over " & $totBytes & " bytes. Press OK to start.")

     Global $hCursor = MakeXhair($hor,$ver)
     MsgBox(0,"Complete","Built a crosshair that is " & $hor & "x" & $ver & " large.")
EndFunc

Func GUI()
     GUICreate("test")
     Local $button_NORMAL      = GUICtrlCreateButton("Set as normal arrow",0,0)
     Local $button_IBEAM       = GUICtrlCreateButton("Set as text select",0,25)
     Local $button_HAND        = GUICtrlCreateButton("Set as hyperlink hand",0,50)
     Local $button_APPSTARTING = GUICtrlCreateButton("Set as hourglass arrow",0,75)
     Local $button_HELP        = GUICtrlCreateButton("Set as help arrow",0,100)
     Local $button_CROSS       = GUICtrlCreateButton("Set as precision select",0,125)
     Local $button_rebuild     = GUICtrlCreateButton("Rebuild crosshair",0,150)
     GUISetState()
     GUIRegisterMsg(0x0020, WM_SETCURSOR)
     Local $GuiMsg
     do
        $GuiMsg = GuiGetMsg()
        Switch $GuiMsg
          Case -3
               Exit
          Case $button_NORMAL
               DllCall( "user32.dll" , "bool" , "SetSystemCursor" , "handle", CopyIcon($hCursor) , "dword" , 32512 )
          Case $button_HAND
               DllCall( "user32.dll" , "bool" , "SetSystemCursor" , "handle", CopyIcon($hCursor) , "dword" , 32649 )
          Case $button_HELP 
               DllCall( "user32.dll" , "bool" , "SetSystemCursor" , "handle", CopyIcon($hCursor) , "dword" , 32651 )
          Case $button_APPSTARTING
               DllCall( "user32.dll" , "bool" , "SetSystemCursor" , "handle", CopyIcon($hCursor) , "dword" , 32650 )
          Case $button_CROSS
               DllCall( "user32.dll" , "bool" , "SetSystemCursor" , "handle", CopyIcon($hCursor) , "dword" , 32515 )
          Case $button_IBEAM
               DllCall( "user32.dll" , "bool" , "SetSystemCursor" , "handle", CopyIcon($hCursor) , "dword" , 32513 )
          Case $button_rebuild
               DllCall( "user32.dll" , "bool" , "DestroyCursor" , $hCursor )
               Dialog()
        EndSwitch
     until 0
EndFunc

;    | AND mask value | XOR mask value | Result displayed                 |
;    |----------------|----------------|----------------------------------|
;    | 0              | 0              | Pixel is black                   |
;    | 0              | 1              | Pixel is white                   |
;    | 1              | 0              | Pixel is unchanged (transparent) |
;    | 1              | 1              | Pixel color is inverted          |

Func MakeXhair($hor,$ver)
     Local $widthInBytes = 2*ceiling(ceiling($hor/2)/8)
     Local $totBytes = $widthInBytes*$ver
     Local $curAND = DllStructCreate("byte[" & $totBytes & "]")
     Local $curXOR = DllStructCreate("byte[" & $totBytes & "]")
     Local $and , $xor

     Local $xByteCenter1Based = ceiling((int($hor/2)+1)/8)
     Local $ctrShift = int($hor/2) - 8*($xByteCenter1Based-1)
     Local $edgShift = 8*ceiling($hor/8)-$hor
     For $i = 1 to $ver
         For $j = 1 to ceiling($hor/8)
             $and = 0xff
             $xor = 0x00
             If $j = $xByteCenter1Based Then
                $xor = BitShift( 0x80 ,$ctrShift)
;                $and = 255-BitShift( 0x80 ,$ctrShift)
             EndIf
             If $i = int($ver/2)+1 Then
                $xor = ( $j=ceiling($hor/8) ? Round(exp($edgShift*log(2))*Int(255*exp(-$edgShift*log(2)))) : 0xff )
;                $and = ( $j=ceiling($hor/8) ? 255-Round(exp($edgShift*log(2))*Int(255*exp(-$edgShift*log(2)))) : 0x00 )
             EndIf
             DllStructSetData( $curAND , 1 , $and , $j+$widthInBytes*($i-1) )
             DllStructSetData( $curXOR , 1 , $xor , $j+$widthInBytes*($i-1) )
        Next
        If Mod(ceiling($hor/8),2)<>0 Then
           DllStructSetData( $curAND , 1 , 0xff , $i*$widthInBytes )
           DllStructSetData( $curXOR , 1 , 0x00 , $i*$widthInBytes )
        EndIf
     Next
     Local $andMaskPtr = DllStructGetPtr($curAnd), $xorMaskPtr = DllStructGetPtr($curXor)
     Return CreateCursor(Null, int($hor/2), int($ver/2), 8*$widthInBytes, $ver, $andMaskPtr, $xorMaskPtr)
EndFunc

Func CreateCursor($hInst, $xHotSpot, $yHotSpot, $nWidth, $nHeight, $pvANDPlane, $pvXORPlane)
     Local $aCall = DllCall("user32.dll", "handle", "CreateCursor", _
                                          "handle", $hInst, _
                                          "int", $xHotSpot, _
                                          "int", $yHotSpot, _
                                          "int", $nWidth, _
                                          "int", $nHeight, _
                                          "ptr", $pvANDPlane, _
                                          "ptr", $pvXORPlane)
     Return $aCall[0]
EndFunc

Func CopyIcon($handle)
     Local $aCall = DllCall("user32.dll", "handle", "CopyIcon", "handle", $handle )
     Return $aCall[0]
EndFunc

Func WM_SETCURSOR($hWnd, $iMsg, $wParam, $lParam)
     Local Static $dll = DllOpen("user32.dll")
     DllCall( $dll , "handle" , "SetCursor" , "handle" , $hCursor )
     Return True
EndFunc

 

 

Edited by AutoXenon
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...