Sign in to follow this  
Followers 0
cal

Button Click Function gets called Twice.

8 posts in this topic

I have a script that gets system uptime and some bios info from remote computers on our network. I could not figure out why the laptops were getting the computer names wrong on the output while the desktops were correct. Yet the laptop names had to be correct as the correct output info was being returned for each laptop I put in.

Lots of messing around and I found the problem in a function that only gets called when I click a button on the input Gui I created. Seems the function is being called twice under certain conditions.

The button does nothing more then putting "L-H-0" in the input field instead of the default "D-H-0". There is a change detection function for this input as well so that the script does its work when you change focus away from the input field. (normally by hitting enter)

I have discovered that this function runs twice if I type the rest of the laptop name and hit enter. If I type the rest of the name and hit tab then it does not get called a second time.

Its likely been like this for awhile but I recently changed the output gui and thats when I noticed it. It seems one of my output fields got named the same as this input one on the first gui. So after the output finishes, the second run of this Button press function kicks in and changes it again.

This should be easy to fix. I should be able to rename the affected control on my output gui and it won't matter that the function runs twice. But it bugs me now that I'm aware of it.

I guess this is my punishment for using global control names and then accidentally reusing one.

But why is it doing this? Is this a bug in autoit or in my script? The input field has focus when I press enter but the button is behaving like it has focus instead. If I tab away from the input field instead, then it the second run of the button press function never happens.

There are no calls to this function anywhere else in the script other then clicking the button.

Any thoughts?

Share this post


Link to post
Share on other sites



I have a script that gets system uptime and some bios info from remote computers on our network. I could not figure out why the laptops were getting the computer names wrong on the output while the desktops were correct. Yet the laptop names had to be correct as the correct output info was being returned for each laptop I put in.

Lots of messing around and I found the problem in a function that only gets called when I click a button on the input Gui I created. Seems the function is being called twice under certain conditions.

The button does nothing more then putting "L-H-0" in the input field instead of the default "D-H-0". There is a change detection function for this input as well so that the script does its work when you change focus away from the input field. (normally by hitting enter)

I have discovered that this function runs twice if I type the rest of the laptop name and hit enter. If I type the rest of the name and hit tab then it does not get called a second time.

Its likely been like this for awhile but I recently changed the output gui and thats when I noticed it. It seems one of my output fields got named the same as this input one on the first gui. So after the output finishes, the second run of this Button press function kicks in and changes it again.

This should be easy to fix. I should be able to rename the affected control on my output gui and it won't matter that the function runs twice. But it bugs me now that I'm aware of it.

I guess this is my punishment for using global control names and then accidentally reusing one.

But why is it doing this? Is this a bug in autoit or in my script? The input field has focus when I press enter but the button is behaving like it has focus instead. If I tab away from the input field instead, then it the second run of the button press function never happens.

There are no calls to this function anywhere else in the script other then clicking the button.

Any thoughts?

Can you show a minimum script which demonstrates the problem, and say what version of AutoIt you are using?

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

I'm using ver v3.2.10.0

I fixed it by changing the name of the output control. But the func still gets called twice as evident of a mesg box I put in the func to show when it gets called. It just no longer can change my output gui when it runs that second time.

I'll see if I can strip it down for easier reading while still showing the issue.

Share this post


Link to post
Share on other sites

OK. Here is a gutted version of the script that still shows the issue. I've left most of the functions in place with dummy statements just setting the data instead of figuring it out.

I have left the gui sections intact. Where things are changed, I commented that its fake stuff for the test.

It does not matter what you put in as a computer name. It will be faked to be online and give fake data as a result. The function in question has a msgbox popup so that you know each time it gets called.

To see the issue do the following.

Run the script and put in some number in the input field and press enter. You should see the fake results. No popup from the "L Button" function will have shown. All is good.

Try it again. This time use the tab key to move the focus out of the input box. Again. It works as expected.

Try again. This time press the "L Button" with the mouse. You should get a popup. The input should now read "L-H-0". Put a number on it and press tab to move the focus. You get the results and all is still as expected.

Try again. This time press the "L Button" with the mouse. You should get a popup. The input should now read "L-H-0". Put a number on it and press enter. The popup happens again showing that the function somehow got rerun when you pressed enter.

Why?

If someone needs clarification and asked me a question but got no response. I'm not ignoring you...

I'm out of town starting after work today for the long weekend so I wont be back till Tuesday and will try to answer any questions put to me then.

Hopefully, there is a small flaw in my logic that I'm just not seeing and it will be pointed out easily by someone looking at it from another viewpoint.

Like I said in the above post. I fixed the issue by renaming one of the output controls so the second run of the function has no effect. But it bugs me that I can't figure out why its running twice. In this script, no big deal. But having a function run more then expected with other scripts could cause unexpected behavior so I'd like to figure out why this is happening so I can fix it properly.

$ver = 'ver 12w'

#include <Constants.au3>
#include <Array.au3>
#include <GUIConstants.au3>
#include <String.au3>
#Include <Date.au3>

Opt("GUIOnEventMode", 1)


If Not @Compiled Then Opt("TrayIconDebug", 1)       ;0=no info, 1=debug line info
Opt("MouseCoordMode", 0)       ;1=absolute, 0=relative
Opt("WinTitleMatchMode", 2) ;1=start, 2=subStr, 3=exact, 4=advanced

; ensure this copy is the running one.
$g_szVersion = "Uptime Script"
If WinExists($g_szVersion) Then WinClose($g_szVersion)
AutoItWinSetTitle($g_szVersion)

Send("{NUMLOCK on}");set numlock to on status


Global $comp_name = ''
Global $mesg = ''
Global $last_user = ''
Dim $history[10]
;~ Global $mesg_norm = ''
Global $used_history = ''
Global $bios_serial = ''
Global $bios_brand = ''
Global $bios_model = ''
Global $totalmem = ''
Global $logged_on_user = ''
Global $install_date = ''

; for wmi stuff.
Global $wbemFlagReturnImmediately = 0x10
Global $wbemFlagForwardOnly = 0x20
Global $colItems = ""

Global $days = ''
Global $hours = ''
Global $min = ''
Global $sec = ''


mygui()


While 1
    Sleep(5000)
WEnd


Func get_uptime()

SplashTextOn("Uptime", "Online Check, Please Wait...", 300, 75, -1, -1, 0, "", 12)
If check_if_online() Then
    
    SplashOff()

;~      $lbt = $objItem.LastBootUpTime
;~      $ldt = $objItem.LocalDateTime
        $install_date = 'install date'  ; all fake results.
        $days = '4'
        $hours = '02'
        $min = '03'
        $sec = '55'

    gui_output()
    
; history section.
    
Else
;~  mygui()
EndIf

EndFunc

#region mygui
Func mygui()

#Region ### START Koda GUI section ### Form=C:\Tools\Scripts\uptime\Uptime.kxf
Global $Uptime = GUICreate("Uptime", 331, 185, 197, 115)
GUISetOnEvent($GUI_EVENT_CLOSE, "UptimeClose")
Global $c_comp = GUICtrlCreateInput("D-H-0", 24, 64, 201, 21)
GUICtrlSetOnEvent(-1, "c_compChange")
Global $c_drop = GUICtrlCreateCombo("Or Pick from History", 24, 104, 201, 25)
GUICtrlSetOnEvent(-1, "c_dropChange")
Global $Label1 = GUICtrlCreateLabel("Enter Computer to Check", 24, 32, 123, 17)
Global $L_Button = GUICtrlCreateButton("L", 248, 64, 41, 21, 0)
GUICtrlSetOnEvent(-1, "L_Buttonclick")
Global $c_highlight = GUICtrlCreateCheckbox("Highlight", 248, 160, 73, 17)
GUICtrlSetOnEvent(-1, "c_highlightClick")
Global $Version = GUICtrlCreateLabel("Version", 8, 160, 39, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

; set gui info
    GUICtrlSetData($Version, $ver)
    Send('{end}')
    MouseMove(280,103,0)
    
    For $i = 0 To 9
        $history[$i] = RegRead('HKEY_CURRENT_USER\Software\Calvin\Uptime', 'History' & $i)
    Next

    For $i = 0 To 9
        GUICtrlSetData($c_drop, $history[$i])
    Next
    GUICtrlSetData($c_drop, 'Or Pick from History','Or Pick from History')
    
    $highlight = RegRead('HKEY_CURRENT_USER\Software\Calvin\Uptime', 'Highlight')   ; 1=checked, 4=unchecked.
    If $highlight = 1 Then
        GUICtrlSetState($c_highlight,$GUI_CHECKED)
        GUICtrlSetState($c_comp, $GUI_FOCUS)
    Else
        GUICtrlSetState($c_highlight,$GUI_UNCHECKED)
        GUICtrlSetState($c_comp, $GUI_FOCUS)
        Send('{end}')
    EndIf
EndFunc  ;==>mygui

Func L_Buttonclick()
    GUICtrlSetData($c_comp, 'L-H-0')
    GUICtrlSetState($c_comp, $GUI_FOCUS)
    $highlight = GUICtrlRead($c_highlight)
    If $highlight <> 1 Then Send('{end}')
    MsgBox(0,'L Button Function was called',$comp_name)
EndFunc
Func c_dropChange()
    GUISetState(@SW_HIDE)
    $comp_name = GUICtrlRead($c_drop)
    $comp_name = StringStripWS($comp_name,3)
    If $comp_name = 'Or Pick from History' Then
        MsgBox(0,'Error','You picked the Prompt')
        GUISetState(@SW_SHOW)
    EndIf
    If $comp_name <> 'Or Pick from History' Then
        $comp_name = StringLeft($comp_name,StringInStr($comp_name,' ')-1)
        $comp_name = StringStripWS($comp_name,3)
        $used_history = 'yes'
        get_uptime()
    EndIf
EndFunc  ;==>c_dropChange
Func c_compChange()
    GUISetState(@SW_HIDE)
    $comp_name = GUICtrlRead($c_comp)
    $comp_name = StringStripWS($comp_name,3)
    $used_history = 'no'
;~  MsgBox(0,'comp change',$comp_name)
    get_uptime()
EndFunc  ;==>c_compChange
Func UptimeClose()
    Exit
EndFunc  ;==>UptimeClose
Func c_highlightClick()
    $highlight = GUICtrlRead($c_highlight)
    RegWrite('HKEY_CURRENT_USER\Software\Calvin\Uptime', 'Highlight', "REG_SZ", $highlight)
    If $highlight = 1 Then
        GUICtrlSetState($c_comp, $GUI_FOCUS)
    Else
        GUICtrlSetState($c_comp, $GUI_FOCUS)
        Send('{end}')
    EndIf
EndFunc
#endregion
;

#region  output
Func gui_output()
    
#Region ### START Koda GUI section ### Form=c:\tools\scripts\uptime\output.kxf
Global $Output = GUICreate("Uptime Output", 399, 227, 288, 269)
GUISetOnEvent($GUI_EVENT_CLOSE, "OutputClose")
Global $OK = GUICtrlCreateButton("OK", 192, 192, 73, 17, 0)
GUICtrlSetOnEvent(-1, "OKClick")
Global $c_o_comp = GUICtrlCreateInput("c_o_comp", 8, 0, 100, 21)
Global $c_last_user = GUICtrlCreateInput("c_last_user", 64, 32, 201, 21)
Global $Label3 = GUICtrlCreateLabel("Brand", 15, 120, 32, 17)
Global $c_brand = GUICtrlCreateInput("c_brand", 64, 120, 97, 21)
Global $c_Model = GUICtrlCreateInput("Input4", 64, 150, 97, 21)
Global $c_serial = GUICtrlCreateInput("Input4", 64, 180, 97, 21)
Global $log_status = GUICtrlCreateLabel("log_status", 336, 8, 52, 17, $SS_CENTER)
Global $ALabel1 = GUICtrlCreateLabel("User is Currently Logged", 208, 8, 119, 17, $SS_CENTER)
Global $UpTime = GUICtrlCreateLabel("UpTime", 16, 72, 41, 17)
Global $Orig_Install_date = GUICtrlCreateLabel("Orig Install date", 184, 120, 77, 17)
Global $Label1 = GUICtrlCreateLabel("Total Memory", 192, 150, 68, 17)
Global $Label2 = GUICtrlCreateLabel("Bios Info", 5, 100, 45, 17)
Global $c_uptime = GUICtrlCreateInput("c_uptime", 64, 72, 281, 21)
Global $c_Orig_Intall_Date = GUICtrlCreateInput("c_Orig_Intall_Date", 264, 120, 110, 21)
Global $c_Total_Memory = GUICtrlCreateInput("c_Total_Memory", 264, 150, 110, 21)
Global $Label4 = GUICtrlCreateLabel("Model", 15, 150, 33, 17)
Global $Label5 = GUICtrlCreateLabel("Serial", 15, 180, 30, 17)
Global $Label6 = GUICtrlCreateLabel("Last User", 8, 32, 49, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

; setup gui.
;~ MsgBox(0,'output at start compname',$comp_name)
GUICtrlSetData($c_o_comp,$comp_name)

$mesg = $days & ' Days, ' & $hours & ' Hours, ' & $min & ' Min, ' & $sec & ' Seconds.'
GUICtrlSetData($c_uptime,$mesg)
GUICtrlSetData($c_Orig_Intall_Date,$install_date)

get_bios_serial()
GUICtrlSetData($c_serial,$bios_serial)

get_compsystem()
GUICtrlSetData($c_brand,$bios_brand)
GUICtrlSetData($c_Model,$bios_model)
GUICtrlSetData($c_Total_Memory,$totalmem)


If $logged_on_user = '' Then 
    GUICtrlSetData($log_status,'off')
    GUICtrlSetBkColor($log_status, 0xff0000); red
Else 
    GUICtrlSetData($log_status,'on')
    GUICtrlSetBkColor($log_status, 0x00ff00); green
EndIf

;~ $last_user = RegRead('\\' & $comp_name & '\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon', 'DefaultUserName')

$last_user = 'first.last'; faking the results for stripped down ver.
GUICtrlSetData($c_last_user,$last_user)
    
GUICtrlSetState($OK, $GUI_FOCUS)
MouseMove(229,228,0)

EndFunc

Func OKClick()
    Exit
EndFunc
Func OutputClose()
    Exit
EndFunc
#endregion
;

Func get_bios_serial()
        $bios_serial = 'bios serial' ; fake
EndFunc

Func get_compsystem()
        $bios_brand = 'bios brand'   ; all fake.
        $bios_model = 'bios mod'
        $totalmem = 'mem'
        $logged_on_user = 'first.last'; is blank when no user is currently logged in. faking someone being logged on.
EndFunc

Func check_if_online()
    Return 1; if online.  fake for test.
EndFunc

Share this post


Link to post
Share on other sites

I can see what you mean.

Once you have clicked the button and it receives focus it becomes the default button for when Enter is pressed.

There is probably a good way to fix this, i.e. not the way I show below. Until you find that better way then changing the on click function like this does what you want.

Method 1

;in mygui function add one line
Global $L_Button = GUICtrlCreateButton("L", 248, 64, 41, 21, 0)
GUICtrlSetOnEvent(-1, "L_Buttonclick")
Global $nobut = GUICtrlCreateButton("",-100,-100,10,10);<-----add
.
.
..
;in on click func add one line
Func L_Buttonclick()
    GUICtrlSetData($c_comp, 'L-H-0')
    GUICtrlSetState($c_comp, $GUI_FOCUS)
    $highlight = GUICtrlRead($c_highlight)
    If $highlight <> 1 Then Send('{end}')
    MsgBox(0,'L Button Function was called',$comp_name)
    GUICtrlSetState($nobut,$GUI_FOCUS);<--------------add
EndFunc

Method 2

Func L_Buttonclick()
    GUICtrlSetData($c_comp, 'L-H-0')
    GUICtrlSetState($c_comp, $GUI_FOCUS)
    $highlight = GUICtrlRead($c_highlight)
    If $highlight <> 1 Then Send('{end}')
    MsgBox(0,'L Button Function was called',$comp_name)
    GUICtrlDelete($L_Button)
    $L_Button = GUICtrlCreateButton("L", 248, 64, 41, 21, 0)
    GUICtrlSetOnEvent(-1, "L_Buttonclick")
EndFunc

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Strange. I used your method 1 in my stripped down version and it worked.

Then tried to put it in my full version and could not make it work. When that highlight and some other stuff I stripped out is functional I need the focus on the input. But now I know the last button clicked seems to be a default when enter is pressed. I fixed it by sending a click to a hidden button that does nothing right after I click the L button before performing its functions. Now when I press enter after entering the rest of the laptop name the extra button does nothing and all is good.

I'll have to remember this. Thanks for the workaround.

So is this a bug? Or just the way buttons work. ie... Last button clicked gets pressed again when enter is hit even if on another field. Feels like a bug. Likely already squished in the betas. I'll try and remember to check when the next version comes out. Perhaps I'll install the beta on another machine and check it out.

Hmmm.. Now that I have reread your method 2. That seems more both more elegant somehow and yet messing with a gui from a function feels wrong to me. I'll have to play with it. I haven't tried it yet.

Thanks again.

Share this post


Link to post
Share on other sites

Interesting. I'll have to check that out next week. I do set a background color on a control but not on the button in question but this very well may be the root cause. I'll check if that's it and then update to the current version of Autoit to see if it's fixed. (just noticed the update last night)

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