Sign in to follow this  
Followers 0
Chris_1013

Beginners Guide

22 posts in this topic

Is it just me or is the GUI stuff in AutoIt much harder than au3gui, but more powerful?

I'm struggling to understand how to do basic things like have something happen when clicking a button. What I want to do is have two list boxes, and update one when a button is clicked. Old styley I would have done this by making the button re-run the script and use the Control functions to update it. Can I be cleverer with the GUI in AutoIt 3?

Share this post


Link to post
Share on other sites



I think the GUI stuff is easier than au3gui since you do not need to mess with EnvSets and a secondary file. The GUI integration seems logical to me; however, the gui lacks replacements for certain Control functions...

If you wanted to get a list of all items in a list you would either need to:

1) use a global variable to keep track of each item as it is added

2) use the still-undocumented GuiSendMsg commands....

3) use Control functions that translate between classnameNN and GuiRefNumbers....

Here's an example that might help you:

#cs - ### Generated by AutoBuilder 0.4 -- do not modify ###
394 271
0   2   0   0   0   0   0   0   0   1   2   0   0   0   0   0   
button  $button_1   Add Item    20  20  100 50  0   0   
button  $button_2   Copy Items  200 20  120 50  0   0   
list    $list_1 List 1  20  90  120 150 0   0   
list    $list_2 List 2  200 90  140 160 0   0   
#ce - ### End of Dump ###

;Script generated by AutoBuilder 0.4 -- but modified

Opt("GUINotifyMode", 1)
GuiCreate("MyGUI", 392,266,(@DesktopWidth-392)/2, (@DesktopHeight-266)/2 , 0x04CF0000)

$button_1 = GUISetControl("button", "Add Item", 20, 20, 100, 50)
$button_2 = GUISetControl("button", "Copy Selected Item", 200, 20, 120, 50)
$list_1 = GUISetControl("list", "List 1", 20, 90, 120, 150)
GUISetControlData($list_1, 0, 0);create initial item
$list_2 = GUISetControl("list", "List 2", 200, 90, 140, 160)

GuiShow()
While 1
    sleep(100)
    $msg = GuiMsg(0)
    Select
    Case $msg = -3
        Exit
    Case $msg = $button_1
      GUISetControlData($list_1, Int(1+10*Random()) )
    Case $msg = $button_2
        $selected = GuiRead($list_1)
        GuiSetControlData($list_2, $selected)
    EndSelect
WEnd
Exit

Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!

Share this post


Link to post
Share on other sites

Thanks, this should be really helpful. I'm going to read the data in from a file and set this to a variable to show in the list, so that isn't a problem. I just need to try and tweak your code to 'move' the item from list 1 to list 2 (or back), and then work out have to save this information back out, but this gives me a good start.

I'm sure there's lots of power in the GuiSendMsg commands, but as you say, being undocumented this is tricky. I'm sure you can add/delete list items with something in this.

Any chance you could give a little explaination of what the While loop at the bottom does so I can help get my head around what's actually happening, and understand the code better?

Share this post


Link to post
Share on other sites

Any chance you could give a little explaination of what the While loop at the bottom does so I can help get my head around what's actually happening, and understand the code better?

The behavior is subject to change, but here how it currently works.

When you do something like clicking a button, an event notification is generated. GUIMsg(0) returns the GuiRefNumber of the last notification. (The GuiRefNumbers correspond to the GUISetControl statements up above.)

If you click the first button, then GUIMsg's return value will be $button_1. If you click the close 'x' button on the window, then GUIMsg returns -3. The select-case block handles the event notification for each control.

In the case of $button_1, GUISetControlData($list_1, Int(1+10*Random()) ) appends a random number to the first list.

The sleep(100) prevents maxing out your CPU.

Hope that makes sense.


Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Maybe the following will help you:

EDIT--added checks to prevent empty entries from adding to list boxes.

#cs - ### Generated by AutoBuilder 0.4 -- do not modify ###
394 271
0   2   0   0   0   0   0   0   0   0   2   0   0   0   0   0   
list    $list_1 List 1  10  20  120 230 0   0   
list    $list_2 List 2  260 20  120 230 0   0   
button  $button_1   Add --->    140 70  110 50  0   0   
button  $button_2   Remove ---> 140 150 110 50  0   0   
#ce - ### End of Dump ###

Dim $NULL
$LB_GETCURSEL =  0x00000188;get index of selected list box item
$LB_DELETESTRING = 0x00000182;delete item at specified index
$LB_ADDSTRING = 0x00000180;add item

;Script generated by AutoBuilder 0.4 -- but modified

Opt("GUINotifyMode", 1)
GuiCreate("MyGUI", 392,266,(@DesktopHeight-392)/2, (@DesktopHeight-266)/2 , 0x04CF0000)

$list_1 = GUISetControl("list", "List 1", 10, 20, 120, 230, 0x0);unsorted...
   GUISetControlData($list_1, "one|two|three|four|five|six|seven", "one")
$list_2 = GUISetControl("list", "List 2", 260, 20, 120, 230)
$button_1 = GUISetControl("button", "Add --->", 140, 70, 110, 50)
$button_2 = GUISetControl("button", "<--- Remove", 140, 150, 110, 50)

GuiShow()

While 1
    sleep(100)
    $msg = GuiMsg(0)
    Select
    Case $msg = -3
        Exit
    Case $msg = $button_1
        $list1selectedIndex = GuiSendMsg($list_1, $LB_GETCURSEL, $NULL, $NULL)
        $list1selectedItem = GuiRead($list_1)
        If $list1selectedItem = "" Then ContinueLoop
        GUISendMsg($list_2, $LB_ADDSTRING, $NULL, $list1selectedItem)
        GUISendMsg($list_1, $LB_DELETESTRING, $list1selectedIndex, $NULL)
       ; if list contains any items, make sure the first item is selected
        ControlCommand ("", "", "ListBox1", "SetCurrentSelection", 0)
        ControlCommand ("", "", "ListBox2", "SetCurrentSelection", 0)
     Case $msg = $button_2
        $list2selectedIndex = GuiSendMsg($list_2, $LB_GETCURSEL, $NULL, $NULL)
        $list2selectedItem = GuiRead($list_2)
        If $list2selectedItem = "" Then ContinueLoop
        GUISendMsg($list_1, $LB_ADDSTRING, $NULL, $list2selectedItem)
        GUISendMsg($list_2, $LB_DELETESTRING, $list2selectedIndex, $NULL)
       ; if list contains any items, make sure the first item is selected
        ControlCommand ("", "", "ListBox1", "SetCurrentSelection", 0)
        ControlCommand ("", "", "ListBox2", "SetCurrentSelection", 0)
    EndSelect
WEnd
Exit
Edited by CyberSlug

Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!

Share this post


Link to post
Share on other sites

Well, that only helps in that it's exactly what I want to do! Cheers mate, this is gonna be a big time saver :-)

Share this post


Link to post
Share on other sites

Maybe the following will help you:

...

Hi CyberSlug,

think there is a bug or it only don't work on my machine.

When I hit the Remove Button, sometimes wrong Items moves to the left. Also wrong Items got deleted on the right side. And sometimes a selected Item on the right get copied to the left without beeing deleted. And then the left side got duplicate entries.

Your script gave me motivation to find my own way. Here is another example. Took your script as template.

GuiCreate("MyGUI", 392,266,(@DesktopHeight-392)/2, (@DesktopHeight-266)/2 , 0x04CF0000)
$list_1 = GUISetControl("list", "List 1", 10, 20, 120, 230, 0x0);unsorted...
GUISetControlData($list_1, "one|two|three|four|five|six|seven", "one")
$list_2 = GUISetControl("list", "List 2", 260, 20, 120, 230)
$button_1 = GUISetControl("button", "Add --->", 140, 70, 110, 50)
GuiSetControlNotify()
$button_2 = GUISetControl("button", "<--- Remove", 140, 150, 110, 50)
GuiSetControlNotify()

GuiShow()
While 1

$msg = GuiMsg(0)
Select
;-----------------------------------
Case $msg = -3
Exit
;-----------------------------------
Case $msg = $button_1

$sel_item_left = GuiRead($list_1)
If $sel_item_left <> "" Then
$item2delete = ControlCommand ( "MyGUI", "", "ListBox1", "FindString", $sel_item_left)
ControlCommand ( "MyGUI", "", "ListBox1", "DelString", $item2delete)
GUISetControlData($list_2, $sel_item_left)

EndIf
;-----------------------------------
Case $msg = $button_2

$sel_item_right = GuiRead($list_2)
If $sel_item_right <> "" Then
$item2delete = ControlCommand ( "MyGUI", "", "ListBox2", "FindString", $sel_item_right)
ControlCommand ( "MyGUI", "", "ListBox2", "DelString", $item2delete)
GUISetControlData($list_1, $sel_item_right)
EndIf

EndSelect
;-----------------------------------

WEnd
Exit

It's just another method for that problem.

But I wish there would be more direct possibilities to work with Listbox Items.

arctor

Share this post


Link to post
Share on other sites

think there is a bug or it only don't work on my machine.

When I hit the Remove Button, sometimes wrong Items moves to the left. Also wrong Items got deleted on the right side. And sometimes a selected Item on the right get copied to the left without beeing deleted. And then the left side got duplicate entries.

Thanks for the feedback. I did very little testing, but I think my 03:49 PM edit fixed most bugs.

Also, I was testing on Win XP Pro sp1 with a June 4 unstable version of AutoIt (I think).

Standard disclaimer: My code is likely to contain bugs :D


Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!

Share this post


Link to post
Share on other sites

OK, any ideas how to read out what's in each of the list boxes? GuiRead only seems to return current selection. I was looking at one fo the messages that can retrieve any entry in the list and thinking about some loop, but I couldn't get that to pick up even one of the entries.

Share this post


Link to post
Share on other sites

Is it just me or is the GUI stuff in AutoIt much harder than au3gui, but more powerful?

I'm struggling to understand how to do basic things like have something happen when clicking a button. What I want to do is have two list boxes, and update one when a button is clicked. Old styley I would have done this by making the button re-run the script and use the Control functions to update it. Can I be cleverer with the GUI in AutoIt 3?

Re: the topic title

It's hard to spend more time on a beginners guide/documentation at the moment as the gui is going through pretty big changes all the time...

Share this post


Link to post
Share on other sites

Yeah I guess so, to be honest I was just in one of those lazy moods where I thought I'd just hammer out a quick question in the hope of some pointers. It's amazing how powerful AutoIt is really coming, but this of course documentation is the bane of anyone who enjoys programming as you just wanna get on and do it!

Share this post


Link to post
Share on other sites

The magic is

GuiSendMsg(...,$LB_GETCOUNT,...)

GUIRecvMsg(...,$LB_GETTEXT,...)

#cs - ### Generated by AutoBuilder 0.4 -- do not modify ###
394 271
0   1   0   0   0   0   0   0   0   0   1   0   0   0   0   0   
list    $list_1 List 1  20  30  140 230 0   0   
button  $button_1   List contents   180 40  170 50  0   0   
#ce - ### End of Dump ###

Global $NULL
Global $LB_GETCOUNT = 0x18B;
Global $LB_GETTEXT = 0x189;

Opt("GUINotifyMode", 1)
GuiCreate("MyGUI", 392,266,(@DesktopWidth-392)/2, (@DesktopHeight-266)/2)
$list_1 = GUISetControl("list", "List 1", 20, 30, 140, 230)
   GUISetControlData($list_1, "one|two|three|four|", "one")
$button_1 = GUISetControl("button", "List contents", 180, 40, 170, 50)

GuiShow()
While 1
    sleep(100)
    $msg = GuiMsg(0)
    Select
    Case $msg = -3
        Exit
    Case $msg = $list_1
       ;;;
    Case $msg = $button_1
      Local $i
      Local $t = ''
      For $i = 0 to GuiSendMsg($list_1, $LB_GETCOUNT, $NULL, $NULL) - 1
         $t = $t & @CRLF & GUIRecvMsg($list_1, $LB_GETTEXT, $i, 1) 
      Next
      MsgBox(4096,"Contents", $t)
    EndSelect
WEnd
Exit

Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!

Share this post


Link to post
Share on other sites

That's exactly what I was trying to do. I was being scuppered by the fact I couldn't find any documentation of what the GETTEXT constant should be defined as.

Share this post


Link to post
Share on other sites

Hi all,

I think this is a good question for this Topic Beginners Guide. Hope I'm not the only one who gets a little confused about the different "main loop" expressions which are in use here.

All examples for the loop I got out of the Documentation or from this forum.

;1st example
FileChangeDir(@ScriptDir)
GUICreate("Title", 120, 100)
$GetOut = GUISetControl ("button", "EXIT", 10,40,100,20)
GuiSetControlNotify()
;-------------------------------------------------------

GuiShow()
While GuiMsg(0) <> -3

$msg = GuiMsg(0)
Select

Case $msg = $GetOut
MsgBox (0, "", "OK, here we go...")
Exit

EndSelect
Wend

;2nd example
FileChangeDir(@ScriptDir)
GUICreate("Title", 120, 100)
$GetOut = GUISetControl ("button", "EXIT", 10,40,100,20)
GuiSetControlNotify()
;-------------------------------------------------------
While GuiMsg() > 0

$msg = GuiMsg(0)
Select

Case $msg = $GetOut
MsgBox (0, "", "OK, here we go...")
Exit

EndSelect
Wend

;3rd example
FileChangeDir(@ScriptDir)
GUICreate("Title", 120, 100)
$GetOut = GUISetControl ("button", "EXIT", 10,40,100,20)
GuiSetControlNotify()
;-------------------------------------------------------

GuiShow()
While 1

$msg = GuiMsg(0)
Select

Case $msg = $GetOut
MsgBox (0, "", "OK, here we go...")
Exit

EndSelect
Wend

So here is what I noticed:

1st example:

I have to use a GuiShow()

My processor usage goes against 100 percent

Also I noticed, that not every click on the button let the MsgBox come up.

2nd example:

I don't have to use a GuiShow()

My processor usage goes against 0 percent :D

All works well (on my machine)

3rd example:

I have to use a GuiShow()

My processor usage goes against 100 percent

Ok, I can do a sleep(100) - But then the reaction of the control is slow.

Not really satisfying.

(For seeing processor usage i used procmon from sysinternals.com - not the microsoft one)

So it should be clear that I prefer example 2.

But does it work on every machine? See posting of kalayaan in Topic "Notify if listbox entry is clicked".

(Quote: ...I also tried transposing your code into the format generated by AutoBuilder using GuiMsg(0) and it works when before it didn't.)

Kalayaan, can you try my example2 unmodified on your machine and give a response to me?

thx

Could anyone clear up the differences between the examples?

In which case I have to use a GuiMsg(0) instead of GuiMsg()

In which case I have to ask for -3

arctor

Share this post


Link to post
Share on other sites

So here is what I noticed:

1st example:

I have to use a GuiShow()

My processor usage goes against 100 percent

Also I noticed, that not every click on the button let the MsgBox come up.

Are you using the latest Unstable?

Jon added a default sleep(10) (i believe)


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

Are you using the latest Unstable?

Jon added a default sleep(10) (i believe)

You are right.

I noticed the posting of jpm in Topic 'GuiMsg return values' too late.

I just downloaded the latest ver from 6th June.

example 2 is working no more. :D

But it was the one with the minimum CPU usage!

Your Assumption with the default sleep(10) seems true.

I didn't add a sleep() and the example 1 and 3 now needs 6 percent CPU Usage.

I hope this will not be the final solution!?

arctor

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

In those examples, 1 and 2 are COMPLETELY wrong - let me know where they are in the docs and I will change.

Using GuiMsg(0) will always give some CPU usage as it is constantly using the CPU to poll the gui. Unless you want to use Adlib then I would recommend never using GuiMsg(0) and use GuiMsg() instead that is more processor friendly.

Edited by Jon

Share this post


Link to post
Share on other sites

In those examples, 1 and 2 are COMPLETELY wrong - let me know where they are in the docs and I will change.

...

Hi Jon, thanks for the info

I found it here. I mean only the "main loops":

Example 1:

While GuiMsg(0) <> -3

AutoIt.chm /Function Reference/Gui Reference/GuiSetCursor

Example 2:

While GUIMsg() > 0

AutoIt.chm /Function Reference/Gui Reference/GuiWrite and GuiSendMessage

Jon: >...1 and 2 are COMPLETELY wrong...

What do you mean? Because of the loop or because of $msg = GuiMsg(0)

;4th example
FileChangeDir(@ScriptDir)
GUICreate("Title", 120, 100)
$GetOut = GUISetControl ("button", "EXIT", 10,40,100,20)
GuiSetControlNotify()
;-------------------------------------------------------
While GuiMsg() > 0

$msg = GuiRead();<--------<<
Select

Case $msg = $GetOut
MsgBox (0, "", "OK, here we go...")
Exit

EndSelect
Wend

This works for me in the latest unstable. Is this correct or is it wrong too?

arctor

Share this post


Link to post
Share on other sites

It's not correct because if you minimize, restore or close the window (using the X), it will exit the script in all those cases.

You can better use this way:

FileChangeDir(@ScriptDir)
GUICreate("Title", 120, 100)
$GetOut = GUISetControl ("button", "EXIT", 10,40,100,20)
GuiSetControlNotify()
;-------------------------------------------------------
While GuiMsg() <> -3

$msg = GuiRead();<--------<<
Select

Case $msg = $GetOut
MsgBox (0, "", "OK, here we go...")
Exit

EndSelect
Wend

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0