Jump to content

Recommended Posts

Posted (edited)
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
Posted

Significant point about this demonstration is that the size can far exceed the 32x32 cursor size limitation, even as far as quadruple the actual size of your screenbuffer.

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...