Joined: December 26th, 2005, 4:40 pm Posts: 8776
|
Quote: ChooseColor()Quote: Credit: This standalone version of ChooseColor is based on majkinetor's work .. Thanks! Scripts & Functions Topic : ChooseColor wrapper
Also refer: Ask-for-Help Topic : How to call the standard Choose-Color-dialog? - Micha ChooseColor() is a 45 line standalone wrapper function to call the built-in windows ChooseColor Dialog. This version of ChooseColor wrapper additionally saves the Custom Colors ( if any selected ) to the default file named CUSTOMCOLOR.BIN into the Windows folder. Usage : ChooseColor( Color, hPar, ccFile)
- The function returns the hex color code ( in R G B format ) or -1 if the dialog was cancelled with close button or if escape was pressed.
- The first parameter may contain a valid color code ( in R G B format ) to initialise a default selected color on the dialog.
- The dialog opens @ coordinates 0,0 relative to the window ID passed as the parameter 2. If parameter 2 is null/void, Desktop is assumed to be the parent window.
- Only 16 different colors can be saved as Custom Colors. Parameter 3 facilitates to specify a different filename so that additional Custom color files can be maintained to overcome this limit.
MSDN Reference : ChooseColor Function, CHOOSECOLOR Structure
The function along with a test demo:
Code: Gui, Add, Button, x200 y275 w150 gChangeBG, Change BackGround Color Gui, Show, , ChooseColor() Demo Return
ChangeBG: GuiColor := ChooseColor( GuiColor, WinExist() ) IfGreaterOrEqual,GuiColor,0, Gui,Color,%GuiColor% Return
GuiClose: ExitApp Return
ChooseColor( Color=0x0, hPar=0x0, ccFile="") { Color := SubStr(Color,1,2)="0x" ? Color : "0x" Color ; Check & Prefix Color with "0x" VarSetCapacity(CHOOSECOLOR, 36, 0) , mainPtr := (&CHOOSECOLOR) ; Create Main structure DllCall( "RtlFillMemory", UInt,mainPtr+0, Int,1, UChar,36 ) ; Insert size of the Structure
hPar := WinExist(ahk_id %hPar%) ; Validate the passed Parent window ID ; Break Parent window ID into 4 bytes H1 := hPar>>0 & 255, H2 := hPar>>8 & 255, H3 := hPar>>16 & 255, H4 := hPar>>24 & 255 Loop 4 ; Insert Parent window ID to CHOOSECOLOR structure @ Offset 4 DllCall( "RtlFillMemory", UInt,mainPtr+3+A_Index, Int,1, UChar,H%A_Index% )
; Break Color into R,G and B values RGB1 := Color>>16 & 255, RGB2 := Color>>8 & 255, RGB3 := Color>>0 & 255 Loop 3 ; Insert R,G and B values to CHOOSECOLOR structure @ Offset 12 DllCall( "RtlFillMemory", UInt,mainPtr+11+A_Index, Int,1, UChar,RGB%A_Index% )
; CustomColors ( CUS1 will be primary array and CUS2 will be a copy to detect any change ) VarSetCapacity(CUS1, 64, 0), aPtr := (&CUS1), VarSetCapacity(CUS2, 64, 0) IfEqual,ccFile,, SetEnv,ccFile,%A_WinDir%\CUSTOMCOLOR.BIN ; Assign default save filename IfExist,%ccFile%, FileRead,CUS1, *m64 %ccFile% ; Array CUS1 will be overwritten Loop 64 ; Copy data from CUS1 to CUS2 oS:=A_Index-1, DllCall( "RtlFillMemory", UInt,&CUS2+oS, Int,1, UChar,*(&CUS1+oS) ) A1 := aPtr>>0 & 255, A2 := aPtr>>8 & 255, A3 := aPtr>>16 & 255, A4 := aPtr>>24 & 255 Loop 4 ; Insert pointer to Custom colors array to CHOOSECOLOR structure @ Offset 16 DllCall( "RtlFillMemory", UInt,mainPtr+15+A_Index, Int,1, UChar,A%A_Index% )
; Insert Integer 259 @ Offset 21 (259 is CC_RGBINIT + CC_FULLOPEN + CC_ANYCOLOR ) DllCall( "RtlFillMemory", UInt,mainPtr+20, Int,1,UChar,3 ) ; CC_RGBINIT=1 + CC_FULLOPEN=2 DllCall( "RtlFillMemory", UInt,mainPtr+21, Int,1,UChar,1 ) ; CC_ANYCOLOR=256
If ! DllCall("comdlg32\ChooseColorA", str, CHOOSECOLOR) OR errorLevel ; Call ChooseColor Return -1 ; and return -1 in case of an error or if no color was selected.
Loop 64 ; Compare data CUS2 and CUS1, if custom color changed, then save array to BIN file If ( *(&CUS1+A_Index-1) != *(&CUS2+A_Index-1) ) { ; Check byte by byte h := DllCall( "_lcreat", Str,ccFile, Int,0 ) ; Overwrite/create file DllCall( "_lwrite", UInt,h, Str,CUS1, Int,64 ) ; write the array, DllCall( "_lclose", UInt,h ) ; close the file, Break ; break the loop. } Hex := "123456789ABCDEF0", RGB := mainPtr+11 Loop 3 ; Extract nibbles directly from main structure and convert it into Hex (initd. abv) HexColorCode .= SubStr(Hex, (*++RGB >> 4), 1) . SubStr(Hex, (*RGB & 15), 1) Return HexColorCode ; finally ... phew! }
Note: This function looks very cryptic as I prefer my functions to be standalone/self-contained. I hope InsertInteger() / ExtractInteger are built into AHK in near future.
 ** Compact Version ** 2008-06-17 Code: ChooseColor( Clr=0x0, Par=0x0 ) { Hex:="123456789ABCDEF0", VarSetCapacity(CC,36,0), RGB:=&CC+11, VarSetCapacity(D,64,0) NumPut(36,CC,0), NumPut(Par,CC,4), NumPut(Clr,CC,12), NumPut(&D,CC,16), NumPut(259,CC,20) If ! DllCall( "comdlg32\ChooseColorA", str,CC ) OR ErrorLevel Return -1 Loop 3 HexCC .= SubStr(Hex, (*++RGB >> 4), 1) . SubStr(Hex, (*RGB & 15), 1) Return HexCC }
Last edited by SKAN on June 17th, 2008, 12:16 pm, edited 1 time in total.
|
|