Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

AutoHotkey_L v1.1.04


  • Please log in to reply
47 replies to this topic
Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
1.1.04.00

This release contains a number of potentially script-breaking changes.
Added exception handling support: try/catch/throw and Exception().
Added StdOut mode for #Warn.
Added Gui +HwndVARNAME option.
Added Gui, New [, Options, Title].
Added automatic support for keyboard accelerators such as Ctrl+O in Gui menus.
Changed handling of #Include <Lib> when the /iLib command-line switch is present to resolve a problem with Ahk2Exe.
Changed GuiControl to retain the Progress control's current value when its style is changed.
Changed GuiControl and GuiControlGet to allow a HWND to be passed in the ControlID parameter.
Removed the 1GB limit from FileRead.
Improved error detection:
[*:18qf9u74]Hotkey, If, Expression, where Expression does not match an existing #If expression, is caught at load-time when possible.
[*:18qf9u74]Hotkey, IfSomething, where Something is invalid, is caught at load-time.
[*:18qf9u74]Class definitions with missing braces are detected as errors.
[*:18qf9u74]If a function call is used on the first line of a class definition, it is now correctly treated as an error.
[*:18qf9u74]GroupAdd now shows an error message when the group name is blank, instead of silently exiting the thread.
[*:18qf9u74]Removed some redundant "unset var" warnings which appeared when using the OutputDebug or StdOut warning modes.
[*:18qf9u74]If an unrecognized option is used with Gui, Gui Show, Gui New or GuiControl, an error message is shown and the thread exits unless try is used. This validation is not done at load-time due to complexity (it is common for the option parameters to contain variable references).
[*:18qf9u74]RegRead, RegWrite and RegDelete now set A_LastError to the result of the operating system's GetLastError() function.
[*:18qf9u74]+LastFoundExist is now treated as an error if it is combined with another option (+LastFound should be used in that case).Fixed a bug affecting recursive variadic functions.

1.1.04.01

Fixed FileRemoveDir setting ErrorLevel incorrectly.

Downloads (etc.)

Many thanks to fincs for his work on try/catch/throw.

just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Added Gui +HwndVARNAME option.
Added Gui, New [, Options, Title].
Changed GuiControl and GuiControlGet to allow a HWND to be passed in the ControlID parameter.

THX, that's great!

fincs
  • Moderators
  • 1662 posts
  • Last active:
  • Joined: 05 May 2007
Awesome!

FYI, I've just added support for try/catch/throw/Exception() to S4AHK.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
Very impressive list of changes, congrats on the release!

Here's an Assert() function:
Assert(Condition, Message="")
{
	if(!Condition)
	{
		try
			throw Exception(Message, -1)
		catch e
			Msgbox % "Assertion failed at " e.File "#" e.Line ": " e.Message
	}
}

I already found two invalid GUI options in my program so that feature has already helped as well :)

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
Terrific! Fantastic! Superb!

* goes to reparse index.hhk

Tuncay
  • Members
  • 1945 posts
  • Last active: Feb 08 2015 03:49 PM
  • Joined: 07 Nov 2006
Incredible! I never thought exception handling would get supported in v1. What does exception handling impact on the execution time of script? In general, does it check after every line of code if exception occurs? Are these commands meant for debugging only?

No signature.


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

What does exception handling impact on the execution time of script?

I ran only a couple of simple benchmarks; one showed a marginal increase and the other showed a marginal decrease in performance. That can be attributed to CPU cache hits and misses (i.e. coincidence).

In general, does it check after every line of code if exception occurs?

A simple check was added to allow objects and built-in functions to throw exceptions; otherwise, it's handled automatically via a pre-existing mechanism also used for run-time errors (which exit the current thread if no try block is present), the Exit command, break, continue, etc.

Are these commands meant for debugging only?

They are meant for general use. However, there's a line in the documentation indicating that the exact structure of the exception object may change in a future version. In retrospect, I think it probably won't (but it did change slightly from fincs' original implementation).

* goes to reparse index.hhk

It's still missing at least one entry - Exception(). I intend to fix this and update the AutoHotkey_L features page soon.

jethrow
  • Moderators
  • 2854 posts
  • Last active: May 17 2017 01:57 AM
  • Joined: 24 May 2009
These Gui updates are excellent - thank you for the release!

Concerning try/catch, is it supposed to suppress error messages?

If ... a runtime error is detected during execution of a try block, execution immediately jumps out of the block. If there is a catch statement, it is executed.

I'm still getting an error message & the catch statement is never executing on the following code. Am I missing something?
; Example #3 (modified): Dealing with COM errors.

try
{
    obj := ComObjCreate("Scripting.Dictionary")
    obj.InvalidMethod() ; This line produces a runtime error.
}
catch e
{
    ; For more detail about the object that e contains, see Catch.
    MsgBox, 16,, % "Exception thrown!`n`nwhat: " e.what "`nfile: " e.file
        . "`nline: " e.line "`nmessage: " e.message "`nextra: " e.extra
}
Note - Example #3 in the Try Documentation needs the language property set, though I'd recommend using a 64-bit compatible example.
Note - There's no Downloads link in the original post.


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
That was a simple error I made while revising fincs' code, related to the way COM errors ask "Continue running the script?". It will be fixed.

Example #3 in the Try Documentation needs the language property set,

OTOH, removing the InvalidMethod() call and moving the comment up one line would result in an even more practical/real-world example.

though I'd recommend using a 64-bit compatible example.

Once I fix the bug, ComObjCreate("ScriptControl") will throw an exception when executed from a 64-bit script. Perhaps this makes the example even more suitable than originally thought...

jethrow
  • Moderators
  • 2854 posts
  • Last active: May 17 2017 01:57 AM
  • Joined: 24 May 2009

It will be fixed.

Ok - I'm still trying to fully understand what all try/catch is meant for. For instance, is the following considered a runtime error?
try
    Nonexistent_Function()
catch
    MsgBox, Cannot call a Nonexistent Function
Is this still supposed to generate an error, or should try suppress the error message & handle it with the catch block?

Perhaps this makes the example even more suitable than originally thought...

Perhaps, though I'd prefer that the example does not require specific knowledge of the Com Object - or at least explains what exactly is causing the error (especially since it would be different on 32 & 64-bit).

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
A "run-time error" is an error which occurs or is detected while the script is running. Since function names are resolved at load time (where possible), Nonexistent_Function() is a load-time error; that is, an error which is detected while the script is loading, before it begins executing. This is one way to demonstrate why "try" can't guard against load-time errors:
ExitApp ; The error is detected before even this line is executed.
try
    Nonexistent_Function()
catch
    MsgBox, Cannot call a Nonexistent Function
Generally any error message that says "The current thread will exit" was caused by a run-time error. There are certain run-time errors which don't throw exceptions (or show error message or set ErrorLevel), such as divide by zero, attempted math with non-numeric operands and dynamic function calls to non-existent functions or with too few parameters. Generally, "try" only guards against errors which cause ErrorLevel to be set or an error message shown.

However, fincs' original implementation of try/catch/throw did not include built-in commands or functions. It was intended to "simplify error handling" in scripts. For instance, if you have a series of function calls where each call can fail, you'd typically need to check ErrorLevel or the function's return value after each call:
Step1()
if !ErrorLevel
{
    Step2()
    if !ErrorLevel
    {
        Step3()
        if !ErrorLevel
            MsgBox All done!
    }
}
if ErrorLevel
    MsgBox Fail. :(
Obviously there would be better ways to write this if it was a real-world script, but it's not. Try/catch/throw allows it to be handled quite easily:
try {
    Step1()
    Step2()
    Step3()
    MsgBox All done!
} catch {
    MsgBox Fail. :(
}
That assumes Step1, Step2 and Step3 throw an exception on failure.

It's basically equivalent to "on error goto (catch block)".

jethrow
  • Moderators
  • 2854 posts
  • Last active: May 17 2017 01:57 AM
  • Joined: 24 May 2009

This is one way to demonstrate ...

Yes - that makes sense. It might be worth putting that in the documentation to clear up confusion on runtime vs loadtime errors.

Many thanks to fincs for his work on try/catch/throw.

+1 - really nice to see someone else submitting updates :) .

JSLover
  • Members
  • 920 posts
  • Last active: Nov 02 2012 09:54 PM
  • Joined: 20 Dec 2004

If no name is given, the new window is set as the default for the current thread.

If a name is specified, any existing GUI with that name is destroyed and the current thread's default GUI is not changed.

...OK, destroyed, yes, fine (I guess)...but why not always set default?...why does adding a name need to make it not set default? I really think it should always set default...you are creating a new Gui & then you need to put controls in it, right?

Gui, New
Gui, Add, Text, , I'm added to the anonymous window above (right?)
Gui, Show

Gui, Name:New
Gui, Add, Text, , Where am I added?
Gui, Show

Useful forum links: New content since: Last visitPast weekPast 2 weeks (links will show YOUR posts, not mine)

OMFG, the AutoHotkey forum is IP.board now (yuck!)...I may not be able to continue coming here (& I love AutoHotkey)...I liked phpBB, but not this...ugh...

Note...
I may not reply to any topics (specifically ones I was previously involved in), mostly cuz I can't find the ones I replied to, to continue helping, but also just cuz I can't stand the new forum...phpBB was soo perfect. This is 100% the opposite of "perfect".

I also semi-plan to start my own, phpBB-based AutoHotkey forum (or take over the old one, if he'll let me)
PM me if you're interested in a new phpBB-based forum (I need to know if anyone would use it)
How (or why) did they create the Neil Armstrong memorial site (neilarmstronginfo.com) BEFORE he died?

  • Guests
  • Last active:
  • Joined: --
Isn't Gui, New just redundant? I don't see the point of using this.

jethrow
  • Moderators
  • 2854 posts
  • Last active: May 17 2017 01:57 AM
  • Joined: 24 May 2009

Isn't Gui, New just redundant?

No - depending on how you use it. Moreover, it is necessary for creating multiple unnamed GUIs (see here):
Loop, 2 {
	x := A_Index*250
	Gui, New, ToolWindow LabelGui HWNDGui%A_Index%, Window%A_Index%
	Gui, Show, x%x% y100 w200 h100
}
return

GuiClose:
	ExitApp

...why does adding a name need to make it not set default?

Why should it? Personally, I don't think that creating an unnamed GUI should make it default - other than the fact that there may be no other way to reference it (outside of finding the hwnd). IMO, if you are creating a named GUI, best practice would be to continue to reference that GUI using it's name.