Jump to content
Sign in to follow this  

System Color Picker WITH Custom Colors

Recommended Posts


One thing was preventing me getting CorzSpaZio (my disk space monitor) to v1.0, and that was custom colors in the system color picker. I figured using my Color Pickin Chooser for picking only two colors was total overkill, and using the picker in comdlg32.dll seemed much smarter, if only the thing would remember custom colors. After searching around the forum, I almost came to the conclusion that it couldn't be done!

Of course it can be done, and figured someone else might be interested in the code, so I've put together a wee demo.

The main function is similar to _ChooseColor() from the UDF's, but a) accepts and returns only AutoIt RGB colors (I have no need for other color values in CorzSpaZio) and B) must be fed (and returns) an array of 17 colors. Also note, it requires the Beta (for the StringSplit(), though it would be trivial to alter it to work with the release version of AutoIt, if anyone uses that). Here goes..

#include <GUIConstants.au3>

; System Color Picker WITH Custom Colors..

Global Const $CC_ANYCOLOR = 0x100
Global Const $CC_FULLOPEN = 0x2
Global Const $CC_RGBINIT  = 0x1

AutoItSetOption("GUIOnEventMode", 1)

global $MyColors[17]

$Gui = GUICreate("Choose a color", 500, 250, -1, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, '_Exit')

GUICtrlCreateButton("Click me to choose a color!", 100, 100, 300, 30)
GUICtrlSetOnEvent(-1, "AltColorPicker")


While 1

Func AltColorPicker()
    local $NewColors = _CustomChooseColor($MyColors, $Gui)
    if not IsArray($NewColors) then return false
    $MyColors = $NewColors 

Func _Exit()

; _CustomChooseColor()
; An alternative version of the AutoIt system color chooser dialog function.
; This version can store and retrieve the 16 custom colors. Nifty.
; Send an array of 17 AutoIt RGB (e.g. 0xF0EBC3) colors, the first $array[0] being the
; color you wish to initially set in the picker, and the other 16, any custom colors
; you want to set. Empty values can be set to 0.
; Returns an array of 17 colors, $array[0] being the color picked, and the other 16, 
; any custom colors the user may have chosen. You can, of course, store these and then
; send them back to the color picker the next time it is called.
; NOTE: This function accepts and returns AutoIt RGB colors. If you need to convert to
; and from other color values, use ConvertColorValue() (from corz_colors.au3)
; corz at corz dot org 2008
func _CustomChooseColor($CustomColors=0, $hWndOwnder=0)
    local $tcc, $tChoose, $color_picked, $iResult, $ret_array[17], $ccolor

    if not IsArray($CustomColors) or Ubound($CustomColors) < 17 then 
        $CustomColors = StringSplit("0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", ",", 2)

    $tChoose = DllStructCreate("dword Size;hwnd hWndOwnder;hwnd;int rgbResult;ptr CustColors;dword Flags;int;ptr;ptr")
    $tcc = DllStructCreate("int ccolors[16]")
    $CustomColors[0] = '0x' & StringMid($CustomColors[0], 7, 2) & StringMid($CustomColors[0], 5, 2) & StringMid($CustomColors[0], 3, 2)

    DllStructSetData($tChoose, "Size", DllStructGetSize($tChoose))
    DllStructSetData($tChoose, "hWndOwnder", $hWndOwnder)
    DllStructSetData($tChoose, "rgbResult", $CustomColors[0])
    DllStructSetData($tChoose, "CustColors", DllStructGetPtr($tcc))

    for $i = 1 to 16 ; set the custom colors..
        $ccolor = Dec(StringMid($CustomColors[$i], 7, 2) & StringMid($CustomColors[$i], 5, 2) & StringMid($CustomColors[$i], 3, 2))
        DllStructSetData($tcc, "ccolors", $ccolor, $i)

    DllStructSetData($tChoose, "Flags", BitOR($CC_ANYCOLOR, $CC_FULLOPEN, $CC_RGBINIT))
    $iResult = DllCall("comdlg32.dll", "long", "ChooseColor", "ptr", DllStructGetPtr($tChoose))
    if ($iResult[0] == 0) then return SetError(-3, -3, -1)

    $color_picked = DllStructGetData($tChoose, "rgbResult")
    if not $color_picked then return SetError(-4, -4, -1)
    for $i = 1 to 16
        $cc = Hex(DllStructGetData($tcc, "ccolors", $i), 6)
        $ret_array[$i] = '0x' & StringMid($cc, 5, 2) & StringMid($cc, 3, 2) & StringMid($cc, 1,   2)

    $color_picked = Hex(String($color_picked), 6)
    $ret_array[0] = '0x' & StringMid($color_picked, 5, 2) & StringMid($color_picked, 3, 2) & StringMid($color_picked, 1, 2)
    return $ret_array

; it would be easy enough to copy this functionality back into _ChooseColor(), if you really wanted to.

; a couple of functions you may find useful when using the custom color chooser..
func SaveCustomColors()
    if not IsArray($MyColors) or UBound($MyColors) < 17 then return false
    local $color_str
    for $i = 1 to 16
        $color_str &= $MyColors[$i] & ","
    $color_str = StringTrimRight($color_str, 1)
    if IniWrite("customcolors.ini", "Custom Colors", "custom_colors", $color_str) then return true

; you application would probably set [0] elsewhere, but here we'll just store and replace
; it temporarily (replacing the AutoIt "total" element $array[0]) for the sake of the demo.
func LoadCustomColors()
    local $tmp = $MyColors[0]
    local $color_str = IniRead("customcolors.ini", "Custom Colors", "custom_colors", "")
    $MyColors = StringSplit($color_str, ",")
    $MyColors[0] = $tmp

Have fun!



nothing is foolproof to the sufficiently talented fool..

Share this post

Link to post
Share on other sites

Oops, got an array subscript error :)

Edit: On line 74

Edited by monoceres

Broken link? PM me and I'll send you the file!

Share this post

Link to post
Share on other sites

Nothing to do with me!



nothing is foolproof to the sufficiently talented fool..

Share this post

Link to post
Share on other sites

From the help file:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>

Opt('MustDeclareVars', 1)


Func _Color_Example()
    Local $GUI, $Btn_COLORREF, $Btn_BGR, $Btn_RGB, $iMemo

    $GUI = GUICreate("_ChooseColor() Example", 400, 300)
    $iMemo = GUICtrlCreateEdit("", 2, 55, 396, 200, BitOR($WS_VSCROLL, $WS_HSCROLL))
    GUICtrlSetFont($iMemo, 10, 400, 0, "Courier New")
    $Btn_COLORREF = GUICtrlCreateButton("COLORREF", 70, 10, 80, 40)
    $Btn_BGR = GUICtrlCreateButton("BGR", 160, 10, 80, 40)
    $Btn_RGB = GUICtrlCreateButton("RGB", 250, 10, 80, 40)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
            Case $Btn_COLORREF
                _ShowChoice($GUI, $iMemo, 0, _ChooseColor(0, 255, 0, $GUI), "COLORREF color of your choice: ")
            Case $Btn_BGR
                _ShowChoice($GUI, $iMemo, 1, _ChooseColor(2, 0x808000, 1, $GUI), "BGR Hex color of your choice: ")
            Case $Btn_RGB
                _ShowChoice($GUI, $iMemo, 2, _ChooseColor(2, 0x0080C0, 2, $GUI), "RGB Hex color of your choice: ")
EndFunc   ;==>_Color_Example

Func _ShowChoice($GUI, $iMemo, $Type, $Choose, $sMessage)
    Local $cr
    If $Choose <> -1 Then
        If $Type = 0 Then ; convert COLORREF to RGB for this example
            $cr = Hex($Choose, 6)
            GUISetBkColor('0x' & StringMid($cr, 5, 2) & StringMid($cr, 3, 2) & StringMid($cr, 1, 2), $GUI)
            GUISetBkColor($Choose, $GUI)
        GUICtrlSetData($iMemo, $sMessage & $Choose & @CRLF, 1)

        GUICtrlSetData($iMemo, "User Canceled Selction" & @CRLF, 1)
EndFunc   ;==>_ShowChoice

SciTE for AutoItDirections for Submitting Standard UDFs


Don't argue with an idiot; people watching may not be able to tell the difference.


Share this post

Link to post
Share on other sites

Gary, I don't understand what that example has to do with custom colors.

Am I missing something?



nothing is foolproof to the sufficiently talented fool..

Share this post

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
Sign in to follow this