PageRenderTime 47ms CodeModel.GetById 36ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/CCheckBoxControl.ahk

http://github.com/Skiouros/Macro
AutoHotKey | 177 lines | 125 code | 2 blank | 50 comment | 33 complexity | 16f998fa54f8e5d5a65391375c19bc59 MD5 | raw file
  1/*
  2Class: CCheckboxControl
  3A checkbox/radio control.
  4
  5This control extends <CControl>. All basic properties and functions are implemented and documented in this class.
  6*/
  7Class CCheckBoxControl Extends CControl ;This class is a radio control as well
  8{
  9	__New(Name, Options, Text, GUINum, Type)
 10	{
 11		Options .= " +0x4000" ;BS_NOTIFY to allow receiving BN_SETFOCUS and BN_KILLFOCUS notifications in CGUI
 12		Base.__New(Name, Options, Text, GUINum)
 13		this.Type := Type
 14		this._.Insert("ControlStyles", {Center : 0x300, Left : 0x100, Right : 0x200, RightButton : 0x20, Default : 0x1, Wrap : 0x2000, Flat : 0x8000})
 15		this._.Insert("Events", ["CheckedChanged"])
 16		this._.Insert("Controls", {})
 17		this._.Insert("Messages", {7 : "KillFocus", 6 : "SetFocus" }) ;Used for automatically registering message callbacks
 18	}
 19	/*
 20	Variable: Checked
 21	If true, the control is checked.
 22	*/
 23	__Get(Name)
 24    {
 25		;~ global CGUI
 26		if(Name != "GUINum" && !CGUI.GUIList[this.GUINum].IsDestroyed)
 27		{
 28			DetectHidden := A_DetectHiddenWindows
 29			DetectHiddenWindows, On
 30			if(Name = "Checked")
 31				ControlGet, Value, Checked,,,% "ahk_id " this.hwnd
 32			else if(Name = "Controls")
 33				Value := this._.Controls
 34			if(!DetectHidden)
 35				DetectHiddenWindows, Off
 36			if(Value != "")
 37				return Value
 38		}
 39	}
 40	__Set(Name, Value)
 41	{
 42		;~ global CGUI
 43		if(!CGUI.GUIList[this.GUINum].IsDestroyed)
 44		{
 45			DetectHidden := A_DetectHiddenWindows
 46			DetectHiddenWindows, On
 47			Handled := true
 48			if(Name = "Checked")
 49			{
 50				GuiControl, % this.GuiNum ":", % this.ClassNN,% (Value = 0 ? 0 : 1)
 51				;~ Control, % (Value = 0 ? "Uncheck" : "Check"),,,% "ahk_id " this.hwnd ;This lines causes weird problems. Only works sometimes and might change focus
 52				Group := this.Type = "Radio" ? this.GetRadioButtonGroup() : [this]
 53				for Index, Control in Group
 54					Control.ProcessSubControlState(Control.Checked ? "" : Control, Control.Checked ? Control : "")
 55			}
 56			else
 57				Handled := false
 58		if(!DetectHidden)
 59			DetectHiddenWindows, Off
 60		if(Handled)
 61			return Value
 62		}
 63	}
 64	/*
 65	Function: AddControl
 66	Adds a control to this control that will be visible/enabled only when this checkbox/radio button is checked. The parameters correspond to the Add() function of CGUI.
 67	
 68	Parameters:
 69		Type - The type of the control.
 70		Name - The name of the control.
 71		Options - Options used for creating the control.
 72		Text - The text of the control.
 73		UseEnabledState - If true, the control will be enabled/disabled instead of visible/hidden.
 74	*/
 75	AddControl(type, Name, Options, Text, UseEnabledState = 0)
 76	{
 77		;~ global CGUI
 78		GUI := CGUI.GUIList[this.GUINum]
 79		if(!this.Checked)
 80			Options .= UseEnabledState ? " Disabled" : " Hidden"
 81		Control := GUI.AddControl(type, Name, Options, Text, this._.Controls)
 82		Control._.UseEnabledState := UseEnabledState
 83		Control.hParentControl := this.hwnd
 84		return Control
 85	}
 86	/*
 87	Function: GetRadioButtonGroup
 88	Returns the group of radio buttons this radio button belongs to as an array of controls.
 89	*/
 90	GetRadioButtonGroup()
 91	{
 92		;~ global CGUI
 93		GUI := CGUI.GUIList[this.GUINum]
 94		if(GUI.IsDestroyed)
 95			return []
 96		Group := [this]
 97		if(this.type = "Checkbox")
 98			return Group
 99		WinGet, style, Style, % "ahk_id " this.hwnd
100		;Backtrack all previous controls in the tab order
101		if(!(style & 0x00020000)) ;WS_GROUP
102		{
103			hwnd := this.hwnd
104			while(true)
105			{
106				;Get previous window handle
107				hwnd := DllCall("GetWindow", "PTR", hwnd, "UINT", 3, "PTR") ;GW_HWNDPREV
108				WinGetClass, class, ahk_id %hwnd%
109				WinGet, style, Style, ahk_id %hwnd%
110				if(class = "Button" && (style & 0x0004 || style & 0x0009)) ;BS_AUTORADIOBUTTON or BS_RADIOBUTTON
111				{
112					if(GUI.Controls.HasKey(hwnd))
113						Group.Insert(Gui.Controls[hwnd])
114					WinGet, style, Style, % "ahk_id " hwnd
115					if(style & 0x00020000) ;WS_GROUP
116						break
117				}
118				else
119					break
120			}
121		}
122		
123		hwnd := this.hwnd
124		;Go forward until the next group is found
125		while(true)
126		{
127			;Get next window handle
128			hwnd := DllCall("GetWindow", "PTR", hwnd, "UINT", 2, "PTR") ;GW_HWNDNEXT
129			WinGetClass, class, ahk_id %hwnd%
130			WinGet, style, Style, ahk_id %hwnd%
131			if(class = "Button" && (style & 0x0004 || style & 0x0009)) ;BS_AUTORADIOBUTTON or BS_RADIOBUTTON
132			{
133				WinGet, style, Style, % "ahk_id " hwnd
134				if(style & 0x00020000) ;WS_GROUP
135					break
136				if(GUI.Controls.HasKey(hwnd))
137					Group.Insert(Gui.Controls[hwnd])
138			}
139			else
140				break
141		}
142		return Group
143	}
144	
145	/*
146	Function: GetSelectedRadioButton
147	Returns the radio button control of the current group which is currently selected. Returns 0 if no button is selected.
148	*/
149	GetSelectedRadioButton()
150	{
151		if(this.type = "Checkbox" && !this.Selected)
152			return 0
153		for index, Control in this.GetRadioButtonGroup()
154			if(Control.Selected)
155				return Control
156		return 0
157	}
158	/*
159	Event: Introduction
160	To handle control events you need to create a function with this naming scheme in your window class: ControlName_EventName(params)
161	The parameters depend on the event and there may not be params at all in some cases.
162	Additionally it is required to create a label with this naming scheme: GUIName_ControlName
163	GUIName is the name of the window class that extends CGUI. The label simply needs to call CGUI.HandleEvent(). 
164	For better readability labels may be chained since they all execute the same code.
165	Instead of using ControlName_EventName() you may also call <CControl.RegisterEvent> on a control instance to register a different event function name.
166	
167	Event: CheckedChanged()
168	Invoked when the checkbox/radio value changes.
169	*/
170	HandleEvent(Event)
171	{
172		Group := this.Type = "Radio" ? this.GetRadioButtonGroup() : [this]
173		for Index, Control in Group
174			Control.ProcessSubControlState(Control.Checked ? "" : Control, Control.Checked ? Control : "")
175		this.CallEvent("CheckedChanged")
176	}
177}