/lib/CCheckBoxControl.ahk

http://github.com/Skiouros/Macro · AutoHotKey · 177 lines · 125 code · 2 blank · 50 comment · 33 complexity · 16f998fa54f8e5d5a65391375c19bc59 MD5 · raw file

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