Proposed New GUI API for AutoHotkey v2

Discuss the future of the AutoHotkey language
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Proposed New GUI API for AutoHotkey v2

22 Apr 2017, 01:36

Code: Select all

GuiObj := GuiFromHwnd(Hwnd, true)  ; A_Gui
My bad, I overlooked the second parameter. It's actually making things easier.

The hwnd parameter will be needed much more frequently than in v1.1. Wouldn't it make sense to change the parameter order?
lexikos
Posts: 9560
Joined: 30 Sep 2013, 04:07
Contact:

Re: Proposed New GUI API for AutoHotkey v2

23 Apr 2017, 20:12

Do you mean MessageCallback(wParam, lParam, hwnd, msg)?

Having hwnd first would be more consistent with GUI events, but probably not ideal.
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Proposed New GUI API for AutoHotkey v2

24 Apr 2017, 02:45

I'd prefer MessageCallback(hwnd, wParam, lParam, msg).
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Proposed New GUI API for AutoHotkey v2

24 Apr 2017, 02:48

With hwnd being similar to "this" in the context of such an API I agree with just me.
Recommends AHK Studio
lexikos
Posts: 9560
Joined: 30 Sep 2013, 04:07
Contact:

Re: Proposed New GUI API for AutoHotkey v2

24 Apr 2017, 23:41

Update: This test build is obsolete. See the next test build.

AutoHotkey_2.0-a078-69+gde353c8.zip
Misc Changes

Swapped Options with Text/Title for GuiCreate() and Gui.Add(), putting Options first and Text/Title second, as in v1.

Code: Select all

MyGui := GuiCreate([Options, Title := A_ScriptName, FuncPrefixOrObj := "Gui"])
MyGui.Add(Ctrl [, Options, Text])
MyGui.AddCtrl([Options, Text])
Changed GuiCreate() to allow an explicitly empty title, so GuiCreate(Opt, "") creates a GUI with no title while GuiCreate(Opt) and GuiCreate(Opt,, Evt) default to A_ScriptName as before.

Changed GuiCreate() to create the window with the right initial title rather than setting it after creation but before returning.

Added Gui.Name, which currently does nothing other than allow you to store a string in the Gui object.

Renamed Gui.BgColor to Gui.BackColor.

Removed Gui.CtrlColor.

Changed which controls are affected by Gui.BackColor.
  • Yes to Text, Pic, GroupBox, CheckBox, Radio, Slider, Tab and Link.
  • No to Edit, DDL, ComboBox and TreeView (-Theme), which previously used it only when disabled/read-only.
  • No to Progress, which previously defaulted to BgColor when the control was created, but was not affected by any changes to BgColor after that (unlike the other controls affected by BgColor).
Added Ctrl.Type.

Added Ctrl.Focused (read-only).

Added Ctrl.Add(ArrayOrList) and Ctrl.Delete([index]) for ListBox/ComboBox/DDL/Tab. Add works like GuiControl or Value:= in previous builds. Delete deletes one item or all items.

[Update: Obsolete; parameter was removed.] Improved Ctrl.Choose() with a non-zero second parameter:
Spoiler
Changed Tab.UseTab(v, true) to be case-insensitive.
  • Tab.UseTab(v) tells the Gui to add subsequent controls to a tab whose name *starts with* v.
  • Tab.UseTab(v, true) tells the Gui to add subsequent controls to a tab whose name = v.
  • Tab.Choose(v) selects a tab whose name *starts with* v.
  • Tab.Text := v selects a tab whose name = v.
  • All are case-insensitive.
Changed Tab.UseTab(0) and Tab.UseTab("") to be equivalent to Tab.UseTab() (don't use any tab).

Changed ActiveX controls to retain a reference to the object, so that the script can use ComObjConnect() without having to also store the wrapper object somewhere (since releasing it would automatically disconnect the event sink).

Fixed cDefault for ListView/TreeView, which previously set the color to black even if that's not the default.

Fixed Ctrl.Opt() to apply c%Color% for several control types which previously ignored it.

Value / Text

Revised GuiControl.Value/Text to be more consistent and meaningful.
  • Prefer Value and Text to do different things whenever it is useful and makes sense.
  • For controls which have no "value", let Value return nothing and raise an error if assignment is attempted. This affects: Link, GroupBox, Button, ListView, TreeView, StatusBar, Custom.
  • For controls which have no visible caption text and no (single) text value, Text corresponds to the control's hidden caption text, the same as ControlGetText/ControlSetText. This affects: MonthCal, Hotkey, UpDown, Slider, Progress, ActiveX, ListView, TreeView.
  • Throw an exception if an invalid value is detected.
Text/Edit: Text and Value both return/set the text.

For multi-line Edit controls, perform EOL-translation only for Value, not Text (making Text consistent with ControlGetText for most controls). Previous builds (including v1) also performed EOL-translation when retrieving text from a single-line Edit control (but not when setting it).

DDL/ListBox/Tab: Value and Text both return/set the selected item and never modify the list of items (for that, use Add/Delete). Value works only by index, while Text works only by the item's full text (case insensitive). Value can be 0, and Text can be "", meaning "no selection" (this is even valid for Tab controls).

Notes:
  • Multi-select ListBox returns an array of items, but only supports setting one item at a time (not an array). Value and Text are not accumulative, so to select multiple items, call Choose() repeatedly, as before.
  • For ListBox/Tab in previous builds (including v1), Text returned the control's hidden caption text (usually empty), the same as ControlGetText.
  • Submit works as before.
  • In v1, GuiControl ChooseString required the parameter to be non-blank.
  • In v1, GuiControl Choose supported index 0 only for DDL/ListBox/ComboBox, not Tab.
ComboBox: Same as above, except that if the user enters text which does not match an item in the list (ignoring case), Value and Text both return the actual text entered by the user.

Note: It now automatically compensates for a Windows bug which causes CB_GETCURSEL to return the index of an item which doesn't match the edit field.

UpDown/Slider/Progress: Value must be absolute, not relative to the current value (any + prefix is now ignored). That is, .Value := "+1" would be the same as .Value := 1. To adjust the value by a relative amount, use +=, -=, ++ or -- instead of :=.

CheckBox/Radio: Assigning a non-numeric string to Value no longer sets the control's caption text.

Events

Removed automatic event handlers for Button controls.

Removed the gCancel option (built-in event handler for Cancel buttons).

ListView events Normal/RightClick/DoubleClick/R/A now report the item associated with the event, which may differ from the focused item (usually by reporting 0 when empty space was clicked). This reduces code size and is more intuitive/useful. The old way was motivated by Win95 compatibility.

Changed Slider controls to call g-label more consistently by default.
  • Redundant TB_ENDTRACK (8, formerly "Normal") events are ignored unless AltSubmit is used.
  • TB_THUMBTRACK (5) is still ignored unless AltSubmit is used.
  • First parameter contains the TB code indicating how the slider was moved (same as before, but now even without AltSubmit).
  • Second parameter contains the current position, but only for TB_THUMBPOSITION (4) and TB_THUMBTRACK (5).
Changed Edit.Value/Text:= to avoid triggering the control's event handler.

House-Cleaning

Changed UpDown to use 32-bit messages all of the time, instead of trying to be compatible with IE4.

Changed Progress to use the PBM_SETRANGE32 message for all ranges, instead of trying to be compatible with IE2.

Cleaned up some other code.

Test Build Bug-Fixes (not relevant to v1)

Fixed an issue where destroying a Gui while enumerating its controls (with a for-loop or _NewEnum) causes the script to crash.

ListBox/DDL/ComboBox/Tab:
  • An error was thrown after successfully deselecting all items in a ListBox/DDL/ComboBox by assigning Text:="".
  • An error was thrown after successfully selecting a new tab if there was previously no tab selected.
  • Choose("") and Text:="" chose the first tab (now they deselects all tabs).
  • Value returned "" if no item was selected, even though Value:="" is invalid (now it returns 0).
  • UseTab(0) and UseTab(257) were supposed to be invalid, but the error detection was not working because an unsigned 8-bit variable was used. Instead, UseTab(0) was equivalent to UseTab(256). Now it is equivalent to UseTab().
  • When a user enters text into a ComboBox and that text matches a list item, ComboBox.Value (with AltSubmit) was supposed to return the index of that item. Due to an error in the code, it was returning the text instead.
Known Issues

[Update: Value now returns 0 if the text doesn't match a list item.] Currently ComboBox.Value can return a string (the text of an item, which might even be composed of digits) or a pure integer (the index of an item), but on assignment it only accepts an index (either a pure integer or a numeric string). In other words, ComboBox.Value := ComboBox.Value fails if the control's text does not match an existing item, and may change the selection if the control's current text is numeric.

There are a couple of ways I can see it working:
  1. Value returns 0 if the text is not in the list, accepts numbers only, and treats numeric strings as numbers. If the current text is not in the list, Value := Value would have the same effect as Text := "". To retrieve the index but fall back to the text when no list item is selected, the script could use cb.Value || cb.Text.
  2. Value returns the text if it does not match a list item, accepts numbers and text, and case-corrects if assigning text which matches a list item. For numeric strings, there are two possibilities:
    • Numeric strings are treated as numbers, so Value := 1 and Value := "1" are equivalent. To assign it as text, the script would use Text := "1". However, if the control's text is a numeric string (and not equal to its index), Value := Value would select a different item.
    • Numeric strings are treated as text, so selecting by index would require a pure integer (the same as Choose()). If the chosen index comes from a configuration file (for example), it must be converted to a pure integer. cb.Value := +n would always choose by index (unless n is non-numeric or contains a decimal point), and Value := Value would always result in no change.
Submit would continue to work as it does now; i.e. storing an index only when AltSubmit is present and the text matches a list item.

There are other issues I'll bring up later.
User avatar
Ragnar
Posts: 611
Joined: 30 Sep 2013, 15:25

Re: Proposed New GUI API for AutoHotkey v2

25 Apr 2017, 02:22

Besides of the other good changes you made:
Lexikos wrote:Swapped Options with Text/Title for GuiCreate() and Gui.Add(), putting Options first and Text/Title second, as in v1.
Why did you do that? In my opinion, the options are of secondary importance when creating Gui/controls. Additionally it's somewhat easier to read, especially for beginners (for example, GuiCreate("Title of Window") vs GuiCreate(, "Title of Window"))
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Proposed New GUI API for AutoHotkey v2

25 Apr 2017, 09:46

I feel like Ragnar. IMO, the previous order is looks and feels better. Very most of the controls will get a value when created. So (previous oder) GuiAdd("Control", ,"Options") will be the exception. For the sake of consistency the previous order should be kept for GuiCreate(), too.

Value/Text:
If used in this manner I propose to use Value only for numeric values like indices or states. In all other cases Value should contain zero. Assignment: Numeric strings should be handled as numbers, other strings should raise an error.
On the other hand, Text should only be used for textual contents.
In case of ComboBoxes Value should contain 0 if Text doesn't match an item.

BTW, is there or do you intend to implement a replacement for the radio group variable of v1?
lexikos
Posts: 9560
Joined: 30 Sep 2013, 04:07
Contact:

Re: Proposed New GUI API for AutoHotkey v2

25 Apr 2017, 19:48

Why did no one object when it was first brought up, before the change was made? :roll:
fincs wrote:By the way, I am not sure if reversing the parameter order in AddCtrl() was a good idea (i.e. Options, Value vs Value, Options).
https://autohotkey.com/boards/viewtopic ... 866#p38866
lexikos wrote:Gui.AddCtrl(Text, Options) vs Gui Add, Ctrl, Options, Text is bound to cause confusion with users familiar with the old order. Since even fincs expressed doubt about it, I'd guess it should be swapped back. Perhaps Options would be omitted more often than Text, but usually there's at least one option. Another point is aesthetics (which can affect readability); with several controls on a Gui, the options parameters often line up (i.e. when they aren't preceded by text of varying length).
https://autohotkey.com/boards/viewtopic ... 57#p138957
fincs wrote:The main reason this was changed was that the syntax for specifying just the text and not the option (e.g. btn := gui.AddButton("", "Text") or gui.AddLabel,, Text) contained that extra empty parameter that looked ugly. I had always thought that the Text parameter was more used than the Options and thus it should be promoted to be the first parameter. However, it is indeed true that existing users would be confused by the change, so ultimately perhaps it should be changed back in gui.AddCtrl. But again, if GuiCreate keeps Title first, it would be inconsistent with it.
joedf wrote:I agree with swapping addCrtl.
(I'm aware just me's request for additional parameters showed Text before Options, but he did not mention it specifically.)
Ragnar wrote:In my opinion, the options are of secondary importance when creating Gui/controls.
just me wrote:Very most of the controls will get a value when created.
I disagree. GUIs intended for collecting input often have no initial values. In my experience, the value is omitted more often than the options.
just me wrote:If used in this manner I propose to use Value only for numeric values like indices or states.
Are you saying that Edit controls (for example) should not use the Value property? I don't see why. I think it is counter-intuitive for Edit.Value to return 0. Also, DateTime and MonthCal return a string (of digits).
Additionally it's somewhat easier to read, especially for beginners
Perhaps when the options are omitted; otherwise, I disagree.
lexikos
Posts: 9560
Joined: 30 Sep 2013, 04:07
Contact:

Re: Proposed New GUI API for AutoHotkey v2

25 Apr 2017, 20:35

just me wrote:BTW, is there or do you intend to implement a replacement for the radio group variable of v1?
I assume you mean this:
The radio button's associated output variable (if any) receives the number 1 for "on" and 0 for "off". However, if only one button in a radio group has a variable, that variable will instead receive the number of the currently selected button: 1 is the first radio button (according to original creation order), 2 is the second, and so on. If there is no button selected, 0 is stored.
As far as I can tell by testing in v1 (I don't have the source code at hand), it only applies to Submit. It still applies to Submit in the same way, only with variables being replaced by array elements.
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Proposed New GUI API for AutoHotkey v2

26 Apr 2017, 01:18

Playing around with the new interface, I don't know how to translate

Code: Select all

Gui, Add, StatusBar, vTest -Theme BackgroundGreen
Gui, +Resize +MinSize320x200
Gui, Font, s8, Arial
into the new interface ...

Code: Select all

C := MyGui.AddStatusBar("vTest -Theme BackgroundGreen") ; this works ...
; ??????????????? Whats to do here?
C.Resize := 1 ; doesn't work
C.Options("+Resize +MinSize320x200") ; doesn't work - esp. MinSize is said to be an invalid option ...
C.Font("s8, Arial") ; doesn't work ...
...
:?: What is the correct syntax? Or isn't it implemented yet?
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Proposed New GUI API for AutoHotkey v2

26 Apr 2017, 02:11

@hoppfrosch:
The OP contains a short description of the new syntax. In v2 you have to explicitly create the GUI:

Code: Select all

MyGui := GuiCreate("+Resize +MinSize320x200", "Test") ; current test built 2.0-a078-69+gde353c8
MyGui.SetFont("s8", "Arial")
MySB := MyGui.AddStatusBar("vTest -Theme BackgroundGreen", "Initial value") ; this works ...
MyGui.Show()
or

Code: Select all

MyGui := GuiCreate()
MyGui.Opt("+Resize +MinSize320x200")
MyGui.SetFont("s8", "Arial")
MySB := MyGui.AddStatusBar("vTest -Theme BackgroundGreen", "Initial value") ; this works ...
MyGui.Show()
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Proposed New GUI API for AutoHotkey v2

26 Apr 2017, 02:23

Thanks, @just me - I have read the OP, but it seems I missed the wood for the trees ...
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Proposed New GUI API for AutoHotkey v2

26 Apr 2017, 02:32

lexikos wrote:I assume you mean this: ... It still applies to Submit in the same way, ...
I didn't expect it would be that easy, sorry.
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Proposed New GUI API for AutoHotkey v2

26 Apr 2017, 04:04

lexikos wrote:
just me wrote:Very most of the controls will get a value when created.
I disagree. GUIs intended for collecting input often have no initial values. In my experience, the value is omitted more often than the options.
I disagree, Button, Checkbox, Radio, Text, Picture, ListBox, DDL, ComboBox controls without initial contents / captions?
Are you saying that Edit controls (for example) should not use the Value property?
Yes. The 'Value' of an Edit control is its 'Text'. And it's redundant to return the 'value' of a large Edit control twice in Value as well as in Text.
Why did no one object when it was first brought up, before the change was made?
Because I didn't expect that you would actually do it based on only 2 pros. I think that the main reason for the change is backward compatibility, which isn't the objective of v2. I don't prefer this order, but I can live with it.
User avatar
Ragnar
Posts: 611
Joined: 30 Sep 2013, 15:25

Re: Proposed New GUI API for AutoHotkey v2

26 Apr 2017, 05:53

hoppfrosch wrote:Thanks, @just me - I have read the OP, but it seems I missed the wood for the trees ...
You can also take a look at the v2 docs, which already contain the new GUI API: https://github.com/Lexikos/AutoHotkey_L-Docs/tree/v2

Just download the whole repository (upper right corner, green button), unzip it and open the index file. But be warned that, since the docs are still in development state, they could be incomplete or have errors.
User avatar
hoppfrosch
Posts: 443
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: Proposed New GUI API for AutoHotkey v2

26 Apr 2017, 07:44

:thumbup: Thanks @Ragnar - much more Details in the V2 docs on github ...
lexikos
Posts: 9560
Joined: 30 Sep 2013, 04:07
Contact:

Re: Proposed New GUI API for AutoHotkey v2

26 Apr 2017, 21:20

just me wrote:I disagree, Button, Checkbox, Radio, Text, Picture, ListBox, DDL, ComboBox controls without initial contents / captions?
My opinion was that options are omitted more rarely than text, not that text is omitted often.
Yes. The 'Value' of an Edit control is its 'Text'.
So tell me why Value should not return the control's value.
And it's redundant to return the 'value' of a large Edit control twice in Value as well as in Text.
It is not redundant if Value and Text perform different functions. A script author may have a reason not to perform EOL translation, such as for performance when the text is already in the right format, or to preserve the content if that is more important than it displaying as multiple lines.

Even if it was redundant, so what? How is it better to return 0?
Because I didn't expect that you would actually do it based on only 2 pros.
I said "I'd guess it should be swapped back" and then no one objected. Why would I not follow through?

As far as I'm concerned, the change being considered is from v1 to v2, not from fincs' test build to v2. "It looks bad" or "it looks and feels better" aren't good reasons; if it's primarily about aesthetics, I'll go with what looks good to me, not what looks good to you. I posted about it rather than just changing it back in my first test build because I wanted better reasons. I haven't heard any convincing ones yet.

I missed quoting one part of the "discussion";
fincs wrote:On the other hand, I realized that for some control types (mostly input related) such as Edit, the Text parameter won't really be used as much as the Options parameter; so we would be back to dealing with the same problem. Users would be irritated that Gui, Add, Edit, vMyEdit would become gui.AddEdit,, vMyEdit (or gui.AddEdit("", "vMyEdit") for that matter). Ultimately I don't know what benefits most users.
Another point I considered (which I don't think has been mentioned) is that LV_Add/LV.Add() puts options first. I think users generally write LV_Add("", ...) rather than LV_Add(, ...) (of course, the latter wasn't always possible).
I think that the main reason for the change is backward compatibility,
Familiarity and backward compatibility aren't the same thing. It is not backward compatible, nor did I bring up backward compatibility.
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Proposed New GUI API for AutoHotkey v2

27 Apr 2017, 04:32

GuiFromHwnd(Hwnd, 1) doesn't seem to work properly within OnMessage() handlers if Hwnd belongs to a sub-control of a Gui control (e.g. ComboBox, DDL, and maybe others). Should it?
lexikos
Posts: 9560
Joined: 30 Sep 2013, 04:07
Contact:

Re: Proposed New GUI API for AutoHotkey v2

27 Apr 2017, 06:01

DDL does not have a "sub-control". The actual drop-down list is a separate window. For that window and every other window which isn't a child or grandchild of a GUI window, A_Gui and A_GuiControl would be blank.
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Proposed New GUI API for AutoHotkey v2

27 Apr 2017, 08:46

It's possible to get the HWND of the ListBox window (ComboLBox ) via GetComboBoxInfo(). So it should be possible to get the corresponding Gui control and Gui also.

If using this message handler function

Code: Select all

WM_LBUTTONDOWN(W, L, M, H) {
   ThisGui := GuiFromHwnd(H, 1)
   If (ThisCtl := GuiCtrlFromHwnd(H))
      CtlType := " - " . ThisCtl.Type
   ToolTip(ThisGui.Name . CtlType)
}
a left click on a ComboBox's ListBox window raises an exeption ("No object to invoke."). Afterwards every left click on whatever area of the Gui will raise the same exeption. Is the latter intended?

Return to “AutoHotkey Development”

Who is online

Users browsing this forum: No registered users and 51 guests