Page 1 of 1

Choose colour by Windows dialogue box?

Posted: 19 Nov 2018, 10:30
by ahketype
Hi, is there a way to use the default Windows colour chooser thingumajig that you see everywhere, rather than having to use a bespoke constructor? I had the feeling this ought to work with an OS call or a command, but I don't see a command for it.

I know there are quite a few AHK scripts for colour pickers (and colour constructors, slider-outputty things), but I just thought it would suit my script to use something built in to the Windows API.
Cheers

Re: Choose colour by Windows dialogue box?  Topic is solved

Posted: 21 Nov 2018, 20:01
by iPhilip
Hi Ahketype,

Would this help?

Code: Select all

#NoEnv

X := "Center"
Y := "Center"
CustomColors := [0xFF0000,0x00FF00,0x0000FF]  ; Red, Green, Blue

Gui, New, +HwndhWnd
Gui, Show, x%X% y%X% w1 h1 Hide
MsgBox, % ChooseColor(0x00FF00, CustomColors, hWnd)
CustomColorsString := "Custom Colors:`n"
for each, Color in CustomColors
   CustomColorsString .= each ".`t" Format("{:06X}", Color) "`n"
MsgBox % CustomColorsString
ExitApp

; https://msdn.microsoft.com/en-us/library/windows/desktop/ms646912(v=vs.85).aspx
; https://docs.microsoft.com/en-us/windows/desktop/api/commdlg/ns-commdlg-tagchoosecolorw
; https://docs.microsoft.com/en-us/windows/desktop/gdi/colorref

ChooseColor(StartingRGB := 0x0, CustomRGBs := "", hWnd := 0x0, Flags := 0x3) {  ; CC_RGBINIT = 0x1, CC_FULLOPEN = 0x2
   VarSetCapacity(CustomColors, 64, 0)
   NumPut(VarSetCapacity(CC, A_PtrSize = 8 ? 72 : 36, 0), CC, 0, "UInt")
   NumPut(hWnd ? hWnd : A_ScriptHwnd, CC, A_PtrSize = 8 ? 8 : 4, "Ptr")
   NumPut(COLORREF(StartingRGB), CC, A_PtrSize = 8 ? 24 : 12, "UInt")
   NumPut(&CustomColors, CC, A_PtrSize = 8 ? 32 : 16, "Ptr")
   NumPut(Flags, CC, A_PtrSize = 8 ? 40 : 20, "UInt")
   if IsObject(CustomRGBs)
      for each, RGB in CustomRGBs
         NumPut(COLORREF(RGB), CustomColors, (each-1)*4, "UInt")
      Until each = 16
   if DllCall("comdlg32\ChooseColor", "Ptr", &CC, "Int") {
      if IsObject(CustomRGBs)
         Loop, 16
            CustomRGBs[A_Index] := COLORREF(NumGet(CustomColors, (A_Index-1)*4, "UInt"))
      Offset := A_PtrSize = 8 ? 24 : 12
      Return Format("{:02X}{:02X}{:02X}", NumGet(CC, Offset, "UChar"), NumGet(CC, Offset+1, "UChar"), NumGet(CC, Offset+2, "UChar"))
   }
}

COLORREF(RGB) {  ; Switches red and blue
   Return ((RGB & 0xFF) << 16) + (RGB & 0xFF00) + ((RGB >> 16) & 0xFF)
}

/*
typedef struct tagCHOOSECOLOR {     Type  Offset  Length
  DWORD        lStructSize;         UInt   0      4
  HWND         hwndOwner;           Ptr    4/8    4/8
  HWND         hInstance;           Ptr    8/16   4/8
  COLORREF     rgbResult;           UInt  12/24   4
  COLORREF     *lpCustColors;       Ptr   16/32   4/8
  DWORD        Flags;               UInt  20/40   4
  LPARAM       lCustData;           Ptr   24/48   4/8
  LPCCHOOKPROC lpfnHook;            Ptr   28/56   4/8
  LPCWSTR      lpTemplateName;      Ptr   32/64   4/8
} CHOOSECOLORW, *LPCHOOSECOLORW;          36/72
*/
Cheers!

-iPhilip

Edit: Added a limit in case the size of the CustomRGBs array is larger than 16.

Re: Choose colour by Windows dialogue box?

Posted: 21 Nov 2018, 20:13
by ahketype
Oh wow! That's the one. :dance:
Thanks a million. Did you code it?

Re: Choose colour by Windows dialogue box?

Posted: 21 Nov 2018, 20:17
by iPhilip
Yes. It was inspired by this post by SKAN but I expanded it. :)

Re: Choose colour by Windows dialogue box?

Posted: 21 Nov 2018, 20:26
by ahketype
Great. I'll check that out too. You just saved me days of work writing a colour picker (which I did once and then somehow lost), but really I wanted the Windows one anyway.

Re: Choose colour by Windows dialogue box?

Posted: 21 Nov 2018, 21:34
by iPhilip
Glad to be of help. :)