argumentum Posted November 30, 2019 Posted November 30, 2019 (edited) ..I'm coding the High Contrast theme editor and using the _ChooseColor() I wandered why it does not keep the the custom colors I've added. Found that adding a static declaration would do it. But why stop there. Why not keep going, So I put this together that is non code braking ( backwards compatible ), to replace the one in <Misc.au3> Spoiler expandcollapse popup_ChooseColor_mod_Example() Func _ChooseColor_mod_Example() Local $aCustColors[17] $aCustColors[1] = 0xFF0000 $aCustColors[16] = 0x0000FF $aCustColors = _ChooseColor_mod(2, "0x00ff00", 2, 0, $aCustColors) ConsoleWrite(@CRLF & $aCustColors[0] & @CRLF & @CRLF) ConsoleWrite(@CRLF & _ChooseColor_mod(2, $aCustColors[0], 2, 0, $aCustColors)[0] & @CRLF & @CRLF) ConsoleWrite(@CRLF & _ChooseColor_mod(2, "0x00ff00", 2) & @CRLF & @CRLF) ; just as default behaviour ConsoleWrite(@CRLF & _ChooseColor_mod(2, "0x00ff00", 2, 0, 'reset as is neither "Default" nor "Array[17]"') & @CRLF & @CRLF) ; just as default behaviour EndFunc ;==>_ChooseColor_mod_Example ; #FUNCTION# ==================================================================================================================== ; Name ..........: _ChooseColor_mod ; Description ...: ; Syntax ........: _ChooseColor_mod([$iReturnType = 0[, $iColorRef = 0[, $iRefType = 0[, $hWndOwnder = 0[, $vCustColors = Default]]]]]) ; Parameters ....: $iReturnType - [optional] an integer value. Default is 0. See remarks for values. ; $iColorRef - [optional] an integer value. Default is 0. ; $iRefType - [optional] an integer value. Default is 0. See remarks for values. ; $hWndOwnder - [optional] a handle to the parent window. Default is 0. ; $vCustColors - [optional] an array of colors to show as custom values. See remarks for values. ; Return values .: Success - Hex value of the selected color ; Failure - $vCustomColors is returned if set, otherwise, -1 is returned. Also sets @error: ; | -2 - User initialized $tagCustcolors via $vCustColors. ; | -3 - User canceled or invalid dll struct. ; | -4 - Invalid $iReturnType value. ; | Other - Error returned from Dll call. ; Author ........: Gary Frost (gafrost) ; Modified ......: argumentum ; Remarks .......: $iReturnType can be 0 (RGB COLORREF), 1 (Hex BGR), or 2 (Hex RGB). ; $iRefType can be 0 (ColorRef), 1 (BGR Hex), or 2 (RGB Hex). ; $vCustColors is a zero based array[17] where: ; index 0 hold the color returned by the function. ; index 1 to 16 are the colors to use in Custom colors in RGB. ; One can pass the array with array[0] = -2 to initialize the custom colors without loading the interface. ; When $vCustColors is used, it returns the modified array. ( not the color as integer ). ; Anything other than Default or a proper array, will clear $tagCustcolors ( holder of the custom colors ). ; When $vCustColors is omited or Default, $tagCustcolors is kept ( hence, no need for the array to keep custom colors ). ; Related .......: Same Func from <Misc.au3> ; Link ..........: https://www.autoitscript.com/forum/topic/200985-_choosecolor-but-better/ ; Example .......: YES ; =============================================================================================================================== Func _ChooseColor_mod($iReturnType = 0, $iColorRef = 0, $iRefType = 0, $hWndOwnder = 0, $vCustColors = Default) ; basic code from Misc.au3 ; https://www.autoitscript.com/forum/topic/200985-_choosecolor-but-better/ ; added here for independance of #include <Misc.au3> Local Static $tagCHOOSECOLOR = "dword Size;hwnd hWndOwnder;handle hInstance;dword rgbResult;ptr CustColors;dword Flags;lparam lCustData;" & _ "ptr lpfnHook;ptr lpTemplateName" Local Static $__MISCCONSTANT_CC_ANYCOLOR = 0x0100 Local Static $__MISCCONSTANT_CC_FULLOPEN = 0x0002 Local Static $__MISCCONSTANT_CC_RGBINIT = 0x0001 ; added here for independance of #include <Misc.au3> Local $vReturn, $bCustColors = False, $tagCustcolors = "dword[16]" Local $tChoose = DllStructCreate($tagCHOOSECOLOR) Local Static $tCc = DllStructCreate($tagCustcolors) ; added Static (mod.), to keep $tagCustcolors changes by user when called again. If $vCustColors == Default Then ; nothing ElseIf UBound($vCustColors) = 17 Then $bCustColors = True For $n = 1 To 16 DllStructSetData($tCc, 1, $vCustColors[$n], $n) Next Else $tCc = DllStructCreate($tagCustcolors) ; reset, just in case you'd want to have it default again EndIf If $iRefType = 1 Then ; BGR hex color to colorref $iColorRef = Int($iColorRef) ElseIf $iRefType = 2 Then ; RGB hex color to colorref $iColorRef = Hex(String($iColorRef), 6) $iColorRef = '0x' & StringMid($iColorRef, 5, 2) & StringMid($iColorRef, 3, 2) & StringMid($iColorRef, 1, 2) EndIf DllStructSetData($tChoose, "Size", DllStructGetSize($tChoose)) DllStructSetData($tChoose, "hWndOwnder", $hWndOwnder) DllStructSetData($tChoose, "rgbResult", $iColorRef) DllStructSetData($tChoose, "CustColors", DllStructGetPtr($tCc)) DllStructSetData($tChoose, "Flags", BitOR($__MISCCONSTANT_CC_ANYCOLOR, $__MISCCONSTANT_CC_FULLOPEN, $__MISCCONSTANT_CC_RGBINIT)) Local $aResult = DllCall("comdlg32.dll", "bool", "ChooseColor", "struct*", $tChoose) If @error Then If Not $bCustColors Then Return SetError(@error, @extended, -1) Else $vCustColors[0] = -1 Return SetError(@error, @extended, $vCustColors) EndIf EndIf If $bCustColors Then ; this here is better than at the end, For $n = 1 To 16 ; that way you'll get the custom colors anyway. $vCustColors[$n] = DllStructGetData($tCc, 1, $n) Next If $vCustColors[0] = -2 Then Return $vCustColors EndIf If $aResult[0] = 0 Then ; Return SetError(-3, -3, -1) ; user selected cancel or struct settings incorrect If Not $bCustColors Then Return SetError(-3, -3, -1) Else $vCustColors[0] = -1 Return SetError(-3, -3, $vCustColors) EndIf EndIf Local $sColor_picked = DllStructGetData($tChoose, "rgbResult") If $iReturnType = 1 Then ; return Hex BGR Color $vReturn = '0x' & Hex(String($sColor_picked), 6) ElseIf $iReturnType = 2 Then ; return Hex RGB Color $sColor_picked = Hex(String($sColor_picked), 6) $vReturn = '0x' & StringMid($sColor_picked, 5, 2) & StringMid($sColor_picked, 3, 2) & StringMid($sColor_picked, 1, 2) ElseIf $iReturnType = 0 Then ; return RGB COLORREF $vReturn = $sColor_picked Else $vReturn = -1 SetError(-4, -4) EndIf If Not $bCustColors Then Return $vReturn $vCustColors[0] = $vReturn Return $vCustColors EndFunc ;==>_ChooseColor_mod Hopefully will replace the default one in the next release Better use the new code down this post. Edited May 17, 2020 by argumentum better code seadoggie01 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
seadoggie01 Posted December 2, 2019 Posted December 2, 2019 I like it! Two (minor) nitpicks: 1. $iCustColors is really a boolean, should be used and named as such (Dyslexia is a b***h with 0's and 1's, so I never remember which is True) 2. Include a header to let us know what the possible results of the function are... I guessed a bit in generating this ; #FUNCTION# ==================================================================================================================== ; Name ..........: _ChooseColor_mod ; Description ...: ; Syntax ........: _ChooseColor_mod([$iReturnType = 0[, $iColorRef = 0[, $iRefType = 0[, $hWndOwnder = 0[, $vCustColors = Default]]]]]) ; Parameters ....: $iReturnType - [optional] an integer value. Default is 0. See remarks for values. ; $iColorRef - [optional] an integer value. Default is 0. ; $iRefType - [optional] an integer value. Default is 0. See remarks for values. ; $hWndOwnder - [optional] a handle to the parent window. Default is 0. ; $vCustColors - [optional] an array of colors to show as custom values. Default is Default. ; Return values .: Success - Hex value of the selected color ; Failure - $vCustomColors is returned if set, otherwise, -1 is returned. Also sets @error: ; | -3 - User canceled or invalid dll struct. ; | -4 - Invalid $iReturnType value. ; | Other - Error returned from Dll call. ; Author ........: argumentum ; Modified ......: ; Remarks .......: $iReturnType can be 0 (RGB COLORREF), 1 (Hex BGR), or 2 (Hex RGB). ;~ $iRefType can be 0 (ColorRef), 1 (BGR Hex), or 2 (RGB Hex). ; Related .......: ; Link ..........: https://www.autoitscript.com/forum/topic/200985-_choosecolor-but-better/ ; Example .......: ; =============================================================================================================================== argumentum 1 All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types
argumentum Posted December 2, 2019 Author Posted December 2, 2019 6 hours ago, seadoggie01 said: Two (minor) nitpicks Done, and done. seadoggie01 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Solution argumentum Posted May 17, 2020 Author Solution Posted May 17, 2020 (edited) ok, this, I believe is a good approach and fixes the lies in the description from the prior incarnation expandcollapse popup#include <AutoItConstants.au3>; For $UBOUND_* #include <GUIConstantsEx.au3> #include <Misc.au3> #include <WindowsConstants.au3> Example() Func Example() Local $hGUI, $idCOLORREF, $idBGR, $idRGB, $idMemo, $idRGBwA1, $idRGBwA2, $idClear $hGUI = GUICreate("_ChooseColor() Example", 400, 300) $idMemo = GUICtrlCreateEdit("", 2, 55, 396, 200, BitOR($WS_VSCROLL, $WS_HSCROLL)) GUICtrlSetFont($idMemo, 10, 400, 0, "Courier New") $idCOLORREF = GUICtrlCreateButton("COLORREF", 40, 10, 80, 40) $idBGR = GUICtrlCreateButton("BGR", 130, 10, 80, 40) $idRGB = GUICtrlCreateButton("RGB", 220, 10, 80, 40) $idClear = GUICtrlCreateButton("Clear", 310, 10, 60, 40) $idRGBwA1 = GUICtrlCreateButton("RGB + custom #1", 80, 260, 100, 40) $idRGBwA2 = GUICtrlCreateButton("RGB + custom #2", 210, 260, 100, 40) GUISetState(@SW_SHOW) Local $aCustColors1[17] $aCustColors1[0] = -9 ; init. the custom colors $aCustColors1[3] = 0xFF0000 ; if you would like to, $aCustColors1[16] = 0x0000FF ; without having to load the interface. _ChooseColor_Mod_2($aCustColors1) Local $aCustColors2[17] $aCustColors2[2] = 0x0000FF $aCustColors2[15] = 0xFF0000 While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIDelete() ExitLoop Case $idClear GUICtrlSetState($idClear, $GUI_DISABLE) _ChooseColor_Mod_2(-10) Sleep(200) ; some feedback to show something was done =) GUICtrlSetState($idClear, $GUI_ENABLE) Case $idCOLORREF _ShowChoice($hGUI, $idMemo, 0, _ChooseColor_Mod_2(0, 255, 0, $hGUI), "COLORREF color of your choice: ") Case $idBGR _ShowChoice($hGUI, $idMemo, 1, _ChooseColor_Mod_2(2, 0x808000, 1, $hGUI), "BGR Hex color of your choice: ") Case $idRGB _ShowChoice($hGUI, $idMemo, 2, _ChooseColor_Mod_2(2, 0x0080C0, 2, $hGUI), "RGB Hex color of your choice: ") Case $idRGBwA1 $aCustColors1[0] = 2 ; this is the "ReturnType" $aCustColors1 = _ChooseColor_Mod_2($aCustColors1, 0x0080C0, 2, $hGUI) ; to update the saved custom colors back to the array _ShowChoice($hGUI, $idMemo, 2, $aCustColors1[0], "RGB Hex color of your choice ( #1 ): ") Case $idRGBwA2 $aCustColors2[0] = 2 _ShowChoice($hGUI, $idMemo, 2, _ChooseColor_Mod_2($aCustColors2, 0x0080C0, 2, $hGUI)[0], "RGB Hex color of your choice ( #2 ): ") EndSwitch WEnd EndFunc ;==>Example Func _ShowChoice($hGUI, $idMemo, $iType, $iChoose, $sMessage) Local $sCr If $iChoose <> -1 Then If $iType = 0 Then ; convert COLORREF to RGB for this example $sCr = Hex($iChoose, 6) GUISetBkColor('0x' & StringMid($sCr, 5, 2) & StringMid($sCr, 3, 2) & StringMid($sCr, 1, 2), $hGUI) Else GUISetBkColor($iChoose, $hGUI) EndIf GUICtrlSetData($idMemo, $sMessage & $iChoose & @CRLF, 1) Else GUICtrlSetData($idMemo, "User Canceled Selction" & @CRLF, 1) EndIf EndFunc ;==>_ShowChoice ; #FUNCTION# ==================================================================================================================== ; Name ..........: _ChooseColor_Mod_2 ; Description ...: ; Syntax ........: _ChooseColor_Mod_2([$vReturnType = 0[, $iColorRef = 0[, $iRefType = 0[, $hWndOwnder = 0]]]]) ; Parameters ....: $vReturnType : [optional] an integer value. Default is 0. See remarks for values. ; $iColorRef : [optional] an integer value. Default is 0. ; $iRefType : [optional] an integer value. Default is 0. See remarks for values. ; $hWndOwnder : [optional] a handle to the parent window. Default is 0. ; Return values .: Success - Hex value of the selected color ; Failure - $vCustomColors is returned if set, otherwise, -1 is returned. Also sets @error: ; | -3 : User canceled or invalid dll struct. ; | -4 : Invalid $vReturnType value. ; | -5 : Invalid $vReturnType array. ; | Other : Error returned from Dll call. ; Author ........: Gary Frost (gafrost) ; Modified ......: argumentum ; Remarks .......: $vReturnType can be 0 (RGB COLORREF), 1 (Hex BGR), 2 (Hex RGB), ; -9 (return saved custom colors), ; -10 (return saved custom colors and clear/remove saved custom colors), ; or an array ( see remark below ). ; ; $iRefType can be 0 (ColorRef), 1 (BGR Hex), or 2 (RGB Hex). ; ; $vReturnType can be an array[17] where: ; index 0 holds a value of: ; 0 : COLORREF rgbcolor ; 1 : BGR hex ; 2 : RGB hex ; -9 : returns the currently saved custom colors as array[17], and by the way, is ; where the return value is placed on return ( when used as array ). ; ; index 1 to 16 are the colors to use in Custom colors in RGB. ; ; When $vReturnType is an array, it returns the modified array. ( not the color as integer ). ; with the selected color in array[0], unless canceled by which no update will occur. ; ; Adding int(10) to $vReturnType, when used as an integer, will also clear the saved custom colors. ; ; Related .......: Same Func from <Misc.au3> ; Link ..........: https://www.autoitscript.com/forum/topic/200985-_choosecolor-but-better/ ; Example .......: YES Func _ChooseColor_Mod_2($vReturnType = 0, $iColorRef = 0, $iRefType = 0, $hWndOwnder = 0) Local $tagCustcolors = "dword[16]" Local $tChoose = DllStructCreate($tagCHOOSECOLOR) ; mod. init. start Local Static $tCc = DllStructCreate($tagCustcolors) ; keep the colors Local $iReturnType, $vReturn If $vReturnType = -9 Or $vReturnType = -10 Then ; get $tagCustcolors as array Local $a_tCc = __ChooseColor_TagToArray($tCc) $a_tCc[0] = -1 If $vReturnType = -10 Then $tCc = DllStructCreate($tagCustcolors) Return $a_tCc ElseIf $vReturnType > 9 Then ; re-init./clear $tCc, and continue on a clean slate, just "10 + ReturnType" $tCc = DllStructCreate($tagCustcolors) ; ( maybe unnecessary but the user may want to ) $iReturnType = $vReturnType - 10 ElseIf IsArray($vReturnType) Then ; user declared Custcolors array If UBound($vReturnType, $UBOUND_ROWS) = 17 And UBound($vReturnType, $UBOUND_DIMENSIONS) = 1 Then For $n = 1 To 16 DllStructSetData($tCc, 1, $vReturnType[$n], $n) Next If $vReturnType[0] = -9 Then ; ..consistent with "-9 = return $tagCustcolors as array" $vReturnType[0] = 0 ; set back to default "ReturnType" Return $vReturnType EndIf If $vReturnType[0] > 9 Then $vReturnType[0] -= 10 ; just in case the user mistakenly think it needs to $iReturnType = $vReturnType[0] Else Return SetError(-5, 0, -1) ; unexpected array format EndIf Else $iReturnType = $vReturnType EndIf If $iReturnType < 0 Or $iReturnType > 2 Then ; unexpected ReturnType SetError(-4, -4) ; moved here to avoid loading If IsArray($vReturnType) Then $vReturnType[0] = -1 Return $vReturnType EndIf Return -1 EndIf ; mod. init. end If $iRefType = 1 Then ; BGR hex color to colorref $iColorRef = Int($iColorRef) ElseIf $iRefType = 2 Then ; RGB hex color to colorref $iColorRef = Hex(String($iColorRef), 6) $iColorRef = '0x' & StringMid($iColorRef, 5, 2) & StringMid($iColorRef, 3, 2) & StringMid($iColorRef, 1, 2) EndIf DllStructSetData($tChoose, "Size", DllStructGetSize($tChoose)) DllStructSetData($tChoose, "hWndOwnder", $hWndOwnder) DllStructSetData($tChoose, "rgbResult", $iColorRef) DllStructSetData($tChoose, "CustColors", DllStructGetPtr($tCc)) DllStructSetData($tChoose, "Flags", BitOR($__MISCCONSTANT_CC_ANYCOLOR, $__MISCCONSTANT_CC_FULLOPEN, $__MISCCONSTANT_CC_RGBINIT)) Local $aResult = DllCall("comdlg32.dll", "bool", "ChooseColor", "struct*", $tChoose) If @error Then SetError(@error, @extended) If IsArray($vReturnType) Then $vReturnType[0] = -1 Return $vReturnType EndIf Return -1 EndIf If $aResult[0] = 0 Then SetError(-3, -3) ; user selected cancel or struct settings incorrect If IsArray($vReturnType) Then $vReturnType[0] = -1 Return $vReturnType EndIf Return -1 EndIf Local $sColor_picked = DllStructGetData($tChoose, "rgbResult") If $iReturnType = 1 Then ; return Hex BGR Color $vReturn = '0x' & Hex(String($sColor_picked), 6) ElseIf $iReturnType = 2 Then ; return Hex RGB Color $sColor_picked = Hex(String($sColor_picked), 6) $vReturn = '0x' & StringMid($sColor_picked, 5, 2) & StringMid($sColor_picked, 3, 2) & StringMid($sColor_picked, 1, 2) ElseIf $iReturnType = 0 Then ; return RGB COLORREF $vReturn = $sColor_picked Else SetError(-4, -4) $vReturn = -1 EndIf If IsArray($vReturnType) Then $vReturnType = __ChooseColor_TagToArray($tCc) $vReturnType[0] = $vReturn Return $vReturnType EndIf Return $vReturn EndFunc ;==>_ChooseColor_Mod_2 Func __ChooseColor_TagToArray(ByRef $tag) ; internal Local $aArray[17] For $n = 1 To 16 $aArray[$n] = DllStructGetData($tag, 1, $n) Next Return $aArray EndFunc ;==>__ChooseColor_TagToArray Edit: I guess the most practical use is to init. the colors and use as usual. The rest of the options, are there for the user's fancy. Edit 2: This is now part of beta 3.3.15.4 Edited December 27, 2021 by argumentum corrected text in the code Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now