Colorette - Simple Color Picker (v 2.1)

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
sumon
Posts: 38
Joined: 01 Oct 2013, 14:05
Location: Stockholm, Sweden

Colorette - Simple Color Picker (v 2.1)

23 Jul 2019, 04:30

Ahoy! Long time lurker (well, actually, used to be an active member, then not) posting due to a slight update in one of my scripts - Colorette. Not sure if it was ported to the new forums, so here it is (with some code cleanup):

Colorette is a simple standalone script that runs when you launch it, lets you pick a color (Hex or RGB) and exits the script. The below code snippet should be everything you need to run Colorette, build upon it, or implement it in another script.

RButton to capture hex code.
Ctrl+RButton to capture RGB values.
Esc to exit app without picking color.

Code: Select all

; ******* General ******* 
; COLORETTE
ScriptVersion := 2.1
; V 2.1: Removed DLG selection, improved hover tooltip.  
; Script created using Autohotkey (http www.autohotkey.com) 
; AHK version: AHK_L (www.autohotkey.net/~Lexikos/AutoHotkey_L)
;
; AUTHOR: sumon @ the Autohotkey forums
; License: sumon's Std License (see my forum signature)
;
; To add a "pick sound", add the pick_click.wav file and uncomment lines the lines with FileCreateDir, FileInstall (23, 24)
; 
; Thanks to: The Naked General _ jamixzol@gmail.com for his "Flashy and impractical color picker" which inspired me to this.
;
; || To-do ||
; Settings?

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance, Force

; Setup
OnExit, Exit
;~ FileCreateDir, data
;~ FileInstall, data\pick_click.wav, data\pick_click.wav
ColoretteIcon := A_ScriptFullPath

; Hotkeys
Hotkey, Rbutton, CatchColor ; HEX (Default)
Hotkey, ^Rbutton, CatchColor ; RGB

; Initiation
Traytip, Colorette:, RIGHTCLICK to copy HEX value`nAdd CTRL for RGB value, 5
SetSystemCursor("IDC_Cross") ; Reset in OnExit

If (FileExist("colorette.exe"))
   Menu, Tray, Icon, Colorette.exe

; MAIN LOOP: Pick Color

Loop
{
   CoordMode, Mouse, Screen
   MouseGetPos X, Y
   PixelGetColor Color, X, Y, RGB
   ColorD := Color ; Build an int based variable
   StringRight, color, color, 6 ; Removes 0x prefix
   SetFormat, IntegerFast, d
   ColorD += 0  ; Sets Var (which previously contained 11) to be 0xb.
   ColorD .= ""  ; Necessary due to the "fast" mode.
   ;~ ModColor := HexModify(Color, 1)
   GetKeyState("LControl") ? ColorMessage := HextoRGB(Color, "Message") : ColorMessage := Color
   Gui, 2:Color, %color%
   Tooltip, %ColorMessage% ; (%ModColor%)
   CoordMode, Pixel 
   mX := X - 30 ; Offset Tooltip from Mouse
   mY := Y - 80
   Gui, 2:-Caption +ToolWindow +LastFound +AlwaysOnTop +Border ; +0x400000 OR +Border
   Gui, 2:Show, NoActivate x%mX% y%mY% w60 h60
}
return

CatchColor: ; Catch Hover'd color
If (A_ThisHotkey = "^Rbutton")
   Out := "RGB"
If (FileExist("data\pick_click.wav"))
   SoundPlay, data\pick_click.wav
; Continue

ColorPicked:
StringRight, color, color, 6 ; Color HEX to RGB (or RGB to RGB)

If (Out = "RGB")
{
   OutColor := HexToRGB(Color)
   OutMsg := HexToRGB(Color, "Message")
   Clipboard := OutMsg
   ;~ OutParse := HexToRGB(Color, "Parse") ; Returns "R,G,B"
}
else
{
   OutColor := Color
   OutMsg :=  "#" . Color  
   Clipboard := OutColor
}

Traytip, Colorette:, %outmsg% picked
RestoreCursors()
Gui, 2:Destroy
Sleep 500
Hotkey, ^Rbutton, Off
Hotkey, Rbutton, Off

Sleep 1500
Gosub, Exit
Return

esc::
Exit:
RestoreCursors()
ExitApp
return

; FUNCTIONS
; : SetSystemCursor() and RestoreCursors()
HexToRGB(Color, Mode="") ; Input: 6 characters HEX-color. Mode can be RGB, Message (R: x, G: y, B: z) or parse (R,G,B)
{
   ; If df, d is *16 and f is *1. Thus, Rx = R*16 while Rn = R*1
   Rx := SubStr(Color, 1,1), Rn := SubStr(Color, 2,1)
   Gx := SubStr(Color, 3,1), Gn := SubStr(Color, 4,1)
   Bx := SubStr(Color, 5,1), Bn := SubStr(Color, 6,1)
   
   AllVars := "Rx|Rn|Gx|Gn|Bx|Bn"
   Loop, Parse, Allvars, | ; Add the Hex values (A - F)
   {
      StringReplace, %A_LoopField%, %A_LoopField%, a, 10
      StringReplace, %A_LoopField%, %A_LoopField%, b, 11
      StringReplace, %A_LoopField%, %A_LoopField%, c, 12
      StringReplace, %A_LoopField%, %A_LoopField%, d, 13
      StringReplace, %A_LoopField%, %A_LoopField%, e, 14
      StringReplace, %A_LoopField%, %A_LoopField%, f, 15
   }
   R := Rx*16+Rn
   G := Gx*16+Gn
   B := Bx*16+Bn
   
   If (Mode = "Message") ; Returns "R: 255 G: 255 B: 255"
      Out := "R:" . R . " G:" . G . " B:" . B
   else if (Mode = "Parse") ; Returns "255,255,255"
      Out := R . "," . G . "," . B
   else
      Out := R . G . B ; Returns 255255255
    return Out
}

; ToBase / FromBase by Lazslo @ http://www.autohotkey.com/forum/post-276241.html#276241
ToBase(n,b) { ; n >= 0, 1 < b <= 36
   Return (n < b ? "" : ToBase(n//b,b)) . ((d:=mod(n,b)) < 10 ? d : Chr(d+87))
}
 
FromBase(s,b) { ; convert base b number s=strings of 0..9,a..z, to AHK number
   Return (L:=StrLen(s))=0 ? "":(L>1 ? FromBase(SubStr(s,1,L-1),b)*b:0) + ((c:=Asc(SubStr(s,0)))>57 ? c-87:c-48)
}

HexModify(n, Add="") ; MsgBox % HexModify("ffffff", -55)
{
   ;~ Hex := "0123456789abcdef"
   R := ToBase(FromBase(SubStr(n, 1, 2), 16) + Add, 16)
   G := ToBase(FromBase(SubStr(n, 3, 2), 16) + Add, 16)
   B := ToBase(FromBase(SubStr(n, 5, 2), 16) + Add, 16)
   return R . G . B
}

RestoreCursors()
{
   SPI_SETCURSORS := 0x57
   DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
}

SetSystemCursor( Cursor = "", cx = 0, cy = 0 )
{
   BlankCursor := 0, SystemCursor := 0, FileCursor := 0 ; init
   
   SystemCursors = 32512IDC_ARROW,32513IDC_IBEAM,32514IDC_WAIT,32515IDC_CROSS
   ,32516IDC_UPARROW,32640IDC_SIZE,32641IDC_ICON,32642IDC_SIZENWSE
   ,32643IDC_SIZENESW,32644IDC_SIZEWE,32645IDC_SIZENS,32646IDC_SIZEALL
   ,32648IDC_NO,32649IDC_HAND,32650IDC_APPSTARTING,32651IDC_HELP
   
   If Cursor = ; empty, so create blank cursor 
   {
      VarSetCapacity( AndMask, 32*4, 0xFF ), VarSetCapacity( XorMask, 32*4, 0 )
      BlankCursor = 1 ; flag for later
   }
   Else If SubStr( Cursor,1,4 ) = "IDC_" ; load system cursor
   {
      Loop, Parse, SystemCursors, `,
      {
         CursorName := SubStr( A_Loopfield, 6, 15 ) ; get the cursor name, no trailing space with substr
         CursorID := SubStr( A_Loopfield, 1, 5 ) ; get the cursor id
         SystemCursor = 1
         If ( CursorName = Cursor )
         {
            CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )   
            Break               
         }
      }   
      If CursorHandle = ; invalid cursor name given
      {
         Msgbox,, SetCursor, Error: Invalid cursor name
         CursorHandle = Error
      }
   }   
   Else If FileExist( Cursor )
   {
      SplitPath, Cursor,,, Ext ; auto-detect type
      If Ext = ico 
         uType := 0x1   
      Else If Ext in cur,ani
         uType := 0x2      
      Else ; invalid file ext
      {
         Msgbox,, SetCursor, Error: Invalid file type
         CursorHandle = Error
      }      
      FileCursor = 1
   }
   Else
   {   
      Msgbox,, SetCursor, Error: Invalid file path or cursor name
      CursorHandle = Error ; raise for later
   }
   If CursorHandle != Error 
   {
      Loop, Parse, SystemCursors, `,
      {
         If BlankCursor = 1 
         {
            Type = BlankCursor
            %Type%%A_Index% := DllCall( "CreateCursor"
            , Uint,0, Int,0, Int,0, Int,32, Int,32, Uint,&AndMask, Uint,&XorMask )
            CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
            DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
         }         
         Else If SystemCursor = 1
         {
            Type = SystemCursor
            CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )   
            %Type%%A_Index% := DllCall( "CopyImage"
            , Uint,CursorHandle, Uint,0x2, Int,cx, Int,cy, Uint,0 )      
            CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
            DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
         }
         Else If FileCursor = 1
         {
            Type = FileCursor
            %Type%%A_Index% := DllCall( "LoadImageA"
            , UInt,0, Str,Cursor, UInt,uType, Int,cx, Int,cy, UInt,0x10 ) 
            DllCall( "SetSystemCursor", Uint,%Type%%A_Index%, Int,SubStr( A_Loopfield, 1, 5 ) )         
         }          
      }
   }   
}
Also recommend you to check out Coloretta Viva which seems to be an extension of this simple color picker, with the added benefit of zooming in.
Last edited by sumon on 13 Aug 2019, 09:36, edited 3 times in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Colorette - Simple Color Picker (v 2.1)

23 Jul 2019, 07:49

Looks good :clap:.

For anyone interested, the hotkeys are Ctrl + Rbutton to save RGB, and Rbutton to save hex, correct me if I'm wrong.

Cheers.
User avatar
sumon
Posts: 38
Joined: 01 Oct 2013, 14:05
Location: Stockholm, Sweden

Re: Colorette - Simple Color Picker (v 2.1)

23 Jul 2019, 13:19

Helgef wrote:
23 Jul 2019, 07:49
Looks good :clap:.

For anyone interested, the hotkeys are Ctrl + Rbutton to save RGB, and Rbutton to save hex, correct me if I'm wrong.

Cheers.
You're the opposite of wrong. Also, Esc to force the script to exit (cancel the color picking). Updating post.

Thanks!
User avatar
tidbit
Posts: 1273
Joined: 29 Sep 2013, 17:15
Location: USA

Re: Colorette - Simple Color Picker (v 2.1)

24 Jul 2019, 10:35

Holy crap it's Sumon! with an update to a classic script!
rawr. fear me.
*poke*
Is it December 21, 2012 yet?
User avatar
sumon
Posts: 38
Joined: 01 Oct 2013, 14:05
Location: Stockholm, Sweden

Re: Colorette - Simple Color Picker (v 2.1)

26 Jul 2019, 06:45

tidbit wrote:
24 Jul 2019, 10:35
Holy crap it's Sumon! with an update to a classic script!
Hey man! Thanks for the compliment, from another classic AHKer ;)
User avatar
Cerberus
Posts: 172
Joined: 12 Jan 2016, 15:46

Re: Colorette - Simple Color Picker (v 2.1)

10 Aug 2019, 10:21

Nice! I still use the old Colorette, have been using it longer than I can remember, just because it is simple and it works so well. Welcome back, Sumon. I wonder what was updated.
Raymond888
Posts: 17
Joined: 11 Aug 2019, 19:14

Re: Colorette - Simple Color Picker (v 2.1)

11 Aug 2019, 19:24

This is nice and simple to use.
User avatar
sumon
Posts: 38
Joined: 01 Oct 2013, 14:05
Location: Stockholm, Sweden

Re: Colorette - Simple Color Picker (v 2.1)

13 Aug 2019, 09:36

Cerberus wrote:
10 Aug 2019, 10:21
Nice! I still use the old Colorette, have been using it longer than I can remember, just because it is simple and it works so well. Welcome back, Sumon. I wonder what was updated.
Thanks! Always nice to hear that scripts I created get used. I mean, that was the purpose when creating them... :)

As for the updates, minor updates only, mostly allowing for easy separation of the parts of the script that would require Colorette resources (sound and icon) to be installed, adjusting the tooltip to be more smooth and properly located, and adding a better tooltip for RGB colors (while holding ctrl). Adding update log for v 2.1.
User avatar
Cerberus
Posts: 172
Joined: 12 Jan 2016, 15:46

Re: Colorette - Simple Color Picker (v 2.1)

14 Aug 2019, 09:06

sumon wrote:
13 Aug 2019, 09:36
Cerberus wrote:
10 Aug 2019, 10:21
Nice! I still use the old Colorette, have been using it longer than I can remember, just because it is simple and it works so well. Welcome back, Sumon. I wonder what was updated.
Thanks! Always nice to hear that scripts I created get used. I mean, that was the purpose when creating them... :)

As for the updates, minor updates only, mostly allowing for easy separation of the parts of the script that would require Colorette resources (sound and icon) to be installed, adjusting the tooltip to be more smooth and properly located, and adding a better tooltip for RGB colors (while holding ctrl). Adding update log for v 2.1.
Cool, I'll get the updated version. It seems I'm still using version 1.01...
User avatar
joedf
Posts: 8977
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: Colorette - Simple Color Picker (v 2.1)

14 Aug 2019, 23:44

@sumon holy moly! I haven’t seen anything from you in ages. Glad to see some activity from you again :dance:
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
rommmcek
Posts: 1478
Joined: 15 Aug 2014, 15:18

Re: Colorette - Simple Color Picker (v 2.1)

16 Aug 2019, 22:33

Simple script has many advantages. E.g. easy to debug and above all easy to modify.
I had to pick color of web element. But it changes it's color when mouse is hovering above.
So I used this simple yet inspiring script to customize it.

Instr.: Run the script, find hot spot, right click, move the mouse away (or not), procede as by the original script!

Code: Select all

; ******* General ******* 
; COLORETTE
ScriptVersion := 2.1 ; modified by rommmcek
; V 2.1: Removed DLG selection, improved hover tooltip.  
; Script created using Autohotkey (http www.autohotkey.com) 
; AHK version: AHK_L (www.autohotkey.net/~Lexikos/AutoHotkey_L)
;
; AUTHOR: sumon @ the Autohotkey forums
; License: sumon's Std License (see my forum signature)
;
; To add a "pick sound", add the pick_click.wav file and uncomment lines the lines with FileCreateDir, FileInstall (23, 24)
; 
; Thanks to: The Naked General _ jamixzol@gmail.com for his "Flashy and impractical color picker" which inspired me to this.
;
; || To-do ||
; Settings?

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance, Force

; Setup
OnExit, Exit
;~ FileCreateDir, data
;~ FileInstall, data\pick_click.wav, data\pick_click.wav
ColoretteIcon := A_ScriptFullPath

; Hotkeys
Hotkey, Rbutton, CatchColor ; HEX (Default)
Hotkey, ^Rbutton, CatchColor ; RGB

; Initiation
Traytip, Colorette:, RIGHTCLICK to copy HEX value`nAdd CTRL for RGB value, 5
SetSystemCursor("IDC_Cross") ; Reset in OnExit

If (FileExist("colorette.exe"))
   Menu, Tray, Icon, Colorette.exe

; MAIN LOOP: Pick Color

Loop
{
   CoordMode, Mouse, Screen
   if !FixedPoint {
      MouseGetPos X, Y
      if (x>A_ScreenWidth-100)
       mX:= X-75
      else mX := X + 25 ; Offset Tooltip from Mouse
      if y<120
       mY:= Y + 75
      else mY := Y - 120
   }
   PixelGetColor Color, X, Y, RGB
   ColorD := Color ; Build an int based variable
   StringRight, color, color, 6 ; Removes 0x prefix
   SetFormat, IntegerFast, d
   ColorD += 0  ; Sets Var (which previously contained 11) to be 0xb.
   ColorD .= ""  ; Necessary due to the "fast" mode.
   ;~ ModColor := HexModify(Color, 1)
   GetKeyState("LControl") ? ColorMessage := HextoRGB(Color, "Message") : ColorMessage := Color
   Gui, 2:Color, %color%
   Tooltip, %ColorMessage% ; (%ModColor%)
   CoordMode, Pixel 
   Gui, 2:-Caption +ToolWindow +LastFound +AlwaysOnTop +Border ; +0x400000 OR +Border
   Gui, 2:Show, NoActivate x%mX% y%mY% w60 h60
}
return

CatchColor: ; Catch Hover'd color
if !FixedPoint {
   FixedPoint:=1
   return
}

If (A_ThisHotkey = "^Rbutton")
   Out := "RGB"
If (FileExist("data\pick_click.wav"))
   SoundPlay, data\pick_click.wav
; Continue

ColorPicked:
StringRight, color, color, 6 ; Color HEX to RGB (or RGB to RGB)

If (Out = "RGB")
{
   OutColor := HexToRGB(Color)
   OutMsg := HexToRGB(Color, "Message")
   Clipboard := OutMsg
   ;~ OutParse := HexToRGB(Color, "Parse") ; Returns "R,G,B"
}
else
{
   OutColor := Color
   OutMsg :=  "#" . Color  
   Clipboard := OutColor
}

Traytip, Colorette:, %outmsg% picked
RestoreCursors()
Gui, 2:Destroy
Sleep 500
Hotkey, ^Rbutton, Off
Hotkey, Rbutton, Off

Sleep 1500
Gosub, Exit
Return

esc::
Exit:
RestoreCursors()
ExitApp
return

; FUNCTIONS
; : SetSystemCursor() and RestoreCursors()
HexToRGB(Color, Mode="") ; Input: 6 characters HEX-color. Mode can be RGB, Message (R: x, G: y, B: z) or parse (R,G,B)
{
   ; If df, d is *16 and f is *1. Thus, Rx = R*16 while Rn = R*1
   Rx := SubStr(Color, 1,1), Rn := SubStr(Color, 2,1)
   Gx := SubStr(Color, 3,1), Gn := SubStr(Color, 4,1)
   Bx := SubStr(Color, 5,1), Bn := SubStr(Color, 6,1)
   
   AllVars := "Rx|Rn|Gx|Gn|Bx|Bn"
   Loop, Parse, Allvars, | ; Add the Hex values (A - F)
   {
      StringReplace, %A_LoopField%, %A_LoopField%, a, 10
      StringReplace, %A_LoopField%, %A_LoopField%, b, 11
      StringReplace, %A_LoopField%, %A_LoopField%, c, 12
      StringReplace, %A_LoopField%, %A_LoopField%, d, 13
      StringReplace, %A_LoopField%, %A_LoopField%, e, 14
      StringReplace, %A_LoopField%, %A_LoopField%, f, 15
   }
   R := Rx*16+Rn
   G := Gx*16+Gn
   B := Bx*16+Bn
   
   If (Mode = "Message") ; Returns "R: 255 G: 255 B: 255"
      Out := "R:" . R . " G:" . G . " B:" . B
   else if (Mode = "Parse") ; Returns "255,255,255"
      Out := R . "," . G . "," . B
   else
      Out := R . G . B ; Returns 255255255
    return Out
}

; ToBase / FromBase by Lazslo @ http://www.autohotkey.com/forum/post-276241.html#276241
ToBase(n,b) { ; n >= 0, 1 < b <= 36
   Return (n < b ? "" : ToBase(n//b,b)) . ((d:=mod(n,b)) < 10 ? d : Chr(d+87))
}
 
FromBase(s,b) { ; convert base b number s=strings of 0..9,a..z, to AHK number
   Return (L:=StrLen(s))=0 ? "":(L>1 ? FromBase(SubStr(s,1,L-1),b)*b:0) + ((c:=Asc(SubStr(s,0)))>57 ? c-87:c-48)
}

HexModify(n, Add="") ; MsgBox % HexModify("ffffff", -55)
{
   ;~ Hex := "0123456789abcdef"
   R := ToBase(FromBase(SubStr(n, 1, 2), 16) + Add, 16)
   G := ToBase(FromBase(SubStr(n, 3, 2), 16) + Add, 16)
   B := ToBase(FromBase(SubStr(n, 5, 2), 16) + Add, 16)
   return R . G . B
}

RestoreCursors()
{
   SPI_SETCURSORS := 0x57
   DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
}

SetSystemCursor( Cursor = "", cx = 0, cy = 0 )
{
   BlankCursor := 0, SystemCursor := 0, FileCursor := 0 ; init
   
   SystemCursors = 32512IDC_ARROW,32513IDC_IBEAM,32514IDC_WAIT,32515IDC_CROSS
   ,32516IDC_UPARROW,32640IDC_SIZE,32641IDC_ICON,32642IDC_SIZENWSE
   ,32643IDC_SIZENESW,32644IDC_SIZEWE,32645IDC_SIZENS,32646IDC_SIZEALL
   ,32648IDC_NO,32649IDC_HAND,32650IDC_APPSTARTING,32651IDC_HELP
   
   If Cursor = ; empty, so create blank cursor 
   {
      VarSetCapacity( AndMask, 32*4, 0xFF ), VarSetCapacity( XorMask, 32*4, 0 )
      BlankCursor = 1 ; flag for later
   }
   Else If SubStr( Cursor,1,4 ) = "IDC_" ; load system cursor
   {
      Loop, Parse, SystemCursors, `,
      {
         CursorName := SubStr( A_Loopfield, 6, 15 ) ; get the cursor name, no trailing space with substr
         CursorID := SubStr( A_Loopfield, 1, 5 ) ; get the cursor id
         SystemCursor = 1
         If ( CursorName = Cursor )
         {
            CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )   
            Break               
         }
      }   
      If CursorHandle = ; invalid cursor name given
      {
         Msgbox,, SetCursor, Error: Invalid cursor name
         CursorHandle = Error
      }
   }   
   Else If FileExist( Cursor )
   {
      SplitPath, Cursor,,, Ext ; auto-detect type
      If Ext = ico 
         uType := 0x1   
      Else If Ext in cur,ani
         uType := 0x2      
      Else ; invalid file ext
      {
         Msgbox,, SetCursor, Error: Invalid file type
         CursorHandle = Error
      }      
      FileCursor = 1
   }
   Else
   {   
      Msgbox,, SetCursor, Error: Invalid file path or cursor name
      CursorHandle = Error ; raise for later
   }
   If CursorHandle != Error 
   {
      Loop, Parse, SystemCursors, `,
      {
         If BlankCursor = 1 
         {
            Type = BlankCursor
            %Type%%A_Index% := DllCall( "CreateCursor"
            , Uint,0, Int,0, Int,0, Int,32, Int,32, Uint,&AndMask, Uint,&XorMask )
            CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
            DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
         }         
         Else If SystemCursor = 1
         {
            Type = SystemCursor
            CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )   
            %Type%%A_Index% := DllCall( "CopyImage"
            , Uint,CursorHandle, Uint,0x2, Int,cx, Int,cy, Uint,0 )      
            CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
            DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
         }
         Else If FileCursor = 1
         {
            Type = FileCursor
            %Type%%A_Index% := DllCall( "LoadImageA"
            , UInt,0, Str,Cursor, UInt,uType, Int,cx, Int,cy, UInt,0x10 ) 
            DllCall( "SetSystemCursor", Uint,%Type%%A_Index%, Int,SubStr( A_Loopfield, 1, 5 ) )         
         }          
      }
   }   
}
P.s.: I modified gui display position too, especially when near top or right edge of the screen.
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: Colorette - Simple Color Picker (v 2.1)

19 Aug 2019, 07:59

Thanks sumon and rommmcek for all your improvements.
I really like this script. I use it all the time. ;)
I think the script will work better with a magnifying tool.
Here is an easy to use one from the archived forum. (by holomind :thumbup: )

Shortcuts:
#c ...................... hide/show the cross
^+WheelUp ........... Ctrl+Shift+WheelUp to zoom in
^+WheelDown ....... Ctrl+Shift+WheelDown to zoom out
F9 ...................... Hold down F9 key to slow the mouse speed
#Up .................... Mouse move one step with arrow keys
#down ................ Mouse move one step with arrow keys
#left .................. Mouse move one step with arrow keys
#right ................. Mouse move one step with arrow keys
#x ..................... Exit the script

Code: Select all

; =====================================================================================================================
; Name:				Screen Magnifier
; Description:		Simple screen magnifier
; Topic:            https://autohotkey.com/board/topic/10660-screenmagnifier/page-3     
; AHK Version:		1.1.24.03 (A32/U32/U64)
; Tested on:		Win 7 (x64)
; Author:			holomind
; Shortcuts:	  	#c ................ hide/show the cross 
;					^+WheelUp ......... Ctrl+Shift+WheelUp to zoom in
;					^+WheelDown ....... Ctrl+Shift+WheelDown to zoom out
;					F9 ................ Hold down F9 key to slow the mouse speed
;                   #Up ............... Mouse move one step with arrow keys
;                   #down ..............Mouse move one step with arrow keys
;                   #left ..............Mouse move one step with arrow keys
;                   #right .............Mouse move one step with arrow keys
;					#x ................ exit the script
;=======================================================================================================================

#NoEnv
SetBatchLines -1

CoordMode Mouse, Screen
OnExit #x
  zoom = 8                ; initial magnification, 1..32
  halfside = 128          ; circa halfside of the magnifier
  part := halfside/zoom
  Rz := Round(part)
  R := Rz*zoom
  LineMargin := 10
                        ; GUI 2 shows the magnified image
Gui 2:+AlwaysOnTop -Caption +Resize +ToolWindow +E0x20
Gui 2:Show, % "w" 2*R+zoom+3 " h" 2*R+zoom+3 " x0 y0", Magnifier
WinGet MagnifierID, id,  Magnifier
WinSet Transparent, 255, Magnifier ; makes the window invisible to magnification
WinGet PrintSourceID, ID

hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
hdc_frame := DllCall("GetDC", UInt, MagnifierID)

;#############   draw cross lines   ###########################################
DrawCross( M_C , R_C, zoom_c, dc )
  {
        ;specify the style, thickness and color of the cross lines
    h_pen := DllCall( "gdi32.dll\CreatePen", "int", 0, "int", 1, "uint", 0x0000FF)
        ;select the correct pen into DC
    DllCall( "gdi32.dll\SelectObject", "uint", dc, "uint", h_pen )         
        ;update the current position to specified point - 1st horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", M_C, "int", R_C, "uint", 0)
        ;draw a line from the current position up to, but not including, the specified point.
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", R_C)
        ; 2nd horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", M_C, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", R_C+zoom_c)
        ; 3rd horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", R_C, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", 2*R_C+zoom_c-M_C, "int", R_C)
        ; 4th horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", 2*R_C+zoom_c-M_C, "int", R_C+zoom_c)       
        ; 1st vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C, "int", M_C, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", R_C)
        ; 2nd vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", M_C, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C+zoom_c, "int", R_C)
        ; 3rd vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", 2*R_C+zoom_c-M_C)
        ; 4th vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C+zoom_c, "int", 2*R_C+zoom_c-M_C)
} 
SetTimer Repaint, 50   ; flow through

Repaint:
     MouseGetPos x, y
     xz := x-Rz
     yz := y-Rz

     DllCall("gdi32.dll\StretchBlt", UInt,hdc_frame, Int,0, Int,0, Int,2*R+zoom, Int,2*R+zoom
     , UInt,hdd_frame, UInt,xz, UInt,yz, Int,2*Rz+1, Int,2*Rz+1, UInt,0xCC0020) ; SRCCOPY
     
     if (!toggle)
     DrawCross( LineMargin, R, zoom, hdc_frame )
     
     ; keep the frame outside the magnifier and precalculate wanted position
     If (x < (2*R+zoom+8) and y < (2*R+zoom+8))
           pos_new := (2*R+zoom+8)
     Else
           pos_new := 0

     if ( pos_old <> pos_new )          ; only move if the real position of window needs to change
        WinMove Magnifier,, ,pos_new
    
     pos_old := pos_new     ; store value for next loop
    
Return

#c::                        ;hide/show the cross
toggle:=!toggle
return



#x::
     DllCall("gdi32.dll\DeleteDC", UInt,hdc_frame )
     DllCall("gdi32.dll\DeleteDC", UInt,hdd_frame )
   
ExitApp

#+::
^+WheelUp::                      ; Ctrl+Shift+WheelUp to zoom in
#-::
^+WheelDown::                    ; Ctrl+Shift+WheelDown to zoom out
    If (zoom < 31 and ( A_ThisHotKey = "^+WheelUp" or A_ThisHotKey ="#+") )
       zoom *= 1.189207115         ; sqrt(sqrt(2))
    If (zoom >  1 and ( A_ThisHotKey = "^+WheelDown" or A_ThisHotKey = "#-"))
       zoom /= 1.189207115
   
    part := halfside/zoom           ;new calculation of the magnified image
    Rz := Round(part)
    R := Rz*zoom
    Gui 2:Show, % "w" 2*R+zoom+3 " h" 2*R+zoom+3 " x0 y0", Magnifier
    TrayTip,,% "Zoom = " Round(100*zoom) "%"
   
Return

      ; Mouse slow down:
      ; The first parameter is always 0x71 (SPI_SETMOUSESPEED).
      ; The third parameter is the speed (range is 1-20, 10 is default).
F9::
   if  mouse_slow = 
   {
      ; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getting_hardware_information.asp
      ; http://www.autohotkey.com/forum/topic5264.html

    DllCall("SystemParametersInfo", UInt, 0x70, UInt, 0, UIntP, mouse_speed_old, UInt, 0) ; important UintP (eg. return P(ointer) ?) 
    TrayTip,, your old mousespeed was %mouse_speed_old% , setting to 3
    DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, 3, UInt, 0)
    mouse_slow = 1
   }
return

F9 up::
    DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, 10, UInt, 0)
    TrayTip,, restoring your mousespeed 
    mouse_slow = 
return

;Mouse move one step with arrow keys
#Up::MouseMove, 0, -1, 0, R

#Down::MouseMove, 0, 1, 0, R

#Left::MouseMove, -1, 0, 0, R

#Right::MouseMove, 1, 0, 0, R
Cheers,
User avatar
SirSocks
Posts: 360
Joined: 26 Oct 2018, 08:14

Re: Colorette - Simple Color Picker (v 2.1)

01 Apr 2020, 07:18

This is perfect! Thank you!
User avatar
submeg
Posts: 326
Joined: 14 Apr 2017, 20:39
Contact:

Re: Colorette - Simple Color Picker (v 2.1)

02 May 2020, 05:34

SpeedMaster wrote:
19 Aug 2019, 07:59
Thanks sumon and rommmcek for all your improvements.
I really like this script. I use it all the time. ;)
I think the script will work better with a magnifying tool.
Here is an easy to use one from the archived forum. (by holomind :thumbup: )

Shortcuts:
#c ...................... hide/show the cross
^+WheelUp ........... Ctrl+Shift+WheelUp to zoom in
^+WheelDown ....... Ctrl+Shift+WheelDown to zoom out
F9 ...................... Hold down F9 key to slow the mouse speed
#Up .................... Mouse move one step with arrow keys
#down ................ Mouse move one step with arrow keys
#left .................. Mouse move one step with arrow keys
#right ................. Mouse move one step with arrow keys
#x ..................... Exit the script

Code: Select all

; =====================================================================================================================
; Name:				Screen Magnifier
; Description:		Simple screen magnifier
; Topic:            https://autohotkey.com/board/topic/10660-screenmagnifier/page-3     
; AHK Version:		1.1.24.03 (A32/U32/U64)
; Tested on:		Win 7 (x64)
; Author:			holomind
; Shortcuts:	  	#c ................ hide/show the cross 
;					^+WheelUp ......... Ctrl+Shift+WheelUp to zoom in
;					^+WheelDown ....... Ctrl+Shift+WheelDown to zoom out
;					F9 ................ Hold down F9 key to slow the mouse speed
;                   #Up ............... Mouse move one step with arrow keys
;                   #down ..............Mouse move one step with arrow keys
;                   #left ..............Mouse move one step with arrow keys
;                   #right .............Mouse move one step with arrow keys
;					#x ................ exit the script
;=======================================================================================================================

#NoEnv
SetBatchLines -1

CoordMode Mouse, Screen
OnExit #x
  zoom = 8                ; initial magnification, 1..32
  halfside = 128          ; circa halfside of the magnifier
  part := halfside/zoom
  Rz := Round(part)
  R := Rz*zoom
  LineMargin := 10
                        ; GUI 2 shows the magnified image
Gui 2:+AlwaysOnTop -Caption +Resize +ToolWindow +E0x20
Gui 2:Show, % "w" 2*R+zoom+3 " h" 2*R+zoom+3 " x0 y0", Magnifier
WinGet MagnifierID, id,  Magnifier
WinSet Transparent, 255, Magnifier ; makes the window invisible to magnification
WinGet PrintSourceID, ID

hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
hdc_frame := DllCall("GetDC", UInt, MagnifierID)

;#############   draw cross lines   ###########################################
DrawCross( M_C , R_C, zoom_c, dc )
  {
        ;specify the style, thickness and color of the cross lines
    h_pen := DllCall( "gdi32.dll\CreatePen", "int", 0, "int", 1, "uint", 0x0000FF)
        ;select the correct pen into DC
    DllCall( "gdi32.dll\SelectObject", "uint", dc, "uint", h_pen )         
        ;update the current position to specified point - 1st horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", M_C, "int", R_C, "uint", 0)
        ;draw a line from the current position up to, but not including, the specified point.
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", R_C)
        ; 2nd horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", M_C, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", R_C+zoom_c)
        ; 3rd horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", R_C, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", 2*R_C+zoom_c-M_C, "int", R_C)
        ; 4th horizontal
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", 2*R_C+zoom_c-M_C, "int", R_C+zoom_c)       
        ; 1st vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C, "int", M_C, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", R_C)
        ; 2nd vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", M_C, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C+zoom_c, "int", R_C)
        ; 3rd vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C, "int", 2*R_C+zoom_c-M_C)
        ; 4th vertical
    DllCall( "gdi32.dll\MoveToEx", "uint", dc, "int", R_C+zoom_c, "int", R_C+zoom_c, "uint", 0)
    DllCall( "gdi32.dll\LineTo", "uint", dc, "int", R_C+zoom_c, "int", 2*R_C+zoom_c-M_C)
} 
SetTimer Repaint, 50   ; flow through

Repaint:
     MouseGetPos x, y
     xz := x-Rz
     yz := y-Rz

     DllCall("gdi32.dll\StretchBlt", UInt,hdc_frame, Int,0, Int,0, Int,2*R+zoom, Int,2*R+zoom
     , UInt,hdd_frame, UInt,xz, UInt,yz, Int,2*Rz+1, Int,2*Rz+1, UInt,0xCC0020) ; SRCCOPY
     
     if (!toggle)
     DrawCross( LineMargin, R, zoom, hdc_frame )
     
     ; keep the frame outside the magnifier and precalculate wanted position
     If (x < (2*R+zoom+8) and y < (2*R+zoom+8))
           pos_new := (2*R+zoom+8)
     Else
           pos_new := 0

     if ( pos_old <> pos_new )          ; only move if the real position of window needs to change
        WinMove Magnifier,, ,pos_new
    
     pos_old := pos_new     ; store value for next loop
    
Return

#c::                        ;hide/show the cross
toggle:=!toggle
return



#x::
     DllCall("gdi32.dll\DeleteDC", UInt,hdc_frame )
     DllCall("gdi32.dll\DeleteDC", UInt,hdd_frame )
   
ExitApp

#+::
^+WheelUp::                      ; Ctrl+Shift+WheelUp to zoom in
#-::
^+WheelDown::                    ; Ctrl+Shift+WheelDown to zoom out
    If (zoom < 31 and ( A_ThisHotKey = "^+WheelUp" or A_ThisHotKey ="#+") )
       zoom *= 1.189207115         ; sqrt(sqrt(2))
    If (zoom >  1 and ( A_ThisHotKey = "^+WheelDown" or A_ThisHotKey = "#-"))
       zoom /= 1.189207115
   
    part := halfside/zoom           ;new calculation of the magnified image
    Rz := Round(part)
    R := Rz*zoom
    Gui 2:Show, % "w" 2*R+zoom+3 " h" 2*R+zoom+3 " x0 y0", Magnifier
    TrayTip,,% "Zoom = " Round(100*zoom) "%"
   
Return

      ; Mouse slow down:
      ; The first parameter is always 0x71 (SPI_SETMOUSESPEED).
      ; The third parameter is the speed (range is 1-20, 10 is default).
F9::
   if  mouse_slow = 
   {
      ; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getting_hardware_information.asp
      ; http://www.autohotkey.com/forum/topic5264.html

    DllCall("SystemParametersInfo", UInt, 0x70, UInt, 0, UIntP, mouse_speed_old, UInt, 0) ; important UintP (eg. return P(ointer) ?) 
    TrayTip,, your old mousespeed was %mouse_speed_old% , setting to 3
    DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, 3, UInt, 0)
    mouse_slow = 1
   }
return

F9 up::
    DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, 10, UInt, 0)
    TrayTip,, restoring your mousespeed 
    mouse_slow = 
return

;Mouse move one step with arrow keys
#Up::MouseMove, 0, -1, 0, R

#Down::MouseMove, 0, 1, 0, R

#Left::MouseMove, -1, 0, 0, R

#Right::MouseMove, 1, 0, 0, R
Cheers,
This code is great! But I have been having trouble getting it to close when I've #Include it into my main script due to overlapping hotkeys.

I had a look on that thread, and came across Icarus' variant, and it's got some awesome changes such as changing the size of the magnifier, and being able to specify where the box sits.

I was wondering, would it be possible to add holomind's crosshair to the above linked script?
____________________________________
Check out my site, submeg.com
Connect with me on LinkedIn
Courses on AutoHotkey :ugeek:
LAPIII
Posts: 669
Joined: 01 Aug 2021, 06:01

Re: Colorette - Simple Color Picker (v 2.1)

12 Jul 2022, 10:28

Can someone tell me how to start Screen Magnifier?
User avatar
boiler
Posts: 17079
Joined: 21 Dec 2014, 02:44

Re: Colorette - Simple Color Picker (v 2.1)

12 Jul 2022, 21:08

LAPIII wrote: Can someone tell me how to start Screen Magnifier?
It starts upon running the script. Did you try it?
LAPIII
Posts: 669
Joined: 01 Aug 2021, 06:01

Re: Colorette - Simple Color Picker (v 2.1)

12 Jul 2022, 21:10

Okay, now it's working for me.
User avatar
spaceowl
Posts: 22
Joined: 16 May 2021, 06:46

Re: Colorette - Simple Color Picker (v 2.1)

25 Jul 2023, 07:54

Hello, when I use this script the first time after login in windows, it shows wrong colors: I had to restart it, after the first restart, it always shows the right colors. This is strange.
User avatar
sumon
Posts: 38
Joined: 01 Oct 2013, 14:05
Location: Stockholm, Sweden

Re: Colorette - Simple Color Picker (v 2.1)

25 Jul 2023, 11:55

spaceowl wrote:
25 Jul 2023, 07:54
Hello, when I use this script the first time after login in windows, it shows wrong colors: I had to restart it, after the first restart, it always shows the right colors. This is strange.
Hi! Sounds quite strange, maybe if I had more information I could guess what is wrong.

One issue I have had with wrong colors is when the screen resolution is virtually set. Not sure, but could be something like that?
iseahound
Posts: 1451
Joined: 13 Aug 2016, 21:04
Contact:

Re: Colorette - Simple Color Picker (v 2.1)

26 Jul 2023, 14:54

Have you considered migrating this script to AutoHotkey v2?

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: gwarble, Jasonosaj, Skrell and 107 guests