 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
jballi
Joined: 01 Oct 2005 Posts: 297 Location: Texas, USA
|
Posted: Fri Dec 28, 2007 4:03 am Post subject: GUIControlGet bugs |
|
|
v1.0.47.05
Another GUI in a function issue...
The GUIControlGet command does not return valid values sometimes if called from a non-primary thread (GUI Event thread, menu thread, timer, etc.). The Pos sub-command always fails whereas the Enabled, Visible, and hWnd sub-commands do not work when using a static variable. The Focus and FocusV sub-commands work correctly under all conditions.
Example script includes GUI controls with static, global, and no variables. Just run the script to see examples of the problem.
| Code: | #NoEnv
#SingleInstance Force
test()
return
;-- Test function
test()
{
gui 23:Default
gui Margin,0,0
;-- Global variable assigned to this control
Global $Button1
gui Add
,Button
,w320 h40
|| v$Button1
|| gButton1
,Button 1, Global variable. Click to get attributes for this button
;-- static variable assigned to this control
Static $Button2
gui Add
,Button
,w350 h40
|| v$Button2
|| gButton2
,Button 2, Static variable. Click to get attributes for this button
;-- No variable assigned to this control
gui Add
,ListView
,w350 h200
|| gListAction
,ListView
LV_Add("","ListView, No variable. Double-click here to get attributes for this control")
GUIControl Focus,Button2
gui Show,AutoSize,Test23
gui +OwnDialogs ;-- Attach message to the current GUI
msgbox 64,Information,
(ltrim
About to collect and display attributes for the GUI's controls using
GUIControlGet...
`nPlease note that all GUIControlGet values for all of the controls are
defined correctly.
)
GUIControl Focus,Button1
GUIControlGet NT_Button1_Focus,Focus
GUIControlGet NT_Button1_FocusV,FocusV
GUIControlGet NT_Button1_Pos,Pos,$Button1
GUIControlGet NT_Button1_Enabled,Enabled,$Button1
GUIControlGet NT_Button1_Visible,Visible,$Button1
GUIControlGet NT_Button1_hWnd,hWnd,$Button1
MsgBox,
(ltrim
---- Button1 (Normal thread) ----
Pos values:
%A_Space% PosX=%NT_Button1_PosX%
%A_Space% PosY=%NT_Button1_PosY%
%A_Space% PosW=%NT_Button1_PosW%
%A_Space% PosH=%NT_Button1_PosH%
Focus=%NT_Button1_Focus%
FocusV=%NT_Button1_FocusV%
Enabled=%NT_Button1_Enabled%
Visible=%NT_Button1_Visible%
hWnd=%NT_Button1_hWnd%
)
GUIControl Focus,Button2
GUIControlGet NT_Button2_Focus,Focus
GUIControlGet NT_Button2_FocusV,FocusV
GUIControlGet NT_Button2_Pos,Pos,$Button2
GUIControlGet NT_Button2_Enabled,Enabled,$Button2
GUIControlGet NT_Button2_Visible,Visible,$Button2
GUIControlGet NT_Button2_hWnd,hWnd,$Button2
MsgBox,
(ltrim
---- Button2 (Normal thread) ----
Pos values:
%A_Space% PosX=%NT_Button2_PosX%
%A_Space% PosY=%NT_Button2_PosY%
%A_Space% PosW=%NT_Button2_PosW%
%A_Space% PosH=%NT_Button2_PosH%
Focus=%NT_Button2_Focus%
FocusV=%NT_Button2_FocusV%
Enabled=%NT_Button2_Enabled%
Visible=%NT_Button2_Visible%
hWnd=%NT_Button2_hWnd%
)
GUIControl Focus,SysListView321
GUIControlGet NT_SysListView321_Focus,Focus
GUIControlGet NT_SysListView321_FocusV,FocusV
GUIControlGet NT_SysListView321_Pos,Pos,SysListView321
GUIControlGet NT_SysListView321_Enabled,Enabled,SysListView321
GUIControlGet NT_SysListView321_Visible,Visible,SysListView321
GUIControlGet NT_SysListView321_hWnd,hWnd,SysListView321
MsgBox,
(ltrim
---- ListView (Normal thread) ----
Pos values:
%A_Space% PosX=%NT_SysListView321_PosX%
%A_Space% PosY=%NT_SysListView321_PosY%
%A_Space% PosW=%NT_SysListView321_PosW%
%A_Space% PosH=%NT_SysListView321_PosH%
Focus=%NT_SysListView321_Focus%
FocusV=%NT_SysListView321_FocusV% (Blank OK. No variable for this control)
Enabled=%NT_SysListView321_Enabled%
Visible=%NT_SysListView321_Visible%
hWnd=%NT_SysListView321_hWnd%
)
msgbox 64,Information,
(ltrim
Continue the test by following the instructions on the controls.
`nNote than some of the GUIControlGet values are set but many are not.
`nAlso note that the function does not return until the GUI window is
closed.
)
WinWaitClose Test23
return
23GUIClose:
23GUIEscape:
ExitApp
Button1:
gui 23:Default
GUIControlGet IT_Button1_Focus,Focus
GUIControlGet IT_Button1_FocusV,FocusV
GUIControlGet IT_Button1_Pos,Pos,$Button1
GUIControlGet IT_Button1_Enabled,Enabled,$Button1
GUIControlGet IT_Button1_Visible,Visible,$Button1
GUIControlGet IT_Button1_hWnd,hWnd,$Button1
MsgBox,
(ltrim
---- Button1 (GUI Event thread) ----
Pos values:
%A_Space% PosX=%IT_Button1_PosX%
%A_Space% PosY=%IT_Button1_PosY%
%A_Space% PosW=%IT_Button1_PosW%
%A_Space% PosH=%IT_Button1_PosH%
Focus=%IT_Button1_Focus%
FocusV=%IT_Button1_FocusV%
Enabled=%IT_Button1_Enabled%
Visible=%IT_Button1_Visible%
hWnd=%IT_Button1_hWnd%
)
return
Button2:
gui 23:Default
GUIControlGet IT_Button2_Focus,Focus
GUIControlGet IT_Button2_FocusV,FocusV
GUIControlGet IT_Button2_Pos,Pos,$Button2
GUIControlGet IT_Button2_Enabled,Enabled,$Button2
GUIControlGet IT_Button2_Visible,Visible,$Button2
GUIControlGet IT_Button2_hWnd,hWnd,$Button2
MsgBox,
(ltrim
---- Button2 (GUI Event thread) ----
Pos values:
%A_Space% PosX=%IT_Button2_PosX%
%A_Space% PosY=%IT_Button2_PosY%
%A_Space% PosW=%IT_Button2_PosW%
%A_Space% PosH=%IT_Button2_PosH%
Focus=%IT_Button2_Focus%
FocusV=%IT_Button2_FocusV%
Enabled=%IT_Button2_Enabled%
Visible=%IT_Button2_Visible%
hWnd=%IT_Button2_hWnd%
)
return
ListAction:
gui 23:Default
if A_GUIEvent=DoubleClick
{
GUIControlGet IT_SysListView321_Focus,Focus
GUIControlGet IT_SysListView321_FocusV,FocusV
GUIControlGet IT_SysListView321_Pos,Pos,SysListView321
GUIControlGet IT_SysListView321_Enabled,Enabled,SysListView321
GUIControlGet IT_SysListView321_Visible,Visible,SysListView321
GUIControlGet IT_SysListView321_hWnd,hWnd,SysListView321
MsgBox,
(ltrim
---- ListView (GUI Event thread) ----
Pos values:
%A_Space% PosX=%IT_SysListView321_PosX%
%A_Space% PosY=%IT_SysListView321_PosY%
%A_Space% PosW=%IT_SysListView321_PosW%
%A_Space% PosH=%IT_SysListView321_PosH%
Focus=%IT_SysListView321_Focus%
FocusV=%IT_SysListView321_FocusV% (Blank OK. No variable for this control)
Enabled=%IT_SysListView321_Enabled%
Visible=%IT_SysListView321_Visible%
hWnd=%IT_SysListView321_hWnd%
)
}
return
}
|
Thank you for your attention. Let me know if you have any questions or if you need any additional information. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3544 Location: Belgrade
|
Posted: Fri Dec 28, 2007 11:37 am Post subject: |
|
|
I experienced the same thing on various places.
I just didn't have nerves to document it the way you did.
This is definitely nasty bug.
EDIT:
I noticed that even using the DllCall to set adquate window option failes, while functions even report success. For instance, settting always on top in dock module sometimes failed, while SetWindowPos function was returning success. The way to know was just to explicitely check ex styles. _________________
 |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10450
|
Posted: Sun Mar 02, 2008 4:17 pm Post subject: |
|
|
You can see better what's going on by putting a ListVars before each MsgBox. I believe some of this, possibly all, is covered by the following information in the documentation: | Quote: | A function may contain externally-called subroutines such as timers, GUI g-labels, and menu items. This is generally done to encapsulate them in a separate file for use with #Include, which prevents them from interfering with the script's auto-execute section. However, the following limitations apply:- Such subroutines should use only static and global variables (not locals) if their function is ever called normally. This is because a subroutine thread that interrupts a function-call thread (or vice versa) would be able to change the values of local variables seen by the interrupted thread. Furthermore, any time a function returns to its caller, all of its local variables are made blank to free their memory.
- Such subroutines should use only global variables (not static variables) as GUI control variables.
- When a function is entered by a subroutine thread, any references to dynamic variables made by that thread are treated as globals (including commands that create arrays).
| While counterintuitive, these behaviors can't be changed without a major redesign (not to mention breaking scripts). Another factor is that the ability of functions to contain externally-called subroutines wasn't originally intended. This somewhat "impure" functionality was left in place because some people were using it and said they wanted it.
If any issues remain, I can try to look into them. |
|
| Back to top |
|
 |
jballi
Joined: 01 Oct 2005 Posts: 297 Location: Texas, USA
|
Posted: Wed Mar 05, 2008 4:04 am Post subject: |
|
|
Thank you for your feedback.
I think the best word to describe the GUIControlGet command when used by an interrupt thread (GUI Event thread, menu thread, timer, etc.) is inconsistent.
Based upon your feedback, I did some additional tests. The results can be described using the following table. It's a bit cryptic but it does cover all of the conditions.
| Code: | Global Static None
------ ------ ----
Pos 2 3 2
Focus 1 1 1
FocusV 1 1 n/a
Enabled 1 3 1
Visable 1 3 1
hWnd 1 3 1
X Titles: Type of variable assigned to GUI object
Y Titles: GUIControlGet sub-command
Legend:
1 - Uses local, static, or global variables (Expected/Desired result)
2 - Uses global variables only
3 - Does not work under any condition
|
Thank you for your consideration. Let me know if you need any additional information.
Edit 20080319: Correction to the legend description #3.
Last edited by jballi on Wed Mar 19, 2008 8:48 pm; edited 1 time in total |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10450
|
Posted: Fri Mar 07, 2008 4:37 pm Post subject: |
|
|
I don't see anything in the AutoHotkey code that can be fixed other than a complete redesign. However, if the documentation is incomplete about these limitations, I'd appreciate suggestions about how to improve it.
Thanks for your research. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|