hoppfrosch
6/28/2013 - 5:00 AM

Class CTLCOLORS - coloured background and/or text for controls which don't support colouring natively.

Class CTLCOLORS - coloured background and/or text for controls which don't support colouring natively.

; ======================================================================================================================
; AHK 1.1 +
; ======================================================================================================================
; Function:          Helper object to color controls on WM_CTLCOLOR... notifications.
;                    Supported controls are: Checkbox, ComboBox, DropDownList, Edit, ListBox, Radio, Text.
;                    Checkboxes and Radios accept background colors only due to design.
; Namespace:         CTLCOLORS
; AHK version:       1.1.11.01
; Language:          English
; Version:           0.9.01.00/2012-04-05/just me
;                    0.9.02.00/2013-06-26/just me  -  fixed to run on Win 7 x64
;                    0.9.03.00/2013-06-27/just me  -  added support for disabled edit controls
;
; How to use:        To register a control for coloring call
;                       CTLCOLORS.Attach()
;                    passing up to three parameters:
;                       Hwnd        - Hwnd of the GUI control                                   (Integer)
;                       BkColor     - HTML color name, 6-digit hex value ("RRGGBB")             (String)
;                                     or "" for default color
;                       ------------- Optional -------------------------------------------------------------------------
;                       TextColor   - HTML color name, 6-digit hex value ("RRGGBB")             (String)
;                                     or "" for default color
;                    If both BkColor and TextColor are "" the control will not be added and the call returns False.
;
;                    To change the colors for a registered control call
;                       CTLCOLORS.Change()
;                    passing up to three parameters:
;                       Hwnd        - see above
;                       BkColor     - see above
;                       ------------- Optional -------------------------------------------------------------------------
;                       TextColor   - see above
;                    Both BkColor and TextColor may be "" to reset them to default colors.
;                    If the control is not registered yet, CTLCOLORS.Attach() is called internally.
;
;                    To unregister a control from coloring call
;                       CTLCOLORS.Detach()
;                    passing one parameter:
;                       Hwnd      - see above
;
;                    To stop all coloring and free the resources call
;                       CTLCOLORS.Free()
;                    It's a good idea to insert this call into the scripts exit-routine.
;
;                    To check if a control is already registered call
;                       CTLCOLORS.IsAttached()
;                    passing one parameter:
;                       Hwnd      - see above
;
;                    To get a control's Hwnd use either the option "HwndOutputVar" with "Gui, Add" or the command
;                    "GuiControlGet" with sub-command "Hwnd".
;
;                    Properties/methods/functions declared as PRIVATE must not be set/called by the script!
;
; Special features:  On the first call for a specific control class the function registers the CTLCOLORS_OnMessage()
;                    function as message handler for WM_CTLCOLOR messages of this class(es).
;
;                    Buttons (Checkboxes and Radios) do not make use of the TextColor to draw the text, instead of
;                    that they use it to draw the focus rectangle.
;
;                    After displaying the GUI per "Gui, Show" you have to execute "WinSet, Redraw" once.
;                    It's no bad idea to do it using a GuiSize label, because it avoids rare problems when restoring
;                    a minimized window:
;                       GuiSize:
;                          If (A_EventInfo != 1) {
;                             Gui, %A_Gui%:+LastFound
;                             WinSet, ReDraw
;                          }
;                       Return
; ======================================================================================================================
; This software is provided 'as-is', without any express or implied warranty.
; In no event will the authors be held liable for any damages arising from the use of this software.
; ======================================================================================================================
Class CTLCOLORS {
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; PRIVATE Properties and Methods ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; Registered Controls
   Static Attached := {}
   ; OnMessage Handlers
   Static HandledMessages := {Edit: 0, ListBox: 0, Static: 0}
   ; Message Handler Function
   Static MessageHandler := "CTLCOLORS_OnMessage"
   ; Windows Messages
   Static WM_CTLCOLOR := {Edit: 0x0133, ListBox: 0x134, Static: 0x0138}
   ; HTML Colors (BGR)
   Static HTML := {AQUA:    0xFFFF00, BLACK:   0x000000, BLUE:    0xFF0000, FUCHSIA: 0xFF00FF, GRAY:    0x808080
                 , GREEN:   0x008000, LIME:    0x00FF00, MAROON:  0x000080, NAVY:    0x800000, OLIVE:   0x008080
                 , PURPLE:  0x800080, RED:     0x0000FF, SILVER:  0xC0C0C0, TEAL:    0x808000, WHITE:   0xFFFFFF
                 , YELLOW:  0x00FFFF}
   ; System Colors
   Static SYSCOLORS := {Edit: "", ListBox: "", Static: ""}
   Static Initialize := CTLCOLORS.InitClass()
   ; ===================================================================================================================
   ; PRIVATE SUBCLASS CTLCOLORS_Base  - Base class
   ; ===================================================================================================================
   Class CTLCOLORS_Base {
      __New() {   ; This class is a helper object, you must not instantiate it.
         Return False
      }
      __Delete() {
         This.Free()
      }
   }
   ; ===================================================================================================================
   ; PRIVATE METHOD Init  Class       - Set the base
   ; ===================================================================================================================
   InitClass() {
      This.Base := This.CTLCOLORS_Base
      Return "DONE"
   }
   ; ===================================================================================================================
   ; PRIVATE METHOD CheckColors       - Check parameters BkColor and TextColor not to be empty both
   ; ===================================================================================================================
   CheckColors(BkColor, TextColor) {
      This.ErrorMsg := ""
      If (BkColor = "") && (TextColor = "") {
         This.ErrorMsg := "Both parameters BkColor and TextColor are empty!"
         Return False
      }
      Return True
   }
   ; ===================================================================================================================
   ; PRIVATE METHOD CheckBkColor      - Check parameter BkColor
   ; ===================================================================================================================
   CheckBkColor(ByRef BkColor, Class) {
      This.ErrorMsg := ""
      If (BkColor != "") && !This.HTML.HasKey(BkColor) && !RegExMatch(BkColor, "i)^[0-9A-F]{6}$") {
         This.ErrorMsg := "Invalid parameter BkColor: " . BkColor
         Return False
      }
      BkColor := BkColor = "" ? This.SYSCOLORS[Class]
               : This.HTML.HasKey(BkColor) ? This.HTML[BkColor]
               : "0x" . SubStr(BkColor, 5, 2) . SubStr(BkColor, 3, 2) . SubStr(BkColor, 1, 2)
      Return True
   }
   ; ===================================================================================================================
   ; PRIVATE METHOD CheckTextColor    - Check parameter TextColor
   ; ===================================================================================================================
   CheckTextColor(ByRef TextColor) {
      This.ErrorMsg := ""
      If (TextColor != "") && !This.HTML.HasKey(TextColor) && !RegExMatch(TextColor, "i)^[\dA-F]{6}$") {
         This.ErrorMsg := "Invalid parameter TextColor: " . TextColor
         Return False
      }
      TextColor := TextColor = "" ? ""
                 : This.HTML.HasKey(TextColor) ? This.HTML[TextColor]
                 : "0x" . SubStr(TextColor, 5, 2) . SubStr(TextColor, 3, 2) . SubStr(TextColor, 1, 2)
      Return True
   }
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; PUBLIC Interface ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ; Error message in case of errors
   Static ErrorMsg := ""
   ; ===================================================================================================================
   ; METHOD Attach         Register control for coloring
   ; Parameters:           Hwnd        - HWND of the GUI control                                   (Integer)
   ;                       BkColor     - HTML color name, 6-digit hex value ("RRGGBB")             (String)
   ;                                     or "" for default color
   ;                       ------------- Optional ----------------------------------------------------------------------
   ;                       TextColor   - HTML color name, 6-digit hex value ("RRGGBB")             (String)
   ;                                     or "" for default color
   ; Return values:        On success  - True
   ;                       On failure  - False, CTLCOLORS.ErrorMsg contains additional informations
   ; ===================================================================================================================
   Attach(Hwnd, BkColor, TextColor = "") {
      ; Names of supported classes
      Static ClassNames := {Button: "", ComboBox: "", Edit: "", ListBox: "", Static: ""}
      ; Button styles
      Static BS_CHECKBOX := 0x2
           , BS_RADIOBUTTON := 0x8
      ; Editstyles
      Static ES_READONLY := 0x800
      ; Default class background colors
      Static COLOR_3DFACE := 15
           , COLOR_WINDOW := 5
      ; Initialize default background colors on first call -------------------------------------------------------------
      If (This.SYSCOLORS.Edit = "") {
         This.SYSCOLORS.Static := DllCall("User32.dll\GetSysColor", "Int", COLOR_3DFACE, "UInt")
         This.SYSCOLORS.Edit := DllCall("User32.dll\GetSysColor", "Int", COLOR_WINDOW, "UInt")
         This.SYSCOLORS.ListBox := This.SYSCOLORS.Edit
      }
      ; Check Hwnd -----------------------------------------------------------------------------------------------------
      This.ErrorMsg := ""
      If !(CtrlHwnd := Hwnd + 0)
      Or !DllCall("User32.dll\IsWindow", "UPtr", Hwnd, "UInt") {
         This.ErrorMsg := "Invalid parameter Hwnd: " . Hwnd
         Return False
      }
      If This.Attached.HasKey(Hwnd) {
         This.ErrorMsg := "Control " . Hwnd . " is already registered!"
         Return False
      }
      Hwnds := [CtrlHwnd]
      ; Check control's class ------------------------------------------------------------------------------------------
      Classes := ""
      WinGetClass, CtrlClass, ahk_id %CtrlHwnd%
      This.ErrorMsg := "Unsupported control class: " . CtrlClass
      If !ClassNames.HasKey(CtrlClass)
         Return False
      ControlGet, CtrlStyle, Style, , , ahk_id %CtrlHwnd%
      If (CtrlClass = "Edit")
         Classes := ["Edit", "Static"]
      Else If (CtrlClass = "Button") {
         IF (CtrlStyle & BS_RADIOBUTTON) || (CtrlStyle & BS_CHECKBOX)
            Classes := ["Static"]
         Else
            Return False
      }
      Else If (CtrlClass = "ComboBox") {
         VarSetCapacity(CBBI, 40 + (A_PtrSize * 3), 0)
         NumPut(40 + (A_PtrSize * 3), CBBI, 0, "UInt")
         DllCall("User32.dll\GetComboBoxInfo", "Ptr", CtrlHwnd, "Ptr", &CBBI)
         Hwnds.Insert(NumGet(CBBI, 40 + (A_PtrSize * 2, "UPtr")) + 0)
         Hwnds.Insert(Numget(CBBI, 40 + A_PtrSize, "UPtr") + 0)
         Classes := ["Edit", "Static", "ListBox"]
      }
      If !IsObject(Classes)
         Classes := [CtrlClass]
      ; Check colors ---------------------------------------------------------------------------------------------------
      If !This.CheckColors(BkColor, TextColor)
         Return False
      ; Check background color -----------------------------------------------------------------------------------------
      If !This.CheckBkColor(BkColor, Classes[1])
         Return False
      ; Check text color -----------------------------------------------------------------------------------------------
      If !This.CheckTextColor(TextColor)
         Return False
      ; Activate message handling on the first call for a class --------------------------------------------------------
      For I, V In Classes {
         If (This.HandledMessages[V] = 0)
            OnMessage(This.WM_CTLCOLOR[V], This.MessageHandler)
         This.HandledMessages[V] += 1
      }
      ; Store values for Hwnd ------------------------------------------------------------------------------------------
      Brush := DllCall("Gdi32.dll\CreateSolidBrush", "UInt", BkColor, "UPtr")
      For I, V In Hwnds
         This.Attached[V] := {Brush: Brush, TextColor: TextColor, BkColor: BkColor, Classes: Classes, Hwnds: Hwnds}
      ; Redraw control -------------------------------------------------------------------------------------------------
      DllCall("User32.dll\InvalidateRect", "Ptr", Hwnd, "Ptr", 0, "Int", 1)
      This.ErrorMsg := ""
      Return True
   }
   ; ===================================================================================================================
   ; METHOD Change         Change control colors
   ; Parameters:           Hwnd        - HWND of the GUI control                                   (Integer)
   ;                       BkColor     - HTML color name, 6-digit hex value ("RRGGBB")             (String)
   ;                                     or "" for default color
   ;                       ------------- Optional ----------------------------------------------------------------------
   ;                       TextColor   - HTML color name, 6-digit hex value ("RRGGBB")             (String)
   ;                                     or "" for default color
   ; Return values:        On success  - True
   ;                       On failure  - False, CTLCOLORS.ErrorMsg contains additional informations
   ; Remarks:              If the control isn't registered yet, METHOD Add() is called instead internally.
   ; ===================================================================================================================
   Change(Hwnd, BkColor, TextColor = "") {
      ; Check Hwnd -----------------------------------------------------------------------------------------------------
      This.ErrorMsg := ""
      Hwnd += 0
      If !This.Attached.HasKey(Hwnd)
         Return This.Attach(Hwnd, BkColor, TextColor)
      CTL := This.Attached[Hwnd]
      ; Check BkColor --------------------------------------------------------------------------------------------------
      If !This.CheckBkColor(BkColor, CTL.Classes[1])
         Return False
      ; Check TextColor ------------------------------------------------------------------------------------------------
      If !This.CheckTextColor(TextColor)
         Return False
      ; Store Colors ---------------------------------------------------------------------------------------------------
      If (BkColor <> CTL.BkColor) {
         If (CTL.Brush) {
            DllCall("Gdi32.dll\DeleteObject", "Prt", CTL.Brush)
            This.Attached[Hwnd].Brush := 0
         }
         Brush := DllCall("Gdi32.dll\CreateSolidBrush", "UInt", BkColor, "UPtr")
         This.Attached[Hwnd].Brush := Brush
         This.Attached[Hwnd].BkColor := BkColor
      }
      This.Attached[Hwnd].TextColor := TextColor
      This.ErrorMsg := ""
      DllCall("User32.dll\InvalidateRect", "Ptr", Hwnd, "Ptr", 0, "Int", 1)
      Return True
   }
   ; ===================================================================================================================
   ; METHOD Detach         Stop control coloring
   ; Parameters:           Hwnd        - HWND of the GUI control                                   (Integer)
   ; Return values:        On success  - True
   ;                       On failure  - False, CTLCOLORS.ErrorMsg contains additional informations
   ; ===================================================================================================================
   Detach(Hwnd) {
      This.ErrorMsg := ""
      Hwnd += 0
      If This.Attached.HasKey(Hwnd) {
         CTL := This.Attached[Hwnd].Clone()
         If (CTL.Brush)
            DllCall("Gdi32.dll\DeleteObject", "Prt", CTL.Brush)
         For I, V In CTL.Classes {
            If This.HandledMessages[V] > 0 {
               This.HandledMessages[V] -= 1
               If This.HandledMessages[V] = 0
                  OnMessage(This.WM_CTLCOLOR[V], "")
         }  }
         For I, V In CTL.Hwnds
            This.Attached.Remove(V, "")
         DllCall("User32.dll\InvalidateRect", "Ptr", Hwnd, "Ptr", 0, "Int", 1)
         CTL := ""
         Return True
      }
      This.ErrorMsg := "Control " . Hwnd . " is not registered!"
      Return False
   }
   ; ===================================================================================================================
   ; METHOD Free           Stop coloring for all controls and free resources
   ; Return values:        Always True
   ; ===================================================================================================================
   Free() {
      For K, V In This.Attached
         DllCall("Gdi32.dll\DeleteObject", "Ptr", V.Brush)
      For K, V In This.HandledMessages
         If (V > 0) {
            OnMessage(This.WM_CTLCOLOR[K], "")
            This.HandledMessages[K] := 0
         }
      This.Attached := {}
      Return True
   }
   ; ===================================================================================================================
   ; METHOD IsAttached     Check if the control is registered for coloring
   ; Parameters:           Hwnd        - HWND of the GUI control                                   (Integer)
   ; Return values:        On success  - True
   ;                       On failure  - False
   ; ===================================================================================================================
   IsAttached(Hwnd) {
      Return This.Attached.HasKey(Hwnd)
   }
}
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE Functions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ======================================================================================================================
; PRIVATE FUNCTION CTLCOLORS_OnMessage
; This function is destined to handle CTLCOLOR messages. There's no reason to call it manually!
; ======================================================================================================================
CTLCOLORS_OnMessage(wParam, lParam) {
   Global CTLCOLORS
   Static SetTextColor := 0, SetBkColor := 0, Counter := 0
   Critical, 50
   If (SetTextColor = 0) {
      HM := DllCall("Kernel32.dll\GetModuleHandle", "Str", "Gdi32.dll", "UPtr")
      SetTextColor := DllCall("Kernel32.dll\GetProcAddress", "Ptr", HM, "AStr", "SetTextColor", "UPtr")
      SetBkColor := DllCall("Kernel32.dll\GetProcAddress", "Ptr", HM, "AStr", "SetBkColor", "UPtr")
   }
   Hwnd := lParam + 0, HDC := wParam + 0
   If CTLCOLORS.IsAttached(Hwnd) {
      CTL := CTLCOLORS.Attached[Hwnd]
      If (CTL.TextColor != "")
         DllCall(SetTextColor, "Ptr", HDC, "UInt", CTL.TextColor)
      DllCall(SetBkColor, "Ptr", HDC, "UInt", CTL.BkColor)
      Return CTL.Brush
   }
}
#NoEnv
#Include Class_CTLCOLORS.ahk
OnExit, GuiClose
; ----------------------------------------------------------------------------------------------------------------------
LB_SETCURSEL := 0x186
CB_SETCURSEL := 0x14E
Red   := "FF0000"
Green := "00C000"
Blue  := "0000FF"
Pink  := "FF20FF"
; ----------------------------------------------------------------------------------------------------------------------
Gui, Margin, 10, 10
Gui, Add, Radio, vSTDRB1 gSTDRBG hwndRBID1 Checked, Standard Radio 1
CTLCOLORS.Attach(RBID1, "Lime", "")
Gui, Add, Radio, x+55 ym vSTDRB2 gSTDRBG hwndRBID2, Standard Radio 2
Gui, Add, CheckBox, xm vSTDCB1 gSTDCB1 hwndCBID1, Standard CheckBox
CTLCOLORS.Attach(CBID1, "C0C0C0", "Red")
; ----------------------------------------------------------------------------------------------------------------------
Gui, Add, Text, xm w292 h2 +0x1000
; "Faked" RadioButtons -------------------------------------------------------------------------------------------------
; Note: Minimum width and height are font, font size and OS dependend, if you get below the limit, nothing is shown!!!
Gui, Add, Radio, xm w15 h20 gRBG vRB1 Section Group Checked
Gui, Add, Radio, xm wp hp gRBG vRB2
Gui, Add, Radio, xm wp hp gRBG vRB3
Gui, Add, Text, ys x+5 w50 hp 0x200 cBlue gRBG vRT1 hwndRTID1, % "Radio 1"
Gui, Add, Text, xp y+10 wp hp 0x200 cBlue gRBG vRT2 hwndRTID2, % "Radio 2"
Gui, Add, Text, xp y+10 wp hp 0x200 cBlue gRBG vRT3 hwndRTID3, % "Radio 3"
RBGA := 1
CTLCOLORS.Attach(RTID%RBGA%, "Yellow", "Blue")
; "Faked" CheckBox -----------------------------------------------------------------------------------------------------
; Note: for minimum width see "Faked" RadioButtons
Gui, Add, CheckBox, ys x+80 w15 h20 gCB1 vCB1 Section
Gui, Add, Text, x+5 yp hp 0x200 gCB1 vCT1 hwndCTID1, % " Check me! "
CTLCOLORS.Attach(CTID1, "", "Green")
; ComboBox -------------------------------------------------------------------------------------------------------------
Gui, Add, Combobox, xs y+40 w141 gCBB1 vCBB1 hwndCBBID1
   , ComboBox 1||ComboBox 2|ComboBox 3
CTLCOLORS.Attach(CBBID1, "Aqua", "Red")
; ----------------------------------------------------------------------------------------------------------------------
Gui, Add, Text, xm w292 h2 +0x1000
; ListBox --------------------------------------------------------------------------------------------------------------
Gui, Add, ListBox, xm w292 r4 gLB1 vLB1 hwndLBID1
   , ListBox Red|ListBox Green|ListBox Blue|ListBox Pink
CTLCOLORS.Attach(LBID1, Red, "White")
GuiControl, Choose, LB1, |1
; ----------------------------------------------------------------------------------------------------------------------
Gui, Add, Text, xm w292 h2 +0x1000
; Edit -----------------------------------------------------------------------------------------------------------------
Gui, Font, s10
Gui, Add, Edit, xm w292 r10 vED1 hwndEDID1, I'm an Edit, edit me!
CTLCOLORS.Attach(EDID1, "606060", "Aqua")
Gui, Add, Edit, xm w292 vED2 hwndEDID2 +Disabled, % " I'm disabled!"
CTLCOLORS.Attach(EDID2, "Gray", "Lime")
Gui, Add, ListView, xm w292 r5 Grid -HDR

; ----------------------------------------------------------------------------------------------------------------------
Gui, Show, , Colored Controls
Return
; ----------------------------------------------------------------------------------------------------------------------
GuiClose:
GuiEscape:
   Gui, Destroy
   CTLCOLORS.Free()
ExitApp
; ----------------------------------------------------------------------------------------------------------------------
GuiSize:
   If (A_EventInfo != 1) {
      Gui, %A_Gui%:+LastFound
      WinSet, ReDraw
   }
Return
; ----------------------------------------------------------------------------------------------------------------------
STDRBG:
   GuiControlGet, STDRB1
   CTLCOLORS.Change(RBID1, (STDRB1 ? "Lime" : ""), "006000")
   CTLCOLORS.Change(RBID2, (STDRB1 ? "" : "Lime"), "006000")
Return
; ----------------------------------------------------------------------------------------------------------------------
STDCB1:
   GuiControlGet, STDCB1
   CTLCOLORS.Change(CBID1, (STDCB1 ? "Lime" : "C0C0C0"), "Red")
   Return
; ----------------------------------------------------------------------------------------------------------------------
RBG:
   RBG := SubStr(A_GuiControl, 3)
   If (RBG != RBGA) {
      CTLCOLORS.Detach(RTID%RBGA%)
      CTLCOLORS.Attach(RTID%RBG%, "Yellow", "Blue")
      GuiControl, , RB%RBG%, 1
      RBGA := RBG
   }
Return
; ----------------------------------------------------------------------------------------------------------------------
LB1:
   GuiControlGet, LB1
   StringSplit, LC, LB1, %A_Space%
   If (%LC2%) {
      BG := %LC2%, TX := "White"
      CTLCOLORS.Change(LBID1, BG, TX)
      SendMessage, LB_SETCURSEL, -1, 0, , ahk_id %LBID1%
   }
Return
; ----------------------------------------------------------------------------------------------------------------------
CB1:
   GuiControlGet, CB1
   If (A_GuiControl = "CT1")
      CB1 ^= True
   If (CB1)
      CTLCOLORS.Change(CTID1, "Lime", "406060")
   Else
      CTLCOLORS.Change(CTID1, "", "Green")
   GuiControl, , CB1, %CB1%
Return
; ----------------------------------------------------------------------------------------------------------------------
CBB1:
Return